1 /* $OpenBSD: lib_slkset.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */ 2 3 /**************************************************************************** 4 * Copyright (c) 1998-2005,2007 Free Software Foundation, Inc. * 5 * * 6 * Permission is hereby granted, free of charge, to any person obtaining a * 7 * copy of this software and associated documentation files (the * 8 * "Software"), to deal in the Software without restriction, including * 9 * without limitation the rights to use, copy, modify, merge, publish, * 10 * distribute, distribute with modifications, sublicense, and/or sell * 11 * copies of the Software, and to permit persons to whom the Software is * 12 * furnished to do so, subject to the following conditions: * 13 * * 14 * The above copyright notice and this permission notice shall be included * 15 * in all copies or substantial portions of the Software. * 16 * * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 24 * * 25 * Except as contained in this notice, the name(s) of the above copyright * 26 * holders shall not be used in advertising or otherwise to promote the * 27 * sale, use or other dealings in this Software without prior written * 28 * authorization. * 29 ****************************************************************************/ 30 31 /**************************************************************************** 32 * Author: Juergen Pfeifer * 33 * and: Thomas E. Dickey * 34 ****************************************************************************/ 35 36 /* 37 * lib_slkset.c 38 * Set soft label text. 39 */ 40 #include <curses.priv.h> 41 #include <ctype.h> 42 43 #if USE_WIDEC_SUPPORT 44 #if HAVE_WCTYPE_H 45 #include <wctype.h> 46 #endif 47 #endif 48 49 MODULE_ID("$Id: lib_slkset.c,v 1.4 2010/01/12 23:22:06 nicm Exp $") 50 51 NCURSES_EXPORT(int) 52 slk_set(int i, const char *astr, int format) 53 { 54 SLK *slk; 55 int offset; 56 int numchrs; 57 int numcols; 58 int limit; 59 const char *str = astr; 60 const char *p; 61 62 T((T_CALLED("slk_set(%d, \"%s\", %d)"), i, str, format)); 63 64 if (SP == 0 65 || (slk = SP->_slk) == 0 66 || i < 1 67 || i > slk->labcnt 68 || format < 0 69 || format > 2) 70 returnCode(ERR); 71 if (str == NULL) 72 str = ""; 73 --i; /* Adjust numbering of labels */ 74 75 limit = MAX_SKEY_LEN(SP->slk_format); 76 while (isspace(UChar(*str))) 77 str++; /* skip over leading spaces */ 78 p = str; 79 80 #if USE_WIDEC_SUPPORT 81 numcols = 0; 82 while (*p != 0) { 83 mbstate_t state; 84 wchar_t wc; 85 size_t need; 86 87 init_mb(state); 88 need = mbrtowc(0, p, strlen(p), &state); 89 if (need == (size_t) -1) 90 break; 91 mbrtowc(&wc, p, need, &state); 92 if (!iswprint((wint_t) wc)) 93 break; 94 if (wcwidth(wc) + numcols > limit) 95 break; 96 numcols += wcwidth(wc); 97 p += need; 98 } 99 numchrs = (p - str); 100 #else 101 while (isprint(UChar(*p))) 102 p++; /* The first non-print stops */ 103 104 numcols = (p - str); 105 if (numcols > limit) 106 numcols = limit; 107 numchrs = numcols; 108 #endif 109 110 FreeIfNeeded(slk->ent[i].ent_text); 111 if ((slk->ent[i].ent_text = strdup(str)) == 0) 112 returnCode(ERR); 113 slk->ent[i].ent_text[numchrs] = '\0'; 114 115 if ((slk->ent[i].form_text = (char *) _nc_doalloc(slk->ent[i].form_text, 116 (unsigned) (limit + 117 numchrs + 1)) 118 ) == 0) 119 returnCode(ERR); 120 121 switch (format) { 122 default: 123 case 0: /* left-justified */ 124 offset = 0; 125 break; 126 case 1: /* centered */ 127 offset = (limit - numcols) / 2; 128 break; 129 case 2: /* right-justified */ 130 offset = limit - numcols; 131 break; 132 } 133 if (offset <= 0) 134 offset = 0; 135 else 136 memset(slk->ent[i].form_text, ' ', (unsigned) offset); 137 138 memcpy(slk->ent[i].form_text + offset, 139 slk->ent[i].ent_text, 140 (unsigned) numchrs); 141 142 if (offset < limit) { 143 memset(slk->ent[i].form_text + offset + numchrs, 144 ' ', 145 (unsigned) (limit - (offset + numcols))); 146 } 147 148 slk->ent[i].form_text[numchrs - numcols + limit] = 0; 149 slk->ent[i].dirty = TRUE; 150 returnCode(OK); 151 } 152