xref: /netbsd-src/lib/libcurses/attributes.c (revision c9496f6b604074a9451a67df576a5b423068e71e)
1 /*	$NetBSD: attributes.c,v 1.23 2017/01/10 21:56:50 roy Exp $	*/
2 
3 /*-
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Julian Coleman.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __RCSID("$NetBSD: attributes.c,v 1.23 2017/01/10 21:56:50 roy Exp $");
35 #endif				/* not lint */
36 
37 #include "curses.h"
38 #include "curses_private.h"
39 
40 void __wcolor_set(WINDOW *, attr_t);
41 
42 #ifndef _CURSES_USE_MACROS
43 /*
44  * attr_get --
45  *	Get wide attributes and color pair from stdscr
46  */
47 /* ARGSUSED */
48 int
49 attr_get(attr_t *attr, short *pair, void *opt)
50 {
51 	return wattr_get(stdscr, attr, pair, opt);
52 }
53 
54 /*
55  * attr_on --
56  *	Test and set wide attributes on stdscr
57  */
58 /* ARGSUSED */
59 int
60 attr_on(attr_t attr, void *opt)
61 {
62 	return wattr_on(stdscr, attr, opt);
63 }
64 
65 /*
66  * attr_off --
67  *	Test and unset wide attributes on stdscr
68  */
69 /* ARGSUSED */
70 int
71 attr_off(attr_t attr, void *opt)
72 {
73 	return wattr_off(stdscr, attr, opt);
74 }
75 
76 /*
77  * attr_set --
78  *	Set wide attributes and color pair on stdscr
79  */
80 /* ARGSUSED */
81 int
82 attr_set(attr_t attr, short pair, void *opt)
83 {
84 	return wattr_set(stdscr, attr, pair, opt);
85 }
86 
87 /*
88  * color_set --
89  *	Set color pair on stdscr
90  */
91 /* ARGSUSED */
92 int
93 color_set(short pair, void *opt)
94 {
95 	return wcolor_set(stdscr, pair, opt);
96 }
97 
98 /*
99  * attron --
100  *	Test and set attributes on stdscr
101  */
102 int
103 attron(int attr)
104 {
105 	return wattr_on(stdscr, (attr_t) attr, NULL);
106 }
107 
108 /*
109  * attroff --
110  *	Test and unset attributes on stdscr.
111  */
112 int
113 attroff(int attr)
114 {
115 	return wattr_off(stdscr, (attr_t) attr, NULL);
116 }
117 
118 /*
119  * attrset --
120  *	Set specific attribute modes.
121  *	Unset others.  On stdscr.
122  */
123 int
124 attrset(int attr)
125 {
126 	return wattrset(stdscr, attr);
127 }
128 #endif	/* _CURSES_USE_MACROS */
129 
130 /*
131  * wattr_get --
132  *	Get wide attributes and colour pair from window
133  *	Note that attributes also includes colour.
134  */
135 /* ARGSUSED */
136 int
137 wattr_get(WINDOW *win, attr_t *attr, short *pair, void *opt)
138 {
139 #ifdef DEBUG
140 	__CTRACE(__CTRACE_ATTR, "wattr_get: win %p\n", win);
141 #endif
142 	if (attr != NULL) {
143 		*attr = win->wattr;
144 #ifdef HAVE_WCHAR
145 		*attr &= WA_ATTRIBUTES;
146 #endif
147 	}
148 
149 	if (pair != NULL)
150 		*pair = PAIR_NUMBER(win->wattr);
151 	return OK;
152 }
153 
154 /*
155  * wattr_on --
156  *	Test and set wide attributes on window
157  */
158 /* ARGSUSED */
159 int
160 wattr_on(WINDOW *win, attr_t attr, void *opt)
161 {
162 	const TERMINAL *t = win->screen->term;
163 
164 #ifdef DEBUG
165 	__CTRACE(__CTRACE_ATTR, "wattr_on: win %p, attr %08x\n", win, attr);
166 #endif
167 	/* If can enter modes, set the relevent attribute bits. */
168 	if (t_exit_attribute_mode(t) != NULL) {
169 		if (attr & __BLINK && t_enter_blink_mode(t) != NULL)
170 			win->wattr |= __BLINK;
171 		if (attr & __BOLD && t_enter_bold_mode(t) != NULL)
172 			win->wattr |= __BOLD;
173 		if (attr & __DIM && t_enter_dim_mode(t) != NULL)
174 			win->wattr |= __DIM;
175 		if (attr & __BLANK && t_enter_secure_mode(t) != NULL)
176 			win->wattr |= __BLANK;
177 		if (attr & __PROTECT && t_enter_protected_mode(t) != NULL)
178 			win->wattr |= __PROTECT;
179 		if (attr & __REVERSE && t_enter_reverse_mode(t) != NULL)
180 			win->wattr |= __REVERSE;
181 #ifdef HAVE_WCHAR
182 		if (attr & WA_LOW && t_enter_low_hl_mode(t) != NULL)
183 			win->wattr |= WA_LOW;
184 		if (attr & WA_TOP && t_enter_top_hl_mode(t) != NULL)
185 			win->wattr |= WA_TOP;
186 		if (attr & WA_LEFT && t_enter_left_hl_mode(t) != NULL)
187 			win->wattr |= WA_LEFT;
188 		if (attr & WA_RIGHT && t_enter_right_hl_mode(t) != NULL)
189 			win->wattr |= WA_RIGHT;
190 		if (attr & WA_HORIZONTAL && t_enter_horizontal_hl_mode(t) != NULL)
191 			win->wattr |= WA_HORIZONTAL;
192 		if (attr & WA_VERTICAL && t_enter_vertical_hl_mode(t) != NULL)
193 			win->wattr |= WA_VERTICAL;
194 #endif /* HAVE_WCHAR */
195 	}
196 	if (attr & __STANDOUT && t_enter_standout_mode(t) != NULL &&
197 	    t_exit_standout_mode(t) != NULL)
198 		wstandout(win);
199 	if (attr & __UNDERSCORE && t_enter_underline_mode(t) != NULL &&
200 	    t_exit_underline_mode(t) != NULL)
201 		wunderscore(win);
202 	if ((attr_t) attr & __COLOR)
203 		__wcolor_set(win, (attr_t) attr);
204 	return OK;
205 }
206 
207 /*
208  * wattr_off --
209  *	Test and unset wide attributes on window
210  *
211  *	Note that the 'me' sequence unsets all attributes.  We handle
212  *	which attributes should really be set in refresh.c:makech().
213  */
214 /* ARGSUSED */
215 int
216 wattr_off(WINDOW *win, attr_t attr, void *opt)
217 {
218 	const TERMINAL *t = win->screen->term;
219 
220 #ifdef DEBUG
221 	__CTRACE(__CTRACE_ATTR, "wattr_off: win %p, attr %08x\n", win, attr);
222 #endif
223 	/* If can do exit modes, unset the relevent attribute bits. */
224 	if (t_exit_attribute_mode(t) != NULL) {
225 		if (attr & __BLINK)
226 			win->wattr &= ~__BLINK;
227 		if (attr & __BOLD)
228 			win->wattr &= ~__BOLD;
229 		if (attr & __DIM)
230 			win->wattr &= ~__DIM;
231 		if (attr & __BLANK)
232 			win->wattr &= ~__BLANK;
233 		if (attr & __PROTECT)
234 			win->wattr &= ~__PROTECT;
235 		if (attr & __REVERSE)
236 			win->wattr &= ~__REVERSE;
237 #ifdef HAVE_WCHAR
238 		if (attr & WA_LOW)
239 			win->wattr &= ~WA_LOW;
240 		if (attr & WA_TOP)
241 			win->wattr &= ~WA_TOP;
242 		if (attr & WA_LEFT)
243 			win->wattr &= ~WA_LEFT;
244 		if (attr & WA_RIGHT)
245 			win->wattr &= ~WA_RIGHT;
246 		if (attr & WA_HORIZONTAL)
247 			win->wattr &= ~WA_HORIZONTAL;
248 	if (attr & WA_VERTICAL)
249 			win->wattr &= ~WA_VERTICAL;
250 #endif /* HAVE_WCHAR */
251 	}
252 	if (attr & __STANDOUT)
253 		wstandend(win);
254 	if (attr & __UNDERSCORE)
255 		wunderend(win);
256 	if ((attr_t) attr & __COLOR) {
257 		if (max_colors != 0)
258 			win->wattr &= ~__COLOR;
259 	}
260 	return OK;
261 }
262 
263 /*
264  * wattr_set --
265  *	Set wide attributes and color pair on window
266  */
267 int
268 wattr_set(WINDOW *win, attr_t attr, short pair, void *opt)
269 {
270 #ifdef DEBUG
271 	__CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n",
272 	    win, attr, pair);
273 #endif
274 	wattr_off(win, __ATTRIBUTES, opt);
275 	/*
276 	 * This overwrites any colour setting from the attributes
277 	 * and is compatible with ncurses.
278 	 */
279 	attr = (attr & ~__COLOR) | COLOR_PAIR(pair);
280 	wattr_on(win, attr, opt);
281 	return OK;
282 }
283 
284 /*
285  * wattron --
286  *	Test and set attributes.
287  */
288 int
289 wattron(WINDOW *win, int attr)
290 {
291 #ifdef DEBUG
292 	__CTRACE(__CTRACE_ATTR, "wattron: win %p, attr %08x\n", win, attr);
293 #endif
294 	return wattr_on(win, (attr_t) attr, NULL);
295 }
296 
297 /*
298  * wattroff --
299  *	Test and unset attributes.
300  */
301 int
302 wattroff(WINDOW *win, int attr)
303 {
304 #ifdef DEBUG
305 	__CTRACE(__CTRACE_ATTR, "wattroff: win %p, attr %08x\n", win, attr);
306 #endif
307 	return wattr_off(win, (attr_t) attr, NULL);
308 }
309 
310 /*
311  * wattrset --
312  *	Set specific attribute modes.
313  *	Unset others.
314  */
315 int
316 wattrset(WINDOW *win, int attr)
317 {
318 #ifdef DEBUG
319 	__CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr);
320 #endif
321 	wattr_off(win, __ATTRIBUTES, NULL);
322 	wattr_on(win, (attr_t) attr, NULL);
323 	return OK;
324 }
325 
326 /*
327  * wcolor_set --
328  *	Set color pair on window
329  */
330 /* ARGSUSED */
331 int
332 wcolor_set(WINDOW *win, short pair, void *opt)
333 {
334 #ifdef DEBUG
335 	__CTRACE(__CTRACE_COLOR, "wolor_set: win %p, pair %d\n", win, pair);
336 #endif
337 	__wcolor_set(win, (attr_t) COLOR_PAIR(pair));
338 	return OK;
339 }
340 
341 /*
342  * getattrs --
343  *	Get window attributes.
344  */
345 chtype
346 getattrs(WINDOW *win)
347 {
348 #ifdef DEBUG
349 	__CTRACE(__CTRACE_ATTR, "getattrs: win %p\n", win);
350 #endif
351 	return((chtype) win->wattr);
352 }
353 
354 /*
355  * termattrs --
356  *	Get terminal attributes
357  */
358 chtype
359 termattrs(void)
360 {
361 	chtype ch = 0;
362 
363 #ifdef DEBUG
364 	__CTRACE(__CTRACE_ATTR, "termattrs\n");
365 #endif
366 	if (exit_attribute_mode != NULL) {
367 #ifdef DEBUG
368 	__CTRACE(__CTRACE_ATTR, "termattrs: have exit attribute mode\n");
369 #endif
370 		if (enter_blink_mode != NULL)
371 			ch |= __BLINK;
372 		if (enter_bold_mode != NULL)
373 			ch |= __BOLD;
374 		if (enter_dim_mode != NULL)
375 			ch |= __DIM;
376 		if (enter_secure_mode != NULL)
377 			ch |= __BLANK;
378 		if (enter_protected_mode != NULL)
379 			ch |= __PROTECT;
380 		if (enter_reverse_mode != NULL)
381 			ch |= __REVERSE;
382 	}
383 	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
384 		ch |= __STANDOUT;
385 	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
386 		ch |= __UNDERSCORE;
387 	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
388 		ch |= __ALTCHARSET;
389 
390 	return ch;
391 }
392 
393 /*
394  * term_attrs --
395  *	Get terminal wide attributes
396  */
397 attr_t
398 term_attrs(void)
399 {
400 	attr_t attr = 0;
401 
402 #ifdef DEBUG
403 	__CTRACE(__CTRACE_ATTR, "term_attrs\n");
404 #endif
405 	if (exit_attribute_mode != NULL) {
406 		if (enter_blink_mode != NULL)
407 			attr |= __BLINK;
408 		if (enter_bold_mode != NULL)
409 			attr |= __BOLD;
410 		if (enter_dim_mode != NULL)
411 			attr |= __DIM;
412 		if (enter_secure_mode != NULL)
413 			attr |= __BLANK;
414 		if (enter_protected_mode != NULL)
415 			attr |= __PROTECT;
416 		if (enter_reverse_mode != NULL)
417 			attr |= __REVERSE;
418 #ifdef HAVE_WCHAR
419 		if (enter_low_hl_mode != NULL)
420 			attr |= WA_LOW;
421 		if (enter_top_hl_mode != NULL)
422 			attr |= WA_TOP;
423 		if (enter_left_hl_mode != NULL)
424 			attr |= WA_LEFT;
425 		if (enter_right_hl_mode != NULL)
426 			attr |= WA_RIGHT;
427 		if (enter_horizontal_hl_mode != NULL)
428 			attr |= WA_HORIZONTAL;
429 		if (enter_vertical_hl_mode != NULL)
430 			attr |= WA_VERTICAL;
431 #endif /* HAVE_WCHAR */
432 	}
433 	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
434 		attr |= __STANDOUT;
435 	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
436 		attr |= __UNDERSCORE;
437 	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
438 		attr |= __ALTCHARSET;
439 
440 	return attr;
441 }
442 
443 /*
444  * __wcolor_set --
445  * Set color attribute on window
446  */
447 void
448 __wcolor_set(WINDOW *win, attr_t attr)
449 {
450 	const TERMINAL *t = win->screen->term;
451 
452 	/* If another color pair is set, turn that off first. */
453 	win->wattr &= ~__COLOR;
454 	/* If can do color video, set the color pair bits. */
455 	if (t_max_colors(t) != 0 && attr & __COLOR)
456 		win->wattr |= attr & __COLOR;
457 }
458