10e3d5408SPeter Wemm /**************************************************************************** 24a1a9510SRong-En Fan * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. * 30e3d5408SPeter Wemm * * 40e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 50e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 60e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 70e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 80e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 90e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 100e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 110e3d5408SPeter Wemm * * 120e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 130e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 140e3d5408SPeter Wemm * * 150e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 160e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 170e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 180e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 190e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 200e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 210e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 220e3d5408SPeter Wemm * * 230e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 240e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 250e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 260e3d5408SPeter Wemm * authorization. * 270e3d5408SPeter Wemm ****************************************************************************/ 280e3d5408SPeter Wemm 290e3d5408SPeter Wemm /**************************************************************************** 300e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 310e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> * 324a1a9510SRong-En Fan * and: Thomas E. Dickey 1996 on * 330e3d5408SPeter Wemm ****************************************************************************/ 340e3d5408SPeter Wemm 350e3d5408SPeter Wemm /* 360e3d5408SPeter Wemm * vidputs(newmode, outc) 370e3d5408SPeter Wemm * 380e3d5408SPeter Wemm * newmode is taken to be the logical 'or' of the symbols in curses.h 390e3d5408SPeter Wemm * representing graphic renditions. The terminal is set to be in all of 400e3d5408SPeter Wemm * the given modes, if possible. 410e3d5408SPeter Wemm * 420e3d5408SPeter Wemm * if the new attribute is normal 430e3d5408SPeter Wemm * if exit-alt-char-set exists 440e3d5408SPeter Wemm * emit it 450e3d5408SPeter Wemm * emit exit-attribute-mode 460e3d5408SPeter Wemm * else if set-attributes exists 470e3d5408SPeter Wemm * use it to set exactly what you want 480e3d5408SPeter Wemm * else 490e3d5408SPeter Wemm * if exit-attribute-mode exists 500e3d5408SPeter Wemm * turn off everything 510e3d5408SPeter Wemm * else 520e3d5408SPeter Wemm * turn off those which can be turned off and aren't in 530e3d5408SPeter Wemm * newmode. 540e3d5408SPeter Wemm * turn on each mode which should be on and isn't, one by one 550e3d5408SPeter Wemm * 560e3d5408SPeter Wemm * NOTE that this algorithm won't achieve the desired mix of attributes 570e3d5408SPeter Wemm * in some cases, but those are probably just those cases in which it is 580e3d5408SPeter Wemm * actually impossible, anyway, so... 590e3d5408SPeter Wemm * 600e3d5408SPeter Wemm * NOTE that we cannot assume that there's no interaction between color 610e3d5408SPeter Wemm * and other attribute resets. So each time we reset color (or other 620e3d5408SPeter Wemm * attributes) we'll have to be prepared to restore the other. 630e3d5408SPeter Wemm */ 640e3d5408SPeter Wemm 650e3d5408SPeter Wemm #include <curses.priv.h> 660e3d5408SPeter Wemm #include <term.h> 670e3d5408SPeter Wemm 684a1a9510SRong-En Fan MODULE_ID("$Id: lib_vidattr.c,v 1.46 2006/01/21 23:39:40 tom Exp $") 690e3d5408SPeter Wemm 700e3d5408SPeter Wemm #define doPut(mode) TPUTS_TRACE(#mode); tputs(mode, 1, outc) 710e3d5408SPeter Wemm 720e3d5408SPeter Wemm #define TurnOn(mask,mode) \ 730e3d5408SPeter Wemm if ((turn_on & mask) && mode) { doPut(mode); } 740e3d5408SPeter Wemm 750e3d5408SPeter Wemm #define TurnOff(mask,mode) \ 760e3d5408SPeter Wemm if ((turn_off & mask) && mode) { doPut(mode); turn_off &= ~mask; } 770e3d5408SPeter Wemm 780e3d5408SPeter Wemm /* if there is no current screen, assume we *can* do color */ 790e3d5408SPeter Wemm #define SetColorsIf(why,old_attr) \ 8015589c42SPeter Wemm if (can_color && (why)) { \ 810e3d5408SPeter Wemm int old_pair = PAIR_NUMBER(old_attr); \ 8218259542SPeter Wemm TR(TRACE_ATTRS, ("old pair = %d -- new pair = %d", old_pair, pair)); \ 830e3d5408SPeter Wemm if ((pair != old_pair) \ 8415589c42SPeter Wemm || (fix_pair0 && (pair == 0)) \ 850e3d5408SPeter Wemm || (reverse ^ ((old_attr & A_REVERSE) != 0))) { \ 8615589c42SPeter Wemm _nc_do_color(old_pair, pair, reverse, outc); \ 870e3d5408SPeter Wemm } \ 880e3d5408SPeter Wemm } 890e3d5408SPeter Wemm 907a69bbfbSPeter Wemm NCURSES_EXPORT(int) 914a1a9510SRong-En Fan vidputs(chtype newmode, int (*outc) (int)) 920e3d5408SPeter Wemm { 930e3d5408SPeter Wemm static attr_t previous_attr = A_NORMAL; 940e3d5408SPeter Wemm attr_t turn_on, turn_off; 950e3d5408SPeter Wemm int pair; 960e3d5408SPeter Wemm bool reverse = FALSE; 9715589c42SPeter Wemm bool can_color = (SP == 0 || SP->_coloron); 9818259542SPeter Wemm #if NCURSES_EXT_FUNCS 9915589c42SPeter Wemm bool fix_pair0 = (SP != 0 && SP->_coloron && !SP->_default_color); 10015589c42SPeter Wemm #else 10115589c42SPeter Wemm #define fix_pair0 FALSE 10215589c42SPeter Wemm #endif 1030e3d5408SPeter Wemm 1040e3d5408SPeter Wemm T((T_CALLED("vidputs(%s)"), _traceattr(newmode))); 1050e3d5408SPeter Wemm 1060e3d5408SPeter Wemm /* this allows us to go on whether or not newterm() has been called */ 1070e3d5408SPeter Wemm if (SP) 1084a1a9510SRong-En Fan previous_attr = AttrOf(SCREEN_ATTRS(SP)); 1090e3d5408SPeter Wemm 11018259542SPeter Wemm TR(TRACE_ATTRS, ("previous attribute was %s", _traceattr(previous_attr))); 1110e3d5408SPeter Wemm 1120e3d5408SPeter Wemm if ((SP != 0) 1134a1a9510SRong-En Fan && (magic_cookie_glitch > 0)) { 1144a1a9510SRong-En Fan #if USE_XMC_SUPPORT 1154a1a9510SRong-En Fan static chtype table[] = 1164a1a9510SRong-En Fan { 1174a1a9510SRong-En Fan A_STANDOUT, 1184a1a9510SRong-En Fan A_UNDERLINE, 1194a1a9510SRong-En Fan A_REVERSE, 1204a1a9510SRong-En Fan A_BLINK, 1214a1a9510SRong-En Fan A_DIM, 1224a1a9510SRong-En Fan A_BOLD, 1234a1a9510SRong-En Fan A_INVIS, 1244a1a9510SRong-En Fan A_PROTECT, 1254a1a9510SRong-En Fan }; 1264a1a9510SRong-En Fan unsigned n; 1274a1a9510SRong-En Fan int used = 0; 1284a1a9510SRong-En Fan int limit = (max_attributes <= 0) ? 1 : max_attributes; 1294a1a9510SRong-En Fan chtype retain = 0; 1304a1a9510SRong-En Fan 1314a1a9510SRong-En Fan /* 1324a1a9510SRong-En Fan * Limit the number of attribute bits set in the newmode according to 1334a1a9510SRong-En Fan * the terminfo max_attributes value. 1344a1a9510SRong-En Fan */ 1354a1a9510SRong-En Fan for (n = 0; n < SIZEOF(table); ++n) { 1364a1a9510SRong-En Fan if ((table[n] & SP->_ok_attributes) == 0) { 1374a1a9510SRong-En Fan newmode &= ~table[n]; 1384a1a9510SRong-En Fan } else if ((table[n] & newmode) != 0) { 1394a1a9510SRong-En Fan if (used++ >= limit) { 1404a1a9510SRong-En Fan newmode &= ~table[n]; 1414a1a9510SRong-En Fan if (newmode == retain) 1424a1a9510SRong-En Fan break; 1434a1a9510SRong-En Fan } else { 1444a1a9510SRong-En Fan retain = newmode; 1454a1a9510SRong-En Fan } 1464a1a9510SRong-En Fan } 1474a1a9510SRong-En Fan } 1484a1a9510SRong-En Fan #else 1490e3d5408SPeter Wemm newmode &= ~(SP->_xmc_suppress); 1500e3d5408SPeter Wemm #endif 1514a1a9510SRong-En Fan TR(TRACE_ATTRS, ("suppressed attribute is %s", _traceattr(newmode))); 1524a1a9510SRong-En Fan } 1530e3d5408SPeter Wemm 1540e3d5408SPeter Wemm /* 1550e3d5408SPeter Wemm * If we have a terminal that cannot combine color with video 1560e3d5408SPeter Wemm * attributes, use the colors in preference. 1570e3d5408SPeter Wemm */ 15815589c42SPeter Wemm if (((newmode & A_COLOR) != 0 15915589c42SPeter Wemm || fix_pair0) 1600e3d5408SPeter Wemm && (no_color_video > 0)) { 16118259542SPeter Wemm /* 16218259542SPeter Wemm * If we had chosen the A_xxx definitions to correspond to the 16318259542SPeter Wemm * no_color_video mask, we could simply shift it up and mask off the 16418259542SPeter Wemm * attributes. But we did not (actually copied Solaris' definitions). 16518259542SPeter Wemm * However, this is still simpler/faster than a lookup table. 16618259542SPeter Wemm * 16718259542SPeter Wemm * The 63 corresponds to A_STANDOUT, A_UNDERLINE, A_REVERSE, A_BLINK, 16818259542SPeter Wemm * A_DIM, A_BOLD which are 1:1 with no_color_video. The bits that 16918259542SPeter Wemm * correspond to A_INVIS, A_PROTECT (192) must be shifted up 1 and 17018259542SPeter Wemm * A_ALTCHARSET (256) down 2 to line up. We use the NCURSES_BITS 17118259542SPeter Wemm * macro so this will work properly for the wide-character layout. 17218259542SPeter Wemm */ 1737a69bbfbSPeter Wemm unsigned value = no_color_video; 1747a69bbfbSPeter Wemm attr_t mask = NCURSES_BITS((value & 63) 1757a69bbfbSPeter Wemm | ((value & 192) << 1) 1767a69bbfbSPeter Wemm | ((value & 256) >> 2), 8); 17715589c42SPeter Wemm 1787a69bbfbSPeter Wemm if ((mask & A_REVERSE) != 0 1797a69bbfbSPeter Wemm && (newmode & A_REVERSE) != 0) { 1800e3d5408SPeter Wemm reverse = TRUE; 18118259542SPeter Wemm mask &= ~A_REVERSE; 1820e3d5408SPeter Wemm } 18318259542SPeter Wemm newmode &= ~mask; 1840e3d5408SPeter Wemm } 1850e3d5408SPeter Wemm 1860e3d5408SPeter Wemm if (newmode == previous_attr) 1870e3d5408SPeter Wemm returnCode(OK); 1880e3d5408SPeter Wemm 1890e3d5408SPeter Wemm pair = PAIR_NUMBER(newmode); 1900e3d5408SPeter Wemm 1910e3d5408SPeter Wemm if (reverse) { 1920e3d5408SPeter Wemm newmode &= ~A_REVERSE; 1930e3d5408SPeter Wemm } 1940e3d5408SPeter Wemm 1950e3d5408SPeter Wemm turn_off = (~newmode & previous_attr) & ALL_BUT_COLOR; 1960e3d5408SPeter Wemm turn_on = (newmode & ~previous_attr) & ALL_BUT_COLOR; 1970e3d5408SPeter Wemm 19815589c42SPeter Wemm SetColorsIf(((pair == 0) && !fix_pair0), previous_attr); 1990e3d5408SPeter Wemm 2000e3d5408SPeter Wemm if (newmode == A_NORMAL) { 2010e3d5408SPeter Wemm if ((previous_attr & A_ALTCHARSET) && exit_alt_charset_mode) { 2020e3d5408SPeter Wemm doPut(exit_alt_charset_mode); 2030e3d5408SPeter Wemm previous_attr &= ~A_ALTCHARSET; 2040e3d5408SPeter Wemm } 2050e3d5408SPeter Wemm if (previous_attr) { 20618259542SPeter Wemm if (exit_attribute_mode) { 2070e3d5408SPeter Wemm doPut(exit_attribute_mode); 20818259542SPeter Wemm } else { 20918259542SPeter Wemm if (!SP || SP->_use_rmul) { 21018259542SPeter Wemm TurnOff(A_UNDERLINE, exit_underline_mode); 21118259542SPeter Wemm } 21218259542SPeter Wemm if (!SP || SP->_use_rmso) { 21318259542SPeter Wemm TurnOff(A_STANDOUT, exit_standout_mode); 21418259542SPeter Wemm } 21518259542SPeter Wemm } 2164a1a9510SRong-En Fan previous_attr &= ALL_BUT_COLOR; 2170e3d5408SPeter Wemm } 2180e3d5408SPeter Wemm 21915589c42SPeter Wemm SetColorsIf((pair != 0) || fix_pair0, previous_attr); 22039f2269fSPeter Wemm } else if (set_attributes) { 2210e3d5408SPeter Wemm if (turn_on || turn_off) { 2220e3d5408SPeter Wemm TPUTS_TRACE("set_attributes"); 2230e3d5408SPeter Wemm tputs(tparm(set_attributes, 2240e3d5408SPeter Wemm (newmode & A_STANDOUT) != 0, 2250e3d5408SPeter Wemm (newmode & A_UNDERLINE) != 0, 2260e3d5408SPeter Wemm (newmode & A_REVERSE) != 0, 2270e3d5408SPeter Wemm (newmode & A_BLINK) != 0, 2280e3d5408SPeter Wemm (newmode & A_DIM) != 0, 2290e3d5408SPeter Wemm (newmode & A_BOLD) != 0, 2300e3d5408SPeter Wemm (newmode & A_INVIS) != 0, 2310e3d5408SPeter Wemm (newmode & A_PROTECT) != 0, 2320e3d5408SPeter Wemm (newmode & A_ALTCHARSET) != 0), 1, outc); 2334a1a9510SRong-En Fan previous_attr &= ALL_BUT_COLOR; 2340e3d5408SPeter Wemm } 23515589c42SPeter Wemm SetColorsIf((pair != 0) || fix_pair0, previous_attr); 2360e3d5408SPeter Wemm } else { 2370e3d5408SPeter Wemm 23818259542SPeter Wemm TR(TRACE_ATTRS, ("turning %s off", _traceattr(turn_off))); 2390e3d5408SPeter Wemm 2400e3d5408SPeter Wemm TurnOff(A_ALTCHARSET, exit_alt_charset_mode); 2410e3d5408SPeter Wemm 2420e3d5408SPeter Wemm if (!SP || SP->_use_rmul) { 2430e3d5408SPeter Wemm TurnOff(A_UNDERLINE, exit_underline_mode); 2440e3d5408SPeter Wemm } 2450e3d5408SPeter Wemm 2460e3d5408SPeter Wemm if (!SP || SP->_use_rmso) { 2470e3d5408SPeter Wemm TurnOff(A_STANDOUT, exit_standout_mode); 2480e3d5408SPeter Wemm } 2490e3d5408SPeter Wemm 2500e3d5408SPeter Wemm if (turn_off && exit_attribute_mode) { 2510e3d5408SPeter Wemm doPut(exit_attribute_mode); 2524a1a9510SRong-En Fan turn_on |= (newmode & ALL_BUT_COLOR); 2534a1a9510SRong-En Fan previous_attr &= ALL_BUT_COLOR; 2540e3d5408SPeter Wemm } 25515589c42SPeter Wemm SetColorsIf((pair != 0) || fix_pair0, previous_attr); 2560e3d5408SPeter Wemm 25718259542SPeter Wemm TR(TRACE_ATTRS, ("turning %s on", _traceattr(turn_on))); 25815589c42SPeter Wemm /* *INDENT-OFF* */ 2590e3d5408SPeter Wemm TurnOn(A_ALTCHARSET, enter_alt_charset_mode); 2600e3d5408SPeter Wemm TurnOn(A_BLINK, enter_blink_mode); 2610e3d5408SPeter Wemm TurnOn(A_BOLD, enter_bold_mode); 2620e3d5408SPeter Wemm TurnOn(A_DIM, enter_dim_mode); 2630e3d5408SPeter Wemm TurnOn(A_REVERSE, enter_reverse_mode); 2640e3d5408SPeter Wemm TurnOn(A_STANDOUT, enter_standout_mode); 2650e3d5408SPeter Wemm TurnOn(A_PROTECT, enter_protected_mode); 2660e3d5408SPeter Wemm TurnOn(A_INVIS, enter_secure_mode); 2670e3d5408SPeter Wemm TurnOn(A_UNDERLINE, enter_underline_mode); 2684a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT 2690e3d5408SPeter Wemm TurnOn(A_HORIZONTAL, enter_horizontal_hl_mode); 2700e3d5408SPeter Wemm TurnOn(A_LEFT, enter_left_hl_mode); 2710e3d5408SPeter Wemm TurnOn(A_LOW, enter_low_hl_mode); 2720e3d5408SPeter Wemm TurnOn(A_RIGHT, enter_right_hl_mode); 2730e3d5408SPeter Wemm TurnOn(A_TOP, enter_top_hl_mode); 2740e3d5408SPeter Wemm TurnOn(A_VERTICAL, enter_vertical_hl_mode); 27539f2269fSPeter Wemm #endif 27615589c42SPeter Wemm /* *INDENT-ON* */ 27715589c42SPeter Wemm 2780e3d5408SPeter Wemm } 2790e3d5408SPeter Wemm 2800e3d5408SPeter Wemm if (reverse) 2810e3d5408SPeter Wemm newmode |= A_REVERSE; 2820e3d5408SPeter Wemm 2830e3d5408SPeter Wemm if (SP) 2844a1a9510SRong-En Fan SetAttr(SCREEN_ATTRS(SP), newmode); 2850e3d5408SPeter Wemm else 2860e3d5408SPeter Wemm previous_attr = newmode; 2870e3d5408SPeter Wemm 2880e3d5408SPeter Wemm returnCode(OK); 2890e3d5408SPeter Wemm } 2900e3d5408SPeter Wemm 2917a69bbfbSPeter Wemm NCURSES_EXPORT(int) 29239f2269fSPeter Wemm vidattr(chtype newmode) 2930e3d5408SPeter Wemm { 2940e3d5408SPeter Wemm T((T_CALLED("vidattr(%s)"), _traceattr(newmode))); 2950e3d5408SPeter Wemm 2960e3d5408SPeter Wemm returnCode(vidputs(newmode, _nc_outch)); 2970e3d5408SPeter Wemm } 2980e3d5408SPeter Wemm 2997a69bbfbSPeter Wemm NCURSES_EXPORT(chtype) 30015589c42SPeter Wemm termattrs(void) 3010e3d5408SPeter Wemm { 3020e3d5408SPeter Wemm chtype attrs = A_NORMAL; 3030e3d5408SPeter Wemm 30418259542SPeter Wemm T((T_CALLED("termattrs()"))); 3050e3d5408SPeter Wemm if (enter_alt_charset_mode) 3060e3d5408SPeter Wemm attrs |= A_ALTCHARSET; 3070e3d5408SPeter Wemm 3080e3d5408SPeter Wemm if (enter_blink_mode) 3090e3d5408SPeter Wemm attrs |= A_BLINK; 3100e3d5408SPeter Wemm 3110e3d5408SPeter Wemm if (enter_bold_mode) 3120e3d5408SPeter Wemm attrs |= A_BOLD; 3130e3d5408SPeter Wemm 3140e3d5408SPeter Wemm if (enter_dim_mode) 3150e3d5408SPeter Wemm attrs |= A_DIM; 3160e3d5408SPeter Wemm 3170e3d5408SPeter Wemm if (enter_reverse_mode) 3180e3d5408SPeter Wemm attrs |= A_REVERSE; 3190e3d5408SPeter Wemm 3200e3d5408SPeter Wemm if (enter_standout_mode) 3210e3d5408SPeter Wemm attrs |= A_STANDOUT; 3220e3d5408SPeter Wemm 3230e3d5408SPeter Wemm if (enter_protected_mode) 3240e3d5408SPeter Wemm attrs |= A_PROTECT; 3250e3d5408SPeter Wemm 3260e3d5408SPeter Wemm if (enter_secure_mode) 3270e3d5408SPeter Wemm attrs |= A_INVIS; 3280e3d5408SPeter Wemm 3290e3d5408SPeter Wemm if (enter_underline_mode) 3300e3d5408SPeter Wemm attrs |= A_UNDERLINE; 3310e3d5408SPeter Wemm 3320e3d5408SPeter Wemm if (SP->_coloron) 3330e3d5408SPeter Wemm attrs |= A_COLOR; 3340e3d5408SPeter Wemm 33518259542SPeter Wemm returnChar(attrs); 3360e3d5408SPeter Wemm } 337