4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
44 #include <sys/types.h>
46 #include "curses_inc.h"
50 #include <sys/console.h>
53 #define NUM_OF_SPECIFIC_TURN_OFFS 3
54 extern chtype bit_attributes
[];
56 int Oldcolors
[] = { COLOR_BLACK
, COLOR_BLUE
, COLOR_GREEN
, COLOR_CYAN
,
57 COLOR_RED
, COLOR_MAGENTA
, COLOR_YELLOW
, COLOR_WHITE
};
60 vidupdate(chtype newmode
, chtype oldmode
, int (*outc
)(char))
62 bool color_terminal
= (cur_term
->_pairs_tbl
) ? TRUE
: FALSE
;
63 chtype oldvideo
= (oldmode
& A_ATTRIBUTES
) & ~A_COLOR
;
64 chtype newvideo
= (newmode
& A_ATTRIBUTES
) & ~A_COLOR
;
65 int _change_video(chtype
, chtype
, int (*)(char));
66 void _change_color(short, int (*)(char));
68 /* if colors are used, extract the color related information from */
69 /* the old and new modes and then erase color-pairs fields in */
74 short oldcolor
= (short) PAIR_NUMBER(oldmode
& A_COLOR
);
76 short newcolor
= (short) PAIR_NUMBER(newmode
& A_COLOR
);
77 chtype turn_off
= A_COLOR
;
79 /* erase information about video attributes that could not */
80 /* have been used with colors */
83 oldvideo
&= ~turn_off
;
85 if (no_color_video
!= -1)
86 turn_off
|= (((chtype
) no_color_video
) << 16);
89 oldvideo
&= ~turn_off
;
92 /* if the new mode contains color information, then first */
93 /* deal with video attributes, and then with colors. This */
94 /* way color information will overwrite video information. */
97 /* erase information about video attributes that */
98 /* should not be used with colors */
100 newvideo
&= ~turn_off
;
102 /* if the new and the old video modes became */
103 /* the same don't bother with them */
105 if (newvideo
!= oldvideo
) {
106 if ((_change_video(newvideo
, oldvideo
,
108 _Color_pair
*cur_pair
=
109 &cur_term
->_cur_pair
;
111 cur_pair
->background
=
112 cur_pair
->foreground
= -1;
115 if (newcolor
!= oldcolor
)
116 _change_color(newcolor
, outc
);
119 /* new mode doesn't contain any color information. Deal */
120 /* with colors first (possibly turning of the colors that */
121 /* were contained in the oldmode, and then deal with video. */
122 /* This way video attributes will overwrite colors. */
125 if (newcolor
!= oldcolor
)
126 _change_color(newcolor
, outc
);
127 if (newvideo
!= oldvideo
)
128 (void) _change_video(newvideo
, oldvideo
, outc
);
131 (void) _change_video(newvideo
, oldvideo
, outc
);
136 _change_video(chtype newmode
, chtype oldmode
, int (*outc
)(char))
140 /* If you have set_attributes let the terminfo writer */
141 /* worry about it. */
143 if (!set_attributes
) {
145 * The trick is that we want to pre-process the new and oldmode
146 * so that we now know what they will really translate to on
147 * the physical screen.
148 * In the case where some attributes are being faked
149 * we get rid of the attributes being asked for and just have
150 * STANDOUT mode set. Therefore, if STANDOUT and UNDERLINE were
151 * on the screen but UNDERLINE was being faked to STANDOUT; and
152 * the new mode is just UNDERLINE, we will get rid of any faked
153 * modes and be left with and oldmode of STANDOUT and a new mode
154 * of STANDOUT, in which case the check for newmode and oldmode
155 * being equal will be true.
158 * This test is similar to the concept explained above.
159 * counter is the maximum attributes allowed on a terminal.
160 * For instance, on an hp/tvi950 without set_attributes
161 * the last video sequence sent will be the one the terminal
162 * will be in (on that spot). Therefore, in setupterm.c
163 * if ceol_standout_glitch or magic_cookie_glitch is set
164 * max_attributes is set to 1. This is because on those terminals
165 * only one attribute can be on at once. So, we pre-process the
166 * oldmode and the newmode and only leave the bits that are
167 * significant. In other words, if on an hp you ask for STANDOUT
168 * and UNDERLINE it will become only STANDOUT since that is the
169 * first bit that is looked at. If then the user goes from
170 * STANDOUT and UNDERLINE to STANDOUT and REVERSE the oldmode will
171 * become STANDOUT and the newmode will become STANDOUT.
173 * This also helps the code below in that on a hp or tvi950 only
174 * one bit will ever be set so that no code has to be added to
175 * cut out early in case two attributes were asked for.
178 chtype check_faked
, modes
[2];
179 int counter
= max_attributes
, i
, j
, tempmode
;
180 int k
= (cur_term
->sgr_mode
== oldmode
) ? 1 : 2;
186 if ((check_faked
= (modes
[k
] &
187 cur_term
->sgr_faked
)) != A_NORMAL
) {
188 modes
[k
] &= ~check_faked
;
189 modes
[k
] |= A_STANDOUT
;
192 if ((j
= counter
) >= 0) {
195 for (i
= 0; i
< NUM_ATTRIBUTES
; i
++) {
212 if (newmode
== oldmode
)
217 fprintf(outf
, "vidupdate oldmode=%o, newmode=%o\n",
221 if (set_attributes
) {
222 (void) tputs(tparm(set_attributes
,
223 newmode
& A_STANDOUT
,
224 newmode
& A_UNDERLINE
,
231 newmode
& A_ALTCHARSET
),
235 chtype turn_on
, turn_off
;
239 * If we are going to turn something on anyway and we are
240 * on a glitchy terminal, don't bother turning it off
241 * since by turning something on you turn everything else off.
244 if ((ceol_standout_glitch
|| magic_cookie_glitch
>= 0) &&
245 ((turn_on
= ((oldmode
^ newmode
) & newmode
)) !=
250 if ((turn_off
= (oldmode
& newmode
) ^ oldmode
) != A_NORMAL
) {
252 * Check for things to turn off.
253 * First see if we are going to turn off something
254 * that doesn't have a specific turn off capability.
256 * Then check to see if, even though there may be a specific
257 * turn off sequence, this terminal doesn't have one or
258 * the turn off sequence also turns off something else.
260 if ((turn_off
& ~(A_ALTCHARSET
| A_STANDOUT
| A_UNDERLINE
)) ||
261 (turn_off
!= (turn_off
& cur_term
->check_turn_off
))) {
262 (void) tputs(tparm_p0(exit_attribute_mode
), 1, outc
);
266 for (i
= 0; i
< NUM_OF_SPECIFIC_TURN_OFFS
; i
++) {
267 if (turn_off
& bit_attributes
[i
]) {
268 (void) tputs(tparm_p0
269 (cur_term
->turn_off_seq
[i
]),
271 oldmode
&= ~bit_attributes
[i
];
278 if ((turn_on
= ((oldmode
^ newmode
) & newmode
)) != A_NORMAL
) {
281 /* Check for modes to turn on. */
283 for (i
= 0; i
< NUM_ATTRIBUTES
; i
++)
284 if (turn_on
& bit_attributes
[i
]) {
285 (void) tputs(tparm_p0(cur_term
->turn_on_seq
[i
]),
289 * Keep turning off the bit(s) that we just
290 * sent to the screen. As soon as turn_on
291 * reaches A_NORMAL we don't have to turn
292 * anything else on and we can
293 * break out of the loop.
295 if ((turn_on
&= ~bit_attributes
[i
]) ==
301 if (magic_cookie_glitch
> 0)
302 (void) tputs(cursor_left
, 1, outc
);
304 cur_term
->sgr_mode
= newmode
;
310 _change_color(short newcolor
, int (*outc
)(char))
314 _Color_pair
*ptp
= cur_term
->_pairs_tbl
;
315 /* pairs table pointer */
316 _Color_pair
*cur_pair
= &cur_term
->_cur_pair
;
318 /* MORE: we may have to change some stuff, depending on whether */
319 /* HP terminals will be changing the background, or not */
323 (void) tputs(tparm_p0(orig_pair
), 1, outc
);
324 if (set_a_background
|| set_a_foreground
||
325 set_background
|| set_foreground
) {
326 cur_pair
->background
= -1;
327 cur_pair
->foreground
= -1;
332 /* if we are on HP type terminal, just send an escape sequence */
333 /* to use desired color pair (we could have done some optimization: */
334 /* check if both the foreground and background of newcolor match */
335 /* the ones of cur_term->_cur_pair. but that will happen only when */
336 /* two color pairs are defined exacly the same, and probably not */
337 /* worth the effort). */
340 (void) tputs(tparm_p1(set_color_pair
, newcolor
), 1, outc
);
342 /* on Tek model we can do some optimization. */
345 if (ptp
[newcolor
].background
!= cur_pair
->background
) {
346 if (set_a_background
)
347 (void) tputs(tparm_p1(set_a_background
,
348 ptp
[newcolor
].background
), 1, outc
);
349 else if (set_background
)
350 (void) tputs(tparm_p1(set_background
,
351 Oldcolors
[ptp
[newcolor
].background
]),
353 cur_pair
->background
= ptp
[newcolor
].background
;
355 if (ptp
[newcolor
].foreground
!= cur_pair
->foreground
) {
356 if (set_a_foreground
)
357 (void) tputs(tparm_p1(set_a_foreground
,
358 ptp
[newcolor
].foreground
), 1, outc
);
359 else if (set_foreground
)
360 (void) tputs(tparm_p1(set_foreground
,
361 Oldcolors
[ptp
[newcolor
].foreground
]),
363 cur_pair
->foreground
= ptp
[newcolor
].foreground
;
369 /* the following code is for PC6300 PLUS: it uses BOLD terminfo */
370 /* entry for turning on colors, and SGR0 for turning them off. */
371 /* Every time a new color-pair is used, we are forced to do an */
372 /* ioctl read, and the send 'enter_bold_mode' escape sequence. */
373 /* This could be improved by using */
374 /* DIM, UNDERLINE, and REVERSE in addition to BOLD */
377 _Color_pair
*ptp
= cur_term
->_pairs_tbl
;
378 /* pairs table pointer */
379 back
= ptp
[newcolor
].background
;
380 fore
= ptp
[newcolor
].foreground
;
382 (void) fflush(SP
->term_file
);
383 ioctl(cur_term
->Filedes
, CONIOGETDATA
, &con
);
385 con
.l
[con
.page
].colors
[BOLD
] =
386 ((back
+ back
+ (fore
> 5)) * 8 + fore
) & 0177;
387 ioctl(cur_term
->Filedes
, CONIOSETDATA
, &con
);
388 (void) tputs(enter_bold_mode
, 1, outc
);