diff options
author | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-01-18 12:04:32 +0000 |
---|---|---|
committer | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-01-18 12:04:32 +0000 |
commit | e2d147e01aa8bd00b79c8288fa1c490d187c9e82 (patch) | |
tree | 0e50849418106307cd3b6ae5346d11cdcec8756c /ncurses/tty/lib_vidattr.c | |
download | ncurses-e2d147e01aa8bd00b79c8288fa1c490d187c9e82.tar.gz |
Tarball conversion
Diffstat (limited to 'ncurses/tty/lib_vidattr.c')
-rw-r--r-- | ncurses/tty/lib_vidattr.c | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/ncurses/tty/lib_vidattr.c b/ncurses/tty/lib_vidattr.c new file mode 100644 index 0000000..9656b3c --- /dev/null +++ b/ncurses/tty/lib_vidattr.c @@ -0,0 +1,389 @@ +/**************************************************************************** + * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * + * and: Eric S. Raymond <esr@snark.thyrsus.com> * + * and: Thomas E. Dickey 1996-on * + * and: Juergen Pfeifer 2009 * + ****************************************************************************/ + +/* + * vidputs(newmode, outc) + * + * newmode is taken to be the logical 'or' of the symbols in curses.h + * representing graphic renditions. The terminal is set to be in all of + * the given modes, if possible. + * + * if the new attribute is normal + * if exit-alt-char-set exists + * emit it + * emit exit-attribute-mode + * else if set-attributes exists + * use it to set exactly what you want + * else + * if exit-attribute-mode exists + * turn off everything + * else + * turn off those which can be turned off and aren't in + * newmode. + * turn on each mode which should be on and isn't, one by one + * + * NOTE that this algorithm won't achieve the desired mix of attributes + * in some cases, but those are probably just those cases in which it is + * actually impossible, anyway, so... + * + * NOTE that we cannot assume that there's no interaction between color + * and other attribute resets. So each time we reset color (or other + * attributes) we'll have to be prepared to restore the other. + */ + +#include <curses.priv.h> + +#ifndef CUR +#define CUR SP_TERMTYPE +#endif + +MODULE_ID("$Id: lib_vidattr.c,v 1.61 2010/06/05 22:22:04 tom Exp $") + +#define doPut(mode) \ + TPUTS_TRACE(#mode); \ + NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx mode, 1, outc) + +#define TurnOn(mask,mode) \ + if ((turn_on & mask) && mode) { doPut(mode); } + +#define TurnOff(mask,mode) \ + if ((turn_off & mask) && mode) { doPut(mode); turn_off &= ~mask; } + + /* if there is no current screen, assume we *can* do color */ +#define SetColorsIf(why,old_attr) \ + if (can_color && (why)) { \ + int old_pair = PairNumber(old_attr); \ + TR(TRACE_ATTRS, ("old pair = %d -- new pair = %d", old_pair, pair)); \ + if ((pair != old_pair) \ + || (fix_pair0 && (pair == 0)) \ + || (reverse ^ ((old_attr & A_REVERSE) != 0))) { \ + NCURSES_SP_NAME(_nc_do_color)(NCURSES_SP_ARGx \ + (short) old_pair, \ + (short) pair, \ + reverse, outc); \ + } \ + } + +#define PreviousAttr _nc_prescreen.previous_attr + +NCURSES_EXPORT(int) +NCURSES_SP_NAME(vidputs) (NCURSES_SP_DCLx + chtype newmode, + NCURSES_SP_OUTC outc) +{ + attr_t turn_on, turn_off; + int pair; + bool reverse = FALSE; + bool can_color = (SP_PARM == 0 || SP_PARM->_coloron); +#if NCURSES_EXT_FUNCS + bool fix_pair0 = (SP_PARM != 0 && SP_PARM->_coloron && !SP_PARM->_default_color); +#else +#define fix_pair0 FALSE +#endif + + newmode &= A_ATTRIBUTES; + + T((T_CALLED("vidputs(%p,%s)"), (void *) SP_PARM, _traceattr(newmode))); + + if (!IsTermInfo(SP_PARM)) + returnCode(ERR); + + /* this allows us to go on whether or not newterm() has been called */ + if (SP_PARM) + PreviousAttr = AttrOf(SCREEN_ATTRS(SP_PARM)); + + TR(TRACE_ATTRS, ("previous attribute was %s", _traceattr(PreviousAttr))); + + if ((SP_PARM != 0) + && (magic_cookie_glitch > 0)) { +#if USE_XMC_SUPPORT + static const chtype table[] = + { + A_STANDOUT, + A_UNDERLINE, + A_REVERSE, + A_BLINK, + A_DIM, + A_BOLD, + A_INVIS, + A_PROTECT, + }; + unsigned n; + int used = 0; + int limit = (max_attributes <= 0) ? 1 : max_attributes; + chtype retain = 0; + + /* + * Limit the number of attribute bits set in the newmode according to + * the terminfo max_attributes value. + */ + for (n = 0; n < SIZEOF(table); ++n) { + if ((table[n] & SP_PARM->_ok_attributes) == 0) { + newmode &= ~table[n]; + } else if ((table[n] & newmode) != 0) { + if (used++ >= limit) { + newmode &= ~table[n]; + if (newmode == retain) + break; + } else { + retain = newmode; + } + } + } +#else + newmode &= ~(SP_PARM->_xmc_suppress); +#endif + TR(TRACE_ATTRS, ("suppressed attribute is %s", _traceattr(newmode))); + } + + /* + * If we have a terminal that cannot combine color with video + * attributes, use the colors in preference. + */ + if (((newmode & A_COLOR) != 0 + || fix_pair0) + && (no_color_video > 0)) { + /* + * If we had chosen the A_xxx definitions to correspond to the + * no_color_video mask, we could simply shift it up and mask off the + * attributes. But we did not (actually copied Solaris' definitions). + * However, this is still simpler/faster than a lookup table. + * + * The 63 corresponds to A_STANDOUT, A_UNDERLINE, A_REVERSE, A_BLINK, + * A_DIM, A_BOLD which are 1:1 with no_color_video. The bits that + * correspond to A_INVIS, A_PROTECT (192) must be shifted up 1 and + * A_ALTCHARSET (256) down 2 to line up. We use the NCURSES_BITS + * macro so this will work properly for the wide-character layout. + */ + unsigned value = (unsigned) no_color_video; + attr_t mask = NCURSES_BITS((value & 63) + | ((value & 192) << 1) + | ((value & 256) >> 2), 8); + + if ((mask & A_REVERSE) != 0 + && (newmode & A_REVERSE) != 0) { + reverse = TRUE; + mask &= ~A_REVERSE; + } + newmode &= ~mask; + } + + if (newmode == PreviousAttr) + returnCode(OK); + + pair = PairNumber(newmode); + + if (reverse) { + newmode &= ~A_REVERSE; + } + + turn_off = (~newmode & PreviousAttr) & ALL_BUT_COLOR; + turn_on = (newmode & ~PreviousAttr) & ALL_BUT_COLOR; + + SetColorsIf(((pair == 0) && !fix_pair0), PreviousAttr); + + if (newmode == A_NORMAL) { + if ((PreviousAttr & A_ALTCHARSET) && exit_alt_charset_mode) { + doPut(exit_alt_charset_mode); + PreviousAttr &= ~A_ALTCHARSET; + } + if (PreviousAttr) { + if (exit_attribute_mode) { + doPut(exit_attribute_mode); + } else { + if (!SP_PARM || SP_PARM->_use_rmul) { + TurnOff(A_UNDERLINE, exit_underline_mode); + } + if (!SP_PARM || SP_PARM->_use_rmso) { + TurnOff(A_STANDOUT, exit_standout_mode); + } + } + PreviousAttr &= ALL_BUT_COLOR; + } + + SetColorsIf((pair != 0) || fix_pair0, PreviousAttr); + } else if (set_attributes) { + if (turn_on || turn_off) { + TPUTS_TRACE("set_attributes"); + NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx + tparm(set_attributes, + (newmode & A_STANDOUT) != 0, + (newmode & A_UNDERLINE) != 0, + (newmode & A_REVERSE) != 0, + (newmode & A_BLINK) != 0, + (newmode & A_DIM) != 0, + (newmode & A_BOLD) != 0, + (newmode & A_INVIS) != 0, + (newmode & A_PROTECT) != 0, + (newmode & A_ALTCHARSET) != 0), + 1, outc); + PreviousAttr &= ALL_BUT_COLOR; + } + SetColorsIf((pair != 0) || fix_pair0, PreviousAttr); + } else { + + TR(TRACE_ATTRS, ("turning %s off", _traceattr(turn_off))); + + TurnOff(A_ALTCHARSET, exit_alt_charset_mode); + + if (!SP_PARM || SP_PARM->_use_rmul) { + TurnOff(A_UNDERLINE, exit_underline_mode); + } + + if (!SP_PARM || SP_PARM->_use_rmso) { + TurnOff(A_STANDOUT, exit_standout_mode); + } + + if (turn_off && exit_attribute_mode) { + doPut(exit_attribute_mode); + turn_on |= (newmode & ALL_BUT_COLOR); + PreviousAttr &= ALL_BUT_COLOR; + } + SetColorsIf((pair != 0) || fix_pair0, PreviousAttr); + + TR(TRACE_ATTRS, ("turning %s on", _traceattr(turn_on))); + /* *INDENT-OFF* */ + TurnOn(A_ALTCHARSET, enter_alt_charset_mode); + TurnOn(A_BLINK, enter_blink_mode); + TurnOn(A_BOLD, enter_bold_mode); + TurnOn(A_DIM, enter_dim_mode); + TurnOn(A_REVERSE, enter_reverse_mode); + TurnOn(A_STANDOUT, enter_standout_mode); + TurnOn(A_PROTECT, enter_protected_mode); + TurnOn(A_INVIS, enter_secure_mode); + TurnOn(A_UNDERLINE, enter_underline_mode); +#if USE_WIDEC_SUPPORT + TurnOn(A_HORIZONTAL, enter_horizontal_hl_mode); + TurnOn(A_LEFT, enter_left_hl_mode); + TurnOn(A_LOW, enter_low_hl_mode); + TurnOn(A_RIGHT, enter_right_hl_mode); + TurnOn(A_TOP, enter_top_hl_mode); + TurnOn(A_VERTICAL, enter_vertical_hl_mode); +#endif + /* *INDENT-ON* */ + + } + + if (reverse) + newmode |= A_REVERSE; + + if (SP_PARM) + SetAttr(SCREEN_ATTRS(SP_PARM), newmode); + else + PreviousAttr = newmode; + + returnCode(OK); +} + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(int) +vidputs(chtype newmode, NCURSES_OUTC outc) +{ + SetSafeOutcWrapper(outc); + return NCURSES_SP_NAME(vidputs) (CURRENT_SCREEN, + newmode, + _nc_outc_wrapper); +} +#endif + +NCURSES_EXPORT(int) +NCURSES_SP_NAME(vidattr) (NCURSES_SP_DCLx chtype newmode) +{ + T((T_CALLED("vidattr(%p,%s)"), (void *) SP_PARM, _traceattr(newmode))); + returnCode(NCURSES_SP_NAME(vidputs) (NCURSES_SP_ARGx + newmode, + NCURSES_SP_NAME(_nc_outch))); +} + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(int) +vidattr(chtype newmode) +{ + return NCURSES_SP_NAME(vidattr) (CURRENT_SCREEN, newmode); +} +#endif + +NCURSES_EXPORT(chtype) +NCURSES_SP_NAME(termattrs) (NCURSES_SP_DCL0) +{ + chtype attrs = A_NORMAL; + + T((T_CALLED("termattrs(%p)"), (void *) SP_PARM)); +#ifdef USE_TERM_DRIVER + if (HasTerminal(SP_PARM)) + attrs = CallDriver(SP_PARM, conattr); +#else + + if (enter_alt_charset_mode) + attrs |= A_ALTCHARSET; + + if (enter_blink_mode) + attrs |= A_BLINK; + + if (enter_bold_mode) + attrs |= A_BOLD; + + if (enter_dim_mode) + attrs |= A_DIM; + + if (enter_reverse_mode) + attrs |= A_REVERSE; + + if (enter_standout_mode) + attrs |= A_STANDOUT; + + if (enter_protected_mode) + attrs |= A_PROTECT; + + if (enter_secure_mode) + attrs |= A_INVIS; + + if (enter_underline_mode) + attrs |= A_UNDERLINE; + + if (SP_PARM->_coloron) + attrs |= A_COLOR; + +#endif + returnChtype(attrs); +} + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(chtype) +termattrs(void) +{ + return NCURSES_SP_NAME(termattrs) (CURRENT_SCREEN); +} +#endif |