Home | History | Annotate | Line # | Download | only in libcurses
addbytes.c revision 1.30.6.6
      1  1.30.6.6    blymn /*	$NetBSD: addbytes.c,v 1.30.6.6 2007/02/26 09:49:28 blymn Exp $	*/
      2      1.11    mikel 
      3       1.1      cgd /*
      4      1.10      cgd  * Copyright (c) 1987, 1993, 1994
      5       1.7      cgd  *	The Regents of the University of California.  All rights reserved.
      6       1.1      cgd  *
      7       1.1      cgd  * Redistribution and use in source and binary forms, with or without
      8       1.1      cgd  * modification, are permitted provided that the following conditions
      9       1.1      cgd  * are met:
     10       1.1      cgd  * 1. Redistributions of source code must retain the above copyright
     11       1.1      cgd  *    notice, this list of conditions and the following disclaimer.
     12       1.1      cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1      cgd  *    notice, this list of conditions and the following disclaimer in the
     14       1.1      cgd  *    documentation and/or other materials provided with the distribution.
     15      1.28      agc  * 3. Neither the name of the University nor the names of its contributors
     16       1.1      cgd  *    may be used to endorse or promote products derived from this software
     17       1.1      cgd  *    without specific prior written permission.
     18       1.1      cgd  *
     19       1.1      cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20       1.1      cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21       1.1      cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22       1.1      cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23       1.1      cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24       1.1      cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25       1.1      cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26       1.1      cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27       1.1      cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28       1.1      cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29       1.1      cgd  * SUCH DAMAGE.
     30       1.1      cgd  */
     31       1.1      cgd 
     32      1.11    mikel #include <sys/cdefs.h>
     33       1.1      cgd #ifndef lint
     34      1.11    mikel #if 0
     35      1.10      cgd static char sccsid[] = "@(#)addbytes.c	8.4 (Berkeley) 5/4/94";
     36      1.11    mikel #else
     37  1.30.6.6    blymn __RCSID("$NetBSD: addbytes.c,v 1.30.6.6 2007/02/26 09:49:28 blymn Exp $");
     38      1.11    mikel #endif
     39      1.13      mrg #endif				/* not lint */
     40       1.1      cgd 
     41  1.30.6.1    blymn #include <stdlib.h>
     42      1.10      cgd #include "curses.h"
     43      1.15    blymn #include "curses_private.h"
     44  1.30.6.3      jdc #ifdef DEBUG
     45  1.30.6.3      jdc #include <assert.h>
     46  1.30.6.3      jdc #endif
     47       1.1      cgd 
     48       1.7      cgd #define	SYNCH_IN	{y = win->cury; x = win->curx;}
     49       1.7      cgd #define	SYNCH_OUT	{win->cury = y; win->curx = x;}
     50  1.30.6.6    blymn #define	PSYNCH_IN	{*y = win->cury; *x = win->curx;}
     51  1.30.6.6    blymn #define	PSYNCH_OUT	{win->cury = *y; win->curx = *x;}
     52       1.3      alm 
     53      1.17    blymn #ifndef _CURSES_USE_MACROS
     54      1.17    blymn 
     55      1.17    blymn /*
     56      1.17    blymn  * addbytes --
     57      1.17    blymn  *      Add the character to the current position in stdscr.
     58      1.17    blymn  */
     59      1.17    blymn int
     60      1.17    blymn addbytes(const char *bytes, int count)
     61      1.17    blymn {
     62      1.17    blymn 	return __waddbytes(stdscr, bytes, count, 0);
     63      1.17    blymn }
     64      1.17    blymn 
     65      1.17    blymn /*
     66      1.17    blymn  * waddbytes --
     67      1.17    blymn  *      Add the character to the current position in the given window.
     68      1.17    blymn  */
     69      1.17    blymn int
     70      1.17    blymn waddbytes(WINDOW *win, const char *bytes, int count)
     71      1.17    blymn {
     72      1.17    blymn 	return __waddbytes(win, bytes, count, 0);
     73      1.17    blymn }
     74      1.17    blymn 
     75      1.17    blymn /*
     76      1.17    blymn  * mvaddbytes --
     77      1.17    blymn  *      Add the characters to stdscr at the location given.
     78      1.17    blymn  */
     79      1.17    blymn int
     80      1.17    blymn mvaddbytes(int y, int x, const char *bytes, int count)
     81      1.17    blymn {
     82      1.17    blymn 	return mvwaddbytes(stdscr, y, x, bytes, count);
     83      1.17    blymn }
     84      1.17    blymn 
     85      1.17    blymn /*
     86      1.17    blymn  * mvwaddbytes --
     87      1.17    blymn  *      Add the characters to the given window at the location given.
     88      1.17    blymn  */
     89      1.17    blymn int
     90      1.17    blymn mvwaddbytes(WINDOW *win, int y, int x, const char *bytes, int count)
     91      1.17    blymn {
     92      1.17    blymn 	if (wmove(win, y, x) == ERR)
     93      1.17    blymn 		return ERR;
     94      1.17    blymn 
     95      1.17    blymn 	return __waddbytes(win, bytes, count, 0);
     96      1.17    blymn }
     97      1.17    blymn 
     98      1.17    blymn #endif
     99      1.17    blymn 
    100       1.1      cgd /*
    101       1.5  mycroft  * waddbytes --
    102       1.5  mycroft  *	Add the character to the current position in the given window.
    103       1.1      cgd  */
    104       1.5  mycroft int
    105      1.17    blymn __waddbytes(WINDOW *win, const char *bytes, int count, attr_t attr)
    106       1.1      cgd {
    107  1.30.6.6    blymn 	int		 c, x, y, err;
    108      1.15    blymn 	__LINE		*lp;
    109  1.30.6.6    blymn #ifdef HAVE_WCHAR
    110  1.30.6.6    blymn 	int		n;
    111  1.30.6.6    blymn 	cchar_t		cc;
    112  1.30.6.6    blymn 	wchar_t		wc;
    113  1.30.6.6    blymn #endif
    114      1.23    blymn #ifdef DEBUG
    115      1.23    blymn 	int             i;
    116       1.5  mycroft 
    117      1.23    blymn 	for (i = 0; i < win->maxy; i++) {
    118      1.23    blymn 		assert(win->lines[i]->sentinel == SENTINEL_VALUE);
    119      1.23    blymn 	}
    120  1.30.6.6    blymn 
    121  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT, "ADDBYTES: add %d bytes\n", count);
    122      1.23    blymn #endif
    123  1.30.6.1    blymn 
    124  1.30.6.6    blymn 	err = OK;
    125       1.5  mycroft 	SYNCH_IN;
    126      1.23    blymn 	lp = win->lines[y];
    127       1.1      cgd 
    128  1.30.6.6    blymn 	while (count > 0) {
    129  1.30.6.6    blymn #ifndef HAVE_WCHAR
    130      1.11    mikel 		c = *bytes++;
    131       1.5  mycroft #ifdef DEBUG
    132  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT, "ADDBYTES('%c', %x) at (%d, %d)\n",
    133  1.30.6.6    blymn 		 c, attr, y, x);
    134       1.5  mycroft #endif
    135  1.30.6.6    blymn 		err = _cursesi_addbyte(win, &lp, &y, &x, c, attr);
    136  1.30.6.6    blymn 		count--;
    137  1.30.6.6    blymn #else
    138  1.30.6.6    blymn 		/*
    139  1.30.6.6    blymn 		 * For wide character support only, try and convert the
    140  1.30.6.6    blymn 		 * given string into a wide character - we do this because
    141  1.30.6.6    blymn 		 * this is how ncurses behaves (not that I think this is
    142  1.30.6.6    blymn 		 * actually the correct thing to do but if we don't do it
    143  1.30.6.6    blymn 		 * a lot of things that rely on this behaviour will break
    144  1.30.6.6    blymn 		 * and we will be blamed).  If the conversion succeeds
    145  1.30.6.6    blymn 		 * then we eat the n characters used to make the wide char
    146  1.30.6.6    blymn 		 * from the string.
    147  1.30.6.6    blymn 		 */
    148  1.30.6.6    blymn 		n = mbtowc(&wc, bytes, count);
    149  1.30.6.6    blymn 		if (n == 0)
    150       1.5  mycroft 			break;
    151  1.30.6.6    blymn 		else if (n < 0) { /* not a valid conversion just eat a char */
    152  1.30.6.6    blymn 			wc = *bytes;
    153  1.30.6.6    blymn 			n = 1;
    154  1.30.6.6    blymn 		}
    155  1.30.6.6    blymn 
    156  1.30.6.6    blymn 
    157  1.30.6.6    blymn #ifdef DEBUG
    158  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT,
    159  1.30.6.6    blymn 		 "ADDBYTES WIDE(0x%x, %x) at (%d, %d), ate %d bytes\n",
    160  1.30.6.6    blymn 		 (unsigned) wc, attr, y, x, n);
    161  1.30.6.6    blymn #endif
    162  1.30.6.6    blymn 		cc.vals[0] = wc;
    163  1.30.6.6    blymn 		cc.elements = 1;
    164  1.30.6.6    blymn 		cc.attributes = attr;
    165  1.30.6.6    blymn 		err = _cursesi_addwchar(win, &lp, &y, &x, &cc);
    166  1.30.6.6    blymn 		bytes += n;
    167  1.30.6.6    blymn 		count -= n;
    168  1.30.6.6    blymn #endif
    169  1.30.6.6    blymn 	}
    170  1.30.6.6    blymn 
    171  1.30.6.6    blymn 	SYNCH_OUT;
    172  1.30.6.6    blymn 
    173  1.30.6.6    blymn #ifdef DEBUG
    174  1.30.6.6    blymn 	for (i = 0; i < win->maxy; i++) {
    175  1.30.6.6    blymn 		assert(win->lines[i]->sentinel == SENTINEL_VALUE);
    176  1.30.6.6    blymn 	}
    177  1.30.6.6    blymn #endif
    178  1.30.6.6    blymn 
    179  1.30.6.6    blymn 	return (err);
    180  1.30.6.6    blymn }
    181  1.30.6.6    blymn 
    182  1.30.6.6    blymn /*
    183  1.30.6.6    blymn  * _cursesi_addbyte -
    184  1.30.6.6    blymn  *	Internal function to add a byte and update the row and column
    185  1.30.6.6    blymn  * positions as appropriate.  This function is only used in the narrow
    186  1.30.6.6    blymn  * character version of curses.
    187  1.30.6.6    blymn  */
    188  1.30.6.6    blymn int
    189  1.30.6.6    blymn _cursesi_addbyte(WINDOW *win, __LINE **lp, int *y, int *x, int c,
    190  1.30.6.6    blymn 		 attr_t attr)
    191  1.30.6.6    blymn {
    192  1.30.6.6    blymn 	static char	 blanks[] = "        ";
    193  1.30.6.6    blymn 	int		 newx;
    194  1.30.6.6    blymn 	attr_t		 attributes;
    195       1.5  mycroft 
    196  1.30.6.6    blymn 	switch (c) {
    197  1.30.6.6    blymn 	case '\t':
    198  1.30.6.6    blymn 		PSYNCH_OUT;
    199  1.30.6.6    blymn 		if (waddbytes(win, blanks, 8 - (*x % 8)) == ERR)
    200  1.30.6.6    blymn 			return (ERR);
    201  1.30.6.6    blymn 		PSYNCH_IN;
    202  1.30.6.6    blymn 		break;
    203  1.30.6.6    blymn 
    204  1.30.6.6    blymn 	default:
    205       1.5  mycroft #ifdef DEBUG
    206  1.30.6.6    blymn 		__CTRACE(__CTRACE_INPUT, "ADDBYTES(%p, %d, %d)\n",
    207  1.30.6.6    blymn 			 win, *y, *x);
    208       1.5  mycroft #endif
    209      1.14   simonb 
    210  1.30.6.6    blymn 		if ((*lp)->flags & __ISPASTEOL) {
    211  1.30.6.6    blymn 		  newline:
    212  1.30.6.6    blymn 			*x = 0;
    213  1.30.6.6    blymn 			(*lp)->flags &= ~__ISPASTEOL;
    214  1.30.6.6    blymn 			if (*y == win->scr_b) {
    215  1.30.6.6    blymn #ifdef DEBUG
    216  1.30.6.6    blymn 				__CTRACE(__CTRACE_INPUT,
    217  1.30.6.6    blymn 					 "ADDBYTES - on bottom "
    218  1.30.6.6    blymn 					 "of scrolling region\n");
    219  1.30.6.6    blymn #endif
    220  1.30.6.6    blymn 				if (!(win->flags & __SCROLLOK))
    221  1.30.6.6    blymn 					return ERR;
    222  1.30.6.6    blymn 				PSYNCH_OUT;
    223  1.30.6.6    blymn 				scroll(win);
    224  1.30.6.6    blymn 				PSYNCH_IN;
    225  1.30.6.6    blymn 			} else {
    226  1.30.6.6    blymn 				(*y)++;
    227       1.7      cgd 			}
    228  1.30.6.6    blymn 			*lp = win->lines[*y];
    229  1.30.6.6    blymn 			if (c == '\n')
    230  1.30.6.6    blymn 				break;
    231  1.30.6.6    blymn 		}
    232      1.14   simonb 
    233  1.30.6.6    blymn 		attributes = (win->wattr | attr) &
    234  1.30.6.6    blymn 			(__ATTRIBUTES & ~__COLOR);
    235  1.30.6.6    blymn 		if (attr & __COLOR)
    236  1.30.6.6    blymn 			attributes |= attr & __COLOR;
    237  1.30.6.6    blymn 		else if (win->wattr & __COLOR)
    238  1.30.6.6    blymn 			attributes |= win->wattr & __COLOR;
    239       1.5  mycroft #ifdef DEBUG
    240  1.30.6.6    blymn 		__CTRACE(__CTRACE_INPUT,
    241  1.30.6.6    blymn 			 "ADDBYTES: 1: y = %d, x = %d, firstch = %d, "
    242  1.30.6.6    blymn 			 "lastch = %d\n",
    243  1.30.6.6    blymn 			 *y, *x, *win->lines[*y]->firstchp,
    244  1.30.6.6    blymn 			 *win->lines[*y]->lastchp);
    245  1.30.6.6    blymn #endif
    246  1.30.6.6    blymn 		/*
    247  1.30.6.6    blymn 		 * Always update the change pointers.  Otherwise,
    248  1.30.6.6    blymn 		 * we could end up not displaying 'blank' characters
    249  1.30.6.6    blymn 		 * when overlapping windows are displayed.
    250  1.30.6.6    blymn 		 */
    251  1.30.6.6    blymn 		newx = *x + win->ch_off;
    252  1.30.6.6    blymn 		(*lp)->flags |= __ISDIRTY;
    253  1.30.6.6    blymn 		/*
    254  1.30.6.6    blymn 		 * firstchp/lastchp are shared between
    255  1.30.6.6    blymn 		 * parent window and sub-window.
    256  1.30.6.6    blymn 		 */
    257  1.30.6.6    blymn 		if (newx < *(*lp)->firstchp)
    258  1.30.6.6    blymn 			*(*lp)->firstchp = newx;
    259  1.30.6.6    blymn 		if (newx > *(*lp)->lastchp)
    260  1.30.6.6    blymn 			*(*lp)->lastchp = newx;
    261  1.30.6.6    blymn #ifdef DEBUG
    262  1.30.6.6    blymn 		__CTRACE(__CTRACE_INPUT,
    263  1.30.6.6    blymn 			 "ADDBYTES: change gives f/l: %d/%d [%d/%d]\n",
    264  1.30.6.6    blymn 			 *(*lp)->firstchp, *(*lp)->lastchp,
    265  1.30.6.6    blymn 			 *(*lp)->firstchp - win->ch_off,
    266  1.30.6.6    blymn 			 *(*lp)->lastchp - win->ch_off);
    267  1.30.6.6    blymn #endif
    268  1.30.6.6    blymn 		if (win->bch != ' ' && c == ' ')
    269  1.30.6.6    blymn 			(*lp)->line[*x].ch = win->bch;
    270  1.30.6.6    blymn 		else
    271  1.30.6.6    blymn 			(*lp)->line[*x].ch = c;
    272  1.30.6.6    blymn 
    273  1.30.6.6    blymn 		if (attributes & __COLOR)
    274  1.30.6.6    blymn 			(*lp)->line[*x].attr =
    275  1.30.6.6    blymn 				attributes | (win->battr & ~__COLOR);
    276  1.30.6.6    blymn 		else
    277  1.30.6.6    blymn 			(*lp)->line[*x].attr = attributes | win->battr;
    278  1.30.6.6    blymn 
    279  1.30.6.6    blymn 		if (*x == win->maxx - 1)
    280  1.30.6.6    blymn 			(*lp)->flags |= __ISPASTEOL;
    281  1.30.6.6    blymn 		else
    282  1.30.6.6    blymn 			(*x)++;
    283  1.30.6.6    blymn #ifdef DEBUG
    284  1.30.6.6    blymn 		__CTRACE(__CTRACE_INPUT,
    285  1.30.6.6    blymn 			 "ADDBYTES: 2: y = %d, x = %d, firstch = %d, "
    286  1.30.6.6    blymn 			 "lastch = %d\n",
    287  1.30.6.6    blymn 			 *y, *x, *win->lines[*y]->firstchp,
    288  1.30.6.6    blymn 			 *win->lines[*y]->lastchp);
    289  1.30.6.6    blymn #endif
    290  1.30.6.6    blymn 		break;
    291  1.30.6.6    blymn 	case '\n':
    292  1.30.6.6    blymn 		PSYNCH_OUT;
    293  1.30.6.6    blymn 		wclrtoeol(win);
    294  1.30.6.6    blymn 		PSYNCH_IN;
    295  1.30.6.6    blymn 		goto newline;
    296  1.30.6.6    blymn 	case '\r':
    297  1.30.6.6    blymn 		*x = 0;
    298  1.30.6.6    blymn 		break;
    299  1.30.6.6    blymn 	case '\b':
    300  1.30.6.6    blymn 		if (--(*x) < 0)
    301  1.30.6.6    blymn 			*x = 0;
    302  1.30.6.6    blymn 		break;
    303  1.30.6.6    blymn 	}
    304  1.30.6.6    blymn 
    305  1.30.6.6    blymn 	return (OK);
    306  1.30.6.6    blymn }
    307  1.30.6.6    blymn 
    308  1.30.6.6    blymn /*
    309  1.30.6.6    blymn  * _cursesi_addwchar -
    310  1.30.6.6    blymn  *	Internal function to add a wide character and update the row
    311  1.30.6.6    blymn  * and column positions.
    312  1.30.6.6    blymn  */
    313  1.30.6.6    blymn int
    314  1.30.6.6    blymn _cursesi_addwchar(WINDOW *win, __LINE **lnp, int *y, int *x,
    315  1.30.6.6    blymn 		  const cchar_t *wch)
    316  1.30.6.6    blymn {
    317  1.30.6.6    blymn #ifndef HAVE_WCHAR
    318  1.30.6.6    blymn 	return (ERR);
    319  1.30.6.6    blymn #else
    320  1.30.6.6    blymn 	int sx = 0, ex = 0, cw = 0, i = 0, newx = 0;
    321  1.30.6.6    blymn 	__LDATA *lp = &win->lines[*y]->line[*x], *tp = NULL;
    322  1.30.6.6    blymn 	nschar_t *np = NULL, *tnp = NULL;
    323  1.30.6.6    blymn 	cchar_t cc;
    324  1.30.6.6    blymn 	attr_t attributes;
    325  1.30.6.6    blymn 
    326  1.30.6.6    blymn 	/* special characters handling */
    327  1.30.6.6    blymn 	switch (wch->vals[0]) {
    328  1.30.6.6    blymn 	case L'\b':
    329  1.30.6.6    blymn 		if (--*x < 0)
    330  1.30.6.6    blymn 			*x = 0;
    331  1.30.6.6    blymn 		win->curx = *x;
    332  1.30.6.6    blymn 		return OK;
    333  1.30.6.6    blymn 	case L'\r':
    334  1.30.6.6    blymn 		win->curx = 0;
    335  1.30.6.6    blymn 		return OK;
    336  1.30.6.6    blymn 	case L'\n':
    337  1.30.6.6    blymn 		wclrtoeol(win);
    338  1.30.6.6    blymn 		PSYNCH_IN;
    339  1.30.6.6    blymn 		*x = 0;
    340  1.30.6.6    blymn 		(*lnp)->flags &= ~__ISPASTEOL;
    341  1.30.6.6    blymn 		if (*y == win->scr_b) {
    342  1.30.6.6    blymn 			if (!(win->flags & __SCROLLOK))
    343  1.30.6.6    blymn 				return ERR;
    344  1.30.6.6    blymn 			PSYNCH_OUT;
    345  1.30.6.6    blymn 			scroll(win);
    346  1.30.6.6    blymn 			PSYNCH_IN;
    347  1.30.6.6    blymn 		} else {
    348  1.30.6.6    blymn 			(*y)++;
    349  1.30.6.6    blymn 		}
    350  1.30.6.6    blymn 		PSYNCH_OUT;
    351  1.30.6.6    blymn 		return OK;
    352  1.30.6.6    blymn 	case L'\t':
    353  1.30.6.6    blymn 		cc.vals[0] = L' ';
    354  1.30.6.6    blymn 		cc.elements = 1;
    355  1.30.6.6    blymn 		cc.attributes = win->wattr;
    356  1.30.6.6    blymn 		for (i = 0; i < 8 - (*x % 8); i++) {
    357  1.30.6.6    blymn 			if (wadd_wch(win, &cc) == ERR)
    358  1.30.6.6    blymn 				return ERR;
    359  1.30.6.6    blymn 		}
    360  1.30.6.6    blymn 		return OK;
    361  1.30.6.6    blymn 	}
    362  1.30.6.6    blymn 
    363  1.30.6.6    blymn 	/* check for non-spacing character */
    364  1.30.6.6    blymn 	if (!wcwidth(wch->vals[0])) {
    365  1.30.6.6    blymn #ifdef DEBUG
    366  1.30.6.6    blymn 		__CTRACE(__CTRACE_INPUT,
    367  1.30.6.6    blymn 			 "_cursesi_addwchar: char '%c' is non-spacing\n",
    368  1.30.6.6    blymn 			 wch->vals[0]);
    369  1.30.6.6    blymn #endif /* DEBUG */
    370  1.30.6.6    blymn 		cw = WCOL(*lp);
    371  1.30.6.6    blymn 		if (cw < 0) {
    372  1.30.6.6    blymn 			lp += cw;
    373  1.30.6.6    blymn 			*x += cw;
    374  1.30.6.6    blymn 		}
    375  1.30.6.6    blymn 		for (i = 0; i < wch->elements; i++) {
    376  1.30.6.6    blymn 			if (!(np = (nschar_t *) malloc(sizeof(nschar_t))))
    377  1.30.6.6    blymn 				return ERR;;
    378  1.30.6.6    blymn 			np->ch = wch->vals[i];
    379  1.30.6.6    blymn 			np->next = lp->nsp;
    380  1.30.6.6    blymn 			lp->nsp = np;
    381  1.30.6.6    blymn 		}
    382  1.30.6.6    blymn 		(*lnp)->flags |= __ISDIRTY;
    383  1.30.6.6    blymn 		newx = *x + win->ch_off;
    384  1.30.6.6    blymn 		if (newx < *(*lnp)->firstchp)
    385  1.30.6.6    blymn 			*(*lnp)->firstchp = newx;
    386  1.30.6.6    blymn 		if (newx > *(*lnp)->lastchp)
    387  1.30.6.6    blymn 			*(*lnp)->lastchp = newx;
    388  1.30.6.6    blymn 		__touchline(win, *y, *x, *x);
    389  1.30.6.6    blymn 		return OK;
    390  1.30.6.6    blymn 	}
    391  1.30.6.6    blymn 	/* check for new line first */
    392  1.30.6.6    blymn 	if ((*lnp)->flags & __ISPASTEOL) {
    393  1.30.6.6    blymn 		*x = 0;
    394  1.30.6.6    blymn 		(*lnp)->flags &= ~__ISPASTEOL;
    395  1.30.6.6    blymn 		if (*y == win->scr_b) {
    396  1.30.6.6    blymn 			if (!(win->flags & __SCROLLOK))
    397  1.30.6.6    blymn 				return ERR;
    398  1.30.6.6    blymn 			PSYNCH_OUT;
    399  1.30.6.6    blymn 			scroll(win);
    400  1.30.6.6    blymn 			PSYNCH_IN;
    401  1.30.6.6    blymn 		} else {
    402  1.30.6.6    blymn 			(*y)++;
    403  1.30.6.6    blymn 		}
    404  1.30.6.6    blymn 		(*lnp) = win->lines[*y];
    405  1.30.6.6    blymn 		lp = &win->lines[*y]->line[*x];
    406  1.30.6.6    blymn 	}
    407  1.30.6.6    blymn 	/* clear out the current character */
    408  1.30.6.6    blymn 	cw = WCOL(*lp);
    409  1.30.6.6    blymn 	if (cw >= 0) {
    410  1.30.6.6    blymn 		sx = *x;
    411  1.30.6.6    blymn 	} else {
    412  1.30.6.6    blymn 		for (sx = *x - 1; sx >= max(*x + cw, 0); sx--) {
    413      1.24      jdc #ifdef DEBUG
    414  1.30.6.2      jdc 			__CTRACE(__CTRACE_INPUT,
    415  1.30.6.6    blymn 				 "_cursesi_addwchar: clear current char (%d,%d)\n",
    416  1.30.6.6    blymn 				 *y, sx);
    417  1.30.6.6    blymn #endif /* DEBUG */
    418  1.30.6.6    blymn 			tp = &win->lines[*y]->line[sx];
    419  1.30.6.6    blymn 			tp->ch = (wchar_t) btowc((int) win->bch);
    420  1.30.6.6    blymn 			if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
    421  1.30.6.6    blymn 				return ERR;
    422  1.30.6.1    blymn 
    423  1.30.6.6    blymn 			tp->attr = win->battr;
    424  1.30.6.6    blymn 			SET_WCOL(*tp, 1);
    425  1.30.6.6    blymn 		}
    426  1.30.6.6    blymn 		sx = *x + cw;
    427  1.30.6.6    blymn 		(*lnp)->flags |= __ISDIRTY;
    428  1.30.6.6    blymn 		newx = sx + win->ch_off;
    429  1.30.6.6    blymn 		if (newx < *(*lnp)->firstchp)
    430  1.30.6.6    blymn 			*(*lnp)->firstchp = newx;
    431  1.30.6.6    blymn 	}
    432  1.30.6.6    blymn 
    433  1.30.6.6    blymn 	/* check for enough space before the end of line */
    434  1.30.6.6    blymn 	cw = wcwidth(wch->vals[0]);
    435  1.30.6.6    blymn 	if (cw > win->maxx - *x) {
    436  1.30.6.6    blymn #ifdef DEBUG
    437  1.30.6.6    blymn 		__CTRACE(__CTRACE_INPUT,
    438  1.30.6.6    blymn 			 "_cursesi_addwchar: clear EOL (%d,%d)\n",
    439  1.30.6.6    blymn 			 *y, *x);
    440  1.30.6.6    blymn #endif /* DEBUG */
    441  1.30.6.6    blymn 		(*lnp)->flags |= __ISDIRTY;
    442  1.30.6.6    blymn 		newx = *x + win->ch_off;
    443  1.30.6.6    blymn 		if (newx < *(*lnp)->firstchp)
    444  1.30.6.6    blymn 			*(*lnp)->firstchp = newx;
    445  1.30.6.6    blymn 		for (tp = lp; *x < win->maxx; tp++, (*x)++) {
    446  1.30.6.6    blymn 			tp->ch = (wchar_t) btowc((int) win->bch);
    447  1.30.6.6    blymn 			if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
    448  1.30.6.1    blymn 				return ERR;
    449  1.30.6.6    blymn 			tp->attr = win->battr;
    450  1.30.6.6    blymn 			SET_WCOL(*tp, 1);
    451  1.30.6.6    blymn 		}
    452  1.30.6.6    blymn 		newx = win->maxx - 1 + win->ch_off;
    453  1.30.6.6    blymn 		if (newx > *(*lnp)->lastchp)
    454  1.30.6.6    blymn 			*(*lnp)->lastchp = newx;
    455  1.30.6.6    blymn 		__touchline(win, *y, sx, (int) win->maxx - 1);
    456  1.30.6.6    blymn 		sx = *x = 0;
    457  1.30.6.6    blymn 		if (*y == win->scr_b) {
    458  1.30.6.6    blymn 			if (!(win->flags & __SCROLLOK))
    459  1.30.6.6    blymn 				return ERR;
    460  1.30.6.6    blymn 			PSYNCH_OUT;
    461  1.30.6.6    blymn 			scroll(win);
    462  1.30.6.6    blymn 			PSYNCH_IN;
    463  1.30.6.6    blymn 		} else {
    464  1.30.6.6    blymn 			(*y)++;
    465  1.30.6.6    blymn 		}
    466  1.30.6.6    blymn 		lp = &win->lines[*y]->line[0];
    467  1.30.6.6    blymn 		(*lnp) = win->lines[*y];
    468  1.30.6.6    blymn 	}
    469  1.30.6.6    blymn 	win->cury = *y;
    470  1.30.6.1    blymn 
    471  1.30.6.6    blymn 	/* add spacing character */
    472  1.30.6.6    blymn #ifdef DEBUG
    473  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT,
    474  1.30.6.6    blymn 		 "_cursesi_addwchar: add character (%d,%d) 0x%x\n",
    475  1.30.6.6    blymn 		 *y, *x, wch->vals[0]);
    476  1.30.6.6    blymn #endif /* DEBUG */
    477  1.30.6.6    blymn 	(*lnp)->flags |= __ISDIRTY;
    478  1.30.6.6    blymn 	newx = *x + win->ch_off;
    479  1.30.6.6    blymn 	if (newx < *(*lnp)->firstchp)
    480  1.30.6.6    blymn 		*(*lnp)->firstchp = newx;
    481  1.30.6.6    blymn 	if (lp->nsp) {
    482  1.30.6.6    blymn 		__cursesi_free_nsp(lp->nsp);
    483  1.30.6.6    blymn 		lp->nsp = NULL;
    484  1.30.6.6    blymn 	}
    485  1.30.6.6    blymn 
    486  1.30.6.6    blymn 	lp->ch = wch->vals[0];
    487  1.30.6.1    blymn 
    488  1.30.6.6    blymn 	attributes = (win->wattr | wch->attributes)
    489  1.30.6.6    blymn 		& (WA_ATTRIBUTES & ~__COLOR);
    490  1.30.6.6    blymn 	if (wch->attributes & __COLOR)
    491  1.30.6.6    blymn 		attributes |= wch->attributes & __COLOR;
    492  1.30.6.6    blymn 	else if (win->wattr & __COLOR)
    493  1.30.6.6    blymn 		attributes |= win->wattr & __COLOR;
    494  1.30.6.6    blymn 	if (attributes & __COLOR)
    495  1.30.6.6    blymn 		lp->attr = attributes | (win->battr & ~__COLOR);
    496  1.30.6.6    blymn 	else
    497  1.30.6.6    blymn 		lp->attr = attributes | win->battr;
    498  1.30.6.6    blymn 
    499  1.30.6.6    blymn 	SET_WCOL(*lp, cw);
    500  1.30.6.6    blymn 
    501  1.30.6.6    blymn #ifdef DEBUG
    502  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT,
    503  1.30.6.6    blymn 		 "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n",
    504  1.30.6.6    blymn 		 lp->ch, lp->attr);
    505  1.30.6.6    blymn #endif /* DEBUG */
    506  1.30.6.6    blymn 
    507  1.30.6.6    blymn 	if (wch->elements > 1) {
    508  1.30.6.6    blymn 		for (i = 1; i < wch->elements; i++) {
    509  1.30.6.6    blymn 			np = (nschar_t *)malloc(sizeof(nschar_t));
    510  1.30.6.6    blymn 			if (!np)
    511  1.30.6.6    blymn 				return ERR;;
    512  1.30.6.6    blymn 			np->ch = wch->vals[i];
    513  1.30.6.6    blymn 			np->next = lp->nsp;
    514       1.5  mycroft #ifdef DEBUG
    515  1.30.6.2      jdc 			__CTRACE(__CTRACE_INPUT,
    516  1.30.6.6    blymn 			    "_cursesi_addwchar: add non-spacing char 0x%x\n", np->ch);
    517  1.30.6.6    blymn #endif /* DEBUG */
    518  1.30.6.6    blymn 			lp->nsp = np;
    519       1.5  mycroft 		}
    520       1.5  mycroft 	}
    521      1.23    blymn #ifdef DEBUG
    522  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: non-spacing list header: %p\n",
    523  1.30.6.6    blymn 	    lp->nsp);
    524  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add rest columns (%d:%d)\n",
    525  1.30.6.6    blymn 		sx + 1, sx + cw - 1);
    526  1.30.6.6    blymn #endif /* DEBUG */
    527  1.30.6.6    blymn 	for (tp = lp + 1, *x = sx + 1; *x - sx <= cw - 1; tp++, (*x)++) {
    528  1.30.6.6    blymn 		if (tp->nsp) {
    529  1.30.6.6    blymn 			__cursesi_free_nsp(tp->nsp);
    530  1.30.6.6    blymn 			tp->nsp = NULL;
    531  1.30.6.6    blymn 		}
    532  1.30.6.6    blymn 		tp->ch = wch->vals[0];
    533  1.30.6.6    blymn 		tp->attr = wch->attributes & WA_ATTRIBUTES;
    534  1.30.6.6    blymn 		SET_WCOL(*tp, sx - *x);
    535  1.30.6.6    blymn 	}
    536  1.30.6.6    blymn 	if (*x == win->maxx) {
    537  1.30.6.6    blymn 		(*lnp)->flags |= __ISPASTEOL;
    538  1.30.6.6    blymn 		newx = win->maxx - 1 + win->ch_off;
    539  1.30.6.6    blymn 		if (newx > *(*lnp)->lastchp)
    540  1.30.6.6    blymn 			*(*lnp)->lastchp = newx;
    541  1.30.6.6    blymn 		__touchline(win, *y, sx, (int) win->maxx - 1);
    542  1.30.6.6    blymn 		win->curx = sx;
    543  1.30.6.6    blymn 	} else {
    544  1.30.6.6    blymn 		win->curx = *x;
    545  1.30.6.6    blymn 
    546  1.30.6.6    blymn 		/* clear the remining of the current characer */
    547  1.30.6.6    blymn 		if (*x && *x < win->maxx) {
    548  1.30.6.6    blymn 			ex = sx + cw;
    549  1.30.6.6    blymn 			tp = &win->lines[*y]->line[ex];
    550  1.30.6.6    blymn 			while (ex < win->maxx && WCOL(*tp) < 0) {
    551  1.30.6.6    blymn #ifdef DEBUG
    552  1.30.6.6    blymn 				__CTRACE(__CTRACE_INPUT,
    553  1.30.6.6    blymn 					 "_cursesi_addwchar: clear "
    554  1.30.6.6    blymn 					 "remaining of current char (%d,%d)nn",
    555  1.30.6.6    blymn 					 *y, ex);
    556  1.30.6.6    blymn #endif /* DEBUG */
    557  1.30.6.6    blymn 				tp->ch = (wchar_t) btowc((int) win->bch);
    558  1.30.6.6    blymn 				if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
    559  1.30.6.6    blymn 					return ERR;
    560  1.30.6.6    blymn 				tp->attr = win->battr;
    561  1.30.6.6    blymn 				SET_WCOL(*tp, 1);
    562  1.30.6.6    blymn 				tp++, ex++;
    563  1.30.6.6    blymn 			}
    564  1.30.6.6    blymn 			newx = ex - 1 + win->ch_off;
    565  1.30.6.6    blymn 			if (newx > *(*lnp)->lastchp)
    566  1.30.6.6    blymn 				*(*lnp)->lastchp = newx;
    567  1.30.6.6    blymn 			__touchline(win, *y, sx, ex - 1);
    568  1.30.6.6    blymn 		}
    569      1.23    blymn 	}
    570      1.23    blymn 
    571  1.30.6.6    blymn #ifdef DEBUG
    572  1.30.6.6    blymn 	__CTRACE(__CTRACE_INPUT, "add_wch: %d : 0x%x\n", lp->ch, lp->attr);
    573  1.30.6.6    blymn #endif /* DEBUG */
    574  1.30.6.6    blymn 	return OK;
    575  1.30.6.6    blymn #endif
    576       1.1      cgd }
    577