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