GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcurses/tty/lib_vidattr.c Lines: 0 105 0.0 %
Date: 2017-11-07 Branches: 0 210 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: lib_vidattr.c,v 1.9 2010/01/12 23:22:07 nicm Exp $ */
2
3
/****************************************************************************
4
 * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
5
 *                                                                          *
6
 * Permission is hereby granted, free of charge, to any person obtaining a  *
7
 * copy of this software and associated documentation files (the            *
8
 * "Software"), to deal in the Software without restriction, including      *
9
 * without limitation the rights to use, copy, modify, merge, publish,      *
10
 * distribute, distribute with modifications, sublicense, and/or sell       *
11
 * copies of the Software, and to permit persons to whom the Software is    *
12
 * furnished to do so, subject to the following conditions:                 *
13
 *                                                                          *
14
 * The above copyright notice and this permission notice shall be included  *
15
 * in all copies or substantial portions of the Software.                   *
16
 *                                                                          *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
20
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
21
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
22
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
23
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
24
 *                                                                          *
25
 * Except as contained in this notice, the name(s) of the above copyright   *
26
 * holders shall not be used in advertising or otherwise to promote the     *
27
 * sale, use or other dealings in this Software without prior written       *
28
 * authorization.                                                           *
29
 ****************************************************************************/
30
31
/****************************************************************************
32
 *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
33
 *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
34
 *     and: Thomas E. Dickey                        1996 on                 *
35
 ****************************************************************************/
36
37
/*
38
 *	vidputs(newmode, outc)
39
 *
40
 *	newmode is taken to be the logical 'or' of the symbols in curses.h
41
 *	representing graphic renditions.  The terminal is set to be in all of
42
 *	the given modes, if possible.
43
 *
44
 *	if the new attribute is normal
45
 *		if exit-alt-char-set exists
46
 *			emit it
47
 *		emit exit-attribute-mode
48
 *	else if set-attributes exists
49
 *		use it to set exactly what you want
50
 *	else
51
 *		if exit-attribute-mode exists
52
 *			turn off everything
53
 *		else
54
 *			turn off those which can be turned off and aren't in
55
 *			newmode.
56
 *		turn on each mode which should be on and isn't, one by one
57
 *
58
 *	NOTE that this algorithm won't achieve the desired mix of attributes
59
 *	in some cases, but those are probably just those cases in which it is
60
 *	actually impossible, anyway, so...
61
 *
62
 * 	NOTE that we cannot assume that there's no interaction between color
63
 *	and other attribute resets.  So each time we reset color (or other
64
 *	attributes) we'll have to be prepared to restore the other.
65
 */
66
67
#include <curses.priv.h>
68
#include <term.h>
69
70
MODULE_ID("$Id: lib_vidattr.c,v 1.9 2010/01/12 23:22:07 nicm Exp $")
71
72
#define doPut(mode) TPUTS_TRACE(#mode); tputs(mode, 1, outc)
73
74
#define TurnOn(mask,mode) \
75
	if ((turn_on & mask) && mode) { doPut(mode); }
76
77
#define TurnOff(mask,mode) \
78
	if ((turn_off & mask) && mode) { doPut(mode); turn_off &= ~mask; }
79
80
	/* if there is no current screen, assume we *can* do color */
81
#define SetColorsIf(why,old_attr) \
82
	if (can_color && (why)) { \
83
		int old_pair = PAIR_NUMBER(old_attr); \
84
		TR(TRACE_ATTRS, ("old pair = %d -- new pair = %d", old_pair, pair)); \
85
		if ((pair != old_pair) \
86
		 || (fix_pair0 && (pair == 0)) \
87
		 || (reverse ^ ((old_attr & A_REVERSE) != 0))) { \
88
			_nc_do_color(old_pair, pair, reverse, outc); \
89
		} \
90
	}
