1/****************************************************************************
2 * Copyright (c) 2002-2003,2005 Free Software Foundation, Inc.              *
3 *                                                                          *
4 * Permission is hereby granted, free of charge, to any person obtaining a  *
5 * copy of this software and associated documentation files (the            *
6 * "Software"), to deal in the Software without restriction, including      *
7 * without limitation the rights to use, copy, modify, merge, publish,      *
8 * distribute, distribute with modifications, sublicense, and/or sell       *
9 * copies of the Software, and to permit persons to whom the Software is    *
10 * furnished to do so, subject to the following conditions:                 *
11 *                                                                          *
12 * The above copyright notice and this permission notice shall be included  *
13 * in all copies or substantial portions of the Software.                   *
14 *                                                                          *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22 *                                                                          *
23 * Except as contained in this notice, the name(s) of the above copyright   *
24 * holders shall not be used in advertising or otherwise to promote the     *
25 * sale, use or other dealings in this Software without prior written       *
26 * authorization.                                                           *
27 ****************************************************************************/
28
29/****************************************************************************
30 *  Author: Thomas Dickey 2002                                              *
31 ****************************************************************************/
32
33/*
34**	lib_ins_wch.c
35**
36**	The routine wins_wch().
37**
38*/
39
40#include <curses.priv.h>
41
42MODULE_ID("$Id: lib_ins_wch.c,v 1.8 2005/12/03 20:24:19 tom Exp $")
43
44/*
45 * Insert the given character, updating the current location to simplify
46 * inserting a string.
47 */
48static int
49_nc_insert_wch(WINDOW *win, const cchar_t *wch)
50{
51    int cells = wcwidth(CharOf(CHDEREF(wch)));
52    int cell;
53
54    if (cells <= 0)
55	cells = 1;
56
57    if (win->_curx <= win->_maxx) {
58	struct ldat *line = &(win->_line[win->_cury]);
59	NCURSES_CH_T *end = &(line->text[win->_curx]);
60	NCURSES_CH_T *temp1 = &(line->text[win->_maxx]);
61	NCURSES_CH_T *temp2 = temp1 - cells;
62
63	CHANGED_TO_EOL(line, win->_curx, win->_maxx);
64	while (temp1 > end)
65	    *temp1-- = *temp2--;
66
67	*temp1 = _nc_render(win, *wch);
68	for (cell = 1; cell < cells; ++cell) {
69	    SetWidecExt(temp1[cell], cell);
70	}
71
72	win->_curx++;
73    }
74    return OK;
75}
76
77NCURSES_EXPORT(int)
78wins_wch(WINDOW *win, const cchar_t *wch)
79{
80    NCURSES_SIZE_T oy;
81    NCURSES_SIZE_T ox;
82    int code = ERR;
83
84    T((T_CALLED("wins_wch(%p, %s)"), win, _tracecchar_t(wch)));
85
86    if (win != 0) {
87	oy = win->_cury;
88	ox = win->_curx;
89
90	code = _nc_insert_wch(win, wch);
91
92	win->_curx = ox;
93	win->_cury = oy;
94	_nc_synchook(win);
95    }
96    returnCode(code);
97}
98
99NCURSES_EXPORT(int)
100wins_nwstr(WINDOW *win, const wchar_t *wstr, int n)
101{
102    int code = ERR;
103    NCURSES_SIZE_T oy;
104    NCURSES_SIZE_T ox;
105    const wchar_t *cp;
106
107    T((T_CALLED("wins_nwstr(%p,%s,%d)"), win, _nc_viswbufn(wstr, n), n));
108
109    if (win != 0
110	&& wstr != 0) {
111	if (n < 1)
112	    n = wcslen(wstr);
113	code = OK;
114	if (n > 0) {
115	    oy = win->_cury;
116	    ox = win->_curx;
117	    for (cp = wstr; *cp && ((cp - wstr) < n); cp++) {
118		int len = wcwidth(*cp);
119
120		if (len != 1 || !is8bits(*cp)) {
121		    cchar_t tmp_cchar;
122		    wchar_t tmp_wchar = *cp;
123		    memset(&tmp_cchar, 0, sizeof(tmp_cchar));
124		    (void) setcchar(&tmp_cchar,
125				    &tmp_wchar,
126				    WA_NORMAL,
127				    0,
128				    (void *) 0);
129		    code = _nc_insert_wch(win, &tmp_cchar);
130		} else {
131		    /* tabs, other ASCII stuff */
132		    code = _nc_insert_ch(win, (chtype) (*cp));
133		}
134		if (code != OK)
135		    break;
136	    }
137
138	    win->_curx = ox;
139	    win->_cury = oy;
140	    _nc_synchook(win);
141	}
142    }
143    returnCode(code);
144}
145