xref: /netbsd-src/lib/libcurses/attributes.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: attributes.c,v 1.20 2010/02/03 15:34:40 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.20 2010/02/03 15:34:40 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 #ifdef DEBUG
163 	__CTRACE(__CTRACE_ATTR, "wattr_on: win %p, attr %08x\n", win, attr);
164 #endif
165 	/* If can enter modes, set the relevent attribute bits. */
166 	if (exit_attribute_mode != NULL) {
167 		if (attr & __BLINK && enter_blink_mode != NULL)
168 			win->wattr |= __BLINK;
169 		if (attr & __BOLD && enter_bold_mode != NULL)
170 			win->wattr |= __BOLD;
171 		if (attr & __DIM && enter_dim_mode != NULL)
172 			win->wattr |= __DIM;
173 		if (attr & __BLANK && enter_secure_mode != NULL)
174 			win->wattr |= __BLANK;
175 		if (attr & __PROTECT && enter_protected_mode != NULL)
176 			win->wattr |= __PROTECT;
177 		if (attr & __REVERSE && enter_reverse_mode != NULL)
178 			win->wattr |= __REVERSE;
179 #ifdef HAVE_WCHAR
180 		if (attr & WA_LOW && enter_low_hl_mode != NULL)
181 			win->wattr |= WA_LOW;
182 		if (attr & WA_TOP && enter_top_hl_mode != NULL)
183 			win->wattr |= WA_TOP;
184 		if (attr & WA_LEFT && enter_left_hl_mode != NULL)
185 			win->wattr |= WA_LEFT;
186 		if (attr & WA_RIGHT && enter_right_hl_mode != NULL)
187 			win->wattr |= WA_RIGHT;
188 		if (attr & WA_HORIZONTAL && enter_horizontal_hl_mode != NULL)
189 			win->wattr |= WA_HORIZONTAL;
190 		if (attr & WA_VERTICAL && enter_vertical_hl_mode != NULL)
191 			win->wattr |= WA_VERTICAL;
192 #endif /* HAVE_WCHAR */
193 	}
194 	if (attr & __STANDOUT && enter_standout_mode != NULL && exit_standout_mode != NULL)
195 		wstandout(win);
196 	if (attr & __UNDERSCORE && enter_underline_mode != NULL && exit_underline_mode != NULL)
197 		wunderscore(win);
198 	if ((attr_t) attr & __COLOR)
199 		__wcolor_set(win, (attr_t) attr);
200 	return OK;
201 }
202 
203 /*
204  * wattr_off --
205  *	Test and unset wide attributes on window
206  *
207  *	Note that the 'me' sequence unsets all attributes.  We handle
208  *	which attributes should really be set in refresh.c:makech().
209  */
210 /* ARGSUSED */
211 int
212 wattr_off(WINDOW *win, attr_t attr, void *opt)
213 {
214 #ifdef DEBUG
215 	__CTRACE(__CTRACE_ATTR, "wattr_off: win %p, attr %08x\n", win, attr);
216 #endif
217 	/* If can do exit modes, unset the relevent attribute bits. */
218 	if (exit_attribute_mode != NULL) {
219 		if (attr & __BLINK)
220 			win->wattr &= ~__BLINK;
221 		if (attr & __BOLD)
222 			win->wattr &= ~__BOLD;
223 		if (attr & __DIM)
224 			win->wattr &= ~__DIM;
225 		if (attr & __BLANK)
226 			win->wattr &= ~__BLANK;
227 		if (attr & __PROTECT)
228 			win->wattr &= ~__PROTECT;
229 		if (attr & __REVERSE)
230 			win->wattr &= ~__REVERSE;
231 #ifdef HAVE_WCHAR
232 		if (attr & WA_LOW)
233 			win->wattr &= ~WA_LOW;
234 		if (attr & WA_TOP)
235 			win->wattr &= ~WA_TOP;
236 		if (attr & WA_LEFT)
237 			win->wattr &= ~WA_LEFT;
238 		if (attr & WA_RIGHT)
239 			win->wattr &= ~WA_RIGHT;
240 		if (attr & WA_HORIZONTAL)
241 			win->wattr &= ~WA_HORIZONTAL;
242 	if (attr & WA_VERTICAL)
243 			win->wattr &= ~WA_VERTICAL;
244 #endif /* HAVE_WCHAR */
245 	}
246 	if (attr & __STANDOUT)
247 		wstandend(win);
248 	if (attr & __UNDERSCORE)
249 		wunderend(win);
250 	if ((attr_t) attr & __COLOR) {
251 		if (max_colors != 0)
252 			win->wattr &= ~__COLOR;
253 	}
254 	return OK;
255 }
256 
257 /*
258  * wattr_set --
259  *	Set wide attributes and color pair on window
260  */
261 int
262 wattr_set(WINDOW *win, attr_t attr, short pair, void *opt)
263 {
264 #ifdef DEBUG
265 	__CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n",
266 	    win, attr, pair);
267 #endif
268  	wattr_off(win, __ATTRIBUTES, opt);
269 	/*
270 	 * This overwrites any colour setting from the attributes
271 	 * and is compatible with ncurses.
272 	 */
273  	attr = (attr & ~__COLOR) | COLOR_PAIR(pair);
274  	wattr_on(win, attr, opt);
275 	return OK;
276 }
277 
278 /*
279  * wattron --
280  *	Test and set attributes.
281  */
282 int
283 wattron(WINDOW *win, int attr)
284 {
285 #ifdef DEBUG
286 	__CTRACE(__CTRACE_ATTR, "wattron: win %p, attr %08x\n", win, attr);
287 #endif
288 	return wattr_on(win, (attr_t) attr, NULL);
289 }
290 
291 /*
292  * wattroff --
293  *	Test and unset attributes.
294  */
295 int
296 wattroff(WINDOW *win, int attr)
297 {
298 #ifdef DEBUG
299 	__CTRACE(__CTRACE_ATTR, "wattroff: win %p, attr %08x\n", win, attr);
300 #endif
301 	return wattr_off(win, (attr_t) attr, NULL);
302 }
303 
304 /*
305  * wattrset --
306  *	Set specific attribute modes.
307  *	Unset others.
308  */
309 int
310 wattrset(WINDOW *win, int attr)
311 {
312 #ifdef DEBUG
313 	__CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr);
314 #endif
315 	wattr_off(win, __ATTRIBUTES, NULL);
316 	wattr_on(win, (attr_t) attr, NULL);
317 	return OK;
318 }
319 
320 /*
321  * wcolor_set --
322  *	Set color pair on window
323  */
324 /* ARGSUSED */
325 int
326 wcolor_set(WINDOW *win, short pair, void *opt)
327 {
328 #ifdef DEBUG
329 	__CTRACE(__CTRACE_COLOR, "wolor_set: win %p, pair %d\n", win, pair);
330 #endif
331 	__wcolor_set(win, (attr_t) COLOR_PAIR(pair));
332 	return OK;
333 }
334 
335 /*
336  * getattrs --
337  *	Get window attributes.
338  */
339 chtype
340 getattrs(WINDOW *win)
341 {
342 #ifdef DEBUG
343 	__CTRACE(__CTRACE_ATTR, "getattrs: win %p\n", win);
344 #endif
345 	return((chtype) win->wattr);
346 }
347 
348 /*
349  * termattrs --
350  *	Get terminal attributes
351  */
352 chtype
353 termattrs(void)
354 {
355 	chtype ch = 0;
356 
357 #ifdef DEBUG
358 	__CTRACE(__CTRACE_ATTR, "termattrs\n");
359 #endif
360 	if (exit_attribute_mode != NULL) {
361 		if (enter_blink_mode != NULL)
362 			ch |= __BLINK;
363 		if (enter_bold_mode != NULL)
364 			ch |= __BOLD;
365 		if (enter_dim_mode != NULL)
366 			ch |= __DIM;
367 		if (enter_secure_mode != NULL)
368 			ch |= __BLANK;
369 		if (enter_protected_mode != NULL)
370 			ch |= __PROTECT;
371 		if (enter_reverse_mode != NULL)
372 			ch |= __REVERSE;
373 	}
374 	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
375 		ch |= __STANDOUT;
376 	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
377 		ch |= __UNDERSCORE;
378 	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
379 		ch |= __ALTCHARSET;
380 
381 	return ch;
382 }
383 
384 /*
385  * term_attrs --
386  *	Get terminal wide attributes
387  */
388 attr_t
389 term_attrs(void)
390 {
391 	attr_t attr = 0;
392 
393 #ifdef DEBUG
394 	__CTRACE(__CTRACE_ATTR, "term_attrs\n");
395 #endif
396 	if (exit_attribute_mode != NULL) {
397 		if (enter_blink_mode != NULL)
398 			attr |= __BLINK;
399 		if (enter_bold_mode != NULL)
400 			attr |= __BOLD;
401 		if (enter_dim_mode != NULL)
402 			attr |= __DIM;
403 		if (enter_secure_mode != NULL)
404 			attr |= __BLANK;
405 		if (enter_protected_mode != NULL)
406 			attr |= __PROTECT;
407 		if (enter_reverse_mode != NULL)
408 			attr |= __REVERSE;
409 #ifdef HAVE_WCHAR
410 		if (enter_low_hl_mode != NULL)
411 			attr |= WA_LOW;
412 		if (enter_top_hl_mode != NULL)
413 			attr |= WA_TOP;
414 		if (enter_left_hl_mode != NULL)
415 			attr |= WA_LEFT;
416 		if (enter_right_hl_mode != NULL)
417 			attr |= WA_RIGHT;
418 		if (enter_horizontal_hl_mode != NULL)
419 			attr |= WA_HORIZONTAL;
420 		if (enter_vertical_hl_mode != NULL)
421 			attr |= WA_VERTICAL;
422 #endif /* HAVE_WCHAR */
423 	}
424 	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
425 		attr |= __STANDOUT;
426 	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
427 		attr |= __UNDERSCORE;
428 	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
429 		attr |= __ALTCHARSET;
430 
431 	return attr;
432 }
433 
434 /*
435  * __wcolor_set --
436  * Set color attribute on window
437  */
438 void
439 __wcolor_set(WINDOW *win, attr_t attr)
440 {
441 	/* If another color pair is set, turn that off first. */
442 	win->wattr &= ~__COLOR;
443 	/* If can do color video, set the color pair bits. */
444 	if (max_colors != 0 && attr & __COLOR)
445 		win->wattr |= attr & __COLOR;
446 }
447