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