Home | History | Annotate | Line # | Download | only in libcurses
attributes.c revision 1.30
      1 /*	$NetBSD: attributes.c,v 1.30 2018/11/24 01:04:18 uwe 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.30 2018/11/24 01:04:18 uwe Exp $");
     35 #endif				/* not lint */
     36 
     37 #include "curses.h"
     38 #include "curses_private.h"
     39 
     40 static int __wattr_off(WINDOW *, attr_t);
     41 static int __wattr_on(WINDOW *, attr_t);
     42 static void __wcolor_set(WINDOW *, attr_t);
     43 
     44 
     45 #ifndef _CURSES_USE_MACROS
     46 /*
     47  * attr_get --
     48  *	Get wide attributes and color pair from stdscr
     49  */
     50 /* ARGSUSED */
     51 int
     52 attr_get(attr_t *attr, short *pair, void *opts)
     53 {
     54 	return wattr_get(stdscr, attr, pair, opts);
     55 }
     56 
     57 /*
     58  * attr_on --
     59  *	Test and set wide attributes on stdscr
     60  */
     61 /* ARGSUSED */
     62 int
     63 attr_on(attr_t attr, void *opts)
     64 {
     65 	return wattr_on(stdscr, attr, opts);
     66 }
     67 
     68 /*
     69  * attr_off --
     70  *	Test and unset wide attributes on stdscr
     71  */
     72 /* ARGSUSED */
     73 int
     74 attr_off(attr_t attr, void *opts)
     75 {
     76 	return wattr_off(stdscr, attr, opts);
     77 }
     78 
     79 /*
     80  * attr_set --
     81  *	Set wide attributes and color pair on stdscr
     82  */
     83 /* ARGSUSED */
     84 int
     85 attr_set(attr_t attr, short pair, void *opts)
     86 {
     87 	return wattr_set(stdscr, attr, pair, opts);
     88 }
     89 
     90 /*
     91  * color_set --
     92  *	Set color pair on stdscr
     93  */
     94 /* ARGSUSED */
     95 int
     96 color_set(short pair, void *opts)
     97 {
     98 	return wcolor_set(stdscr, pair, opts);
     99 }
    100 
    101 /*
    102  * attron --
    103  *	Test and set attributes on stdscr
    104  */
    105 int
    106 attron(int attr)
    107 {
    108 	return wattron(stdscr, attr);
    109 }
    110 
    111 /*
    112  * attroff --
    113  *	Test and unset attributes on stdscr.
    114  */
    115 int
    116 attroff(int attr)
    117 {
    118 	return wattroff(stdscr, attr);
    119 }
    120 
    121 /*
    122  * attrset --
    123  *	Set specific attribute modes.
    124  *	Unset others.  On stdscr.
    125  */
    126 int
    127 attrset(int attr)
    128 {
    129 	return wattrset(stdscr, attr);
    130 }
    131 #endif	/* _CURSES_USE_MACROS */
    132 
    133 /*
    134  * wattr_get --
    135  *	Get wide attributes and colour pair from window
    136  *	Note that attributes also includes colour.
    137  */
    138 /* ARGSUSED */
    139 int
    140 wattr_get(WINDOW *win, attr_t *attr, short *pair, void *opts)
    141 {
    142 #ifdef DEBUG
    143 	__CTRACE(__CTRACE_ATTR, "wattr_get: win %p\n", win);
    144 #endif
    145 	if (attr != NULL) {
    146 		*attr = win->wattr;
    147 #ifdef HAVE_WCHAR
    148 		*attr &= WA_ATTRIBUTES;
    149 #endif
    150 	}
    151 
    152 	if (pair != NULL)
    153 		*pair = PAIR_NUMBER(win->wattr);
    154 	return OK;
    155 }
    156 
    157 /*
    158  * wattr_on --
    159  *	Test and set wide attributes on window
    160  */
    161 int
    162 wattr_on(WINDOW *win, attr_t attr, void *opts)
    163 {
    164 	if (__predict_false(opts != NULL))
    165 		return ERR;
    166 
    167 	return __wattr_on(win, attr);
    168 }
    169 
    170 /*
    171  * wattr_off --
    172  *	Test and unset wide attributes on window
    173  *
    174  *	Note that the 'me' sequence unsets all attributes.  We handle
    175  *	which attributes should really be set in refresh.c:makech().
    176  */
    177 int
    178 wattr_off(WINDOW *win, attr_t attr, void *opts)
    179 {
    180 	if (__predict_false(opts != NULL))
    181 		return ERR;
    182 
    183 	return __wattr_off(win, attr);
    184 }
    185 
    186 
    187 /*
    188  * wattr_set --
    189  *	Set wide attributes and color pair on window
    190  */
    191 int
    192 wattr_set(WINDOW *win, attr_t attr, short pair, void *opts)
    193 {
    194 #ifdef DEBUG
    195 	__CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n",
    196 	    win, attr, pair);
    197 #endif
    198 	if (__predict_false(opts != NULL))
    199 		return ERR;
    200 
    201 	/*
    202 	 * This overwrites any colour setting from the attributes
    203 	 * and is compatible with ncurses.
    204 	 */
    205 	attr = (attr & ~__COLOR) | COLOR_PAIR(pair);
    206 
    207 	__wattr_off(win, WA_ATTRIBUTES);
    208 	__wattr_on(win, attr);
    209 	return OK;
    210 }
    211 
    212 /*
    213  * wcolor_set --
    214  *	Set color pair on window
    215  */
    216 /* ARGSUSED */
    217 int
    218 wcolor_set(WINDOW *win, short pair, void *opts)
    219 {
    220 #ifdef DEBUG
    221 	__CTRACE(__CTRACE_COLOR, "wolor_set: win %p, pair %d\n", win, pair);
    222 #endif
    223 	__wcolor_set(win, (attr_t) COLOR_PAIR(pair));
    224 	return OK;
    225 }
    226 
    227 /*
    228  * getattrs --
    229  *	Get window attributes.
    230  */
    231 chtype
    232 getattrs(WINDOW *win)
    233 {
    234 #ifdef DEBUG
    235 	__CTRACE(__CTRACE_ATTR, "getattrs: win %p\n", win);
    236 #endif
    237 	return((chtype) win->wattr);
    238 }
    239 
    240 /*
    241  * wattron --
    242  *	Test and set attributes.
    243  */
    244 int
    245 wattron(WINDOW *win, int attr)
    246 {
    247 #ifdef DEBUG
    248 	__CTRACE(__CTRACE_ATTR, "wattron: win %p, attr %08x\n", win, attr);
    249 #endif
    250 	return __wattr_on(win, (attr_t) attr);
    251 }
    252 
    253 /*
    254  * wattroff --
    255  *	Test and unset attributes.
    256  */
    257 int
    258 wattroff(WINDOW *win, int attr)
    259 {
    260 #ifdef DEBUG
    261 	__CTRACE(__CTRACE_ATTR, "wattroff: win %p, attr %08x\n", win, attr);
    262 #endif
    263 	return __wattr_off(win, (attr_t) attr);
    264 }
    265 
    266 /*
    267  * wattrset --
    268  *	Set specific attribute modes.
    269  *	Unset others.
    270  */
    271 int
    272 wattrset(WINDOW *win, int attr)
    273 {
    274 #ifdef DEBUG
    275 	__CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr);
    276 #endif
    277 	__wattr_off(win, __ATTRIBUTES);
    278 	__wattr_on(win, (attr_t) attr);
    279 	return OK;
    280 }
    281 
    282 /*
    283  * termattrs --
    284  *	Get terminal attributes
    285  */
    286 chtype
    287 termattrs(void)
    288 {
    289 	chtype ch = 0;
    290 
    291 #ifdef DEBUG
    292 	__CTRACE(__CTRACE_ATTR, "termattrs\n");
    293 #endif
    294 	if (exit_attribute_mode != NULL) {
    295 #ifdef DEBUG
    296 	__CTRACE(__CTRACE_ATTR, "termattrs: have exit attribute mode\n");
    297 #endif
    298 		if (enter_blink_mode != NULL)
    299 			ch |= __BLINK;
    300 		if (enter_bold_mode != NULL)
    301 			ch |= __BOLD;
    302 		if (enter_dim_mode != NULL)
    303 			ch |= __DIM;
    304 		if (enter_secure_mode != NULL)
    305 			ch |= __BLANK;
    306 		if (enter_protected_mode != NULL)
    307 			ch |= __PROTECT;
    308 		if (enter_reverse_mode != NULL)
    309 			ch |= __REVERSE;
    310 	}
    311 	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
    312 		ch |= __STANDOUT;
    313 	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
    314 		ch |= __UNDERSCORE;
    315 	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
    316 		ch |= __ALTCHARSET;
    317 
    318 	return ch;
    319 }
    320 
    321 /*
    322  * term_attrs --
    323  *	Get terminal wide attributes
    324  */
    325 attr_t
    326 term_attrs(void)
    327 {
    328 	attr_t attr = 0;
    329 
    330 #ifdef DEBUG
    331 	__CTRACE(__CTRACE_ATTR, "term_attrs\n");
    332 #endif
    333 	if (exit_attribute_mode != NULL) {
    334 		if (enter_blink_mode != NULL)
    335 			attr |= __BLINK;
    336 		if (enter_bold_mode != NULL)
    337 			attr |= __BOLD;
    338 		if (enter_dim_mode != NULL)
    339 			attr |= __DIM;
    340 		if (enter_secure_mode != NULL)
    341 			attr |= __BLANK;
    342 		if (enter_protected_mode != NULL)
    343 			attr |= __PROTECT;
    344 		if (enter_reverse_mode != NULL)
    345 			attr |= __REVERSE;
    346 #ifdef HAVE_WCHAR
    347 		if (enter_low_hl_mode != NULL)
    348 			attr |= WA_LOW;
    349 		if (enter_top_hl_mode != NULL)
    350 			attr |= WA_TOP;
    351 		if (enter_left_hl_mode != NULL)
    352 			attr |= WA_LEFT;
    353 		if (enter_right_hl_mode != NULL)
    354 			attr |= WA_RIGHT;
    355 		if (enter_horizontal_hl_mode != NULL)
    356 			attr |= WA_HORIZONTAL;
    357 		if (enter_vertical_hl_mode != NULL)
    358 			attr |= WA_VERTICAL;
    359 #endif /* HAVE_WCHAR */
    360 	}
    361 	if (enter_standout_mode != NULL && exit_standout_mode != NULL)
    362 		attr |= __STANDOUT;
    363 	if (enter_underline_mode != NULL && exit_underline_mode != NULL)
    364 		attr |= __UNDERSCORE;
    365 	if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
    366 		attr |= __ALTCHARSET;
    367 
    368 	return attr;
    369 }
    370 
    371 
    372 static int
    373 __wattr_on(WINDOW *win, attr_t attr)
    374 {
    375 	const TERMINAL *t = win->screen->term;
    376 
    377 #ifdef DEBUG
    378 	__CTRACE(__CTRACE_ATTR, "wattr_on: win %p, attr %08x\n", win, attr);
    379 #endif
    380 	/* If can enter modes, set the relevent attribute bits. */
    381 	if (t_exit_attribute_mode(t) != NULL) {
    382 		if (attr & __BLINK && t_enter_blink_mode(t) != NULL)
    383 			win->wattr |= __BLINK;
    384 		if (attr & __BOLD && t_enter_bold_mode(t) != NULL)
    385 			win->wattr |= __BOLD;
    386 		if (attr & __DIM && t_enter_dim_mode(t) != NULL)
    387 			win->wattr |= __DIM;
    388 		if (attr & __BLANK && t_enter_secure_mode(t) != NULL)
    389 			win->wattr |= __BLANK;
    390 		if (attr & __PROTECT && t_enter_protected_mode(t) != NULL)
    391 			win->wattr |= __PROTECT;
    392 		if (attr & __REVERSE && t_enter_reverse_mode(t) != NULL)
    393 			win->wattr |= __REVERSE;
    394 #ifdef HAVE_WCHAR
    395 		if (attr & WA_LOW && t_enter_low_hl_mode(t) != NULL)
    396 			win->wattr |= WA_LOW;
    397 		if (attr & WA_TOP && t_enter_top_hl_mode(t) != NULL)
    398 			win->wattr |= WA_TOP;
    399 		if (attr & WA_LEFT && t_enter_left_hl_mode(t) != NULL)
    400 			win->wattr |= WA_LEFT;
    401 		if (attr & WA_RIGHT && t_enter_right_hl_mode(t) != NULL)
    402 			win->wattr |= WA_RIGHT;
    403 		if (attr & WA_HORIZONTAL && t_enter_horizontal_hl_mode(t) != NULL)
    404 			win->wattr |= WA_HORIZONTAL;
    405 		if (attr & WA_VERTICAL && t_enter_vertical_hl_mode(t) != NULL)
    406 			win->wattr |= WA_VERTICAL;
    407 #endif /* HAVE_WCHAR */
    408 	}
    409 	if (attr & __STANDOUT && t_enter_standout_mode(t) != NULL &&
    410 	    t_exit_standout_mode(t) != NULL)
    411 		wstandout(win);
    412 	if (attr & __UNDERSCORE && t_enter_underline_mode(t) != NULL &&
    413 	    t_exit_underline_mode(t) != NULL)
    414 		wunderscore(win);
    415 	if (attr & __COLOR)
    416 		__wcolor_set(win, attr);
    417 	return OK;
    418 }
    419 
    420 
    421 static int
    422 __wattr_off(WINDOW *win, attr_t attr)
    423 {
    424 	const TERMINAL *t = win->screen->term;
    425 
    426 #ifdef DEBUG
    427 	__CTRACE(__CTRACE_ATTR, "wattr_off: win %p, attr %08x\n", win, attr);
    428 #endif
    429 	/* If can do exit modes, unset the relevent attribute bits. */
    430 	if (t_exit_attribute_mode(t) != NULL) {
    431 		if (attr & __BLINK)
    432 			win->wattr &= ~__BLINK;
    433 		if (attr & __BOLD)
    434 			win->wattr &= ~__BOLD;
    435 		if (attr & __DIM)
    436 			win->wattr &= ~__DIM;
    437 		if (attr & __BLANK)
    438 			win->wattr &= ~__BLANK;
    439 		if (attr & __PROTECT)
    440 			win->wattr &= ~__PROTECT;
    441 		if (attr & __REVERSE)
    442 			win->wattr &= ~__REVERSE;
    443 #ifdef HAVE_WCHAR
    444 		if (attr & WA_LOW)
    445 			win->wattr &= ~WA_LOW;
    446 		if (attr & WA_TOP)
    447 			win->wattr &= ~WA_TOP;
    448 		if (attr & WA_LEFT)
    449 			win->wattr &= ~WA_LEFT;
    450 		if (attr & WA_RIGHT)
    451 			win->wattr &= ~WA_RIGHT;
    452 		if (attr & WA_HORIZONTAL)
    453 			win->wattr &= ~WA_HORIZONTAL;
    454 		if (attr & WA_VERTICAL)
    455 			win->wattr &= ~WA_VERTICAL;
    456 #endif /* HAVE_WCHAR */
    457 	}
    458 	if (attr & __STANDOUT)
    459 		wstandend(win);
    460 	if (attr & __UNDERSCORE)
    461 		wunderend(win);
    462 	if (attr & __COLOR) {
    463 		if (max_colors != 0)
    464 			win->wattr &= ~__COLOR;
    465 	}
    466 	return OK;
    467 }
    468 
    469 
    470 static void
    471 __wcolor_set(WINDOW *win, attr_t attr)
    472 {
    473 	const TERMINAL *t = win->screen->term;
    474 
    475 	/* If another color pair is set, turn that off first. */
    476 	win->wattr &= ~__COLOR;
    477 	/* If can do color video, set the color pair bits. */
    478 	if (t_max_colors(t) != 0 && attr & __COLOR)
    479 		win->wattr |= attr & __COLOR;
    480 }
    481