Exemple #1
0
/*
 * wbkgd --
 *	Set new background and new background attributes.
 */
int
wbkgd(WINDOW *win, chtype ch)
{
	int	y, x;

#ifdef DEBUG
	__CTRACE(__CTRACE_ATTR, "wbkgd: (%p), '%s', %08x\n",
	    win, unctrl(ch & +__CHARTEXT), ch & __ATTRIBUTES);
#endif

	/* Background attributes (check colour). */
	if (__using_color && !(ch & __COLOR))
		ch |= __default_color;

	win->battr = (attr_t) ch & __ATTRIBUTES;
	wbkgdset(win, ch);
	for (y = 0; y < win->maxy; y++)
		for (x = 0; x < win->maxx; x++) {
			/* Copy character if space */
			if (ch & A_CHARTEXT && win->alines[y]->line[x].ch == ' ')
				win->alines[y]->line[x].ch = ch & __CHARTEXT;
			/* Merge attributes */
			if (win->alines[y]->line[x].attr & __ALTCHARSET)
				win->alines[y]->line[x].attr =
				    (ch & __ATTRIBUTES) | __ALTCHARSET;
			else
				win->alines[y]->line[x].attr =
				    ch & __ATTRIBUTES;
#ifdef HAVE_WCHAR
			SET_WCOL(win->alines[y]->line[x], 1);
#endif
		}
	__touchwin(win);
	return(OK);
}
Exemple #2
0
/*
 * wbkgd --
 *	Set new background and new background attributes.
 */
int
wbkgd(WINDOW *win, chtype ch)
{
	int	y, x;

	/* Background attributes (check colour). */
	if (__using_color && !(ch & __COLOR))
		ch |= __default_color;

	win->battr = (attr_t) ch & __ATTRIBUTES;
	wbkgdset(win, ch);
	for (y = 0; y < win->maxy; y++)
		for (x = 0; x < win->maxx; x++) {
			/* Copy character if space */
			if (ch & A_CHARTEXT && win->alines[y]->line[x].ch == ' ')
				win->alines[y]->line[x].ch = ch & __CHARTEXT;
			/* Merge attributes */
			if (win->alines[y]->line[x].attr & __ALTCHARSET)
				win->alines[y]->line[x].attr =
				    (ch & __ATTRIBUTES) | __ALTCHARSET;
			else
				win->alines[y]->line[x].attr =
				    ch & __ATTRIBUTES;
			SET_WCOL(win->alines[y]->line[x], 1);
		}
	__touchwin(win);
	return(OK);
}
Exemple #3
0
WINDOW *
__newwin(SCREEN *screen, int nlines, int ncols, int by, int bx, int ispad)
{
	WINDOW *win;
	__LINE *lp;
	int     i, j;
	int	maxy, maxx;
	__LDATA *sp;

	if (by < 0 || bx < 0)
		return (NULL);

	maxy = nlines > 0 ? nlines : LINES - by + nlines;
	maxx = ncols > 0 ? ncols : COLS - bx + ncols;

	if ((win = __makenew(screen, maxy, maxx, by, bx, 0, ispad)) == NULL)
		return (NULL);

	win->bch = ' ';
	if (__using_color)
		win->battr = __default_color;
	else
		win->battr = 0;
	win->nextp = win;
	win->ch_off = 0;
	win->orig = NULL;
	win->reqy = nlines;
	win->reqx = ncols;

#ifdef DEBUG
	__CTRACE(__CTRACE_WINDOW, "newwin: win->ch_off = %d\n", win->ch_off);
#endif

	for (i = 0; i < maxy; i++) {
		lp = win->alines[i];
		if (ispad)
			lp->flags = __ISDIRTY;
		else
			lp->flags = 0;
		for (sp = lp->line, j = 0; j < maxx; j++, sp++) {
			sp->attr = 0;
#ifndef HAVE_WCHAR
			sp->ch = win->bch;
#else
			sp->ch = ( wchar_t )btowc(( int ) win->bch );
			sp->nsp = NULL;
			SET_WCOL( *sp, 1 );
#endif /* HAVE_WCHAR */
		}
		lp->hash = __hash((char *)(void *)lp->line,
		    (size_t) (ncols * __LDATASIZE));
	}
	return (win);
}
Exemple #4
0
/*
 * werase --
 *	Erases everything on the window.
 */
