1 /* $NetBSD: attributes.c,v 1.35 2022/10/25 06:20:01 blymn 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.35 2022/10/25 06:20:01 blymn 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 if (__predict_false(win == NULL)) 147 return ERR; 148 149 __CTRACE(__CTRACE_ATTR, "wattr_get: win %p\n", win); 150 if (attr != NULL) { 151 *attr = win->wattr; 152 #ifdef HAVE_WCHAR 153 *attr &= WA_ATTRIBUTES; 154 #endif 155 } 156 157 if (pair != NULL) 158 *pair = PAIR_NUMBER(win->wattr); 159 return OK; 160 } 161 162 /* 163 * wattr_on -- 164 * Test and set wide attributes on window 165 */ 166 int 167 wattr_on(WINDOW *win, attr_t attr, void *opts) 168 { 169 if (__predict_false(opts != NULL)) 170 return ERR; 171 172 return __wattr_on(win, attr); 173 } 174 175 /* 176 * wattr_off -- 177 * Test and unset wide attributes on window 178 * 179 * Note that the 'me' sequence unsets all attributes. We handle 180 * which attributes should really be set in refresh.c:makech(). 181 */ 182 int 183 wattr_off(WINDOW *win, attr_t attr, void *opts) 184 { 185 if (__predict_false(opts != NULL)) 186 return ERR; 187 188 return __wattr_off(win, attr); 189 } 190 191 192 /* 193 * wattr_set -- 194 * Set wide attributes and color pair on window 195 */ 196 int 197 wattr_set(WINDOW *win, attr_t attr, short pair, void *opts) 198 { 199 __CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n", 200 win, attr, pair); 201 if (__predict_false(opts != NULL)) 202 return ERR; 203 204 /* 205 * This overwrites any colour setting from the attributes 206 * and is compatible with ncurses. 207 */ 208 attr = (attr & ~__COLOR) | COLOR_PAIR(pair); 209 210 __wattr_off(win, WA_ATTRIBUTES); 211 __wattr_on(win, attr); 212 return OK; 213 } 214 215 /* 216 * wcolor_set -- 217 * Set color pair on window 218 */ 219 /* ARGSUSED */ 220 int 221 wcolor_set(WINDOW *win, short pair, void *opts) 222 { 223 __CTRACE(__CTRACE_COLOR, "wolor_set: win %p, pair %d\n", win, pair); 224 __wcolor_set(win, (attr_t) COLOR_PAIR(pair)); 225 return OK; 226 } 227 #endif /* HAVE_WCHAR */ 228 229 230 /* 231 * getattrs -- 232 * Get window attributes. 233 */ 234 chtype 235 getattrs(WINDOW *win) 236 { 237 if (__predict_false(win == NULL)) 238 return ERR; 239 240 __CTRACE(__CTRACE_ATTR, "getattrs: win %p\n", win); 241 return((chtype) win->wattr); 242 } 243 244 /* 245 * wattron -- 246 * Test and set attributes. 247 */ 248 int 249 wattron(WINDOW *win, int attr) 250 { 251 __CTRACE(__CTRACE_ATTR, "wattron: win %p, attr %08x\n", win, attr); 252 return __wattr_on(win, (attr_t) attr); 253 } 254 255 /* 256 * wattroff -- 257 * Test and unset attributes. 258 */ 259 int 260 wattroff(WINDOW *win, int attr) 261 { 262 __CTRACE(__CTRACE_ATTR, "wattroff: win %p, attr %08x\n", win, attr); 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 __CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr); 275 __wattr_off(win, __ATTRIBUTES); 276 __wattr_on(win, (attr_t) attr); 277 return OK; 278 } 279 280 /* 281 * termattrs -- 282 * Get terminal attributes 283 */ 284 chtype 285 termattrs(void) 286 { 287 chtype ch = 0; 288 289 __CTRACE(__CTRACE_ATTR, "termattrs\n"); 290 if (exit_attribute_mode != NULL) { 291 __CTRACE(__CTRACE_ATTR, "termattrs: have exit attribute mode\n"); 292 if (enter_blink_mode != NULL) 293 ch |= __BLINK; 294 if (enter_bold_mode != NULL) 295 ch |= __BOLD; 296 if (enter_dim_mode != NULL) 297 ch |= __DIM; 298 if (enter_secure_mode != NULL) 299 ch |= __BLANK; 300 if (enter_protected_mode != NULL) 301 ch |= __PROTECT; 302 if (enter_reverse_mode != NULL) 303 ch |= __REVERSE; 304 } 305 if (enter_standout_mode != NULL && exit_standout_mode != NULL) 306 ch |= __STANDOUT; 307 if (enter_underline_mode != NULL && exit_underline_mode != NULL) 308 ch |= __UNDERSCORE; 309 if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL) 310 ch |= __ALTCHARSET; 311 312 return ch; 313 } 314 315 316 #ifdef HAVE_WCHAR 317 /* 318 * term_attrs -- 319 * Get terminal wide attributes 320 */ 321 attr_t 322 term_attrs(void) 323 { 324 attr_t attr = 0; 325 326 __CTRACE(__CTRACE_ATTR, "term_attrs\n"); 327 if (exit_attribute_mode != NULL) { 328 if (enter_blink_mode != NULL) 329 attr |= __BLINK; 330 if (enter_bold_mode != NULL) 331 attr |= __BOLD; 332 if (enter_dim_mode != NULL) 333 attr |= __DIM; 334 if (enter_secure_mode != NULL) 335 attr |= __BLANK; 336 if (enter_protected_mode != NULL) 337 attr |= __PROTECT; 338 if (enter_reverse_mode != NULL) 339 attr |= __REVERSE; 340 #ifdef HAVE_WCHAR 341 if (enter_low_hl_mode != NULL) 342 attr |= WA_LOW; 343 if (enter_top_hl_mode != NULL) 344 attr |= WA_TOP; 345 if (enter_left_hl_mode != NULL) 346 attr |= WA_LEFT; 347 if (enter_right_hl_mode != NULL) 348 attr |= WA_RIGHT; 349 if (enter_horizontal_hl_mode != NULL) 350 attr |= WA_HORIZONTAL; 351 if (enter_vertical_hl_mode != NULL) 352 attr |= WA_VERTICAL; 353 #endif /* HAVE_WCHAR */ 354 } 355 if (enter_standout_mode != NULL && exit_standout_mode != NULL) 356 attr |= __STANDOUT; 357 if (enter_underline_mode != NULL && exit_underline_mode != NULL) 358 attr |= __UNDERSCORE; 359 if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL) 360 attr |= __ALTCHARSET; 361 362 return attr; 363 } 364 #endif /* HAVE_WCHAR */ 365 366 367 static int 368 __wattr_on(WINDOW *win, attr_t attr) 369 { 370 const TERMINAL *t; 371 372 if (__predict_false(win == NULL)) 373 return ERR; 374 375 t = win->screen->term; 376 377 __CTRACE(__CTRACE_ATTR, "wattr_on: win %p, attr %08x\n", win, attr); 378 /* If can enter modes, set the relevant attribute bits. */ 379 if (t_exit_attribute_mode(t) != NULL) { 380 if (attr & __BLINK && t_enter_blink_mode(t) != NULL) 381 win->wattr |= __BLINK; 382 if (attr & __BOLD && t_enter_bold_mode(t) != NULL) 383 win->wattr |= __BOLD; 384 if (attr & __DIM && t_enter_dim_mode(t) != NULL) 385 win->wattr |= __DIM; 386 if (attr & __BLANK && t_enter_secure_mode(t) != NULL) 387 win->wattr |= __BLANK; 388 if (attr & __PROTECT && t_enter_protected_mode(t) != NULL) 389 win->wattr |= __PROTECT; 390 if (attr & __REVERSE && t_enter_reverse_mode(t) != NULL) 391 win->wattr |= __REVERSE; 392 #ifdef HAVE_WCHAR 393 if (attr & WA_LOW && t_enter_low_hl_mode(t) != NULL) 394 win->wattr |= WA_LOW; 395 if (attr & WA_TOP && t_enter_top_hl_mode(t) != NULL) 396 win->wattr |= WA_TOP; 397 if (attr & WA_LEFT && t_enter_left_hl_mode(t) != NULL) 398 win->wattr |= WA_LEFT; 399 if (attr & WA_RIGHT && t_enter_right_hl_mode(t) != NULL) 400 win->wattr |= WA_RIGHT; 401 if (attr & WA_HORIZONTAL && t_enter_horizontal_hl_mode(t) != NULL) 402 win->wattr |= WA_HORIZONTAL; 403 if (attr & WA_VERTICAL && t_enter_vertical_hl_mode(t) != NULL) 404 win->wattr |= WA_VERTICAL; 405 #endif /* HAVE_WCHAR */ 406 } 407 if (attr & __STANDOUT && t_enter_standout_mode(t) != NULL && 408 t_exit_standout_mode(t) != NULL) 409 wstandout(win); 410 if (attr & __UNDERSCORE && t_enter_underline_mode(t) != NULL && 411 t_exit_underline_mode(t) != NULL) 412 wunderscore(win); 413 if (attr & __COLOR) 414 __wcolor_set(win, attr); 415 return OK; 416 } 417 418 419 static int 420 __wattr_off(WINDOW *win, attr_t attr) 421 { 422 const TERMINAL *t; 423 424 if (__predict_false(win == NULL)) 425 return ERR; 426 427 t = win->screen->term; 428 429 __CTRACE(__CTRACE_ATTR, "wattr_off: win %p, attr %08x\n", win, attr); 430 /* If can do exit modes, unset the relevant attribute bits. */ 431 if (t_exit_attribute_mode(t) != NULL) { 432 if (attr & __BLINK) 433 win->wattr &= ~__BLINK; 434 if (attr & __BOLD) 435 win->wattr &= ~__BOLD; 436 if (attr & __DIM) 437 win->wattr &= ~__DIM; 438 if (attr & __BLANK) 439 win->wattr &= ~__BLANK; 440 if (attr & __PROTECT) 441 win->wattr &= ~__PROTECT; 442 if (attr & __REVERSE) 443 win->wattr &= ~__REVERSE; 444 #ifdef HAVE_WCHAR 445 if (attr & WA_LOW) 446 win->wattr &= ~WA_LOW; 447 if (attr & WA_TOP) 448 win->wattr &= ~WA_TOP; 449 if (attr & WA_LEFT) 450 win->wattr &= ~WA_LEFT; 451 if (attr & WA_RIGHT) 452 win->wattr &= ~WA_RIGHT; 453 if (attr & WA_HORIZONTAL) 454 win->wattr &= ~WA_HORIZONTAL; 455 if (attr & WA_VERTICAL) 456 win->wattr &= ~WA_VERTICAL; 457 #endif /* HAVE_WCHAR */ 458 } 459 if (attr & __STANDOUT) 460 wstandend(win); 461 if (attr & __UNDERSCORE) 462 wunderend(win); 463 if (attr & __COLOR) { 464 if (max_colors != 0) 465 win->wattr &= ~__COLOR; 466 } 467 return OK; 468 } 469 470 471 static void 472 __wcolor_set(WINDOW *win, attr_t attr) 473 { 474 const TERMINAL *t; 475 476 if (__predict_false(win == NULL)) 477 return; 478 479 t = win->screen->term; 480 481 /* If another color pair is set, turn that off first. */ 482 win->wattr &= ~__COLOR; 483 /* If can do color video, set the color pair bits. */ 484 if (t_max_colors(t) != 0) 485 win->wattr |= attr & __COLOR; 486 } 487