1 /* $OpenBSD: lib_addstr.c,v 1.6 2023/10/17 09:52:08 nicm Exp $ */ 2 3 /**************************************************************************** 4 * Copyright 2019-2020,2022 Thomas E. Dickey * 5 * Copyright 1998-2016,2017 Free Software Foundation, Inc. * 6 * * 7 * Permission is hereby granted, free of charge, to any person obtaining a * 8 * copy of this software and associated documentation files (the * 9 * "Software"), to deal in the Software without restriction, including * 10 * without limitation the rights to use, copy, modify, merge, publish, * 11 * distribute, distribute with modifications, sublicense, and/or sell * 12 * copies of the Software, and to permit persons to whom the Software is * 13 * furnished to do so, subject to the following conditions: * 14 * * 15 * The above copyright notice and this permission notice shall be included * 16 * in all copies or substantial portions of the Software. * 17 * * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 21 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 24 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 25 * * 26 * Except as contained in this notice, the name(s) of the above copyright * 27 * holders shall not be used in advertising or otherwise to promote the * 28 * sale, use or other dealings in this Software without prior written * 29 * authorization. * 30 ****************************************************************************/ 31 32 /**************************************************************************** 33 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 34 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 35 * * 36 * Rewritten 2001-2004 to support wide-characters by * 37 * Sven Verdoolaege * 38 * Thomas Dickey * 39 ****************************************************************************/ 40 41 /* 42 ** lib_addstr.c 43 * 44 ** The routines waddnstr(), waddchnstr(). 45 ** 46 */ 47 48 #include <curses.priv.h> 49 50 MODULE_ID("$Id: lib_addstr.c,v 1.6 2023/10/17 09:52:08 nicm Exp $") 51 52 NCURSES_EXPORT(int) 53 waddnstr(WINDOW *win, const char *astr, int n) 54 { 55 const char *str = astr; 56 int code = ERR; 57 58 T((T_CALLED("waddnstr(%p,%s,%d)"), (void *) win, _nc_visbufn(astr, n), n)); 59 60 if (win && (str != 0)) { 61 TR(TRACE_VIRTPUT | TRACE_ATTRS, 62 ("... current %s", _traceattr(WINDOW_ATTRS(win)))); 63 code = OK; 64 65 TR(TRACE_VIRTPUT, ("str is not null, length = %d", 66 ((n > 0) ? n : (int) strlen(str)))); 67 if (n < 0) 68 n = INT_MAX; 69 while ((*str != '\0') && (n-- > 0)) { 70 NCURSES_CH_T ch; 71 TR(TRACE_VIRTPUT, ("*str = %#o", UChar(*str))); 72 SetChar(ch, UChar(*str++), A_NORMAL); 73 if (_nc_waddch_nosync(win, ch) == ERR) { 74 code = ERR; 75 break; 76 } 77 } 78 _nc_synchook(win); 79 } 80 TR(TRACE_VIRTPUT, ("waddnstr returns %d", code)); 81 returnCode(code); 82 } 83 84 NCURSES_EXPORT(int) 85 waddchnstr(WINDOW *win, const chtype *astr, int n) 86 { 87 NCURSES_SIZE_T y, x; 88 int code = OK; 89 int i; 90 struct ldat *line; 91 92 T((T_CALLED("waddchnstr(%p,%p,%d)"), (void *) win, (const void *) astr, n)); 93 94 if (!win || !astr) 95 returnCode(ERR); 96 97 y = win->_cury; 98 x = win->_curx; 99 if (n < 0) { 100 const chtype *str; 101 n = 0; 102 for (str = (const chtype *) astr; *str != 0; str++) 103 n++; 104 } 105 if (n > win->_maxx - x + 1) 106 n = win->_maxx - x + 1; 107 if (n == 0) 108 returnCode(code); 109 110 line = &(win->_line[y]); 111 for (i = 0; i < n && ChCharOf(astr[i]) != '\0'; ++i) { 112 SetChar2(line->text[i + x], astr[i]); 113 } 114 CHANGED_RANGE(line, x, (NCURSES_SIZE_T) (x + n - 1)); 115 116 _nc_synchook(win); 117 returnCode(code); 118 } 119 120 #if USE_WIDEC_SUPPORT 121 122 NCURSES_EXPORT(int) 123 _nc_wchstrlen(const cchar_t *s) 124 { 125 int result = 0; 126 if (s != 0) { 127 while (CharOf(s[result]) != L'\0') { 128 result++; 129 } 130 } 131 return result; 132 } 133 134 NCURSES_EXPORT(int) 135 wadd_wchnstr(WINDOW *win, const cchar_t *astr, int n) 136 { 137 static const NCURSES_CH_T blank = NewChar(BLANK_TEXT); 138 NCURSES_SIZE_T y; 139 NCURSES_SIZE_T x; 140 int code = OK; 141 struct ldat *line; 142 int i, j, start, len, end; 143 144 T((T_CALLED("wadd_wchnstr(%p,%s,%d)"), 145 (void *) win, 146 _nc_viscbuf(astr, n), 147 n)); 148 149 if (!win) 150 returnCode(ERR); 151 152 y = win->_cury; 153 x = win->_curx; 154 if (n < 0) { 155 n = _nc_wchstrlen(astr); 156 } 157 if (n > win->_maxx - x + 1) 158 n = win->_maxx - x + 1; 159 if (n == 0) 160 returnCode(code); 161 162 line = &(win->_line[y]); 163 start = x; 164 end = x + n - 1; 165 166 /* 167 * Reset orphaned cells of multi-column characters that extend up to the 168 * new string's location to blanks. 169 */ 170 if (x > 0 && isWidecExt(line->text[x])) { 171 for (i = 0; i <= x; ++i) { 172 if (!isWidecExt(line->text[x - i])) { 173 /* must be isWidecBase() */ 174 start -= i; 175 while (i > 0) { 176 line->text[x - i--] = _nc_render(win, blank); 177 } 178 break; 179 } 180 } 181 } 182 183 /* 184 * Copy the new string to the window. 185 */ 186 for (i = 0; i < n && CharOf(astr[i]) != L'\0' && x <= win->_maxx; ++i) { 187 if (isWidecExt(astr[i])) 188 continue; 189 190 len = _nc_wacs_width(CharOf(astr[i])); 191 192 if (x + len - 1 <= win->_maxx) { 193 line->text[x] = _nc_render(win, astr[i]); 194 if (len > 1) { 195 for (j = 0; j < len; ++j) { 196 if (j != 0) { 197 line->text[x + j] = line->text[x]; 198 } 199 SetWidecExt(line->text[x + j], j); 200 } 201 } else { 202 len = 1; 203 } 204 x = (NCURSES_SIZE_T) (x + len); 205 end += len - 1; 206 } else { 207 break; 208 } 209 } 210 211 /* 212 * Set orphaned cells of multi-column characters which lie after the new 213 * string to blanks. 214 */ 215 while (x <= win->_maxx && isWidecExt(line->text[x])) { 216 line->text[x] = _nc_render(win, blank); 217 ++end; 218 ++x; 219 } 220 CHANGED_RANGE(line, start, end); 221 222 _nc_synchook(win); 223 returnCode(code); 224 } 225 226 NCURSES_EXPORT(int) 227 waddnwstr(WINDOW *win, const wchar_t *str, int n) 228 { 229 int code = ERR; 230 231 T((T_CALLED("waddnwstr(%p,%s,%d)"), (void *) win, _nc_viswbufn(str, n), n)); 232 233 if (win && (str != 0)) { 234 TR(TRACE_VIRTPUT | TRACE_ATTRS, 235 ("... current %s", _traceattr(WINDOW_ATTRS(win)))); 236 code = OK; 237 238 TR(TRACE_VIRTPUT, ("str is not null, length = %d", 239 ((n > 0) ? n : (int) wcslen(str)))); 240 if (n < 0) 241 n = INT_MAX; 242 while ((*str != L('\0')) && (n-- > 0)) { 243 NCURSES_CH_T ch; 244 TR(TRACE_VIRTPUT, ("*str[0] = %#lx", (unsigned long) *str)); 245 SetChar(ch, *str++, A_NORMAL); 246 if (wadd_wch(win, &ch) == ERR) { 247 code = ERR; 248 break; 249 } 250 } 251 _nc_synchook(win); 252 } 253 TR(TRACE_VIRTPUT, ("waddnwstr returns %d", code)); 254 returnCode(code); 255 } 256 257 #endif 258