/* replace braindamaged vidattr() There is no indication in terminfo of which attributes are cumulative. We assume that attributes defined with "enter_*_mode" and "exit_*_mode" are cumulative, whereas sgr is not. In addition, cookies are never cumulative. Terminfo doesn't tell us which attributes are cookies, but we will assume that if magic_cookie_glitch >= 0, then all attributes set with sgr are cookies. We make a bit mask of cookie attributes available to the caller. sgr is assumed to set any attributes not set with an enter_*_mode command. I.e., we try to use enter_*_mode first. sgr0 must be defined to turn off any enter_*_mode attributes that have no corresponding exit_*_mode command. sgr0 should turn off *all* such cumulative attributes, but should not affect sgr. Like AT&T, we keep track of the current mode attributes in CUR sgr_mode and only output the changes in vidattr(). Unlike AT&T, we can output cookies by setting A_MODIFIED. */ //#include #include "hackterm.h" #define doattr(str,ch) (((ch) && (str))?putp(str),~(ch):~0U) static CHTYPE magic_modes = 0; static CHTYPE magic_exits = 0; static CHTYPE sgr_mode = 0; /* return bitmask of attributes that are "cookies" */ CHTYPE vidinit(CHTYPE ch) { CHTYPE magic_cookies; magic_cookies = magic_modes = 0; if (enter_alt_charset_mode) magic_modes |= A_ALTCHARSET; if (enter_blink_mode) magic_modes |= A_BLINK; if (enter_bold_mode) magic_modes |= A_BOLD; if (enter_dim_mode) magic_modes |= A_DIM; if (enter_protected_mode) magic_modes |= A_PROTECT; if (enter_reverse_mode) magic_modes |= A_REVERSE; if (enter_secure_mode) magic_modes |= A_INVIS; if (enter_standout_mode) magic_modes |= A_STANDOUT; if (enter_underline_mode) magic_modes |= A_UNDERLINE; magic_exits = 0; if (exit_alt_charset_mode) magic_exits |= A_ALTCHARSET; if (exit_underline_mode) magic_exits |= A_UNDERLINE; if (exit_standout_mode) magic_exits |= A_STANDOUT; if (magic_cookie_glitch >= 0) magic_cookies = ~magic_modes & A_ATTRIBUTES & ~A_MODIFIED; sgr_mode = ch; return magic_cookies; } /* caller can force cookie output by setting A_MODIFIED */ void vidattr(CHTYPE ch) { chtype on = ch & ~sgr_mode; chtype off = sgr_mode & ~ch; sgr_mode = ch & ~A_MODIFIED; if (off) { /* some need to be turned off */ if (off & ~magic_exits & magic_modes) { off &= doattr(exit_attribute_mode,off & magic_modes); on |= ch & magic_modes; } off &= doattr(exit_alt_charset_mode,off & A_ALTCHARSET); off &= doattr(exit_underline_mode,off & A_UNDERLINE); off &= doattr(exit_standout_mode,off & A_STANDOUT); } if (on) { /* some need to be turned on */ on &= doattr(enter_alt_charset_mode,on & A_ALTCHARSET); on &= doattr(enter_standout_mode,on & A_STANDOUT); on &= doattr(enter_bold_mode,on & A_BOLD); on &= doattr(enter_reverse_mode,on & A_REVERSE); on &= doattr(enter_blink_mode,on & A_BLINK); on &= doattr(enter_underline_mode,on & A_UNDERLINE); on &= doattr(enter_protected_mode,on & A_PROTECT); on &= doattr(enter_secure_mode,on & A_INVIS); on &= doattr(enter_dim_mode,on & A_DIM); } if (!on && !off) return; // all changes handled via modes /* still some to turn on/off or a cookie to deposit */ if (set_attributes) putp(tparm(set_attributes, (ch&A_STANDOUT), (ch&A_UNDERLINE), (ch&A_REVERSE), (ch&A_BLINK), (ch&A_DIM), (ch&A_BOLD), (ch&A_INVIS), (ch&A_PROTECT), (ch&A_ALTCHARSET) )); }