int
werase(WINDOW *win)
{

	int     y;
	__LDATA *sp, *end, *start;
	attr_t	attr;

#ifdef DEBUG
	__CTRACE(__CTRACE_ERASE, "werase: (%p)\n", win);
#endif
	if (win != curscr)
		attr = win->battr & __ATTRIBUTES;
	else
		attr = 0;
	for (y = 0; y < win->maxy; y++) {
		start = win->alines[y]->line;
		end = &start[win->maxx];
		for (sp = start; sp < end; sp++)
#ifndef HAVE_WCHAR
			if (sp->ch != win->bch || sp->attr != 0) {
#else
			if (sp->ch != ( wchar_t )btowc(( int ) win->bch ) ||
			    (sp->attr & WA_ATTRIBUTES) != 0 || sp->nsp) {
#endif /* HAVE_WCHAR */
				if (sp->attr & __ALTCHARSET)
					sp->attr = attr | __ALTCHARSET;
				else
					sp->attr = attr;
#ifdef HAVE_WCHAR
				sp->ch = ( wchar_t )btowc(( int ) win->bch);
				if (_cursesi_copy_nsp(win->bnsp, sp) == ERR)
					return ERR;
				SET_WCOL( *sp, 1 );
#else
				sp->ch = win->bch;
#endif /* HAVE_WCHAR */
			}
	}
	/*
	 * Mark the whole window as changed in case we have overlapping
	 * windows - this will result in the (intended) clearing of the
	 * screen over the area covered by the window. */
	__touchwin(win);
	wmove(win, 0, 0);
	return (OK);
}
Exemple #5
0
/*
 * wdelch --
 *	Do a delete-char on the line, leaving (cury, curx) unchanged.
 */
int
wdelch(WINDOW *win)
{
	__LDATA *end, *temp1, *temp2;

	int cw, sx;
	nschar_t *np, *tnp;

	end = &win->alines[win->cury]->line[win->maxx - 1];
	sx = win->curx;
	temp1 = &win->alines[win->cury]->line[win->curx];
	cw = WCOL( *temp1 );
	if ( cw < 0 ) {
		temp1 += cw;
		sx += cw;
		cw = WCOL( *temp1 );
	}
	np = temp1->nsp;
	if (np) {
		while ( np ) {
			tnp = np->next;
			free( np );
			np = tnp;
		}
		temp1->nsp = NULL;
	}
	if ( sx + cw < win->maxx ) {
		temp2 = temp1 + cw;
		while ( temp1 < end - ( cw - 1 )) {
			( void )memcpy( temp1, temp2, sizeof( __LDATA ));
			temp1++, temp2++;
		}
	}
	while ( temp1 <= end ) {
		temp1->ch = ( wchar_t )btowc(( int ) win->bch );
		temp1->attr = 0;
		if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR)
			return ERR;
		SET_WCOL(*temp1, 1);
		temp1++;
	}
	__touchline(win, (int) win->cury, sx, (int) win->maxx - 1);
	return (OK);
}
Exemple #6
0
/*
 * winsnstr --
 *	Do an insert-n-string on the line, leaving (cury, curx) unchanged.
 *	Performs wrapping.
 */
int
winsnstr(WINDOW *win, const char *str, int n)
{
	__LDATA	*end, *temp1, *temp2;
	const char *scp;
	int len, x;
	__LINE *lnp;
#ifdef HAVE_WCHAR
	nschar_t *np, *tnp;
#endif /* HAVE_WCHAR */

	/* find string length */
	if ( n > 0 )
		for ( scp = str, len = 0; n-- && *scp++; ++len );
	else
		for ( scp = str, len = 0; *scp++; ++len );
#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT, "winsnstr: len = %d\n", len);
#endif /* DEBUG */

	/* move string */
	end = &win->alines[win->cury]->line[win->curx];
	if ( len < win->maxx - win->curx ) {
#ifdef DEBUG
		__CTRACE(__CTRACE_INPUT, "winsnstr: shift %d cells\n", len);
#endif /* DEBUG */
		temp1 = &win->alines[win->cury]->line[win->maxx - 1];
		temp2 = temp1 - len;
		while (temp2 >= end) {
#ifdef HAVE_WCHAR
			np = temp1->nsp;
			if (np){
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				temp1->nsp = NULL;
			}
#endif /* HAVE_WCHAR */
			(void) memcpy(temp1, temp2, sizeof(__LDATA));
			temp1--, temp2--;
		}
	}

	for ( scp = str, temp1 = end, x = win->curx;
			*scp && x < len + win->curx && x < win->maxx;
			scp++, temp1++, x++ ) {
		temp1->ch = (wchar_t)*scp & __CHARTEXT;
		temp1->attr = win->wattr;
#ifdef HAVE_WCHAR
		SET_WCOL( *temp1, 1 );
#endif /* HAVE_WCHAR */
	}
#ifdef DEBUG
	{
		int i;

		for ( i = win->curx; i < win->curx + len; i++ ) {
			__CTRACE(__CTRACE_INPUT,
			    "winsnstr: (%d,%d)=('%c',%x)\n", win->cury, i,
			    win->alines[win->cury]->line[i].ch,
			    win->alines[win->cury]->line[i].attr);
		}
	}
#endif /* DEBUG */
	lnp = win->alines[ win->cury ];
	lnp->flags |= __ISDIRTY;
	if ( win->ch_off < *lnp->firstchp )
		*lnp->firstchp = win->ch_off;
	if ( win->ch_off + win->maxx - 1 > *lnp->lastchp )
		*lnp->lastchp = win->ch_off + win->maxx - 1;
	__touchline(win, (int)win->cury, (int)win->curx, (int)win->maxx - 1);
	return OK;
}
Exemple #7
0
/*
 * _cursesi_addwchar -
 *	Internal function to add a wide character and update the row
 * and column positions.
 */
