ncurses 4.1
[ncurses.git] / ncurses / lib_vidattr.c
1
2 /***************************************************************************
3 *                            COPYRIGHT NOTICE                              *
4 ****************************************************************************
5 *                ncurses is copyright (C) 1992-1995                        *
6 *                          Zeyd M. Ben-Halim                               *
7 *                          zmbenhal@netcom.com                             *
8 *                          Eric S. Raymond                                 *
9 *                          esr@snark.thyrsus.com                           *
10 *                                                                          *
11 *        Permission is hereby granted to reproduce and distribute ncurses  *
12 *        by any means and for any fee, whether alone or as part of a       *
13 *        larger distribution, in source or in binary form, PROVIDED        *
14 *        this notice is included with any such distribution, and is not    *
15 *        removed from any of its header files. Mention of ncurses in any   *
16 *        applications linked with it is highly appreciated.                *
17 *                                                                          *
18 *        ncurses comes AS IS with no warranty, implied or expressed.       *
19 *                                                                          *
20 ***************************************************************************/
21
22 /*
23  *      vidputs(newmode, outc)
24  *
25  *      newmode is taken to be the logical 'or' of the symbols in curses.h
26  *      representing graphic renditions.  The terminal is set to be in all of
27  *      the given modes, if possible.
28  *
29  *      if the new attribute is normal
30  *              if exit-alt-char-set exists
31  *                      emit it
32  *              emit exit-attribute-mode
33  *      else if set-attributes exists
34  *              use it to set exactly what you want
35  *      else
36  *              if exit-attribute-mode exists
37  *                      turn off everything
38  *              else
39  *                      turn off those which can be turned off and aren't in
40  *                      newmode.
41  *              turn on each mode which should be on and isn't, one by one
42  *
43  *      NOTE that this algorithm won't achieve the desired mix of attributes
44  *      in some cases, but those are probably just those cases in which it is
45  *      actually impossible, anyway, so...
46  *
47  *      NOTE that we cannot assume that there's no interaction between color
48  *      and other attribute resets.  So each time we reset color (or other
49  *      attributes) we'll have to be prepared to restore the other.
50  */
51
52 #include <curses.priv.h>
53 #include <term.h>
54
55 MODULE_ID("$Id: lib_vidattr.c,v 1.14 1997/05/06 16:02:43 tom Exp $")
56
57 #define doPut(mode) TPUTS_TRACE(#mode); tputs(mode, 1, outc)
58
59 #define TurnOn(mask,mode) \
60         if ((turn_on & mask) && mode) { doPut(mode); }
61
62 #define TurnOff(mask,mode) \
63         if ((turn_off & mask) && mode) { doPut(mode); turn_off &= ~mask; }
64
65 int vidputs(attr_t newmode, int  (*outc)(int))
66 {
67 static attr_t previous_attr = A_NORMAL;
68 attr_t turn_on, turn_off;
69 int pair, current_pair;
70
71         T((T_CALLED("vidputs(%s)"), _traceattr(newmode)));
72
73         /* this allows us to go on whether or not newterm() has been called */
74         if (SP)
75                 previous_attr = SP->_current_attr;
76
77         T(("previous attribute was %s", _traceattr(previous_attr)));
78
79         if (newmode == previous_attr)
80                 returnCode(OK);
81
82         turn_off = (~newmode & previous_attr) & ALL_BUT_COLOR;
83         turn_on  = (newmode & ~previous_attr) & ALL_BUT_COLOR;
84
85         pair = PAIR_NUMBER(newmode);
86         current_pair = PAIR_NUMBER(previous_attr);
87
88         /* if there is no current screen, assume we *can* do color */
89         if ((!SP || SP->_coloron) && pair == 0) {
90                 T(("old pair = %d -- new pair = %d", current_pair, pair));
91                 if (pair != current_pair) {
92                         _nc_do_color(pair, outc);
93                         previous_attr &= ~A_COLOR;
94                 }
95         }
96
97         if (newmode == A_NORMAL) {
98                 if((previous_attr & A_ALTCHARSET) && exit_alt_charset_mode) {
99                         doPut(exit_alt_charset_mode);
100                         previous_attr &= ~A_ALTCHARSET;
101                 }
102                 if (previous_attr) {
103                         doPut(exit_attribute_mode);
104                         previous_attr &= ~A_COLOR;
105                 }
106
107         } else if (set_attributes) {
108                 if (turn_on || turn_off) {
109                         TPUTS_TRACE("set_attributes");
110                         tputs(tparm(set_attributes,
111                                 (newmode & A_STANDOUT) != 0,
112                                 (newmode & A_UNDERLINE) != 0,
113                                 (newmode & A_REVERSE) != 0,
114                                 (newmode & A_BLINK) != 0,
115                                 (newmode & A_DIM) != 0,
116                                 (newmode & A_BOLD) != 0,
117                                 (newmode & A_INVIS) != 0,
118                                 (newmode & A_PROTECT) != 0,
119                                 (newmode & A_ALTCHARSET) != 0), 1, outc);
120                         previous_attr &= ~A_COLOR;
121                 }
122         } else {
123
124                 T(("turning %s off", _traceattr(turn_off)));
125
126                 TurnOff(A_ALTCHARSET,  exit_alt_charset_mode);
127                 TurnOff(A_UNDERLINE,   exit_underline_mode);
128                 TurnOff(A_STANDOUT,    exit_standout_mode);
129
130                 if (turn_off && exit_attribute_mode) {
131                         doPut(exit_attribute_mode);
132                         turn_on  |= (newmode & (chtype)(~A_COLOR));
133                         previous_attr &= ~A_COLOR;
134                 }
135
136                 T(("turning %s on", _traceattr(turn_on)));
137
138                 TurnOn (A_ALTCHARSET, enter_alt_charset_mode);
139                 TurnOn (A_BLINK,      enter_blink_mode);
140                 TurnOn (A_BOLD,       enter_bold_mode);
141                 TurnOn (A_DIM,        enter_dim_mode);
142                 TurnOn (A_REVERSE,    enter_reverse_mode);
143                 TurnOn (A_STANDOUT,   enter_standout_mode);
144                 TurnOn (A_PROTECT,    enter_protected_mode);
145                 TurnOn (A_INVIS,      enter_secure_mode);
146                 TurnOn (A_UNDERLINE,  enter_underline_mode);
147                 TurnOn (A_HORIZONTAL, enter_horizontal_hl_mode);
148                 TurnOn (A_LEFT,       enter_left_hl_mode);
149                 TurnOn (A_LOW,        enter_low_hl_mode);
150                 TurnOn (A_RIGHT,      enter_right_hl_mode);
151                 TurnOn (A_TOP,        enter_top_hl_mode);
152                 TurnOn (A_VERTICAL,   enter_vertical_hl_mode);
153         }
154
155         /* if there is no current screen, assume we *can* do color */
156         if ((!SP || SP->_coloron) && pair != 0) {
157                 current_pair = PAIR_NUMBER(previous_attr);
158                 T(("old pair = %d -- new pair = %d", current_pair, pair));
159                 if (pair != current_pair) {
160                         _nc_do_color(pair, outc);
161                 }
162         }
163
164         if (SP)
165                 SP->_current_attr = newmode;
166         else
167                 previous_attr = newmode;
168
169         returnCode(OK);
170 }
171
172 int vidattr(attr_t newmode)
173 {
174         T((T_CALLED("vidattr(%s)"), _traceattr(newmode)));
175
176         returnCode(vidputs(newmode, _nc_outch));
177 }
178
179 attr_t termattrs(void)
180 {
181         int attrs = A_NORMAL;
182
183         if (enter_alt_charset_mode)
184                 attrs |= A_ALTCHARSET;
185
186         if (enter_blink_mode)
187                 attrs |= A_BLINK;
188
189         if (enter_bold_mode)
190                 attrs |= A_BOLD;
191
192         if (enter_dim_mode)
193                 attrs |= A_DIM;
194
195         if (enter_reverse_mode)
196                 attrs |= A_REVERSE;
197
198         if (enter_standout_mode)
199                 attrs |= A_STANDOUT;
200
201         if (enter_protected_mode)
202                 attrs |= A_PROTECT;
203
204         if (enter_secure_mode)
205                 attrs |= A_INVIS;
206
207         if (enter_underline_mode)
208                 attrs |= A_UNDERLINE;
209
210         if (SP->_coloron)
211                 attrs |= A_COLOR;
212
213         return(attrs);
214 }
215