150276Speter/****************************************************************************
2174993Srafan * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
3050276Speter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3150276Speter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32166124Srafan *                                                                          *
33166124Srafan *  Rewritten 2001-2004 to support wide-characters by                       *
34166124Srafan *	Sven Verdoolaege                                                    *
35166124Srafan *	Thomas Dickey                                                       *
3650276Speter ****************************************************************************/
3750276Speter
3850276Speter/*
3950276Speter**	lib_addstr.c
4050276Speter*
4150276Speter**	The routines waddnstr(), waddchnstr().
4250276Speter**
4350276Speter*/
4450276Speter
4550276Speter#include <curses.priv.h>
4650276Speter
47174993SrafanMODULE_ID("$Id: lib_addstr.c,v 1.48 2007/10/13 19:56:57 tom Exp $")
4850276Speter
4976726SpeterNCURSES_EXPORT(int)
50166124Srafanwaddnstr(WINDOW *win, const char *astr, int n)
5150276Speter{
52166124Srafan    const char *str = astr;
5362449Speter    int code = ERR;
5450276Speter
55166124Srafan    T((T_CALLED("waddnstr(%p,%s,%d)"), win, _nc_visbufn(astr, n), n));
5662449Speter
5762449Speter    if (win && (str != 0)) {
58166124Srafan	TR(TRACE_VIRTPUT | TRACE_ATTRS,
59166124Srafan	   ("... current %s", _traceattr(WINDOW_ATTRS(win))));
6062449Speter	code = OK;
6162449Speter	if (n < 0)
6262449Speter	    n = (int) strlen(astr);
6362449Speter
6497049Speter	TR(TRACE_VIRTPUT, ("str is not null, length = %d", n));
65166124Srafan	while ((n-- > 0) && (*str != '\0')) {
6697049Speter	    NCURSES_CH_T ch;
67166124Srafan	    TR(TRACE_VIRTPUT, ("*str = %#o", UChar(*str)));
68166124Srafan	    SetChar(ch, UChar(*str++), A_NORMAL);
6997049Speter	    if (_nc_waddch_nosync(win, ch) == ERR) {
7062449Speter		code = ERR;
7162449Speter		break;
7250276Speter	    }
7350276Speter	}
7462449Speter	_nc_synchook(win);
7562449Speter    }
7662449Speter    TR(TRACE_VIRTPUT, ("waddnstr returns %d", code));
7762449Speter    returnCode(code);
7850276Speter}
7950276Speter
8076726SpeterNCURSES_EXPORT(int)
81166124Srafanwaddchnstr(WINDOW *win, const chtype *astr, int n)
8250276Speter{
83174993Srafan    NCURSES_SIZE_T y, x;
8462449Speter    int code = OK;
85166124Srafan    int i;
8662449Speter    struct ldat *line;
8750276Speter
8862449Speter    T((T_CALLED("waddchnstr(%p,%p,%d)"), win, astr, n));
8950276Speter
9062449Speter    if (!win)
9162449Speter	returnCode(ERR);
9250276Speter
93174993Srafan    y = win->_cury;
94174993Srafan    x = win->_curx;
9562449Speter    if (n < 0) {
9662449Speter	const chtype *str;
9762449Speter	n = 0;
9862449Speter	for (str = (const chtype *) astr; *str != 0; str++)
9962449Speter	    n++;
10062449Speter    }
10162449Speter    if (n > win->_maxx - x + 1)
10262449Speter	n = win->_maxx - x + 1;
10362449Speter    if (n == 0)
10462449Speter	returnCode(code);
10550276Speter
10662449Speter    line = &(win->_line[y]);
107166124Srafan    for (i = 0; i < n && ChCharOf(astr[i]) != '\0'; ++i) {
108166124Srafan	SetChar2(line->text[i + x], astr[i]);
10997049Speter    }
11062449Speter    CHANGED_RANGE(line, x, x + n - 1);
11150276Speter
11262449Speter    _nc_synchook(win);
11362449Speter    returnCode(code);
11450276Speter}
11597049Speter
11697049Speter#if USE_WIDEC_SUPPORT
11797049Speter
118166124SrafanNCURSES_EXPORT(int)
119166124Srafan_nc_wchstrlen(const cchar_t *s)
12097049Speter{
12197049Speter    int result = 0;
12297049Speter    while (CharOf(s[result]) != L'\0') {
12397049Speter	result++;
12497049Speter    }
12597049Speter    return result;
12697049Speter}
12797049Speter
12897049SpeterNCURSES_EXPORT(int)
129166124Srafanwadd_wchnstr(WINDOW *win, const cchar_t *astr, int n)
13097049Speter{
131166124Srafan    static const NCURSES_CH_T blank = NewChar(BLANK_TEXT);
132174993Srafan    NCURSES_SIZE_T y;
133174993Srafan    NCURSES_SIZE_T x;
13497049Speter    int code = OK;
13597049Speter    struct ldat *line;
136166124Srafan    int i, j, start, len, end;
13797049Speter
13897049Speter    T((T_CALLED("wadd_wchnstr(%p,%s,%d)"), win, _nc_viscbuf(astr, n), n));
13997049Speter
14097049Speter    if (!win)
14197049Speter	returnCode(ERR);
14297049Speter
143174993Srafan    y = win->_cury;
144174993Srafan    x = win->_curx;
14597049Speter    if (n < 0) {
14697049Speter	n = _nc_wchstrlen(astr);
14797049Speter    }
14897049Speter    if (n > win->_maxx - x + 1)
14997049Speter	n = win->_maxx - x + 1;
15097049Speter    if (n == 0)
15197049Speter	returnCode(code);
15297049Speter
15397049Speter    line = &(win->_line[y]);
15497049Speter    start = x;
15597049Speter    end = x + n - 1;
156166124Srafan
157166124Srafan    /*
158166124Srafan     * Reset orphaned cells of multi-column characters that extend up to the
159166124Srafan     * new string's location to blanks.
160166124Srafan     */
161166124Srafan    if (x > 0 && isWidecExt(line->text[x])) {
162166124Srafan	for (i = 0; i <= x; ++i) {
163166124Srafan	    if (!isWidecExt(line->text[x - i])) {
164166124Srafan		/* must be isWidecBase() */
165166124Srafan		start -= i;
166166124Srafan		while (i > 0) {
167166124Srafan		    line->text[x - i--] = _nc_render(win, blank);
168166124Srafan		}
169166124Srafan		break;
170166124Srafan	    }
171166124Srafan	}
17297049Speter    }
173166124Srafan
174166124Srafan    /*
175166124Srafan     * Copy the new string to the window.
176166124Srafan     */
177166124Srafan    for (i = 0; i < n && CharOf(astr[i]) != L'\0' && x <= win->_maxx; ++i) {
178166124Srafan	if (isWidecExt(astr[i]))
179166124Srafan	    continue;
180166124Srafan
181166124Srafan	len = wcwidth(CharOf(astr[i]));
182166124Srafan
183166124Srafan	if (x + len - 1 <= win->_maxx) {
184166124Srafan	    line->text[x] = _nc_render(win, astr[i]);
185166124Srafan	    if (len > 1) {
186166124Srafan		for (j = 0; j < len; ++j) {
187166124Srafan		    if (j != 0) {
188166124Srafan			line->text[x + j] = line->text[x];
189166124Srafan		    }
190166124Srafan		    SetWidecExt(line->text[x + j], j);
191166124Srafan		}
192166124Srafan	    }
193166124Srafan	    x += len;
194166124Srafan	    end += len - 1;
195166124Srafan	} else {
196166124Srafan	    break;
19797049Speter	}
19897049Speter    }
199166124Srafan
200166124Srafan    /*
201166124Srafan     * Set orphaned cells of multi-column characters which lie after the new
202166124Srafan     * string to blanks.
203166124Srafan     */
204166124Srafan    while (x <= win->_maxx && isWidecExt(line->text[x])) {
205166124Srafan	line->text[x] = _nc_render(win, blank);
20697049Speter	++end;
207166124Srafan	++x;
20897049Speter    }
20997049Speter    CHANGED_RANGE(line, start, end);
21097049Speter
21197049Speter    _nc_synchook(win);
21297049Speter    returnCode(code);
21397049Speter}
21497049Speter
21597049SpeterNCURSES_EXPORT(int)
216166124Srafanwaddnwstr(WINDOW *win, const wchar_t *str, int n)
21797049Speter{
21897049Speter    int code = ERR;
21997049Speter
220166124Srafan    T((T_CALLED("waddnwstr(%p,%s,%d)"), win, _nc_viswbufn(str, n), n));
22197049Speter
22297049Speter    if (win && (str != 0)) {
223166124Srafan	TR(TRACE_VIRTPUT | TRACE_ATTRS,
224166124Srafan	   ("... current %s", _traceattr(WINDOW_ATTRS(win))));
22597049Speter	code = OK;
22697049Speter	if (n < 0)
22797049Speter	    n = (int) wcslen(str);
22897049Speter
22997049Speter	TR(TRACE_VIRTPUT, ("str is not null, length = %d", n));
23097049Speter	while ((n-- > 0) && (*str != L('\0'))) {
23197049Speter	    NCURSES_CH_T ch;
232166124Srafan	    TR(TRACE_VIRTPUT, ("*str[0] = %#lx", (unsigned long) *str));
23397049Speter	    SetChar(ch, *str++, A_NORMAL);
234166124Srafan	    if (wadd_wch(win, &ch) == ERR) {
23597049Speter		code = ERR;
23697049Speter		break;
23797049Speter	    }
23897049Speter	}
23997049Speter	_nc_synchook(win);
24097049Speter    }
24197049Speter    TR(TRACE_VIRTPUT, ("waddnwstr returns %d", code));
24297049Speter    returnCode(code);
24397049Speter}
24497049Speter
24597049Speter#endif
246