int
_cursesi_addwchar(WINDOW *win, __LINE **lnp, int *y, int *x,
		  const cchar_t *wch)
{
#ifndef HAVE_WCHAR
	return (ERR);
#else
	int sx = 0, ex = 0, cw = 0, i = 0, newx = 0;
	__LDATA *lp = &win->alines[*y]->line[*x], *tp = NULL;
	nschar_t *np = NULL;
	cchar_t cc;
	attr_t attributes;

	/* special characters handling */
	switch (wch->vals[0]) {
	case L'\b':
		if (--*x < 0)
			*x = 0;
		win->curx = *x;
		return OK;
	case L'\r':
		*x = 0;
		return OK;
	case L'\n':
		wclrtoeol(win);
		PSYNCH_IN;
		*x = 0;
		(*lnp)->flags &= ~__ISPASTEOL;
		if (*y == win->scr_b) {
			if (!(win->flags & __SCROLLOK))
				return ERR;
			PSYNCH_OUT;
			scroll(win);
			PSYNCH_IN;
		} else {
			(*y)++;
		}
		PSYNCH_OUT;
		return OK;
	case L'\t':
		cc.vals[0] = L' ';
		cc.elements = 1;
		cc.attributes = win->wattr;
		for (i = 0; i < 8 - (*x % 8); i++) {
			if (wadd_wch(win, &cc) == ERR)
				return ERR;
		}
		return OK;
	}

	/* check for non-spacing character */
	if (!wcwidth(wch->vals[0])) {
#ifdef DEBUG
		__CTRACE(__CTRACE_INPUT,
			 "_cursesi_addwchar: char '%c' is non-spacing\n",
			 wch->vals[0]);
#endif /* DEBUG */
		cw = WCOL(*lp);
		if (cw < 0) {
			lp += cw;
			*x += cw;
		}
		for (i = 0; i < wch->elements; i++) {
			if (!(np = (nschar_t *) malloc(sizeof(nschar_t))))
				return ERR;;
			np->ch = wch->vals[i];
			np->next = lp->nsp;
			lp->nsp = np;
		}
		(*lnp)->flags |= __ISDIRTY;
		newx = *x + win->ch_off;
		if (newx < *(*lnp)->firstchp)
			*(*lnp)->firstchp = newx;
		if (newx > *(*lnp)->lastchp)
			*(*lnp)->lastchp = newx;
		__touchline(win, *y, *x, *x);
		return OK;
	}
	/* check for new line first */
	if ((*lnp)->flags & __ISPASTEOL) {
		*x = 0;
		(*lnp)->flags &= ~__ISPASTEOL;
		if (*y == win->scr_b) {
			if (!(win->flags & __SCROLLOK))
				return ERR;
			PSYNCH_OUT;
			scroll(win);
			PSYNCH_IN;
		} else {
			(*y)++;
		}
		(*lnp) = win->alines[*y];
		lp = &win->alines[*y]->line[*x];
	}
	/* clear out the current character */
	cw = WCOL(*lp);
	if (cw >= 0) {
		sx = *x;
	} else {
		for (sx = *x - 1; sx >= max(*x + cw, 0); sx--) {
#ifdef DEBUG
			__CTRACE(__CTRACE_INPUT,
				 "_cursesi_addwchar: clear current char (%d,%d)\n",
				 *y, sx);
#endif /* DEBUG */
			tp = &win->alines[*y]->line[sx];
			tp->ch = (wchar_t) btowc((int) win->bch);
			if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
				return ERR;

			tp->attr = win->battr;
			SET_WCOL(*tp, 1);
		}
		sx = *x + cw;
		(*lnp)->flags |= __ISDIRTY;
		newx = sx + win->ch_off;
		if (newx < *(*lnp)->firstchp)
			*(*lnp)->firstchp = newx;
	}

	/* check for enough space before the end of line */
	cw = wcwidth(wch->vals[0]);
	if (cw < 0)
		cw = 1;
	if (cw > win->maxx - *x) {
#ifdef DEBUG
		__CTRACE(__CTRACE_INPUT,
			 "_cursesi_addwchar: clear EOL (%d,%d)\n",
			 *y, *x);
#endif /* DEBUG */
		(*lnp)->flags |= __ISDIRTY;
		newx = *x + win->ch_off;
		if (newx < *(*lnp)->firstchp)
			*(*lnp)->firstchp = newx;
		for (tp = lp; *x < win->maxx; tp++, (*x)++) {
			tp->ch = (wchar_t) btowc((int) win->bch);
			if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
				return ERR;
			tp->attr = win->battr;
			SET_WCOL(*tp, 1);
		}
		newx = win->maxx - 1 + win->ch_off;
		if (newx > *(*lnp)->lastchp)
			*(*lnp)->lastchp = newx;
		__touchline(win, *y, sx, (int) win->maxx - 1);
		sx = *x = 0;
		if (*y == win->scr_b) {
			if (!(win->flags & __SCROLLOK))
				return ERR;
			PSYNCH_OUT;
			scroll(win);
			PSYNCH_IN;
		} else {
			(*y)++;
		}
		lp = &win->alines[*y]->line[0];
		(*lnp) = win->alines[*y];
	}
	win->cury = *y;

	/* add spacing character */
#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT,
		 "_cursesi_addwchar: add character (%d,%d) 0x%x\n",
		 *y, *x, wch->vals[0]);
