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, by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 /*
28  * slk.c
29  *
30  * XCurses Library
31  *
32  * Copyright 1990, 1995 by Mortice Kern Systems Inc.  All rights reserved.
33  *
34  */
35 
36 #include <private.h>
37 
38 /*
39  * Flag for initialisation soft label keys once setupterm() has been called.
40  */
41 int
slk_init(int fmt)42 slk_init(int fmt)
43 {
44 	int code = ERR;
45 
46 #ifdef M_CURSES_TRACE
47 	__m_trace("slk_init(%d)", fmt);
48 #endif
49 
50 	if (0 <= fmt && fmt <= 1) {
51 		__m_slk_format = fmt;
52 		code = OK;
53 	}
54 
55 	return __m_return_code("slk_init", code);
56 }
57 
58 int
slk_attron(const chtype at)59 slk_attron(const chtype at)
60 {
61 	int code = ERR;
62 
63 #ifdef M_CURSES_TRACE
64 	__m_trace("slk_attron(%lx)", at);
65 #endif
66 
67 	if (__m_screen->_slk._w != NULL)
68 		code = wattron(__m_screen->_slk._w, at);
69 
70 	return __m_return_code("slk_attron", code);
71 }
72 
73 int
slk_attroff(const chtype at)74 slk_attroff(const chtype at)
75 {
76 	int code = ERR;
77 
78 #ifdef M_CURSES_TRACE
79 	__m_trace("slk_attroff(%lx)", at);
80 #endif
81 
82 	if (__m_screen->_slk._w != NULL)
83 		code = wattroff(__m_screen->_slk._w, at);
84 
85 	return __m_return_code("slk_attroff", code);
86 }
87 
88 int
slk_attrset(const chtype at)89 slk_attrset(const chtype at)
90 {
91 	int code = ERR;
92 
93 #ifdef M_CURSES_TRACE
94 	__m_trace("slk_attrset(%lx)", at);
95 #endif
96 
97 	if (__m_screen->_slk._w != NULL)
98 		code = wattrset(__m_screen->_slk._w, at);
99 
100 	return __m_return_code("slk_attrset", code);
101 }
102 
103 int
slk_attr_off(const attr_t at,void * opts)104 slk_attr_off(const attr_t at, void *opts)
105 {
106 	int code = ERR;
107 
108 #ifdef M_CURSES_TRACE
109 	__m_trace("slk_attr_off(%x, %p)", at, opts);
110 #endif
111 
112 	if (__m_screen->_slk._w != NULL)
113 		code = wattr_off(__m_screen->_slk._w, at, opts);
114 
115 	return __m_return_code("slk_attr_off", code);
116 }
117 
118 int
slk_attr_on(const attr_t at,void * opts)119 slk_attr_on(const attr_t at, void *opts)
120 {
121 	int code = ERR;
122 
123 #ifdef M_CURSES_TRACE
124 	__m_trace("slk_attr_on(%x, %p)", at, opts);
125 #endif
126 
127 	if (__m_screen->_slk._w != NULL)
128 		code = wattr_on(__m_screen->_slk._w, at, opts);
129 
130 	return __m_return_code("slk_attr_on", code);
131 }
132 
133 int
slk_attr_set(const attr_t at,short co,void * opts)134 slk_attr_set(const attr_t at, short co, void *opts)
135 {
136 	int code = ERR;
137 
138 #ifdef M_CURSES_TRACE
139 	__m_trace("slk_attr_set(%x, %d, %p)", at, co, opts);
140 #endif
141 
142 	if (__m_screen->_slk._w != NULL)
143 		code = wattr_set(__m_screen->_slk._w, at, co, opts);
144 
145 	return __m_return_code("slk_attr_set", code);
146 }
147 
148 int
slk_color(short co)149 slk_color(short co)
150 {
151 	int code = ERR;
152 
153 #ifdef M_CURSES_TRACE
154 	__m_trace("slk_color(%d)", co);
155 #endif
156 
157 	if (__m_screen->_slk._w != NULL)
158 		code = wcolor_set(__m_screen->_slk._w, co, NULL);
159 
160 	return __m_return_code("slk_color", code);
161 }
162 
163 int
slk_touch()164 slk_touch()
165 {
166 	int code = ERR;
167 
168 #ifdef M_CURSES_TRACE
169 	__m_trace("slk_touch(void)");
170 #endif
171 
172 	if (__m_screen->_slk._w != NULL)
173 		code = wtouchln(__m_screen->_slk._w, 0, 1, 1);
174 
175 	return __m_return_code("slk_touch", code);
176 }
177 
178 int
slk_clear()179 slk_clear()
180 {
181 	int code = ERR;
182 
183 #ifdef M_CURSES_TRACE
184 	__m_trace("slk_clear(void)");
185 #endif
186 
187 	if (__m_screen->_slk._w != NULL) {
188 		if (werase(__m_screen->_slk._w) == OK)
189 			code = wrefresh(__m_screen->_slk._w);
190 	} else if (label_off != NULL) {
191 		(void) tputs(label_off, 1, __m_outc);
192 		(void) fflush(__m_screen->_of);
193 		code = OK;
194 	}
195 
196 	return __m_return_code("slk_clear", code);
197 }
198 
199 int
slk_restore()200 slk_restore()
201 {
202 	int i, code = ERR;
203 
204 #ifdef M_CURSES_TRACE
205 	__m_trace("slk_clear(void)");
206 #endif
207 
208 	if (__m_screen->_slk._w != NULL) {
209 		for (i = 0; i < 8; ++i) {
210 			if (__m_screen->_slk._labels[i] != NULL) {
211 				(void) slk_set(
212 					i, __m_screen->_slk._labels[i],
213 					__m_screen->_slk._justify[i]
214 				);
215 			}
216 		}
217 
218 		code = slk_refresh();
219 	} else if (label_on != NULL) {
220 		(void) tputs(label_on, 1, __m_outc);
221 		(void) fflush(__m_screen->_of);
222 		code = OK;
223 	}
224 
225 	return __m_return_code("slk_clear", code);
226 }
227 
228 int
slk_noutrefresh()229 slk_noutrefresh()
230 {
231 	int code = ERR;
232 
233 #ifdef M_CURSES_TRACE
234 	__m_trace("slk_noutrefresh(void)");
235 #endif
236 
237 	if (__m_screen->_slk._w != NULL)
238 		code = wnoutrefresh(__m_screen->_slk._w);
239 
240 	return __m_return_code("slk_noutrefresh", code);
241 }
242 
243 int
slk_refresh()244 slk_refresh()
245 {
246 	int code = ERR;
247 
248 #ifdef M_CURSES_TRACE
249 	__m_trace("slk_refresh(void)");
250 #endif
251 
252 	if ((code = slk_noutrefresh()) == OK)
253 		code = doupdate();
254 
255 	return __m_return_code("slk_refresh", code);
256 }
257 
258 char *
slk_label(int index)259 slk_label(int index)
260 {
261 #ifdef M_CURSES_TRACE
262 	__m_trace("slk_label(%d)", index);
263 #endif
264 
265 	return __m_return_pointer("slk_label", __m_screen->_slk._labels[index]);
266 }
267 
268 int
slk_set(int index,const char * label,int justify)269 slk_set(int index, const char *label, int justify)
270 {
271 	int code = ERR;
272 	wchar_t wcs[M_CCHAR_MAX * 8 + 1];
273 
274 #ifdef M_CURSES_TRACE
275 	__m_trace("slk_set(%d, %p, %d)", index, label, justify);
276 #endif
277 
278 	if (0 < mbstowcs(wcs, label, sizeof wcs))
279 		code = slk_wset(index, wcs, justify);
280 
281 	return __m_return_code("slk_set", code);
282 }
283 
284 int
slk_wset(int index,const wchar_t * label,int justify)285 slk_wset(int index, const wchar_t *label, int justify)
286 {
287 	cchar_t cc;
288 	short (*k)[2];
289 	int i, width, code = ERR;
290 	wchar_t wcs[M_CCHAR_MAX * 8 + 1], *wp;
291 	char mbs[MB_LEN_MAX * ((1 + M_CCHAR_MAX) * 8) + 1];
292 
293 	/*
294 	 * These label start columns assume 80 columns in order to
295 	 * fit 8 _slk._labels of 8 columns.
296 	 */
297 	static short format[][8] = {
298 		{ 0, 10, 20, 31, 41, 52, 62, 72 },
299 		{ 0, 10, 20, 30, 42, 52, 62, 72 },
300 	};
301 
302 #ifdef M_CURSES_TRACE
303 	__m_trace("slk_wset(%d, %p, %d)", index, label, justify);
304 #endif
305 
306 	if (index < 1 || 8 < index || justify < 0 || 2 < justify)
307 		goto error1;
308 
309 	if (label == NULL)
310 		label = M_MB_L("");
311 
312 	/* Copy the characters that fill the first 8 columns of the label. */
313 	for (wp = wcs, width = 0; *label != '\0'; label += i, wp += cc._n) {
314 		if ((i = __m_wcs_cc(label, A_NORMAL, 0, &cc)) < 0)
315 			goto error1;
316 
317 
318 		if (8 < (width += __m_cc_width(&cc)))
319 			break;
320 
321 		(void) wcsncpy(wp, cc._wc, cc._n);
322 	}
323 	*wp = '\0';
324 
325 	if (wcstombs(mbs, wcs, sizeof mbs) == (size_t) -1)
326 		goto error1;
327 
328 	/* Remember the new label. */
329 	__m_screen->_slk._justify[index] = (short) justify;
330 	if (__m_screen->_slk._labels[index] != NULL)
331 		free(__m_screen->_slk._labels[index]);
332 	if ((__m_screen->_slk._labels[index] = m_strdup(mbs)) == NULL)
333 		goto error1;
334 
335 	if (__m_screen->_slk._w != NULL) {
336 		/* Write the justified label into the slk window. */
337 		i = format[__m_slk_format][index];
338 		(void) __m_cc_erase(__m_screen->_slk._w, 0, i, 0, i + 7);
339 
340 		switch (justify) {
341 		case 0:
342 			break;
343 		case 1:
344 			i += width / 2;
345 			break;
346 		case 2:
347 			i = i + 8 - width;
348 			break;
349 		}
350 
351 		(void) mvwaddstr(__m_screen->_slk._w, 0, i, mbs);
352 	} else if (plab_norm != NULL) {
353 		(void) tputs(
354 			tparm(
355 				plab_norm, (long) index, (long) mbs,
356 				0L, 0L, 0L, 0L, 0L, 0L, 0L
357 			), 1, __m_outc
358 		);
359 	} else if (pkey_plab != NULL) {
360 		/* Lookup multibyte sequence for the function key. */
361 		for (i = KEY_F(index), k = __m_keyindex; (*k)[1] != i; ++k)
362 			;
363 
364 		if (cur_term->_str[**k] != NULL) {
365 			(void) tputs(
366 				tparm(
367 					pkey_plab, (long) index,
368 					(long) cur_term->_str[**k],
369 					(long) mbs, 0L, 0L, 0L, 0L, 0L, 0L
370 				), 1, __m_outc
371 			);
372 		}
373 	}
374 
375 	code = OK;
376 error1:
377 	return __m_return_code("slk_wset", code);
378 }
379