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