#endif /* DEBUG */
	(*lnp)->flags |= __ISDIRTY;
	newx = *x + win->ch_off;
	if (newx < *(*lnp)->firstchp)
		*(*lnp)->firstchp = newx;
	if (lp->nsp) {
		__cursesi_free_nsp(lp->nsp);
		lp->nsp = NULL;
	}

	lp->ch = wch->vals[0];

	attributes = (win->wattr | wch->attributes)
		& (WA_ATTRIBUTES & ~__COLOR);
	if (wch->attributes & __COLOR)
		attributes |= wch->attributes & __COLOR;
	else if (win->wattr & __COLOR)
		attributes |= win->wattr & __COLOR;
	if (attributes & __COLOR)
		lp->attr = attributes | (win->battr & ~__COLOR);
	else
		lp->attr = attributes | win->battr;

	SET_WCOL(*lp, cw);

#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT,
		 "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n",
		 lp->ch, lp->attr);
#endif /* DEBUG */

	if (wch->elements > 1) {
		for (i = 1; i < wch->elements; i++) {
			np = (nschar_t *)malloc(sizeof(nschar_t));
			if (!np)
				return ERR;;
			np->ch = wch->vals[i];
			np->next = lp->nsp;
#ifdef DEBUG
			__CTRACE(__CTRACE_INPUT,
			    "_cursesi_addwchar: add non-spacing char 0x%x\n", np->ch);
#endif /* DEBUG */
			lp->nsp = np;
		}
	}
#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: non-spacing list header: %p\n",
	    lp->nsp);
	__CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add rest columns (%d:%d)\n",
		sx + 1, sx + cw - 1);
#endif /* DEBUG */
	for (tp = lp + 1, *x = sx + 1; *x - sx <= cw - 1; tp++, (*x)++) {
		if (tp->nsp) {
			__cursesi_free_nsp(tp->nsp);
			tp->nsp = NULL;
		}
		tp->ch = wch->vals[0];
		tp->attr = lp->attr & WA_ATTRIBUTES;
		/* Mark as "continuation" cell */
		tp->attr |= __WCWIDTH;
	}
	if (*x == win->maxx) {
		(*lnp)->flags |= __ISPASTEOL;
		newx = win->maxx - 1 + win->ch_off;
		if (newx > *(*lnp)->lastchp)
			*(*lnp)->lastchp = newx;
		__touchline(win, *y, sx, (int) win->maxx - 1);
		win->curx = sx;
	} else {
		win->curx = *x;

		/* clear the remining of the current characer */
		if (*x && *x < win->maxx) {
			ex = sx + cw;
			tp = &win->alines[*y]->line[ex];
			while (ex < win->maxx && WCOL(*tp) < 0) {
#ifdef DEBUG
				__CTRACE(__CTRACE_INPUT,
					 "_cursesi_addwchar: clear "
					 "remaining of current char (%d,%d)nn",
					 *y, ex);
#endif /* DEBUG */
				tp->ch = (wchar_t) btowc((int) win->bch);
				if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
					return ERR;
				tp->attr = win->battr;
				SET_WCOL(*tp, 1);
				tp++, ex++;
			}
			newx = ex - 1 + win->ch_off;
			if (newx > *(*lnp)->lastchp)
				*(*lnp)->lastchp = newx;
			__touchline(win, *y, sx, ex - 1);
		}
	}

#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT, "add_wch: %d : 0x%x\n", lp->ch, lp->attr);
#endif /* DEBUG */
	return OK;
