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