91
92
#define PreviousAttr _nc_prescreen.previous_attr
93
94
NCURSES_EXPORT(int)
95
vidputs(chtype newmode, int (*outc) (int))
96
{
97
    attr_t turn_on, turn_off;
98
    int pair;
99
    bool reverse = FALSE;
100
    bool can_color = (SP == 0 || SP->_coloron);
101
#if NCURSES_EXT_FUNCS
102
    bool fix_pair0 = (SP != 0 && SP->_coloron && !SP->_default_color);
103
#else
104
#define fix_pair0 FALSE
105
#endif
106
107
    newmode &= A_ATTRIBUTES;
108
    T((T_CALLED("vidputs(%s)"), _traceattr(newmode)));
109
110
    /* this allows us to go on whether or not newterm() has been called */
111
    if (SP)
112
	PreviousAttr = AttrOf(SCREEN_ATTRS(SP));
113
114
    TR(TRACE_ATTRS, ("previous attribute was %s", _traceattr(PreviousAttr)));
115
116
    if ((SP != 0)
117
	&& (magic_cookie_glitch > 0)) {
118
#if USE_XMC_SUPPORT
119
	static const chtype table[] =
120
	{
121
	    A_STANDOUT,
122
	    A_UNDERLINE,
123
	    A_REVERSE,
124
	    A_BLINK,
125
	    A_DIM,
126
	    A_BOLD,
127
	    A_INVIS,
128
	    A_PROTECT,
129
	};
130
	unsigned n;
131
	int used = 0;
132
	int limit = (max_attributes <= 0) ? 1 : max_attributes;
133
	chtype retain = 0;
134
135
	/*
136
	 * Limit the number of attribute bits set in the newmode according to
137
	 * the terminfo max_attributes value.
138
	 */
139
	for (n = 0; n < SIZEOF(table); ++n) {
140
	    if ((table[n] & SP->_ok_attributes) == 0) {
141
		newmode &= ~table[n];
142
	    } else if ((table[n] & newmode) != 0) {
143
		if (used++ >= limit) {
144
		    newmode &= ~table[n];
145
		    if (newmode == retain)
146
			break;
147
		} else {
148
		    retain = newmode;
149
		}
150
	    }
151
	}
152
#else
153
	newmode &= ~(SP->_xmc_suppress);
154
#endif
155
	TR(TRACE_ATTRS, ("suppressed attribute is %s", _traceattr(newmode)));
156
    }
157
158
    /*
159
     * If we have a terminal that cannot combine color with video
160
     * attributes, use the colors in preference.
161
     */
162
    if (((newmode & A_COLOR) != 0
163
	 || fix_pair0)
164
	&& (no_color_video > 0)) {
165
	/*
166
	 * If we had chosen the A_xxx definitions to correspond to the
167
	 * no_color_video mask, we could simply shift it up and mask off the
168
	 * attributes.  But we did not (actually copied Solaris' definitions).
169
	 * However, this is still simpler/faster than a lookup table.
170
	 *
171
	 * The 63 corresponds to A_STANDOUT, A_UNDERLINE, A_REVERSE, A_BLINK,
172
	 * A_DIM, A_BOLD which are 1:1 with no_color_video.  The bits that
173
	 * correspond to A_INVIS, A_PROTECT (192) must be shifted up 1 and
174
	 * A_ALTCHARSET (256) down 2 to line up.  We use the NCURSES_BITS
175
	 * macro so this will work properly for the wide-character layout.
176
	 */
177
	unsigned value = no_color_video;
178
	attr_t mask = NCURSES_BITS((value & 63)
179
				   | ((value & 192) << 1)
180
				   | ((value & 256) >> 2), 8);
181
182
	if ((mask & A_REVERSE) != 0
183
	    && (newmode & A_REVERSE) != 0) {
184
	    reverse = TRUE;
185
	    mask &= ~A_REVERSE;
186
	}
187
	newmode &= ~mask;
188
    }
189
190
    if (newmode == PreviousAttr)
191
	returnCode(OK);
192
193
    pair = PAIR_NUMBER(newmode);
194
195
    if (reverse) {
196
	newmode &= ~A_REVERSE;
197
    }
198
199
    turn_off = (~newmode & PreviousAttr) & ALL_BUT_COLOR;
200
    turn_on = (newmode & ~PreviousAttr) & ALL_BUT_COLOR;
201
202
    SetColorsIf(((pair == 0) && !fix_pair0), PreviousAttr);
203
204
    if (newmode == A_NORMAL) {
205
	if ((PreviousAttr & A_ALTCHARSET) && exit_alt_charset_mode) {
206
	    doPut(exit_alt_charset_mode);
207
	    PreviousAttr &= ~A_ALTCHARSET;
208
	}
209
	if (PreviousAttr) {
210
	    if (exit_attribute_mode) {
211
		doPut(exit_attribute_mode);
212
	    } else {
213
		if (!SP || SP->_use_rmul) {
214
		    TurnOff(A_UNDERLINE, exit_underline_mode);
215
		}
216
		if (!SP || SP->_use_rmso) {
217
		    TurnOff(A_STANDOUT, exit_standout_mode);
218
		}
219
	    }
220
	    PreviousAttr &= ALL_BUT_COLOR;
221
	}
222
223
	SetColorsIf((pair != 0) || fix_pair0, PreviousAttr);
224
    } else if (set_attributes) {
225
	if (turn_on || turn_off) {
226
	    TPUTS_TRACE("set_attributes");
227
	    tputs(tparm(set_attributes,
228
			(newmode & A_STANDOUT) != 0,
229
			(newmode & A_UNDERLINE) != 0,
230
			(newmode & A_REVERSE) != 0,
231
			(newmode & A_BLINK) != 0,
232
			(newmode & A_DIM) != 0,
233
			(newmode & A_BOLD) != 0,
234
			(newmode & A_INVIS) != 0,
235
			(newmode & A_PROTECT) != 0,
236
			(newmode & A_ALTCHARSET) != 0), 1, outc);
237
	    PreviousAttr &= ALL_BUT_COLOR;
238
	}
239
	SetColorsIf((pair != 0) || fix_pair0, PreviousAttr);
240
    } else {
241
242
	TR(TRACE_ATTRS, ("turning %s off", _traceattr(turn_off)));
243
244
	TurnOff(A_ALTCHARSET, exit_alt_charset_mode);
245
246
	if (!SP || SP->_use_rmul) {
247
	    TurnOff(A_UNDERLINE, exit_underline_mode);
248
	}
249
250
	if (!SP || SP->_use_rmso) {
251
	    TurnOff(A_STANDOUT, exit_standout_mode);
252
	}
253
254
	if (turn_off && exit_attribute_mode) {
255
	    doPut(exit_attribute_mode);
256
	    turn_on |= (newmode & ALL_BUT_COLOR);
257
	    PreviousAttr &= ALL_BUT_COLOR;
258
	}
259
	SetColorsIf((pair != 0) || fix_pair0, PreviousAttr);
260
261
	TR(TRACE_ATTRS, ("turning %s on", _traceattr(turn_on)));
262
	/* *INDENT-OFF* */
263
	TurnOn(A_ALTCHARSET,	enter_alt_charset_mode);
264
	TurnOn(A_BLINK,		enter_blink_mode);
265
	TurnOn(A_BOLD,		enter_bold_mode);
266
	TurnOn(A_DIM,		enter_dim_mode);
267
	TurnOn(A_REVERSE,	enter_reverse_mode);
268
	TurnOn(A_STANDOUT,	enter_standout_mode);
269
	TurnOn(A_PROTECT,	enter_protected_mode);
270
	TurnOn(A_INVIS,		enter_secure_mode);
271
	TurnOn(A_UNDERLINE,	enter_underline_mode);
272
#if USE_WIDEC_SUPPORT
273
	TurnOn(A_HORIZONTAL,	enter_horizontal_hl_mode);
274
	TurnOn(A_LEFT,		enter_left_hl_mode);
275
	TurnOn(A_LOW,		enter_low_hl_mode);
276
	TurnOn(A_RIGHT,		enter_right_hl_mode);
277
	TurnOn(A_TOP,		enter_top_hl_mode);
278
	TurnOn(A_VERTICAL,	enter_vertical_hl_mode);
279
#endif
280
	/* *INDENT-ON* */
281
282
    }
283
284
    if (reverse)
285
	newmode |= A_REVERSE;
286
287
    if (SP)
288
	SetAttr(SCREEN_ATTRS(SP), newmode);
289
    else
290
	PreviousAttr = newmode;
291
292
    returnCode(OK);
293
}
294
295
NCURSES_EXPORT(int)
296
vidattr(chtype newmode)
297
{
298
    T((T_CALLED("vidattr(%s)"), _traceattr(newmode)));
299
300
    returnCode(vidputs(newmode, _nc_outch));
301
}
302
303
NCURSES_EXPORT(chtype)
304
termattrs(void)
305
{
306
    chtype attrs = A_NORMAL;
307
308
    T((T_CALLED("termattrs()")));
309
    if (enter_alt_charset_mode)
310
	attrs |= A_ALTCHARSET;
311
312
    if (enter_blink_mode)
313
	attrs |= A_BLINK;
314
315
    if (enter_bold_mode)
316
	attrs |= A_BOLD;
317
318
    if (enter_dim_mode)
319
	attrs |= A_DIM;
320
321
    if (enter_reverse_mode)
322
	attrs |= A_REVERSE;
323
324
    if (enter_standout_mode)
325
	attrs |= A_STANDOUT;
326
327
    if (enter_protected_mode)
328
	attrs |= A_PROTECT;
329
330
    if (enter_secure_mode)
331
	attrs |= A_INVIS;
332
333
    if (enter_underline_mode)
334
	attrs |= A_UNDERLINE;
335
336
    if (SP->_coloron)
337
	attrs |= A_COLOR;
338
339
    returnChar(attrs);
340
}