#endif
}
Exemple #8
0
int 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)
{
#ifndef HAVE_WCHAR
	return ERR;
#else
	int	 endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw;
	cchar_t left, right, bottom, top, topleft, topright, botleft, botright;
	nschar_t *np, *tnp;

	if ( ls && wcwidth( ls->vals[ 0 ]))
		memcpy( &left, ls, sizeof( cchar_t ));
	else
		memcpy( &left, WACS_VLINE, sizeof( cchar_t ));
	if ( rs && wcwidth( rs->vals[ 0 ]))
		memcpy( &right, rs, sizeof( cchar_t ));
	else
		memcpy( &right, WACS_VLINE, sizeof( cchar_t ));
	if ( ts && wcwidth( ts->vals[ 0 ]))
		memcpy( &top, ts, sizeof( cchar_t ));
	else
		memcpy( &top, WACS_HLINE, sizeof( cchar_t ));
	if ( bs && wcwidth( bs->vals[ 0 ]))
		memcpy( &bottom, bs, sizeof( cchar_t ));
	else
		memcpy( &bottom, WACS_HLINE, sizeof( cchar_t ));
	if ( tl && wcwidth( tl->vals[ 0 ]))
		memcpy( &topleft, tl, sizeof( cchar_t ));
	else
		memcpy( &topleft, WACS_ULCORNER, sizeof( cchar_t ));
	if ( tr && wcwidth( tr->vals[ 0 ]))
		memcpy( &topright, tr, sizeof( cchar_t ));
	else
		memcpy( &topright, WACS_URCORNER, sizeof( cchar_t ));
	if ( bl && wcwidth( bl->vals[ 0 ]))
		memcpy( &botleft, bl, sizeof( cchar_t ));
	else
		memcpy( &botleft, WACS_LLCORNER, sizeof( cchar_t ));
	if ( br && wcwidth( br->vals[ 0 ]))
		memcpy( &botright, br, sizeof( cchar_t ));
	else
		memcpy( &botright, WACS_LRCORNER, sizeof( cchar_t ));

#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n",
	    left.vals[0], left.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n",
	    right.vals[0], right.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n",
	    top.vals[0], top.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n",
	    bottom.vals[0], bottom.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n",
	    topleft.vals[0], topleft.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n",
	    topright.vals[0], topright.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n",
	    botleft.vals[0], botleft.attributes );
	__CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n",
	    botright.vals[0], botright.attributes );
