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