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