#endif

	/* Merge window attributes */
	left.attributes |= (left.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	left.attributes |= (left.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	right.attributes |= (right.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	right.attributes |= (right.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	top.attributes |= (top.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	top.attributes |= (top.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	bottom.attributes |= (bottom.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	bottom.attributes |= (bottom.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	topleft.attributes |= (topleft.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	topleft.attributes |= (topleft.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	topright.attributes |= (topright.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	topright.attributes |= (topright.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	botleft.attributes |= (botleft.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	botleft.attributes |= (botleft.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;
	botright.attributes |= (botright.attributes & __COLOR) ?
		(win->wattr & ~__COLOR) : win->wattr;
	botright.attributes |= (botright.attributes & __COLOR) ?
		(win->battr & ~__COLOR) : win->battr;

	endx = win->maxx - 1;
	endy = win->maxy - 1;

	/* Sides */
	for (i = 1; i < endy; i++) {
		/* left border */
		cw = wcwidth( left.vals[ 0 ]);
		if (cw < 0)
			cw = 1;
		for ( j = 0; j < cw; j++ ) {
			win->alines[i]->line[j].ch = left.vals[ 0 ];
			win->alines[i]->line[j].attr = left.attributes;
			np = win->alines[i]->line[j].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[i]->line[j].nsp = NULL;
			}
			if ( j )
				SET_WCOL( win->alines[i]->line[j], -j );
			else {
				SET_WCOL( win->alines[i]->line[j], cw );
				if ( left.elements > 1 ) {
					for (k = 1; k < left.elements; k++) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = left.vals[ k ];
						np->next = win->alines[i]->line[j].nsp;
						win->alines[i]->line[j].nsp
							= np;
					}
				}
			}
		}
		for ( j = cw; WCOL( win->alines[i]->line[j]) < 0; j++ ) {
#ifdef DEBUG
			__CTRACE(__CTRACE_INPUT,
			    "wborder_set: clean out partial char[%d]", j);
#endif /* DEBUG */
			win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch);
			if (_cursesi_copy_nsp(win->bnsp,
					      &win->alines[i]->line[j]) == ERR)
				return ERR;
			SET_WCOL( win->alines[i]->line[j], 1 );
		}
		/* right border */
		cw = wcwidth( right.vals[ 0 ]);
		if (cw < 0)
			cw = 1;
		pcw = WCOL( win->alines[i]->line[endx - cw]);
		for ( j = endx - cw + 1; j <= endx; j++ ) {
			win->alines[i]->line[j].ch = right.vals[ 0 ];
			win->alines[i]->line[j].attr = right.attributes;
			np = win->alines[i]->line[j].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[i]->line[j].nsp = NULL;
			}
			if ( j == endx - cw + 1 ) {
				SET_WCOL( win->alines[i]->line[j], cw );
				if ( right.elements > 1 ) {
					for (k = 1; k < right.elements; k++) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = right.vals[ k ];
						np->next = win->alines[i]->line[j].nsp;
						win->alines[i]->line[j].nsp
							= np;
					}
				}
			} else
				SET_WCOL( win->alines[i]->line[j],
					endx - cw + 1 - j );
		}
		if ( pcw != 1 ) {
#ifdef DEBUG
			__CTRACE(__CTRACE_INPUT,
			    "wborder_set: clean out partial chars[%d:%d]",
			    endx - cw + pcw, endx - cw );
#endif /* DEBUG */
			k = pcw < 0 ? endx -cw + pcw : endx - cw;
			for ( j = endx - cw; j >= k; j-- ) {
				win->alines[i]->line[j].ch
					= (wchar_t)btowc(win->bch);
				if (_cursesi_copy_nsp(win->bnsp,
					       &win->alines[i]->line[j]) == ERR)
					return ERR;
				win->alines[i]->line[j].attr = win->battr;
				SET_WCOL( win->alines[i]->line[j], 1 );
			}
		}
	}
	tlcw = wcwidth( topleft.vals[ 0 ]);
	if (tlcw < 0)
		tlcw = 1;
	blcw = wcwidth( botleft.vals[ 0 ]);
	if (blcw < 0)
		blcw = 1;
	trcw = wcwidth( topright.vals[ 0 ]);
	if (trcw < 0)
		trcw = 1;
	brcw = wcwidth( botright.vals[ 0 ]);
	if (brcw < 0)
		brcw = 1;
	/* upper border */
	cw = wcwidth( top.vals[ 0 ]);
	if (cw < 0)
		cw = 1;
	for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) {
		for ( j = 0; j < cw; j++ ) {
			win->alines[ 0 ]->line[i + j].ch = top.vals[ 0 ];
			win->alines[ 0 ]->line[i + j].attr = top.attributes;
			np = win->alines[ 0 ]->line[i + j].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[ 0 ]->line[i + j].nsp = NULL;
			}
			if ( j )
				SET_WCOL( win->alines[ 0 ]->line[ i + j ], -j );
			else {
				SET_WCOL( win->alines[ 0 ]->line[ i + j ], cw );
				if ( top.elements > 1 ) {
					for ( k = 1; k < top.elements; k++ ) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = top.vals[ k ];
						np->next = win->alines[0]->line[i + j].nsp;
						win->alines[0]->line[i + j].nsp
							= np;
					}
				}
			}
		}
	}
	while ( i <= endx - trcw ) {
		win->alines[0]->line[i].ch =
			( wchar_t )btowc(( int ) win->bch );
		if (_cursesi_copy_nsp(win->bnsp,
				      &win->alines[0]->line[i]) == ERR)
			return ERR;
		win->alines[ 0 ]->line[ i ].attr = win->battr;
		SET_WCOL( win->alines[ 0 ]->line[ i ], 1 );
		i++;
	}
	/* lower border */
	for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) {
		for ( j = 0; j < cw; j++ ) {
			win->alines[ endy ]->line[i + j].ch = bottom.vals[ 0 ];
			win->alines[endy]->line[i + j].attr = bottom.attributes;
			np = win->alines[ endy ]->line[i + j].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[ endy ]->line[i + j].nsp = NULL;
			}
			if ( j )
				SET_WCOL( win->alines[endy]->line[i + j], -j);
			else {
				SET_WCOL( win->alines[endy]->line[i + j], cw );
				if ( bottom.elements > 1 ) {
					for ( k = 1; k < bottom.elements;
							k++ ) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = bottom.vals[ k ];
						np->next = win->alines[endy]->line[i + j].nsp;
						win->alines[endy]->line[i + j].nsp = np;
					}
				}
			}
		}
	}
	while ( i <= endx - brcw ) {
		win->alines[endy]->line[i].ch =
			(wchar_t)btowc((int) win->bch );
		if (_cursesi_copy_nsp(win->bnsp,
				      &win->alines[endy]->line[i]) == ERR)
			return ERR;
		win->alines[ endy ]->line[ i ].attr = win->battr;
		SET_WCOL( win->alines[ endy ]->line[ i ], 1 );
		i++;
	}

	/* Corners */
	if (!(win->maxx == LINES && win->maxy == COLS &&
		(win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) {
		for ( i = 0; i < tlcw; i++ ) {
			win->alines[ 0 ]->line[i].ch = topleft.vals[ 0 ];
			win->alines[ 0 ]->line[i].attr = topleft.attributes;
			np = win->alines[ 0 ]->line[i].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[ 0 ]->line[i].nsp = NULL;
			}
			if ( i )
				SET_WCOL( win->alines[ 0 ]->line[ i ], -i );
			else {
				SET_WCOL( win->alines[ 0 ]->line[ i ], tlcw );
				if ( topleft.elements > 1 ) {
					for ( k = 1; k < topleft.elements;
							k++ ) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = topleft.vals[ k ];
						np->next = win->alines[ 0 ]->line[i].nsp;
						win->alines[ 0 ]->line[i].nsp
							= np;
					}
				}
			}
		}
		for ( i = endx - trcw + 1; i <= endx; i++ ) {
			win->alines[ 0 ]->line[i].ch = topright.vals[ 0 ];
			win->alines[ 0 ]->line[i].attr = topright.attributes;
			np = win->alines[ 0 ]->line[i].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[ 0 ]->line[i].nsp = NULL;
			}
			if ( i == endx - trcw + 1 ) {
				SET_WCOL( win->alines[ 0 ]->line[ i ], trcw );
				if ( topright.elements > 1 ) {
					for ( k = 1; k < topright.elements;
							k++ ) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = topright.vals[ k ];
						np->next = win->alines[0]->line[i].nsp;
						win->alines[ 0 ]->line[i].nsp
							= np;
					}
				}
			} else
				SET_WCOL( win->alines[ 0 ]->line[ i ],
					  endx - trcw + 1 - i );
		}
		for ( i = 0; i < blcw; i++ ) {
			win->alines[ endy ]->line[i].ch = botleft.vals[ 0 ];
			win->alines[ endy ]->line[i].attr = botleft.attributes;
			np = win->alines[ endy ]->line[i].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[ endy ]->line[i].nsp = NULL;
			}
			if ( i )
				SET_WCOL( win->alines[endy]->line[i], -i );
			else {
				SET_WCOL( win->alines[endy]->line[i], blcw );
				if ( botleft.elements > 1 ) {
					for ( k = 1; k < botleft.elements;
							k++ ) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = botleft.vals[ k ];
						np->next = win->alines[endy]->line[i].nsp;
						win->alines[endy]->line[i].nsp
							= np;
					}
				}
			}
		}
		for ( i = endx - brcw + 1; i <= endx; i++ ) {
			win->alines[ endy ]->line[i].ch = botright.vals[ 0 ];
			win->alines[ endy ]->line[i].attr = botright.attributes;
			np = win->alines[ endy ]->line[i].nsp;
			if (np) {
				while ( np ) {
					tnp = np->next;
					free( np );
					np = tnp;
				}
				win->alines[ endy ]->line[i].nsp = NULL;
			}
			if ( i == endx - brcw + 1 ) {
				SET_WCOL( win->alines[ endy ]->line[ i ],
					  brcw );
				if ( botright.elements > 1 ) {
					for ( k = 1; k < botright.elements; k++ ) {
						np = malloc(sizeof(nschar_t));
						if (!np)
							return ERR;
						np->ch = botright.vals[ k ];
						np->next = win->alines[endy]->line[i].nsp;
						win->alines[endy]->line[i].nsp
							= np;
					}
				}
			} else
				SET_WCOL( win->alines[ endy ]->line[ i ],
					endx - brcw + 1 - i );
		}
	}
	__touchwin(win);
	return (OK);
