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
40void __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 */
48int
49attr_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 */
59int
60attr_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 */
70int
71attr_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 */
81int
82attr_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 */
92int
93color_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 */
102int
103attron(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 */
112int
113attroff(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 */
123int
124attrset(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 */
136int
137wattr_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 */
159int
160wattr_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 */
211int
212wattr_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 */
261int
262wattr_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 */
282int
283wattron(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 */
295int
296wattroff(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 */
309int
310wattrset(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 */
325int
326wcolor_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 */
339chtype
340getattrs(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 */
352chtype
353termattrs(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#ifdef DEBUG
362	__CTRACE(__CTRACE_ATTR, "termattrs: have exit attribute mode\n");
363#endif
364		if (enter_blink_mode != NULL)
365			ch |= __BLINK;
366		if (enter_bold_mode != NULL)
367			ch |= __BOLD;
368		if (enter_dim_mode != NULL)
369			ch |= __DIM;
370		if (enter_secure_mode != NULL)
371			ch |= __BLANK;
372		if (enter_protected_mode != NULL)
373			ch |= __PROTECT;
374		if (enter_reverse_mode != NULL)
375			ch |= __REVERSE;
376	}
377	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
378		ch |= __STANDOUT;
379	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
380		ch |= __UNDERSCORE;
381	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
382		ch |= __ALTCHARSET;
383
384	return ch;
385}
386
387/*
388 * term_attrs --
389 *	Get terminal wide attributes
390 */
391attr_t
392term_attrs(void)
393{
394	attr_t attr = 0;
395
396#ifdef DEBUG
397	__CTRACE(__CTRACE_ATTR, "term_attrs\n");
398#endif
399	if (exit_attribute_mode != NULL) {
400		if (enter_blink_mode != NULL)
401			attr |= __BLINK;
402		if (enter_bold_mode != NULL)
403			attr |= __BOLD;
404		if (enter_dim_mode != NULL)
405			attr |= __DIM;
406		if (enter_secure_mode != NULL)
407			attr |= __BLANK;
408		if (enter_protected_mode != NULL)
409			attr |= __PROTECT;
410		if (enter_reverse_mode != NULL)
411			attr |= __REVERSE;
412#ifdef HAVE_WCHAR
413		if (enter_low_hl_mode != NULL)
414			attr |= WA_LOW;
415		if (enter_top_hl_mode != NULL)
416			attr |= WA_TOP;
417		if (enter_left_hl_mode != NULL)
418			attr |= WA_LEFT;
419		if (enter_right_hl_mode != NULL)
420			attr |= WA_RIGHT;
421		if (enter_horizontal_hl_mode != NULL)
422			attr |= WA_HORIZONTAL;
423		if (enter_vertical_hl_mode != NULL)
424			attr |= WA_VERTICAL;
425#endif /* HAVE_WCHAR */
426	}
427	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
428		attr |= __STANDOUT;
429	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
430		attr |= __UNDERSCORE;
431	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
432		attr |= __ALTCHARSET;
433
434	return attr;
435}
436
437/*
438 * __wcolor_set --
439 * Set color attribute on window
440 */
441void
442__wcolor_set(WINDOW *win, attr_t attr)
443{
444	/* If another color pair is set, turn that off first. */
445	win->wattr &= ~__COLOR;
446	/* If can do color video, set the color pair bits. */
447	if (max_colors != 0 && attr & __COLOR)
448		win->wattr |= attr & __COLOR;
449}
450