1 /**************************************************************************** 2 * Copyright 2019-2020,2021 Thomas E. Dickey * 3 * Copyright 2001-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 ** lib_cchar.c 32 ** 33 ** The routines setcchar() and getcchar(). 34 ** 35 */ 36 37 #include <curses.priv.h> 38 #include <wchar.h> 39 40 MODULE_ID("$Id: lib_cchar.c,v 1.35 2021/01/17 00:04:08 tom Exp $") 41 42 /* 43 * The SuSv2 description leaves some room for interpretation. We'll assume wch 44 * points to a string which is L'\0' terminated, contains at least one 45 * character with strictly positive width, which must be the first, and 46 * contains no characters of negative width. 47 */ 48 NCURSES_EXPORT(int) 49 setcchar(cchar_t *wcval, 50 const wchar_t *wch, 51 const attr_t attrs, 52 NCURSES_PAIRS_T pair_arg, 53 const void *opts) 54 { 55 int code = OK; 56 int color_pair = pair_arg; 57 unsigned len; 58 59 TR(TRACE_CCALLS, (T_CALLED("setcchar(%p,%s,attrs=%lu,pair=%d,%p)"), 60 (void *) wcval, _nc_viswbuf(wch), 61 (unsigned long) attrs, color_pair, opts)); 62 63 set_extended_pair(opts, color_pair); 64 if (wch == NULL 65 || ((len = (unsigned) wcslen(wch)) > 1 && _nc_wacs_width(wch[0]) < 0) 66 || color_pair < 0) { 67 code = ERR; 68 } else { 69 unsigned i; 70 71 if (len > CCHARW_MAX) 72 len = CCHARW_MAX; 73 74 /* 75 * If we have a following spacing-character, stop at that point. We 76 * are only interested in adding non-spacing characters. 77 */ 78 for (i = 1; i < len; ++i) { 79 if (_nc_wacs_width(wch[i]) != 0) { 80 len = i; 81 break; 82 } 83 } 84 85 memset(wcval, 0, sizeof(*wcval)); 86 87 if (len != 0) { 88 SetAttr(*wcval, attrs); 89 SetPair(CHDEREF(wcval), color_pair); 90 memcpy(&wcval->chars, wch, len * sizeof(wchar_t)); 91 TR(TRACE_CCALLS, ("copy %d wchars, first is %s", len, 92 _tracecchar_t(wcval))); 93 } 94 } 95 96 TR(TRACE_CCALLS, (T_RETURN("%d"), code)); 97 return (code); 98 } 99 100 NCURSES_EXPORT(int) 101 getcchar(const cchar_t *wcval, 102 wchar_t *wch, 103 attr_t *attrs, 104 NCURSES_PAIRS_T *pair_arg, 105 void *opts) 106 { 107 int code = ERR; 108 int color_pair; 109 110 TR(TRACE_CCALLS, (T_CALLED("getcchar(%p,%p,%p,%p,%p)"), 111 (const void *) wcval, 112 (void *) wch, 113 (void *) attrs, 114 (void *) pair_arg, 115 opts)); 116 117 #if !NCURSES_EXT_COLORS 118 if (opts != NULL) { 119 ; /* empty */ 120 } else 121 #endif 122 if (wcval != NULL) { 123 wchar_t *wp; 124 int len; 125 126 len = ((wp = wmemchr(wcval->chars, L'\0', (size_t) CCHARW_MAX)) 127 ? (int) (wp - wcval->chars) 128 : CCHARW_MAX); 129 130 if (wch == NULL) { 131 /* 132 * If the value is a null, set the length to 1. 133 * If the value is not a null, return the length plus 1 for null. 134 */ 135 code = (len < CCHARW_MAX) ? (len + 1) : CCHARW_MAX; 136 } else if (attrs == 0 || pair_arg == 0) { 137 code = ERR; 138 } else if (len >= 0) { 139 TR(TRACE_CCALLS, ("copy %d wchars, first is %s", len, 140 _tracecchar_t(wcval))); 141 *attrs = AttrOf(*wcval) & A_ATTRIBUTES; 142 color_pair = GetPair(*wcval); 143 get_extended_pair(opts, color_pair); 144 *pair_arg = limit_PAIRS(color_pair); 145 wmemcpy(wch, wcval->chars, (size_t) len); 146 wch[len] = L'\0'; 147 if (*pair_arg >= 0) 148 code = OK; 149 } 150 } 151 152 TR(TRACE_CCALLS, (T_RETURN("%d"), code)); 153 return (code); 154 } 155