#endif /* HAVE_WCHAR */
}
Exemple #9
0
/*
 * __resizewin --
 *	Resize the given window.
 */
static int
__resizewin(WINDOW *win, int nlines, int ncols)
{
	__LINE			*lp, *olp, **newlines, *newlspace;
	__LDATA			*sp;
	__LDATA			*newwspace;
	int			 i, j;
	int			 y, x;
	WINDOW			*swin;

#ifdef	DEBUG
	__CTRACE(__CTRACE_WINDOW, "resize: (%p, %d, %d)\n", win, nlines, ncols);
	__CTRACE(__CTRACE_WINDOW, "resize: win->wattr = %08x\n", win->wattr);
	__CTRACE(__CTRACE_WINDOW, "resize: win->flags = %#.4x\n", win->flags);
	__CTRACE(__CTRACE_WINDOW, "resize: win->maxy = %d\n", win->maxy);
	__CTRACE(__CTRACE_WINDOW, "resize: win->maxx = %d\n", win->maxx);
	__CTRACE(__CTRACE_WINDOW, "resize: win->begy = %d\n", win->begy);
	__CTRACE(__CTRACE_WINDOW, "resize: win->begx = %d\n", win->begx);
	__CTRACE(__CTRACE_WINDOW, "resize: win->scr_t = %d\n", win->scr_t);
	__CTRACE(__CTRACE_WINDOW, "resize: win->scr_b = %d\n", win->scr_b);
#endif

	/*
	 * free up any non-spacing storage before we lose the
	 * pointers...
	 */
#ifdef HAVE_WCHAR
	__cursesi_win_free_nsp(win);
#endif

	if (nlines <= 0 || ncols <= 0)
		nlines = ncols = 0;
	else {
		/* Reallocate line pointer array and line space. */
		newlines = realloc(win->alines, nlines * sizeof(__LINE *));
		if (newlines == NULL)
			return ERR;
		win->alines = newlines;

		newlspace = realloc(win->lspace, nlines * sizeof(__LINE));
		if (newlspace == NULL)
			return ERR;
		win->lspace = newlspace;
	}

	/* Don't allocate window and line space if it's a subwindow */
	if (win->orig == NULL) {
		/*
		 * Allocate window space in one chunk.
		 */
		if (ncols != 0) {
			newwspace = realloc(win->wspace,
					    ncols * nlines * sizeof(__LDATA));
			if (newwspace == NULL)
				return ERR;
			win->wspace = newwspace;
		}

		/*
		 * Point line pointers to line space, and lines themselves into
		 * window space.
		 */
		for (lp = win->lspace, i = 0; i < nlines; i++, lp++) {
			win->alines[i] = lp;
			lp->line = &win->wspace[i * ncols];
#ifdef DEBUG
			lp->sentinel = SENTINEL_VALUE;
#endif
			lp->firstchp = &lp->firstch;
			lp->lastchp = &lp->lastch;
			lp->firstch = 0;
			lp->lastch = ncols - 1;
			lp->flags = __ISDIRTY;
		}
	} else {

		win->ch_off = win->begx - win->orig->begx;
		  /* Point line pointers to line space. */
		for (lp = win->lspace, i = 0; i < nlines; i++, lp++) {
			win->alines[i] = lp;
			olp = win->orig->alines[i + win->begy - win->orig->begy];
			lp->line = &olp->line[win->ch_off];
#ifdef DEBUG
			lp->sentinel = SENTINEL_VALUE;
#endif
			lp->firstchp = &olp->firstch;
			lp->lastchp = &olp->lastch;
			lp->flags = __ISDIRTY;
		}
	}


	win->cury = win->curx = 0;
	win->maxy = nlines;
	win->maxx = ncols;
	win->scr_b = win->maxy - 1;
	__swflags(win);

	  /*
	   * we must zot the window contents otherwise lines may pick
	   * up attributes from the previous line when the window is
	   * made smaller.  The client will redraw the window anyway
	   * so this is no big deal.
	   */
	for (i = 0; i < win->maxy; i++) {
		lp = win->alines[i];
		for (sp = lp->line, j = 0; j < win->maxx; j++, sp++) {
			sp->attr = 0;
#ifndef HAVE_WCHAR
			sp->ch = win->bch;
#else
			sp->ch = ( wchar_t )btowc(( int ) win->bch );
			sp->nsp = NULL;
			if (_cursesi_copy_nsp(win->bnsp, sp) == ERR)
				return ERR;
			SET_WCOL( *sp, 1 );
#endif /* HAVE_WCHAR */
		}
		lp->hash = __hash((char *)(void *)lp->line,
				  (size_t) (ncols * __LDATASIZE));
	}

#ifdef DEBUG
	__CTRACE(__CTRACE_WINDOW, "resize: win->wattr = %08x\n", win->wattr);
	__CTRACE(__CTRACE_WINDOW, "resize: win->flags = %#.4x\n", win->flags);
	__CTRACE(__CTRACE_WINDOW, "resize: win->maxy = %d\n", win->maxy);
	__CTRACE(__CTRACE_WINDOW, "resize: win->maxx = %d\n", win->maxx);
	__CTRACE(__CTRACE_WINDOW, "resize: win->begy = %d\n", win->begy);
	__CTRACE(__CTRACE_WINDOW, "resize: win->begx = %d\n", win->begx);
	__CTRACE(__CTRACE_WINDOW, "resize: win->scr_t = %d\n", win->scr_t);
	__CTRACE(__CTRACE_WINDOW, "resize: win->scr_b = %d\n", win->scr_b);
#endif

	if (win->orig == NULL) {
		/* bound subwindows to new size and fixup their pointers */
		for (swin = win->nextp; swin != win; swin = swin->nextp) {
			y = swin->reqy;
			if (swin->begy > win->begy + win->maxy)
				swin->begy = win->begy + win->maxy - 1;
			if (swin->begy + y > win->begy + win->maxy)
				y = 0;
			if (y <= 0)
				y += win->begy + win->maxy - swin->begy;
			if (y < 1)
				y = 1;
			x = swin->reqx;
			if (swin->begx > win->begx + win->maxx)
				swin->begx = win->begx + win->maxx - 1;
			if (swin->begx + x > win->begx + win->maxx)
				x = 0;
			if (x <= 0)
				x += win->begy + win->maxx - swin->begx;
			if (x < 1)
				x = 1;
			__resizewin(swin, y, x);
		}
	}

	return OK;
}