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