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