1 /**************************************************************************** 2 * Copyright 2019,2020 Thomas E. Dickey * 3 * Copyright 1998-2011,2012 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: Juergen Pfeifer * 32 * and: Thomas E. Dickey * 33 ****************************************************************************/ 34 35 /* 36 * lib_slkset.c 37 * Set soft label text. 38 */ 39 #include <curses.priv.h> 40 #include <ctype.h> 41 42 #if USE_WIDEC_SUPPORT 43 #if HAVE_WCTYPE_H 44 #include <wctype.h> 45 #endif 46 #endif 47 48 MODULE_ID("$Id: lib_slkset.c,v 1.26 2020/02/02 23:34:34 tom Exp $") 49 50 NCURSES_EXPORT(int) 51 NCURSES_SP_NAME(slk_set) (NCURSES_SP_DCLx int i, const char *astr, int format) 52 { 53 SLK *slk; 54 int offset = 0; 55 int numchrs; 56 int numcols; 57 int limit; 58 const char *str = astr; 59 const char *p; 60 61 T((T_CALLED("slk_set(%p, %d, \"%s\", %d)"), (void *) SP_PARM, i, str, format)); 62 63 if (SP_PARM == 0 64 || (slk = SP_PARM->_slk) == 0 65 || i < 1 66 || i > slk->labcnt 67 || format < 0 68 || format > 2) 69 returnCode(ERR); 70 if (str == 0) 71 str = ""; 72 --i; /* Adjust numbering of labels */ 73 74 limit = MAX_SKEY_LEN(SP_PARM->slk_format); 75 while (isspace(UChar(*str))) 76 str++; /* skip over leading spaces */ 77 p = str; 78 79 #if USE_WIDEC_SUPPORT 80 numcols = 0; 81 while (*p != 0) { 82 mbstate_t state; 83 wchar_t wc; 84 size_t need; 85 86 init_mb(state); 87 need = mbrtowc(0, p, strlen(p), &state); 88 if (need == (size_t) -1) 89 break; 90 mbrtowc(&wc, p, need, &state); 91 if (!iswprint((wint_t) wc)) 92 break; 93 if (_nc_wacs_width(wc) + numcols > limit) 94 break; 95 numcols += _nc_wacs_width(wc); 96 p += need; 97 } 98 numchrs = (int) (p - str); 99 #else 100 while (isprint(UChar(*p))) 101 p++; /* The first non-print stops */ 102 103 numcols = (int) (p - str); 104 if (numcols > limit) 105 numcols = limit; 106 numchrs = numcols; 107 #endif 108 109 FreeIfNeeded(slk->ent[i].ent_text); 110 if ((slk->ent[i].ent_text = strdup(str)) == 0) 111 returnCode(ERR); 112 slk->ent[i].ent_text[numchrs] = '\0'; 113 114 if ((slk->ent[i].form_text = (char *) _nc_doalloc(slk->ent[i].form_text, 115 (size_t) (limit + 116 numchrs + 1)) 117 ) == 0) 118 returnCode(ERR); 119 120 switch (format) { 121 case 0: /* left-justified */ 122 offset = 0; 123 break; 124 case 1: /* centered */ 125 offset = (limit - numcols) / 2; 126 break; 127 case 2: /* right-justified */ 128 offset = limit - numcols; 129 break; 130 } 131 if (offset <= 0) 132 offset = 0; 133 else 134 memset(slk->ent[i].form_text, ' ', (size_t) offset); 135 136 memcpy(slk->ent[i].form_text + offset, 137 slk->ent[i].ent_text, 138 (size_t) numchrs); 139 140 if (offset < limit) { 141 memset(slk->ent[i].form_text + offset + numchrs, 142 ' ', 143 (size_t) (limit - (offset + numcols))); 144 } 145 146 slk->ent[i].form_text[numchrs - numcols + limit] = 0; 147 slk->ent[i].dirty = TRUE; 148 returnCode(OK); 149 } 150 151 #if NCURSES_SP_FUNCS 152 NCURSES_EXPORT(int) 153 slk_set(int i, const char *astr, int format) 154 { 155 return NCURSES_SP_NAME(slk_set) (CURRENT_SCREEN, i, astr, format); 156 } 157 #endif 158