1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1995-1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /* LINTLIBRARY */
30
31 /*
32 * slk.c
33 *
34 * XCurses Library
35 *
36 * Copyright 1990, 1995 by Mortice Kern Systems Inc. All rights reserved.
37 *
38 */
39
40 #if M_RCSID
41 #ifndef lint
42 static char rcsID[] =
43 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/"
44 "libxcurses/src/libc/xcurses/rcs/slk.c 1.9 1998/05/20 17:26:23 "
45 "cbates Exp $";
46 #endif
47 #endif
48
49 #include <private.h>
50 #include <string.h>
51
52 int __m_slk_labels_on;
53 int __m_slk_touched = 0;
54 /*
55 * Flag for initialisation soft label keys once setupterm() has been called.
56 */
57 int
slk_init(int fmt)58 slk_init(int fmt)
59 {
60 int code = ERR;
61
62 if (0 <= fmt && fmt <= 1) {
63 __m_slk_format = fmt;
64 __m_slk_labels_on = 1;
65 code = OK;
66 }
67
68 return (code);
69 }
70
71 int
slk_attron(const chtype at)72 slk_attron(const chtype at)
73 {
74 int code = OK;
75
76 if (__m_screen->_slk._w != NULL)
77 code = wattron(__m_screen->_slk._w, (int) at);
78
79 return (code);
80 }
81
82 int
slk_attroff(const chtype at)83 slk_attroff(const chtype at)
84 {
85 int code = OK;
86
87 if (__m_screen->_slk._w != NULL)
88 code = wattroff(__m_screen->_slk._w, (int) at);
89
90 return (code);
91 }
92
93 int
slk_attrset(const chtype at)94 slk_attrset(const chtype at)
95 {
96 int code = OK;
97
98 if (__m_screen->_slk._w != NULL)
99 code = wattrset(__m_screen->_slk._w, (int) at);
100
101 return (code);
102 }
103
104 int
slk_attr_off(const attr_t at,void * opts)105 slk_attr_off(const attr_t at, void *opts)
106 {
107 int code = OK;
108
109 if (__m_screen->_slk._w != NULL)
110 code = wattr_off(__m_screen->_slk._w, at, opts);
111
112 return (code);
113 }
114
115 int
slk_attr_on(const attr_t at,void * opts)116 slk_attr_on(const attr_t at, void *opts)
117 {
118 int code = OK;
119
120 if (__m_screen->_slk._w != NULL)
121 code = wattr_on(__m_screen->_slk._w, at, opts);
122
123 return (code);
124 }
125
126 int
slk_attr_set(const attr_t at,short co,void * opts)127 slk_attr_set(const attr_t at, short co, void *opts)
128 {
129 int code = OK;
130
131 if (__m_screen->_slk._w != NULL)
132 code = wattr_set(__m_screen->_slk._w, at, co, opts);
133
134 return (code);
135 }
136
137 int
slk_color(short co)138 slk_color(short co)
139 {
140 int code = OK;
141
142 if (__m_screen->_slk._w != NULL)
143 code = wcolor_set(__m_screen->_slk._w, co, (void *) 0);
144
145 return (code);
146 }
147
148 int
slk_touch(void)149 slk_touch(void)
150 {
151 int code = OK;
152 WINDOW *w = __m_screen->_slk._w;
153
154 if (w != NULL) {
155 code = wtouchln(w, 0, 1, 1);
156 wtouchln_hard(w, 0, 1);
157 } else
158 __m_slk_touched = 1;
159
160 return (code);
161 }
162
163 /*
164 * These label start columns assume 80 columns in order to
165 * fit 8 _slk._labels of 8 columns.
166 */
167 static const int format[][8] = {
168 { 0, 9, 18, 31, 40, 53, 62, 71 },
169 { 0, 9, 18, 27, 44, 53, 62, 71 },
170 };
171
172 #define _LABEL_LENGTH_MALLOC \
173 (MB_LEN_MAX * ((1 + _M_CCHAR_MAX) * 8) + 1)
174
175 void
__m_slk_set_all(void)176 __m_slk_set_all(void)
177 {
178 int i;
179
180 for (i = 0; i < 8; ++i) {
181 if (__m_screen->_slk._labels[i] != NULL) {
182 (void) slk_set(i + 1, __m_screen->_slk._labels[i],
183 __m_screen->_slk._justify[i]);
184 }
185 }
186 }
187
188 int
__m_slk_clear(int kluge)189 __m_slk_clear(int kluge)
190 {
191 int i;
192 int index;
193 int code = ERR;
194
195 if (__m_screen->_slk._w != NULL) {
196 cchar_t _bg = __m_screen->_slk._w->_bg;
197 if (kluge) {
198 /* Test suite expects spaces to have FG attributes */
199 __m_screen->_slk._w->_bg = __m_screen->_slk._w->_fg;
200 }
201 for (index = 0; index < 8; ++index) {
202 i = format[__m_slk_format][index];
203 (void) __m_cc_erase(__m_screen->_slk._w,
204 0, i, 0, i + 7);
205 }
206 __m_screen->_slk._w->_bg = _bg; /* Restore ... */
207
208 } else if (plab_norm != NULL) {
209 for (index = 0; index < 8; ++index) {
210 char *p;
211 p = __m_screen->_slk._saved[index];
212 if (!p) {
213 p = (char *)malloc(_LABEL_LENGTH_MALLOC);
214 if (p == NULL)
215 goto error;
216 __m_screen->_slk._saved[index] = p;
217 }
218 (void) strcpy(p, (kluge) ? "" : " ");
219 }
220 }
221 if (__m_screen->_slk._w != NULL) {
222 code = wrefresh(__m_screen->_slk._w);
223 } else {
224 __m_slk_labels_on = 0;
225 code = slk_refresh();
226 }
227
228 error:
229 return (code);
230 }
231
232 int
slk_clear(void)233 slk_clear(void)
234 {
235 return (__m_slk_clear(0));
236 }
237
238 int
slk_restore(void)239 slk_restore(void)
240 {
241 int code;
242
243 __m_slk_set_all();
244 __m_slk_labels_on = 1;
245 code = slk_refresh();
246 return (code);
247 }
248
249 int
slk_noutrefresh(void)250 slk_noutrefresh(void)
251 {
252 int code;
253
254 if (__m_screen->_slk._w != NULL)
255 code = wnoutrefresh(__m_screen->_slk._w);
256 else {
257 if (__m_slk_touched) {
258 __m_slk_set_all();
259 __m_slk_touched = 0;
260 }
261 if (__m_slk_labels_on) {
262 if (label_on != NULL) {
263 (void) TPUTS(label_on, 1, __m_outc);
264 }
265 } else {
266 if (label_off != NULL) {
267 (void) TPUTS(label_off, 1, __m_outc);
268 }
269 }
270 (void) fflush(__m_screen->_of);
271 code = OK;
272 }
273
274 return (code);
275 }
276
277 int
slk_refresh(void)278 slk_refresh(void)
279 {
280 int code;
281
282 if ((code = slk_noutrefresh()) == OK)
283 code = doupdate();
284
285 return (code);
286 }
287
288 void
__m_slk_doupdate(void)289 __m_slk_doupdate(void)
290 {
291 if ((__m_screen->_slk._w == NULL) && plab_norm) {
292 int index;
293 for (index = 0; index < 8; index++) {
294 char *s = __m_screen->_slk._saved[index];
295 if (s) {
296 (void) TPUTS(tparm(plab_norm, (long) index+1,
297 (long) s, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
298 1, __m_outc);
299 }
300 }
301 }
302 }
303
304 char *
slk_label(int index)305 slk_label(int index)
306 {
307 char *label;
308
309 if (index < 1 || 8 < index) {
310 label = NULL;
311 } else {
312 label = __m_screen->_slk._labels[index-1];
313 }
314 return (label);
315 }
316
317 int
slk_set(int index,const char * label,int justify)318 slk_set(int index, const char *label, int justify)
319 {
320 int code = ERR;
321 wchar_t wcs[_M_CCHAR_MAX * 8 + 1];
322
323 if ((label == NULL) || *label == '\0')
324 label = " ";
325 if (mbstowcs(wcs, label, sizeof (wcs)) != (size_t)-1)
326 code = slk_wset(index, wcs, justify);
327
328 return (code);
329 }
330
331 int
slk_wset(int index,const wchar_t * label,int justify)332 slk_wset(int index, const wchar_t *label, int justify)
333 {
334 cchar_t cc;
335 int i, width, code = ERR;
336 wchar_t wcs[_M_CCHAR_MAX * 8 + 1], *wp;
337 char mbs[_LABEL_LENGTH_MALLOC];
338 char tmbs[_LABEL_LENGTH_MALLOC];
339 int ww = 0;
340 int left1, left2;
341 static const char *spcs = " ";
342
343 if (index < 1 || 8 < index || justify < 0 || 2 < justify)
344 goto error1;
345
346 index--; /* Shift from {1..8} to {0..7} */
347
348 if (label == NULL)
349 label = L"";
350
351 /* Copy the characters that fill the first 8 columns of the label. */
352 for (wp = wcs, width = 0; *label != '\0'; label += i, wp += cc._n) {
353 if ((i = __m_wcs_cc(label, A_NORMAL, 0, &cc)) < 0)
354 goto error1;
355
356 ww += __m_cc_width(&cc);
357 if (ww > 8)
358 break;
359 else
360 width = ww;
361
362 (void) wcsncpy(wp, cc._wc, cc._n);
363 }
364 *wp = '\0';
365
366 if (wcstombs(tmbs, wcs, sizeof (mbs)) == (size_t) -1)
367 goto error1;
368
369 if (width == 8) {
370 (void) strcpy(mbs, tmbs);
371 } else {
372 switch (justify) {
373 case 0:
374 (void) strcpy(mbs, tmbs);
375 (void) strncat(mbs, spcs, (8 - width));
376 *(mbs + strlen(tmbs) + (8 - width)) = '\0';
377 break;
378 case 1:
379 left1 = (8 - width) / 2;
380 (void) strncpy(mbs, spcs, left1);
381 (void) strcpy(mbs + left1, tmbs);
382 left2 = 8 - width - left1;
383 (void) strncat(mbs, spcs, left2);
384 *(mbs + left1 + strlen(tmbs) + left2) = '\0';
385 break;
386 case 2:
387 left1 = 8 - width;
388 (void) strncpy(mbs, spcs, left1);
389 (void) strcpy(mbs + left1, tmbs);
390 break;
391 }
392 }
393
394 /* Remember the new label. */
395 __m_screen->_slk._justify[index] = (short) justify;
396
397 if (__m_screen->_slk._labels[index] != NULL)
398 free(__m_screen->_slk._labels[index]);
399 if ((__m_screen->_slk._labels[index] = strdup(tmbs)) == NULL)
400 goto error1;
401
402 if (plab_norm != NULL) {
403 char *p;
404 p = __m_screen->_slk._saved[index];
405 if (!p) {
406 p = (char *)malloc(_LABEL_LENGTH_MALLOC);
407 if (p == NULL)
408 goto error1;
409 __m_screen->_slk._saved[index] = p;
410 }
411 (void) strcpy(p, mbs);
412 }
413
414 __m_slk_labels_on = 1;
415
416 if (__m_screen->_slk._w != NULL) {
417 cchar_t _bg = __m_screen->_slk._w->_bg;
418 /* Write the justified label into the slk window. */
419 i = format[__m_slk_format][index];
420 __m_screen->_slk._w->_bg = __m_screen->_slk._w->_fg;
421 (void) __m_cc_erase(__m_screen->_slk._w, 0, i, 0, i + 7);
422 __m_screen->_slk._w->_bg = _bg; /* Restore ... */
423
424 (void) mvwaddstr(__m_screen->_slk._w, 0, i, mbs);
425 }
426
427 code = OK;
428 error1:
429 return (code);
430 }
431