xref: /illumos-gate/usr/src/uts/common/io/tem_safe.c (revision d863b4c1)
1fea9cb91Slq /*
2fea9cb91Slq  * CDDL HEADER START
3fea9cb91Slq  *
4fea9cb91Slq  * The contents of this file are subject to the terms of the
5fea9cb91Slq  * Common Development and Distribution License (the "License").
6fea9cb91Slq  * You may not use this file except in compliance with the License.
7fea9cb91Slq  *
8fea9cb91Slq  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fea9cb91Slq  * or http://www.opensolaris.org/os/licensing.
10fea9cb91Slq  * See the License for the specific language governing permissions
11fea9cb91Slq  * and limitations under the License.
12fea9cb91Slq  *
13fea9cb91Slq  * When distributing Covered Code, include this CDDL HEADER in each
14fea9cb91Slq  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fea9cb91Slq  * If applicable, add the following below this CDDL HEADER, with the
16fea9cb91Slq  * fields enclosed by brackets "[]" replaced with your own identifying
17fea9cb91Slq  * information: Portions Copyright [yyyy] [name of copyright owner]
18fea9cb91Slq  *
19fea9cb91Slq  * CDDL HEADER END
20fea9cb91Slq  */
21fea9cb91Slq 
22fea9cb91Slq /*
23aecfc01dSrui zang - Sun Microsystems - Beijing China  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24fea9cb91Slq  * Use is subject to license terms.
25fea9cb91Slq  */
26fea9cb91Slq 
27a6631734SJoshua M. Clulow /*
28a6631734SJoshua M. Clulow  * Copyright 2016 Joyent, Inc.
29fa9eb222SToomas Soome  * Copyright 2021 Toomas Soome <tsoome@me.com>
30c43f6c55SGarrett D'Amore  * Copyright 2021 RackTop Systems, Inc.
31a6631734SJoshua M. Clulow  */
32a6631734SJoshua M. Clulow 
33fea9cb91Slq /*
34fea9cb91Slq  * Polled I/O safe ANSI terminal emulator module;
35fea9cb91Slq  * Supporting TERM types 'sun' and 'sun-color, parsing
36bbf21555SRichard Lowe  * ANSI x3.64 escape sequences, and the like.  (See wscons(4D)
37fea9cb91Slq  * for more information).
38fea9cb91Slq  *
39fea9cb91Slq  * IMPORTANT:
40fea9cb91Slq  *
41fea9cb91Slq  *   The functions in this file *must* be able to function in
42fea9cb91Slq  *   standalone mode, ie. on a quiesced system.   In that state,
43fea9cb91Slq  *   access is single threaded, only one CPU is running.
44fea9cb91Slq  *   System services are NOT available.
45fea9cb91Slq  *
46fea9cb91Slq  * The following restrictions pertain to every function
47fea9cb91Slq  * in this file:
48fea9cb91Slq  *
49fea9cb91Slq  *     - CANNOT use the DDI or LDI interfaces
50fea9cb91Slq  *     - CANNOT call system services
51fea9cb91Slq  *     - CANNOT use mutexes
52fea9cb91Slq  *     - CANNOT wait for interrupts
53fea9cb91Slq  *     - CANNOT allocate memory
54fea9cb91Slq  *
55aecfc01dSrui zang - Sun Microsystems - Beijing China  * All non-static functions in this file which:
56aecfc01dSrui zang - Sun Microsystems - Beijing China  *     - Operates on tems and tem_vt_state
57aecfc01dSrui zang - Sun Microsystems - Beijing China  *     - Not only called from standalone mode, i.e. has
58aecfc01dSrui zang - Sun Microsystems - Beijing China  *       a "calledfrom" argument
59aecfc01dSrui zang - Sun Microsystems - Beijing China  * should assert this at the beginning:
60aecfc01dSrui zang - Sun Microsystems - Beijing China  *
61aecfc01dSrui zang - Sun Microsystems - Beijing China  *    ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
62aecfc01dSrui zang - Sun Microsystems - Beijing China  *        called_from == CALLED_FROM_STANDALONE);
63fa9eb222SToomas Soome  *
64fa9eb222SToomas Soome  * Color support:
65fa9eb222SToomas Soome  * Text mode can only support standard system colors, 4-bit [0-15] indexed.
66fa9eb222SToomas Soome  * On framebuffer devices, we can aditionally use [16-255] or truecolor.
67fa9eb222SToomas Soome  * Additional colors can be used via CSI 38 and CSI 48 sequences.
68fa9eb222SToomas Soome  * CSI 38/48;5 is using indexed colors [0-255], CSI 38/48;2 does
69fa9eb222SToomas Soome  * specify color by RGB triple.
70fa9eb222SToomas Soome  *
71fa9eb222SToomas Soome  * While sending glyphs to display, we need to process glyph attributes:
72fa9eb222SToomas Soome  * TEM_ATTR_BOLD will cause BOLD font to be used (or BRIGHT color if we
73fa9eb222SToomas Soome  * we use indexed color [0-7]).
74fa9eb222SToomas Soome  * We ignore TEM_ATTR_BRIGHT_FG/TEM_ATTR_BRIGHT_BG with RGB colors.
75fa9eb222SToomas Soome  * TEM_ATTR_REVERSE and TEM_ATTR_SCREEN_REVERSE will cause fg and bg to be
76fa9eb222SToomas Soome  * swapped.
77fea9cb91Slq  */
78fea9cb91Slq 
79fea9cb91Slq #include <sys/types.h>
80fea9cb91Slq #include <sys/ascii.h>
81fea9cb91Slq #include <sys/visual_io.h>
82fea9cb91Slq #include <sys/font.h>
83fea9cb91Slq #include <sys/tem.h>
84fea9cb91Slq #include <sys/tem_impl.h>
85fea9cb91Slq #include <sys/ksynch.h>
86fea9cb91Slq #include <sys/sysmacros.h>
87fea9cb91Slq #include <sys/mutex.h>
88aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/note.h>
89aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/t_lock.h>
90aecfc01dSrui zang - Sun Microsystems - Beijing China 
91aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_callbacks_t tem_safe_text_callbacks = {
92aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_display,
93aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_copy,
94aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_cursor,
95aecfc01dSrui zang - Sun Microsystems - Beijing China 	NULL,
96aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_cls
97aecfc01dSrui zang - Sun Microsystems - Beijing China };
98aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_callbacks_t tem_safe_pix_callbacks = {
99aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_display,
100aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_copy,
101aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_cursor,
102aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_bit2pix,
103aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_cls
104aecfc01dSrui zang - Sun Microsystems - Beijing China };
105fea9cb91Slq 
1060e3b7565SToomas Soome static void	tem_safe_control(struct tem_vt_state *, tem_char_t,
107fea9cb91Slq 			cred_t *, enum called_from);
108aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_setparam(struct tem_vt_state *, int, int);
109aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_selgraph(struct tem_vt_state *);
1100e3b7565SToomas Soome static void	tem_safe_chkparam(struct tem_vt_state *, tem_char_t,
111fea9cb91Slq 			cred_t *, enum called_from);
1120e3b7565SToomas Soome static void	tem_safe_getparams(struct tem_vt_state *, tem_char_t,
113fea9cb91Slq 			cred_t *, enum called_from);
1140e3b7565SToomas Soome static void	tem_safe_outch(struct tem_vt_state *, tem_char_t,
115fea9cb91Slq 			cred_t *, enum called_from);
1160e3b7565SToomas Soome static void	tem_safe_parse(struct tem_vt_state *, tem_char_t,
117fea9cb91Slq 			cred_t *, enum called_from);
118fea9cb91Slq 
119aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_new_line(struct tem_vt_state *,
120fea9cb91Slq 			cred_t *, enum called_from);
121aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_cr(struct tem_vt_state *);
122aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_lf(struct tem_vt_state *,
123fea9cb91Slq 			cred_t *, enum called_from);
124aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_send_data(struct tem_vt_state *, cred_t *,
125fea9cb91Slq 			enum called_from);
126aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_cls(struct tem_vt_state *,
127fea9cb91Slq 			cred_t *, enum called_from);
128aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_tab(struct tem_vt_state *,
129fea9cb91Slq 			cred_t *, enum called_from);
130aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_back_tab(struct tem_vt_state *,
131fea9cb91Slq 			cred_t *, enum called_from);
132aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_clear_tabs(struct tem_vt_state *, int);
133aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_set_tab(struct tem_vt_state *);
134aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_mv_cursor(struct tem_vt_state *, int, int,
135fea9cb91Slq 			cred_t *, enum called_from);
136aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_shift(struct tem_vt_state *, int, int,
137fea9cb91Slq 			cred_t *, enum called_from);
138aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_scroll(struct tem_vt_state *, int, int,
139fea9cb91Slq 			int, int, cred_t *, enum called_from);
140aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_clear_chars(struct tem_vt_state *tem,
141fea9cb91Slq 			int count, screen_pos_t row, screen_pos_t col,
142fea9cb91Slq 			cred_t *credp, enum called_from called_from);
143aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_copy_area(struct tem_vt_state *tem,
144fea9cb91Slq 			screen_pos_t s_col, screen_pos_t s_row,
145fea9cb91Slq 			screen_pos_t e_col, screen_pos_t e_row,
146fea9cb91Slq 			screen_pos_t t_col, screen_pos_t t_row,
147fea9cb91Slq 			cred_t *credp, enum called_from called_from);
148e0721d5aSToomas Soome #if 0
149e0721d5aSToomas Soome /* Currently unused */
150aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_image_display(struct tem_vt_state *, uchar_t *,
151fea9cb91Slq 			int, int, screen_pos_t, screen_pos_t,
152fea9cb91Slq 			cred_t *, enum called_from);
153e0721d5aSToomas Soome #endif
154aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_bell(struct tem_vt_state *tem,
155fea9cb91Slq 			enum called_from called_from);
156aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_pix_clear_prom_output(struct tem_vt_state *tem,
157fea9cb91Slq 			cred_t *credp, enum called_from called_from);
158fa9eb222SToomas Soome static void	tem_safe_get_color(struct tem_vt_state *,
159fa9eb222SToomas Soome 		    text_color_t *, text_color_t *, term_char_t *);
160fa9eb222SToomas Soome static void	tem_safe_set_color(text_color_t *, color_t *);
161fea9cb91Slq 
162aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_virtual_cls(struct tem_vt_state *, int, screen_pos_t,
163aecfc01dSrui zang - Sun Microsystems - Beijing China 		    screen_pos_t);
164aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_virtual_display(struct tem_vt_state *,
165cbc8e155SToomas Soome 		    term_char_t *, int, screen_pos_t, screen_pos_t);
166aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_virtual_copy(struct tem_vt_state *, screen_pos_t,
167aecfc01dSrui zang - Sun Microsystems - Beijing China 		    screen_pos_t, screen_pos_t, screen_pos_t,
168aecfc01dSrui zang - Sun Microsystems - Beijing China 		    screen_pos_t, screen_pos_t);
169aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_align_cursor(struct tem_vt_state *tem);
1700e3b7565SToomas Soome static void	bit_to_pix4(struct tem_vt_state *tem, tem_char_t c,
171aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t fg_color, text_color_t bg_color);
1720e3b7565SToomas Soome static void	bit_to_pix8(struct tem_vt_state *tem, tem_char_t c,
173aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t fg_color, text_color_t bg_color);
1740e3b7565SToomas Soome static void	bit_to_pix16(struct tem_vt_state *tem, tem_char_t c,
1755a801801SToomas Soome 		    text_color_t fg_color, text_color_t bg_color);
1760e3b7565SToomas Soome static void	bit_to_pix24(struct tem_vt_state *tem, tem_char_t c,
177aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t fg_color, text_color_t bg_color);
1780e3b7565SToomas Soome static void	bit_to_pix32(struct tem_vt_state *tem, tem_char_t c,
1793e90f8d3SToomas Soome 		    text_color_t fg_color, text_color_t bg_color);
180aecfc01dSrui zang - Sun Microsystems - Beijing China 
181898c3fecSToomas Soome #define	PIX4TO32(pix4) (uint32_t)(  \
182fea9cb91Slq     cmap4_to_24.red[pix4] << 16 |  \
183fea9cb91Slq     cmap4_to_24.green[pix4] << 8 | \
184fea9cb91Slq     cmap4_to_24.blue[pix4])
185fea9cb91Slq 
186aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_display	(*tems.ts_callbacks->tsc_display)
187aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_copy		(*tems.ts_callbacks->tsc_copy)
188aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_cursor	(*tems.ts_callbacks->tsc_cursor)
189aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_cls		(*tems.ts_callbacks->tsc_cls)
190cbc8e155SToomas Soome #define	tem_safe_callback_bit2pix(tem, c)	{		\
191aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(tems.ts_callbacks->tsc_bit2pix != NULL);			\
192cbc8e155SToomas Soome 	(void) (*tems.ts_callbacks->tsc_bit2pix)((tem), (c));\
193fea9cb91Slq }
194fea9cb91Slq 
195fea9cb91Slq void
tem_safe_check_first_time(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)196aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_check_first_time(
197aecfc01dSrui zang - Sun Microsystems - Beijing China     struct tem_vt_state *tem,
198fea9cb91Slq     cred_t *credp,
199fea9cb91Slq     enum called_from called_from)
200fea9cb91Slq {
201fea9cb91Slq 	static int first_time = 1;
202fea9cb91Slq 
203aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
204aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
205aecfc01dSrui zang - Sun Microsystems - Beijing China 
206fea9cb91Slq 	/*
207fea9cb91Slq 	 * Realign the console cursor. We did this in tem_init().
208fea9cb91Slq 	 * However, drivers in the console stream may emit additional
209fea9cb91Slq 	 * messages before we are ready. This causes text overwrite
210fea9cb91Slq 	 * on the screen. This is a workaround.
211fea9cb91Slq 	 */
212aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!first_time)
213aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
214fea9cb91Slq 
215aecfc01dSrui zang - Sun Microsystems - Beijing China 	first_time = 0;
21640d76caaSToomas Soome 	if (tems.ts_display_mode == VIS_TEXT)
217aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_text_cursor(tem, VIS_GET_CURSOR, credp, called_from);
21840d76caaSToomas Soome 	else
21940d76caaSToomas Soome 		tem_safe_pix_cursor(tem, VIS_GET_CURSOR, credp, called_from);
22040d76caaSToomas Soome 	tem_safe_align_cursor(tem);
221fea9cb91Slq }
222fea9cb91Slq 
223fea9cb91Slq /*
224fea9cb91Slq  * This entry point handles output requests from restricted contexts like
225fea9cb91Slq  * kmdb, where services like mutexes are not available. This function
226fea9cb91Slq  * is entered when OBP or when a kernel debugger (such as kmdb)
227fea9cb91Slq  * are generating console output.  In those cases, power management
228fea9cb91Slq  * concerns are handled by the abort sequence initiation (ie. when
229fea9cb91Slq  * the user hits L1+A or the equivalent to enter OBP or the debugger.).
230fea9cb91Slq  * It is also entered when the kernel is panicing.
231fea9cb91Slq  */
232fea9cb91Slq void
tem_safe_polled_write(tem_vt_state_t tem_arg,uchar_t * buf,int len)233aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_polled_write(
234aecfc01dSrui zang - Sun Microsystems - Beijing China     tem_vt_state_t tem_arg,
235fea9cb91Slq     uchar_t *buf,
236fea9cb91Slq     int len)
237fea9cb91Slq {
238aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
239aecfc01dSrui zang - Sun Microsystems - Beijing China 
240aecfc01dSrui zang - Sun Microsystems - Beijing China #ifdef	__lock_lint
241aecfc01dSrui zang - Sun Microsystems - Beijing China 	_NOTE(NO_COMPETING_THREADS_NOW)
242aecfc01dSrui zang - Sun Microsystems - Beijing China 	_NOTE(NO_COMPETING_THREADS_AS_SIDE_EFFECT)
243aecfc01dSrui zang - Sun Microsystems - Beijing China #endif
244fea9cb91Slq 
245aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_initialized) {
246aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
247aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
248fea9cb91Slq 
249aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_check_first_time(tem, kcred, CALLED_FROM_STANDALONE);
250aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_terminal_emulate(tem, buf, len, NULL, CALLED_FROM_STANDALONE);
251fea9cb91Slq }
252fea9cb91Slq 
253ac9b7c93SToomas Soome /* Process partial UTF-8 sequence. */
254ac9b7c93SToomas Soome static void
tem_safe_input_partial(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)255ac9b7c93SToomas Soome tem_safe_input_partial(struct tem_vt_state *tem, cred_t *credp,
256ac9b7c93SToomas Soome     enum called_from called_from)
257ac9b7c93SToomas Soome {
258cbc8e155SToomas Soome 	unsigned i;
259ac9b7c93SToomas Soome 	uint8_t c;
260ac9b7c93SToomas Soome 
261ac9b7c93SToomas Soome 	if (tem->tvs_utf8_left == 0)
262ac9b7c93SToomas Soome 		return;
263ac9b7c93SToomas Soome 
264ac9b7c93SToomas Soome 	for (i = 0; i < sizeof (tem->tvs_utf8_partial); i++) {
265ac9b7c93SToomas Soome 		c = (tem->tvs_utf8_partial >> (24 - (i << 3))) & 0xff;
266ac9b7c93SToomas Soome 		if (c != 0) {
267ac9b7c93SToomas Soome 			tem_safe_parse(tem, c, credp, called_from);
268ac9b7c93SToomas Soome 		}
269ac9b7c93SToomas Soome 	}
270ac9b7c93SToomas Soome 	tem->tvs_utf8_left = 0;
271ac9b7c93SToomas Soome 	tem->tvs_utf8_partial = 0;
272ac9b7c93SToomas Soome }
273ac9b7c93SToomas Soome 
274ac9b7c93SToomas Soome /*
275ac9b7c93SToomas Soome  * Handle UTF-8 sequences.
276ac9b7c93SToomas Soome  */
277ac9b7c93SToomas Soome static void
tem_safe_input_byte(struct tem_vt_state * tem,uchar_t c,cred_t * credp,enum called_from called_from)278ac9b7c93SToomas Soome tem_safe_input_byte(struct tem_vt_state *tem, uchar_t c, cred_t *credp,
279ac9b7c93SToomas Soome     enum called_from called_from)
280ac9b7c93SToomas Soome {
281ac9b7c93SToomas Soome 	/*
282ac9b7c93SToomas Soome 	 * Check for UTF-8 code points. In case of error fall back to
283ac9b7c93SToomas Soome 	 * 8-bit code. As we only have 8859-1 fonts for console, this will set
284ac9b7c93SToomas Soome 	 * the limits on what chars we actually can display, therefore we
285ac9b7c93SToomas Soome 	 * have to return to this code once we have solved the font issue.
286ac9b7c93SToomas Soome 	 */
287ac9b7c93SToomas Soome 	if ((c & 0x80) == 0x00) {
288ac9b7c93SToomas Soome 		/* One-byte sequence. */
289ac9b7c93SToomas Soome 		tem_safe_input_partial(tem, credp, called_from);
290ac9b7c93SToomas Soome 		tem_safe_parse(tem, c, credp, called_from);
291ac9b7c93SToomas Soome 		return;
292ac9b7c93SToomas Soome 	}
293ac9b7c93SToomas Soome 	if ((c & 0xe0) == 0xc0) {
294ac9b7c93SToomas Soome 		/* Two-byte sequence. */
295ac9b7c93SToomas Soome 		tem_safe_input_partial(tem, credp, called_from);
296ac9b7c93SToomas Soome 		tem->tvs_utf8_left = 1;
297ac9b7c93SToomas Soome 		tem->tvs_utf8_partial = c;
298ac9b7c93SToomas Soome 		return;
299ac9b7c93SToomas Soome 	}
300ac9b7c93SToomas Soome 	if ((c & 0xf0) == 0xe0) {
301ac9b7c93SToomas Soome 		/* Three-byte sequence. */
302ac9b7c93SToomas Soome 		tem_safe_input_partial(tem, credp, called_from);
303ac9b7c93SToomas Soome 		tem->tvs_utf8_left = 2;
304ac9b7c93SToomas Soome 		tem->tvs_utf8_partial = c;
305ac9b7c93SToomas Soome 		return;
306ac9b7c93SToomas Soome 	}
307ac9b7c93SToomas Soome 	if ((c & 0xf8) == 0xf0) {
308ac9b7c93SToomas Soome 		/* Four-byte sequence. */
309ac9b7c93SToomas Soome 		tem_safe_input_partial(tem, credp, called_from);
310ac9b7c93SToomas Soome 		tem->tvs_utf8_left = 3;
311ac9b7c93SToomas Soome 		tem->tvs_utf8_partial = c;
312ac9b7c93SToomas Soome 		return;
313ac9b7c93SToomas Soome 	}
314ac9b7c93SToomas Soome 	if ((c & 0xc0) == 0x80) {
315ac9b7c93SToomas Soome 		/* Invalid state? */
316ac9b7c93SToomas Soome 		if (tem->tvs_utf8_left == 0) {
317ac9b7c93SToomas Soome 			tem_safe_parse(tem, c, credp, called_from);
318ac9b7c93SToomas Soome 			return;
319ac9b7c93SToomas Soome 		}
320ac9b7c93SToomas Soome 		tem->tvs_utf8_left--;
321ac9b7c93SToomas Soome 		tem->tvs_utf8_partial = (tem->tvs_utf8_partial << 8) | c;
322ac9b7c93SToomas Soome 		if (tem->tvs_utf8_left == 0) {
323ac9b7c93SToomas Soome 			tem_char_t v, u;
324ac9b7c93SToomas Soome 			uint8_t b;
325ac9b7c93SToomas Soome 
326ac9b7c93SToomas Soome 			/*
327ac9b7c93SToomas Soome 			 * Transform the sequence of 2 to 4 bytes to
328ac9b7c93SToomas Soome 			 * unicode number.
329ac9b7c93SToomas Soome 			 */
330ac9b7c93SToomas Soome 			v = 0;
331ac9b7c93SToomas Soome 			u = tem->tvs_utf8_partial;
332ac9b7c93SToomas Soome 			b = (u >> 24) & 0xff;
333ac9b7c93SToomas Soome 			if (b != 0) {		/* Four-byte sequence */
334ac9b7c93SToomas Soome 				v = b & 0x07;
335ac9b7c93SToomas Soome 				b = (u >> 16) & 0xff;
336ac9b7c93SToomas Soome 				v = (v << 6) | (b & 0x3f);
337ac9b7c93SToomas Soome 				b = (u >> 8) & 0xff;
338ac9b7c93SToomas Soome 				v = (v << 6) | (b & 0x3f);
339ac9b7c93SToomas Soome 				b = u & 0xff;
340ac9b7c93SToomas Soome 				v = (v << 6) | (b & 0x3f);
341ac9b7c93SToomas Soome 			} else if ((b = (u >> 16) & 0xff) != 0) {
342ac9b7c93SToomas Soome 				v = b & 0x0f;	/* Three-byte sequence */
343ac9b7c93SToomas Soome 				b = (u >> 8) & 0xff;
344ac9b7c93SToomas Soome 				v = (v << 6) | (b & 0x3f);
345ac9b7c93SToomas Soome 				b = u & 0xff;
346ac9b7c93SToomas Soome 				v = (v << 6) | (b & 0x3f);
347ac9b7c93SToomas Soome 			} else if ((b = (u >> 8) & 0xff) != 0) {
348ac9b7c93SToomas Soome 				v = b & 0x1f;	/* Two-byte sequence */
349ac9b7c93SToomas Soome 				b = u & 0xff;
350ac9b7c93SToomas Soome 				v = (v << 6) | (b & 0x3f);
351ac9b7c93SToomas Soome 			}
352ac9b7c93SToomas Soome 
353ac9b7c93SToomas Soome 			tem_safe_parse(tem, v, credp, called_from);
354ac9b7c93SToomas Soome 			tem->tvs_utf8_partial = 0;
355ac9b7c93SToomas Soome 		}
356ac9b7c93SToomas Soome 		return;
357ac9b7c93SToomas Soome 	}
358ac9b7c93SToomas Soome 	/* Anything left is illegal in UTF-8 sequence. */
359ac9b7c93SToomas Soome 	tem_safe_input_partial(tem, credp, called_from);
360ac9b7c93SToomas Soome 	tem_safe_parse(tem, c, credp, called_from);
361ac9b7c93SToomas Soome }
362fea9cb91Slq 
363fea9cb91Slq /*
364fea9cb91Slq  * This is the main entry point into the terminal emulator.
365fea9cb91Slq  *
366fea9cb91Slq  * For each data message coming downstream, ANSI assumes that it is composed
367fea9cb91Slq  * of ASCII characters, which are treated as a byte-stream input to the
368fea9cb91Slq  * parsing state machine. All data is parsed immediately -- there is
369fea9cb91Slq  * no enqueing.
370fea9cb91Slq  */
371fea9cb91Slq void
tem_safe_terminal_emulate(struct tem_vt_state * tem,uchar_t * buf,int len,cred_t * credp,enum called_from called_from)372aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_terminal_emulate(
373aecfc01dSrui zang - Sun Microsystems - Beijing China     struct tem_vt_state *tem,
374fea9cb91Slq     uchar_t *buf,
375fea9cb91Slq     int len,
376fea9cb91Slq     cred_t *credp,
377fea9cb91Slq     enum called_from called_from)
378fea9cb91Slq {
379fea9cb91Slq 
380aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
381aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
382fea9cb91Slq 
383c43f6c55SGarrett D'Amore 	if (tem->tvs_isactive && !tem->tvs_cursor_hidden)
384aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_cursor(tem,
385aecfc01dSrui zang - Sun Microsystems - Beijing China 		    VIS_HIDE_CURSOR, credp, called_from);
386fea9cb91Slq 
387aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (; len > 0; len--, buf++)
388ac9b7c93SToomas Soome 		tem_safe_input_byte(tem, *buf, credp, called_from);
389fea9cb91Slq 
390fea9cb91Slq 	/*
391fea9cb91Slq 	 * Send the data we just got to the framebuffer.
392fea9cb91Slq 	 */
393aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_send_data(tem, credp, called_from);
394fea9cb91Slq 
395c43f6c55SGarrett D'Amore 	if (tem->tvs_isactive && !tem->tvs_cursor_hidden)
396aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_cursor(tem,
397aecfc01dSrui zang - Sun Microsystems - Beijing China 		    VIS_DISPLAY_CURSOR, credp, called_from);
398fea9cb91Slq }
399fea9cb91Slq 
400fea9cb91Slq /*
401fea9cb91Slq  * Display an rectangular image on the frame buffer using the
402fea9cb91Slq  * mechanism appropriate for the system state being called
403fea9cb91Slq  * from quiesced or normal (ie. use polled I/O vs. layered ioctls)
404fea9cb91Slq  */
405fea9cb91Slq static void
tems_safe_display(struct vis_consdisplay * pda,cred_t * credp,enum called_from called_from)406898c3fecSToomas Soome tems_safe_display(struct vis_consdisplay *pda, cred_t *credp,
407898c3fecSToomas Soome     enum called_from called_from)
408fea9cb91Slq {
409fea9cb91Slq 	if (called_from == CALLED_FROM_STANDALONE)
410aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems.ts_fb_polledio->display(tems.ts_fb_polledio->arg, pda);
411fea9cb91Slq 	else
412aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_display_layered(pda, credp);
413fea9cb91Slq }
414fea9cb91Slq 
415fea9cb91Slq /*
416fea9cb91Slq  * Copy a rectangle from one location to another on the frame buffer
417fea9cb91Slq  * using the mechanism appropriate for the system state being called
418fea9cb91Slq  * from, quiesced or normal (ie. use polled I/O vs. layered ioctls)
419fea9cb91Slq  */
420fea9cb91Slq void
tems_safe_copy(struct vis_conscopy * pca,cred_t * credp,enum called_from called_from)421898c3fecSToomas Soome tems_safe_copy(struct vis_conscopy *pca, cred_t *credp,
422898c3fecSToomas Soome     enum called_from called_from)
423fea9cb91Slq {
424fea9cb91Slq 	if (called_from == CALLED_FROM_STANDALONE)
425aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems.ts_fb_polledio->copy(tems.ts_fb_polledio->arg, pca);
426fea9cb91Slq 	else
427aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_copy_layered(pca, credp);
428fea9cb91Slq }
429fea9cb91Slq 
430fea9cb91Slq /*
431fea9cb91Slq  * Display or hide a rectangular block text cursor of a specificsize
432fea9cb91Slq  * at a specific location on frame buffer* using the mechanism
433fea9cb91Slq  * appropriate for the system state being called from, quisced or
434fea9cb91Slq  * normal (ie. use polled I/O vs. layered ioctls).
435fea9cb91Slq  */
436fea9cb91Slq static void
tems_safe_cursor(struct vis_conscursor * pca,cred_t * credp,enum called_from called_from)437898c3fecSToomas Soome tems_safe_cursor(struct vis_conscursor *pca, cred_t *credp,
438898c3fecSToomas Soome     enum called_from called_from)
439fea9cb91Slq {
440fea9cb91Slq 	if (called_from == CALLED_FROM_STANDALONE)
441aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems.ts_fb_polledio->cursor(tems.ts_fb_polledio->arg, pca);
442fea9cb91Slq 	else
443aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_cursor_layered(pca, credp);
444fea9cb91Slq }
445fea9cb91Slq 
446fea9cb91Slq /*
447fea9cb91Slq  * send the appropriate control message or set state based on the
448fea9cb91Slq  * value of the control character ch
449fea9cb91Slq  */
450fea9cb91Slq 
451fea9cb91Slq static void
tem_safe_control(struct tem_vt_state * tem,tem_char_t ch,cred_t * credp,enum called_from called_from)4520e3b7565SToomas Soome tem_safe_control(struct tem_vt_state *tem, tem_char_t ch, cred_t *credp,
453898c3fecSToomas Soome     enum called_from called_from)
454fea9cb91Slq {
455aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
456fea9cb91Slq 	switch (ch) {
457fea9cb91Slq 	case A_BEL:
458aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_bell(tem, called_from);
459fea9cb91Slq 		break;
460fea9cb91Slq 
461fea9cb91Slq 	case A_BS:
462aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem,
463aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
464aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col - 1,
465fea9cb91Slq 		    credp, called_from);
466fea9cb91Slq 		break;
467fea9cb91Slq 
468fea9cb91Slq 	case A_HT:
469aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_tab(tem, credp, called_from);
470fea9cb91Slq 		break;
471fea9cb91Slq 
472fea9cb91Slq 	case A_NL:
473fea9cb91Slq 		/*
474aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * tem_safe_send_data(tem, credp, called_from);
475aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * tem_safe_new_line(tem, credp, called_from);
476fea9cb91Slq 		 * break;
477fea9cb91Slq 		 */
478fea9cb91Slq 
479fea9cb91Slq 	case A_VT:
480aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
481aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_lf(tem, credp, called_from);
482fea9cb91Slq 		break;
483fea9cb91Slq 
484fea9cb91Slq 	case A_FF:
485aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
486aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_cls(tem, credp, called_from);
487fea9cb91Slq 		break;
488fea9cb91Slq 
489fea9cb91Slq 	case A_CR:
490aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
491aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_cr(tem);
492fea9cb91Slq 		break;
493fea9cb91Slq 
494fea9cb91Slq 	case A_ESC:
495aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_ESC;
496fea9cb91Slq 		break;
497fea9cb91Slq 
498fea9cb91Slq 	case A_CSI:
499fea9cb91Slq 		{
500fea9cb91Slq 			int i;
501aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_curparam = 0;
502aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_paramval = 0;
503aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_gotparam = B_FALSE;
504fea9cb91Slq 			/* clear the parameters */
505fea9cb91Slq 			for (i = 0; i < TEM_MAXPARAMS; i++)
506aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_params[i] = -1;
507aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_CSI;
508fea9cb91Slq 		}
509fea9cb91Slq 		break;
510fea9cb91Slq 
511fea9cb91Slq 	case A_GS:
512aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_back_tab(tem, credp, called_from);
513fea9cb91Slq 		break;
514fea9cb91Slq 
515fea9cb91Slq 	default:
516fea9cb91Slq 		break;
517fea9cb91Slq 	}
518fea9cb91Slq }
519fea9cb91Slq 
520fea9cb91Slq 
521fea9cb91Slq /*
522fea9cb91Slq  * if parameters [0..count - 1] are not set, set them to the value
523fea9cb91Slq  * of newparam.
524fea9cb91Slq  */
525fea9cb91Slq 
526fea9cb91Slq static void
tem_safe_setparam(struct tem_vt_state * tem,int count,int newparam)527aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_setparam(struct tem_vt_state *tem, int count, int newparam)
528fea9cb91Slq {
529fea9cb91Slq 	int i;
530fea9cb91Slq 
531fea9cb91Slq 	for (i = 0; i < count; i++) {
532aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_params[i] == -1)
533aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_params[i] = newparam;
534fea9cb91Slq 	}
535fea9cb91Slq }
536fea9cb91Slq 
537e2c4d811SToomas Soome /*
538e2c4d811SToomas Soome  * For colors 0-15 the tem is using color code translation
539e2c4d811SToomas Soome  * from sun colors to vga (dim_xlate and brt_xlate tables, see tem_get_color).
540e2c4d811SToomas Soome  * Colors 16-255 are used without translation.
541e2c4d811SToomas Soome  */
54262efa0e7SToomas Soome static void
tem_select_color(struct tem_vt_state * tem,int color,boolean_t fg)543fa9eb222SToomas Soome tem_select_color(struct tem_vt_state *tem, int color, boolean_t fg)
54462efa0e7SToomas Soome {
545fa9eb222SToomas Soome 	if (color < 0 || color > 255)
546fa9eb222SToomas Soome 		return;
547fa9eb222SToomas Soome 
548fa9eb222SToomas Soome 	/* VGA text mode only does support 16 colors. */
549fa9eb222SToomas Soome 	if (tems.ts_display_mode == VIS_TEXT && color > 15)
550fa9eb222SToomas Soome 		return;
551fa9eb222SToomas Soome 
552fa9eb222SToomas Soome 	/* Switch to use indexed colors. */
553fa9eb222SToomas Soome 	if (fg == B_TRUE) {
554fa9eb222SToomas Soome 		tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
555fa9eb222SToomas Soome 		tem->tvs_fg_color.n = color;
556fa9eb222SToomas Soome 	} else {
557fa9eb222SToomas Soome 		tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
558fa9eb222SToomas Soome 		tem->tvs_bg_color.n = color;
559fa9eb222SToomas Soome 	}
560e2c4d811SToomas Soome 
561e2c4d811SToomas Soome 	/*
562e2c4d811SToomas Soome 	 * For colors 0-7, make sure the BRIGHT attribute is not set.
563e2c4d811SToomas Soome 	 */
564e2c4d811SToomas Soome 	if (color < 8) {
565e2c4d811SToomas Soome 		if (fg == B_TRUE)
56662efa0e7SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
567e2c4d811SToomas Soome 		else
56862efa0e7SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
56962efa0e7SToomas Soome 		return;
57062efa0e7SToomas Soome 	}
57162efa0e7SToomas Soome 
572e2c4d811SToomas Soome 	/*
573e2c4d811SToomas Soome 	 * For colors 8-15, we use color codes 0-7 and set BRIGHT attribute.
574e2c4d811SToomas Soome 	 */
575e2c4d811SToomas Soome 	if (color < 16) {
576e2c4d811SToomas Soome 		if (fg == B_TRUE) {
577fa9eb222SToomas Soome 			tem->tvs_fg_color.n -= 8;
578e2c4d811SToomas Soome 			tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
579e2c4d811SToomas Soome 		} else {
580fa9eb222SToomas Soome 			tem->tvs_bg_color.n -= 8;
581e2c4d811SToomas Soome 			tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
582e2c4d811SToomas Soome 		}
58362efa0e7SToomas Soome 	}
58462efa0e7SToomas Soome }
58562efa0e7SToomas Soome 
586fea9cb91Slq /*
587fea9cb91Slq  * select graphics mode based on the param vals stored in a_params
588fea9cb91Slq  */
589fea9cb91Slq static void
tem_safe_selgraph(struct tem_vt_state * tem)590aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_selgraph(struct tem_vt_state *tem)
591fea9cb91Slq {
592fea9cb91Slq 	int curparam;
593fea9cb91Slq 	int count = 0;
594fea9cb91Slq 	int param;
595fa9eb222SToomas Soome 	int r, g, b;
596fea9cb91Slq 
597aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
598aecfc01dSrui zang - Sun Microsystems - Beijing China 
599aecfc01dSrui zang - Sun Microsystems - Beijing China 	curparam = tem->tvs_curparam;
600fea9cb91Slq 	do {
601aecfc01dSrui zang - Sun Microsystems - Beijing China 		param = tem->tvs_params[count];
602fea9cb91Slq 
603fea9cb91Slq 		switch (param) {
604fea9cb91Slq 		case -1:
605fea9cb91Slq 		case 0:
606aecfc01dSrui zang - Sun Microsystems - Beijing China 			/* reset to initial normal settings */
607aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_fg_color = tems.ts_init_color.fg_color;
608aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_bg_color = tems.ts_init_color.bg_color;
609aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags = tems.ts_init_color.a_flags;
610fea9cb91Slq 			break;
611fea9cb91Slq 
612fea9cb91Slq 		case 1: /* Bold Intense */
613aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags |= TEM_ATTR_BOLD;
614fea9cb91Slq 			break;
615fea9cb91Slq 
616c9503a49Slq 		case 2: /* Faint Intense */
617aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags &= ~TEM_ATTR_BOLD;
618c9503a49Slq 			break;
619c9503a49Slq 
620cbc8e155SToomas Soome 		case 4: /* Underline */
621cbc8e155SToomas Soome 			tem->tvs_flags |= TEM_ATTR_UNDERLINE;
622cbc8e155SToomas Soome 			break;
623fea9cb91Slq 		case 5: /* Blink */
624aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags |= TEM_ATTR_BLINK;
625fea9cb91Slq 			break;
626fea9cb91Slq 
627fea9cb91Slq 		case 7: /* Reverse video */
628aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
629aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags &= ~TEM_ATTR_REVERSE;
630fea9cb91Slq 			} else {
631aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags |= TEM_ATTR_REVERSE;
632fea9cb91Slq 			}
633fea9cb91Slq 			break;
634fea9cb91Slq 
635cbc8e155SToomas Soome 		case 22: /* Remove Bold */
636cbc8e155SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_BOLD;
637cbc8e155SToomas Soome 			break;
638cbc8e155SToomas Soome 
639cbc8e155SToomas Soome 		case 24: /* Remove Underline */
640cbc8e155SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_UNDERLINE;
641cbc8e155SToomas Soome 			break;
642cbc8e155SToomas Soome 
643cbc8e155SToomas Soome 		case 25: /* Remove Blink */
644cbc8e155SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_BLINK;
645cbc8e155SToomas Soome 			break;
646cbc8e155SToomas Soome 
647cbc8e155SToomas Soome 		case 27: /* Remove Reverse */
648cbc8e155SToomas Soome 			if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
649cbc8e155SToomas Soome 				tem->tvs_flags |= TEM_ATTR_REVERSE;
650cbc8e155SToomas Soome 			} else {
651cbc8e155SToomas Soome 				tem->tvs_flags &= ~TEM_ATTR_REVERSE;
652cbc8e155SToomas Soome 			}
653cbc8e155SToomas Soome 			break;
654cbc8e155SToomas Soome 
655a27563ebSToomas Soome 		case 30: /* black	(grey)		foreground */
656a27563ebSToomas Soome 		case 31: /* red		(light red)	foreground */
657a27563ebSToomas Soome 		case 32: /* green	(light green)	foreground */
658a27563ebSToomas Soome 		case 33: /* brown	(yellow)	foreground */
659a27563ebSToomas Soome 		case 34: /* blue	(light blue)	foreground */
660a27563ebSToomas Soome 		case 35: /* magenta	(light magenta)	foreground */
661a27563ebSToomas Soome 		case 36: /* cyan	(light cyan)	foreground */
662a27563ebSToomas Soome 		case 37: /* white	(bright white)	foreground */
663fa9eb222SToomas Soome 			tem->tvs_fg_color.n = param - 30;
664b6bd4f48SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
665fa9eb222SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
666fea9cb91Slq 			break;
667fea9cb91Slq 
668a4e6b9b6SToomas Soome 		case 38:
669fa9eb222SToomas Soome 			/*
670fa9eb222SToomas Soome 			 * We should have 3 parameters for 256 colors and
671fa9eb222SToomas Soome 			 * 5 parameters for 24-bit colors.
672fa9eb222SToomas Soome 			 */
673fa9eb222SToomas Soome 			if (curparam < 3) {
674fa9eb222SToomas Soome 				curparam = 0;
675a4e6b9b6SToomas Soome 				break;
676fa9eb222SToomas Soome 			}
677a4e6b9b6SToomas Soome 
678a4e6b9b6SToomas Soome 			/*
679a4e6b9b6SToomas Soome 			 * 256 and truecolor needs depth at least 24, but
680a4e6b9b6SToomas Soome 			 * we still need to process the sequence.
681a4e6b9b6SToomas Soome 			 */
682a4e6b9b6SToomas Soome 			count++;
683a4e6b9b6SToomas Soome 			curparam--;
684a4e6b9b6SToomas Soome 			param = tem->tvs_params[count];
685a4e6b9b6SToomas Soome 			switch (param) {
686fa9eb222SToomas Soome 			case 2: /* RGB colors */
687fa9eb222SToomas Soome 				if (curparam < 4) {
688fa9eb222SToomas Soome 					curparam = 0;
689fa9eb222SToomas Soome 					break;
690fa9eb222SToomas Soome 				}
691fa9eb222SToomas Soome 				r = tem->tvs_params[++count];
692fa9eb222SToomas Soome 				g = tem->tvs_params[++count];
693fa9eb222SToomas Soome 				b = tem->tvs_params[++count];
694fa9eb222SToomas Soome 				curparam -= 3;
695fa9eb222SToomas Soome 				if (r < 0 || r > 255 || g < 0 || g > 255 ||
696fa9eb222SToomas Soome 				    b < 0 || b > 255)
697fa9eb222SToomas Soome 					break;
698fa9eb222SToomas Soome 
699fa9eb222SToomas Soome 				if (tems.ts_display_mode == VIS_PIXEL &&
700fa9eb222SToomas Soome 				    tems.ts_pdepth > 8) {
701fa9eb222SToomas Soome 					tem->tvs_flags |= TEM_ATTR_RGB_FG;
702fa9eb222SToomas Soome 					tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
703fa9eb222SToomas Soome 					tem->tvs_fg_color.rgb.a =
704fa9eb222SToomas Soome 					    tem->tvs_alpha;
705fa9eb222SToomas Soome 					tem->tvs_fg_color.rgb.r = r;
706fa9eb222SToomas Soome 					tem->tvs_fg_color.rgb.g = g;
707fa9eb222SToomas Soome 					tem->tvs_fg_color.rgb.b = b;
708fa9eb222SToomas Soome 				}
709fa9eb222SToomas Soome 				break;
710a4e6b9b6SToomas Soome 			case 5: /* 256 colors */
711a4e6b9b6SToomas Soome 				count++;
712a4e6b9b6SToomas Soome 				curparam--;
71362efa0e7SToomas Soome 				tem_select_color(tem, tem->tvs_params[count],
71462efa0e7SToomas Soome 				    B_TRUE);
715a4e6b9b6SToomas Soome 				break;
716a4e6b9b6SToomas Soome 			default:
717fa9eb222SToomas Soome 				curparam = 0;
718a4e6b9b6SToomas Soome 				break;
719a4e6b9b6SToomas Soome 			}
720a4e6b9b6SToomas Soome 			break;
721a4e6b9b6SToomas Soome 
722a6631734SJoshua M. Clulow 		case 39:
723a6631734SJoshua M. Clulow 			/*
724b6bd4f48SToomas Soome 			 * Reset the foreground colour and brightness.
725a6631734SJoshua M. Clulow 			 */
726a6631734SJoshua M. Clulow 			tem->tvs_fg_color = tems.ts_init_color.fg_color;
727fa9eb222SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
728b6bd4f48SToomas Soome 			if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_FG)
729b6bd4f48SToomas Soome 				tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
730b6bd4f48SToomas Soome 			else
731b6bd4f48SToomas Soome 				tem->tvs_flags &= ~TEM_ATTR_BRIGHT_FG;
732a6631734SJoshua M. Clulow 			break;
733a6631734SJoshua M. Clulow 
734a27563ebSToomas Soome 		case 40: /* black	(grey)		background */
735a27563ebSToomas Soome 		case 41: /* red		(light red)	background */
736a27563ebSToomas Soome 		case 42: /* green	(light green)	background */
737a27563ebSToomas Soome 		case 43: /* brown	(yellow)	background */
738a27563ebSToomas Soome 		case 44: /* blue	(light blue)	background */
739a27563ebSToomas Soome 		case 45: /* magenta	(light magenta)	background */
740a27563ebSToomas Soome 		case 46: /* cyan	(light cyan)	background */
741a27563ebSToomas Soome 		case 47: /* white	(bright white)	background */
742fa9eb222SToomas Soome 			tem->tvs_bg_color.n = param - 40;
743fa9eb222SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
744b6bd4f48SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
745fea9cb91Slq 			break;
746fea9cb91Slq 
747a4e6b9b6SToomas Soome 		case 48:
748fa9eb222SToomas Soome 			/*
749fa9eb222SToomas Soome 			 * We should have 3 parameters for 256 colors and
750fa9eb222SToomas Soome 			 * 5 parameters for 24-bit colors.
751fa9eb222SToomas Soome 			 */
752fa9eb222SToomas Soome 			if (curparam < 3) {
753fa9eb222SToomas Soome 				curparam = 0;
754a4e6b9b6SToomas Soome 				break;
755fa9eb222SToomas Soome 			}
756a4e6b9b6SToomas Soome 
757a4e6b9b6SToomas Soome 			/*
758a4e6b9b6SToomas Soome 			 * 256 and truecolor needs depth at least 24, but
759a4e6b9b6SToomas Soome 			 * we still need to process the sequence.
760a4e6b9b6SToomas Soome 			 */
761a4e6b9b6SToomas Soome 			count++;
762a4e6b9b6SToomas Soome 			curparam--;
763a4e6b9b6SToomas Soome 			param = tem->tvs_params[count];
764a4e6b9b6SToomas Soome 			switch (param) {
765fa9eb222SToomas Soome 			case 2: /* RGB colors */
766fa9eb222SToomas Soome 				if (curparam < 4) {
767fa9eb222SToomas Soome 					curparam = 0;
768fa9eb222SToomas Soome 					break;
769fa9eb222SToomas Soome 				}
770fa9eb222SToomas Soome 				r = tem->tvs_params[++count];
771fa9eb222SToomas Soome 				g = tem->tvs_params[++count];
772fa9eb222SToomas Soome 				b = tem->tvs_params[++count];
773fa9eb222SToomas Soome 				curparam -= 3;
774fa9eb222SToomas Soome 				if (r < 0 || r > 255 || g < 0 || g > 255 ||
775fa9eb222SToomas Soome 				    b < 0 || b > 255)
776fa9eb222SToomas Soome 					break;
777fa9eb222SToomas Soome 
778fa9eb222SToomas Soome 				if (tems.ts_display_mode == VIS_PIXEL &&
779fa9eb222SToomas Soome 				    tems.ts_pdepth > 8) {
780fa9eb222SToomas Soome 					tem->tvs_flags |= TEM_ATTR_RGB_BG;
781fa9eb222SToomas Soome 					tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
782fa9eb222SToomas Soome 					tem->tvs_bg_color.rgb.a =
783fa9eb222SToomas Soome 					    tem->tvs_alpha;
784fa9eb222SToomas Soome 					tem->tvs_bg_color.rgb.r = r;
785fa9eb222SToomas Soome 					tem->tvs_bg_color.rgb.g = g;
786fa9eb222SToomas Soome 					tem->tvs_bg_color.rgb.b = b;
787fa9eb222SToomas Soome 				}
788fa9eb222SToomas Soome 				break;
789a4e6b9b6SToomas Soome 			case 5: /* 256 colors */
790a4e6b9b6SToomas Soome 				count++;
791a4e6b9b6SToomas Soome 				curparam--;
79262efa0e7SToomas Soome 				tem_select_color(tem, tem->tvs_params[count],
79362efa0e7SToomas Soome 				    B_FALSE);
794a4e6b9b6SToomas Soome 				break;
795a4e6b9b6SToomas Soome 			default:
796fa9eb222SToomas Soome 				curparam = 0;
797a4e6b9b6SToomas Soome 				break;
798a4e6b9b6SToomas Soome 			}
799a4e6b9b6SToomas Soome 			break;
800a4e6b9b6SToomas Soome 
801a6631734SJoshua M. Clulow 		case 49:
802a6631734SJoshua M. Clulow 			/*
803b6bd4f48SToomas Soome 			 * Reset the background colour and brightness.
804a6631734SJoshua M. Clulow 			 */
805a6631734SJoshua M. Clulow 			tem->tvs_bg_color = tems.ts_init_color.bg_color;
806fa9eb222SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
807b6bd4f48SToomas Soome 			if (tems.ts_init_color.a_flags & TEM_ATTR_BRIGHT_BG)
808b6bd4f48SToomas Soome 				tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
809b6bd4f48SToomas Soome 			else
810b6bd4f48SToomas Soome 				tem->tvs_flags &= ~TEM_ATTR_BRIGHT_BG;
811b6bd4f48SToomas Soome 			break;
812b6bd4f48SToomas Soome 
813b6bd4f48SToomas Soome 		case 90: /* black	(grey)		foreground */
814b6bd4f48SToomas Soome 		case 91: /* red		(light red)	foreground */
815b6bd4f48SToomas Soome 		case 92: /* green	(light green)	foreground */
816b6bd4f48SToomas Soome 		case 93: /* brown	(yellow)	foreground */
817b6bd4f48SToomas Soome 		case 94: /* blue	(light blue)	foreground */
818b6bd4f48SToomas Soome 		case 95: /* magenta	(light magenta)	foreground */
819b6bd4f48SToomas Soome 		case 96: /* cyan	(light cyan)	foreground */
820b6bd4f48SToomas Soome 		case 97: /* white	(bright white)	foreground */
821fa9eb222SToomas Soome 			tem->tvs_fg_color.n = param - 90;
822b6bd4f48SToomas Soome 			tem->tvs_flags |= TEM_ATTR_BRIGHT_FG;
823fa9eb222SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_RGB_FG;
824b6bd4f48SToomas Soome 			break;
825b6bd4f48SToomas Soome 
826b6bd4f48SToomas Soome 		case 100: /* black	(grey)		background */
827b6bd4f48SToomas Soome 		case 101: /* red	(light red)	background */
828b6bd4f48SToomas Soome 		case 102: /* green	(light green)	background */
829b6bd4f48SToomas Soome 		case 103: /* brown	(yellow)	background */
830b6bd4f48SToomas Soome 		case 104: /* blue	(light blue)	background */
831b6bd4f48SToomas Soome 		case 105: /* magenta	(light magenta)	background */
832b6bd4f48SToomas Soome 		case 106: /* cyan	(light cyan)	background */
833b6bd4f48SToomas Soome 		case 107: /* white	(bright white)	background */
834fa9eb222SToomas Soome 			tem->tvs_bg_color.n = param - 100;
835b6bd4f48SToomas Soome 			tem->tvs_flags |= TEM_ATTR_BRIGHT_BG;
836fa9eb222SToomas Soome 			tem->tvs_flags &= ~TEM_ATTR_RGB_BG;
837a6631734SJoshua M. Clulow 			break;
838a6631734SJoshua M. Clulow 
839fea9cb91Slq 		default:
840fea9cb91Slq 			break;
841fea9cb91Slq 		}
842fea9cb91Slq 		count++;
843fea9cb91Slq 		curparam--;
844fea9cb91Slq 
845fea9cb91Slq 	} while (curparam > 0);
846fea9cb91Slq }
847fea9cb91Slq 
8485c22bad5SToomas Soome /*
8495c22bad5SToomas Soome  * Handle window manipulation.
8505c22bad5SToomas Soome  */
8515c22bad5SToomas Soome static void
tem_safe_window(struct tem_vt_state * tem,enum called_from called_from)8525c22bad5SToomas Soome tem_safe_window(struct tem_vt_state *tem, enum called_from called_from)
8535c22bad5SToomas Soome {
8545c22bad5SToomas Soome 	int curparam;
8555c22bad5SToomas Soome 	int param;
8565c22bad5SToomas Soome 	int index = 0;
8575c22bad5SToomas Soome 	mblk_t *bp;
8585c22bad5SToomas Soome 	size_t len;
8595c22bad5SToomas Soome 	char buf[27];
8605c22bad5SToomas Soome 
8615c22bad5SToomas Soome 	tem->tvs_state = A_STATE_START;
8625c22bad5SToomas Soome 	curparam = tem->tvs_curparam;
8635c22bad5SToomas Soome 	do {
8645c22bad5SToomas Soome 		param = tem->tvs_params[index];
8655c22bad5SToomas Soome 
8665c22bad5SToomas Soome 		switch (param) {
8675c22bad5SToomas Soome 		case 8:	/* Resize window to Ps2 lines and Ps3 columns. */
8685c22bad5SToomas Soome 			/* We ignore this */
8695c22bad5SToomas Soome 			index += 2;
8705c22bad5SToomas Soome 			curparam -= 2;
8715c22bad5SToomas Soome 			break;
8725c22bad5SToomas Soome 
8735c22bad5SToomas Soome 		case 18: /* Reports terminal size in characters. */
8745c22bad5SToomas Soome 			if (called_from == CALLED_FROM_STANDALONE)
8755c22bad5SToomas Soome 				break;
8765c22bad5SToomas Soome 			if (!canputnext(tem->tvs_queue))
8775c22bad5SToomas Soome 				break;
8785c22bad5SToomas Soome 
8795c22bad5SToomas Soome 			/* Response: CSI 8 ; lines ; columns t */
8805c22bad5SToomas Soome 			len = snprintf(buf, sizeof (buf), "%c[8;%u;%ut",
8815c22bad5SToomas Soome 			    0x1b, tems.ts_c_dimension.height,
8825c22bad5SToomas Soome 			    tems.ts_c_dimension.width);
8835c22bad5SToomas Soome 
8845c22bad5SToomas Soome 			bp = allocb(len, BPRI_HI);
8855c22bad5SToomas Soome 			if (bp != NULL) {
8865c22bad5SToomas Soome 				bp->b_datap->db_type = M_CTL;
8875c22bad5SToomas Soome 				bcopy(buf, bp->b_wptr, len);
8885c22bad5SToomas Soome 				bp->b_wptr += len;
8895c22bad5SToomas Soome 				(void) putnext(tem->tvs_queue, bp);
8905c22bad5SToomas Soome 			}
8915c22bad5SToomas Soome 			break;
8925c22bad5SToomas Soome 		}
8935c22bad5SToomas Soome 
8945c22bad5SToomas Soome 		index++;
8955c22bad5SToomas Soome 		curparam--;
8965c22bad5SToomas Soome 	} while (curparam > 0);
8975c22bad5SToomas Soome }
8985c22bad5SToomas Soome 
899fea9cb91Slq /*
900fea9cb91Slq  * perform the appropriate action for the escape sequence
901fea9cb91Slq  *
902fea9cb91Slq  * General rule:  This code does not validate the arguments passed.
903fea9cb91Slq  *                It assumes that the next lower level will do so.
904fea9cb91Slq  */
905fea9cb91Slq static void
tem_safe_chkparam(struct tem_vt_state * tem,tem_char_t ch,cred_t * credp,enum called_from called_from)9060e3b7565SToomas Soome tem_safe_chkparam(struct tem_vt_state *tem, tem_char_t ch, cred_t *credp,
907898c3fecSToomas Soome     enum called_from called_from)
908fea9cb91Slq {
909fea9cb91Slq 	int	i;
910fea9cb91Slq 	int	row;
911fea9cb91Slq 	int	col;
912fea9cb91Slq 
913fea9cb91Slq 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
914aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
915fea9cb91Slq 
916aecfc01dSrui zang - Sun Microsystems - Beijing China 	row = tem->tvs_c_cursor.row;
917aecfc01dSrui zang - Sun Microsystems - Beijing China 	col = tem->tvs_c_cursor.col;
918fea9cb91Slq 
919fea9cb91Slq 	switch (ch) {
920fea9cb91Slq 
921fea9cb91Slq 	case 'm': /* select terminal graphics mode */
922aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
923aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_selgraph(tem);
924fea9cb91Slq 		break;
925fea9cb91Slq 
926fea9cb91Slq 	case '@':		/* insert char */
927aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
928aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_shift(tem, tem->tvs_params[0], TEM_SHIFT_RIGHT,
929fea9cb91Slq 		    credp, called_from);
930fea9cb91Slq 		break;
931fea9cb91Slq 
932fea9cb91Slq 	case 'A':		/* cursor up */
933aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
934aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row - tem->tvs_params[0], col,
935fea9cb91Slq 		    credp, called_from);
936fea9cb91Slq 		break;
937fea9cb91Slq 
938fea9cb91Slq 	case 'd':		/* VPA - vertical position absolute */
939aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
940aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, tem->tvs_params[0] - 1, col,
941fea9cb91Slq 		    credp, called_from);
942fea9cb91Slq 		break;
943fea9cb91Slq 
944fea9cb91Slq 	case 'e':		/* VPR - vertical position relative */
945fea9cb91Slq 	case 'B':		/* cursor down */
946aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
947aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row + tem->tvs_params[0], col,
948fea9cb91Slq 		    credp, called_from);
949fea9cb91Slq 		break;
950fea9cb91Slq 
951fea9cb91Slq 	case 'a':		/* HPR - horizontal position relative */
952fea9cb91Slq 	case 'C':		/* cursor right */
953aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
954aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, col + tem->tvs_params[0],
955fea9cb91Slq 		    credp, called_from);
956fea9cb91Slq 		break;
957fea9cb91Slq 
958fea9cb91Slq 	case '`':		/* HPA - horizontal position absolute */
959aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
960aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, tem->tvs_params[0] - 1,
961fea9cb91Slq 		    credp, called_from);
962fea9cb91Slq 		break;
963fea9cb91Slq 
964fea9cb91Slq 	case 'D':		/* cursor left */
965aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
966aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, col - tem->tvs_params[0],
967fea9cb91Slq 		    credp, called_from);
968fea9cb91Slq 		break;
969fea9cb91Slq 
970fea9cb91Slq 	case 'E':		/* CNL cursor next line */
971aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
972aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row + tem->tvs_params[0], 0,
973fea9cb91Slq 		    credp, called_from);
974fea9cb91Slq 		break;
975fea9cb91Slq 
976fea9cb91Slq 	case 'F':		/* CPL cursor previous line */
977aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
978aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row - tem->tvs_params[0], 0,
979fea9cb91Slq 		    credp, called_from);
980fea9cb91Slq 		break;
981fea9cb91Slq 
982fea9cb91Slq 	case 'G':		/* cursor horizontal position */
983aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
984aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, tem->tvs_params[0] - 1,
985fea9cb91Slq 		    credp, called_from);
986fea9cb91Slq 		break;
987fea9cb91Slq 
988fea9cb91Slq 	case 'g':		/* clear tabs */
989aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 0);
990aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_tabs(tem, tem->tvs_params[0]);
991fea9cb91Slq 		break;
992fea9cb91Slq 
993fea9cb91Slq 	case 'f':		/* HVP Horizontal and Vertical Position */
994fea9cb91Slq 	case 'H':		/* CUP position cursor */
995aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 2, 1);
996aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem,
997aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0] - 1,
998aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[1] - 1,
999fea9cb91Slq 		    credp, called_from);
1000fea9cb91Slq 		break;
1001fea9cb91Slq 
1002fea9cb91Slq 	case 'I':		/* CHT - Cursor Horizontal Tab */
1003fea9cb91Slq 		/* Not implemented */
1004fea9cb91Slq 		break;
1005fea9cb91Slq 
1006fea9cb91Slq 	case 'J':		/* ED - Erase in Display */
1007aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1008aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 0);
1009aecfc01dSrui zang - Sun Microsystems - Beijing China 		switch (tem->tvs_params[0]) {
1010fea9cb91Slq 		case 0:
1011fea9cb91Slq 			/* erase cursor to end of screen */
1012fea9cb91Slq 			/* FIRST erase cursor to end of line */
1013aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
1014aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width -
1015aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
1016aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1017aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col, credp, called_from);
1018fea9cb91Slq 
1019fea9cb91Slq 			/* THEN erase lines below the cursor */
1020aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (row = tem->tvs_c_cursor.row + 1;
1021aecfc01dSrui zang - Sun Microsystems - Beijing China 			    row < tems.ts_c_dimension.height;
1022c35aa225Smarx 			    row++) {
1023aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_clear_chars(tem,
1024aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tems.ts_c_dimension.width,
1025fea9cb91Slq 				    row, 0, credp, called_from);
1026fea9cb91Slq 			}
1027fea9cb91Slq 			break;
1028fea9cb91Slq 
1029fea9cb91Slq 		case 1:
1030fea9cb91Slq 			/* erase beginning of screen to cursor */
1031fea9cb91Slq 			/* FIRST erase lines above the cursor */
1032fea9cb91Slq 			for (row = 0;
1033aecfc01dSrui zang - Sun Microsystems - Beijing China 			    row < tem->tvs_c_cursor.row;
1034c35aa225Smarx 			    row++) {
1035aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_clear_chars(tem,
1036aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tems.ts_c_dimension.width,
1037fea9cb91Slq 				    row, 0, credp, called_from);
1038fea9cb91Slq 			}
1039fea9cb91Slq 			/* THEN erase beginning of line to cursor */
1040aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
1041aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + 1,
1042aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1043c35aa225Smarx 			    0, credp, called_from);
1044fea9cb91Slq 			break;
1045fea9cb91Slq 
1046fea9cb91Slq 		case 2:
1047fea9cb91Slq 			/* erase whole screen */
1048fea9cb91Slq 			for (row = 0;
1049aecfc01dSrui zang - Sun Microsystems - Beijing China 			    row < tems.ts_c_dimension.height;
1050fea9cb91Slq 			    row++) {
1051aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_clear_chars(tem,
1052aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tems.ts_c_dimension.width,
1053c35aa225Smarx 				    row, 0, credp, called_from);
1054fea9cb91Slq 			}
1055fea9cb91Slq 			break;
1056fea9cb91Slq 		}
1057fea9cb91Slq 		break;
1058fea9cb91Slq 
1059fea9cb91Slq 	case 'K':		/* EL - Erase in Line */
1060aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1061aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 0);
1062aecfc01dSrui zang - Sun Microsystems - Beijing China 		switch (tem->tvs_params[0]) {
1063fea9cb91Slq 		case 0:
1064fea9cb91Slq 			/* erase cursor to end of line */
1065aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
1066aecfc01dSrui zang - Sun Microsystems - Beijing China 			    (tems.ts_c_dimension.width -
1067aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col),
1068aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1069aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
1070fea9cb91Slq 			    credp, called_from);
1071fea9cb91Slq 			break;
1072fea9cb91Slq 
1073fea9cb91Slq 		case 1:
1074fea9cb91Slq 			/* erase beginning of line to cursor */
1075aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
1076aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + 1,
1077aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1078fea9cb91Slq 			    0, credp, called_from);
1079fea9cb91Slq 			break;
1080fea9cb91Slq 
1081fea9cb91Slq 		case 2:
1082fea9cb91Slq 			/* erase whole line */
1083aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
1084aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width,
1085aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1086fea9cb91Slq 			    0, credp, called_from);
1087fea9cb91Slq 			break;
1088fea9cb91Slq 		}
1089fea9cb91Slq 		break;
1090fea9cb91Slq 
1091fea9cb91Slq 	case 'L':		/* insert line */
1092aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1093aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1094aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem,
1095aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
1096aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
1097aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_DOWN,
1098c35aa225Smarx 		    credp, called_from);
1099fea9cb91Slq 		break;
1100fea9cb91Slq 
1101fea9cb91Slq 	case 'M':		/* delete line */
1102aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1103aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1104aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem,
1105aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
1106aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
1107aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_UP,
1108c35aa225Smarx 		    credp, called_from);
1109fea9cb91Slq 		break;
1110fea9cb91Slq 
1111fea9cb91Slq 	case 'P':		/* DCH - delete char */
1112aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1113aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_shift(tem, tem->tvs_params[0], TEM_SHIFT_LEFT,
1114fea9cb91Slq 		    credp, called_from);
1115fea9cb91Slq 		break;
1116fea9cb91Slq 
1117fea9cb91Slq 	case 'S':		/* scroll up */
1118aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1119aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1120aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem, 0,
1121aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
1122aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_UP,
1123c35aa225Smarx 		    credp, called_from);
1124fea9cb91Slq 		break;
1125fea9cb91Slq 
1126fea9cb91Slq 	case 'T':		/* scroll down */
1127aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1128aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1129aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem, 0,
1130aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
1131aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_DOWN,
1132c35aa225Smarx 		    credp, called_from);
1133fea9cb91Slq 		break;
1134fea9cb91Slq 
11355c22bad5SToomas Soome 	case 't':
11365c22bad5SToomas Soome 		tem_safe_send_data(tem, credp, called_from);
11375c22bad5SToomas Soome 		tem_safe_window(tem, called_from);
11385c22bad5SToomas Soome 		break;
11395c22bad5SToomas Soome 
1140fea9cb91Slq 	case 'X':		/* erase char */
1141aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1142aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem,
1143aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0],
1144aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
1145aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col,
1146c35aa225Smarx 		    credp, called_from);
1147fea9cb91Slq 		break;
1148fea9cb91Slq 
1149fea9cb91Slq 	case 'Z':		/* cursor backward tabulation */
1150aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
1151fea9cb91Slq 
1152fea9cb91Slq 		/*
1153fea9cb91Slq 		 * Rule exception - We do sanity checking here.
1154fea9cb91Slq 		 *
1155fea9cb91Slq 		 * Restrict the count to a sane value to keep from
1156fea9cb91Slq 		 * looping for a long time.  There can't be more than one
1157fea9cb91Slq 		 * tab stop per column, so use that as a limit.
1158fea9cb91Slq 		 */
1159aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_params[0] > tems.ts_c_dimension.width)
1160aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_params[0] = tems.ts_c_dimension.width;
1161fea9cb91Slq 
1162aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (i = 0; i < tem->tvs_params[0]; i++)
1163aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_back_tab(tem, credp, called_from);
1164fea9cb91Slq 		break;
1165fea9cb91Slq 	}
1166aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
1167fea9cb91Slq }
1168fea9cb91Slq 
1169c43f6c55SGarrett D'Amore static void
tem_safe_chkparam_qmark(struct tem_vt_state * tem,tem_char_t ch,cred_t * credp,enum called_from called_from)1170c43f6c55SGarrett D'Amore tem_safe_chkparam_qmark(struct tem_vt_state *tem, tem_char_t ch, cred_t *credp,
1171c43f6c55SGarrett D'Amore     enum called_from called_from)
1172c43f6c55SGarrett D'Amore {
1173c43f6c55SGarrett D'Amore 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
1174c43f6c55SGarrett D'Amore 	    MUTEX_HELD(&tem->tvs_lock));
1175c43f6c55SGarrett D'Amore 
1176c43f6c55SGarrett D'Amore 	switch (ch) {
1177c43f6c55SGarrett D'Amore 	case 'h': /* DEC private mode set */
1178c43f6c55SGarrett D'Amore 		tem_safe_setparam(tem, 1, 1);
1179c43f6c55SGarrett D'Amore 		switch (tem->tvs_params[0]) {
1180*d863b4c1SToomas Soome 		case 7: /* Autowrap mode. */
1181*d863b4c1SToomas Soome 			tem->tvs_stateflags |= TVS_AUTOWRAP;
1182*d863b4c1SToomas Soome 			break;
1183*d863b4c1SToomas Soome 
1184c43f6c55SGarrett D'Amore 		case 25: /* show cursor */
1185c43f6c55SGarrett D'Amore 			/*
1186c43f6c55SGarrett D'Amore 			 * Note that cursor is not displayed either way
1187c43f6c55SGarrett D'Amore 			 * at this entry point.  Clearing the flag ensures
1188c43f6c55SGarrett D'Amore 			 * that on exit from tem_safe_terminal_emulate
1189c43f6c55SGarrett D'Amore 			 * we will display the cursor.
1190c43f6c55SGarrett D'Amore 			 */
1191c43f6c55SGarrett D'Amore 			tem_safe_send_data(tem, credp, called_from);
1192c43f6c55SGarrett D'Amore 			tem->tvs_cursor_hidden = B_FALSE;
1193c43f6c55SGarrett D'Amore 			break;
1194c43f6c55SGarrett D'Amore 		}
1195c43f6c55SGarrett D'Amore 		break;
1196c43f6c55SGarrett D'Amore 
1197c43f6c55SGarrett D'Amore 	case 'l':
1198c43f6c55SGarrett D'Amore 		/* DEC private mode reset */
1199c43f6c55SGarrett D'Amore 		tem_safe_setparam(tem, 1, 1);
1200c43f6c55SGarrett D'Amore 		switch (tem->tvs_params[0]) {
1201*d863b4c1SToomas Soome 		case 7: /* Autowrap mode. */
1202*d863b4c1SToomas Soome 			tem->tvs_stateflags &= ~TVS_AUTOWRAP;
1203*d863b4c1SToomas Soome 			break;
1204*d863b4c1SToomas Soome 
1205c43f6c55SGarrett D'Amore 		case 25: /* hide cursor */
1206c43f6c55SGarrett D'Amore 			/*
1207c43f6c55SGarrett D'Amore 			 * Note that the cursor is not displayed already.
1208c43f6c55SGarrett D'Amore 			 * This is true regardless of the flag state.
1209c43f6c55SGarrett D'Amore 			 * Setting this flag ensures we won't display it
1210c43f6c55SGarrett D'Amore 			 * on exit from tem_safe_terminal_emulate.
1211c43f6c55SGarrett D'Amore 			 */
1212c43f6c55SGarrett D'Amore 			tem_safe_send_data(tem, credp, called_from);
1213c43f6c55SGarrett D'Amore 			tem->tvs_cursor_hidden = B_TRUE;
1214c43f6c55SGarrett D'Amore 			break;
1215c43f6c55SGarrett D'Amore 		}
1216c43f6c55SGarrett D'Amore 		break;
1217c43f6c55SGarrett D'Amore 	}
1218c43f6c55SGarrett D'Amore 	tem->tvs_state = A_STATE_START;
1219c43f6c55SGarrett D'Amore }
1220fea9cb91Slq 
1221fea9cb91Slq /*
1222fea9cb91Slq  * Gather the parameters of an ANSI escape sequence
1223fea9cb91Slq  */
1224fea9cb91Slq static void
tem_safe_getparams(struct tem_vt_state * tem,tem_char_t ch,cred_t * credp,enum called_from called_from)12250e3b7565SToomas Soome tem_safe_getparams(struct tem_vt_state *tem, tem_char_t ch,
1226fea9cb91Slq     cred_t *credp, enum called_from called_from)
1227fea9cb91Slq {
1228fea9cb91Slq 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
1229aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
1230fea9cb91Slq 
123151fd4921Slt 	if (ch >= '0' && ch <= '9') {
1232aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_paramval = ((tem->tvs_paramval * 10) + (ch - '0'));
1233aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_gotparam = B_TRUE;  /* Remember got parameter */
1234fea9cb91Slq 		return; /* Return immediately */
1235c43f6c55SGarrett D'Amore 	} else if (tem->tvs_state == A_STATE_CSI_EQUAL) {
1236aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1237c43f6c55SGarrett D'Amore 	} else if (tem->tvs_state == A_STATE_CSI_QMARK) {
1238c43f6c55SGarrett D'Amore 		if (tem->tvs_curparam < TEM_MAXPARAMS) {
1239c43f6c55SGarrett D'Amore 			if (tem->tvs_gotparam) {
1240c43f6c55SGarrett D'Amore 				/* get the parameter value */
1241c43f6c55SGarrett D'Amore 				tem->tvs_params[tem->tvs_curparam] =
1242c43f6c55SGarrett D'Amore 				    tem->tvs_paramval;
1243c43f6c55SGarrett D'Amore 			}
1244c43f6c55SGarrett D'Amore 			tem->tvs_curparam++;
1245c43f6c55SGarrett D'Amore 		}
1246c43f6c55SGarrett D'Amore 		if (ch == ';') {
1247c43f6c55SGarrett D'Amore 			/* Restart parameter search */
1248c43f6c55SGarrett D'Amore 			tem->tvs_gotparam = B_FALSE;
1249c43f6c55SGarrett D'Amore 			tem->tvs_paramval = 0; /* No parameter value yet */
1250c43f6c55SGarrett D'Amore 		} else {
1251c43f6c55SGarrett D'Amore 			/* Handle escape sequence */
1252c43f6c55SGarrett D'Amore 			tem_safe_chkparam_qmark(tem, ch, credp, called_from);
1253c43f6c55SGarrett D'Amore 		}
125451fd4921Slt 	} else {
1255aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_curparam < TEM_MAXPARAMS) {
1256aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_gotparam) {
125751fd4921Slt 				/* get the parameter value */
1258aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_params[tem->tvs_curparam] =
1259aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tem->tvs_paramval;
1260fea9cb91Slq 			}
1261aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_curparam++;
1262fea9cb91Slq 		}
1263fea9cb91Slq 
1264fea9cb91Slq 		if (ch == ';') {
1265fea9cb91Slq 			/* Restart parameter search */
1266aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_gotparam = B_FALSE;
1267c43f6c55SGarrett D'Amore 			tem->tvs_paramval = 0; /* No parameter value yet */
126851fd4921Slt 		} else {
1269fea9cb91Slq 			/* Handle escape sequence */
1270aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_chkparam(tem, ch, credp, called_from);
127151fd4921Slt 		}
1272fea9cb91Slq 	}
1273fea9cb91Slq }
1274fea9cb91Slq 
1275fea9cb91Slq /*
1276fea9cb91Slq  * Add character to internal buffer.
1277fea9cb91Slq  * When its full, send it to the next layer.
1278fea9cb91Slq  */
1279fea9cb91Slq 
1280fea9cb91Slq static void
tem_safe_outch(struct tem_vt_state * tem,tem_char_t ch,cred_t * credp,enum called_from called_from)12810e3b7565SToomas Soome tem_safe_outch(struct tem_vt_state *tem, tem_char_t ch,
1282fea9cb91Slq     cred_t *credp, enum called_from called_from)
1283fea9cb91Slq {
1284cbc8e155SToomas Soome 	text_color_t fg;
1285cbc8e155SToomas Soome 	text_color_t bg;
1286cbc8e155SToomas Soome 	text_attr_t attr;
1287fea9cb91Slq 
1288aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1289aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1290fea9cb91Slq 
1291*d863b4c1SToomas Soome 	/* We have autowrap enabled and we did wrap - get cursor to new line */
1292*d863b4c1SToomas Soome 	if ((tem->tvs_stateflags & (TVS_AUTOWRAP | TVS_WRAPPED)) ==
1293*d863b4c1SToomas Soome 	    (TVS_AUTOWRAP | TVS_WRAPPED)) {
1294*d863b4c1SToomas Soome 		tem_safe_new_line(tem, credp, called_from);
1295*d863b4c1SToomas Soome 	}
1296*d863b4c1SToomas Soome 
1297fea9cb91Slq 	/* buffer up the character until later */
1298cbc8e155SToomas Soome 	tem_safe_get_attr(tem, &fg, &bg, &attr, TEM_ATTR_REVERSE);
1299cbc8e155SToomas Soome 	tem->tvs_outbuf[tem->tvs_outindex].tc_char = ch | TEM_ATTR(attr);
1300cbc8e155SToomas Soome 	tem->tvs_outbuf[tem->tvs_outindex].tc_fg_color = fg;
1301cbc8e155SToomas Soome 	tem->tvs_outbuf[tem->tvs_outindex].tc_bg_color = bg;
1302cbc8e155SToomas Soome 	tem->tvs_outindex++;
1303aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col++;
1304aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_c_cursor.col >= tems.ts_c_dimension.width) {
1305*d863b4c1SToomas Soome 		tem->tvs_stateflags |= TVS_WRAPPED;
1306*d863b4c1SToomas Soome 		tem->tvs_c_cursor.col--;
1307aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
1308*d863b4c1SToomas Soome 	} else {
1309*d863b4c1SToomas Soome 		tem->tvs_stateflags &= ~TVS_WRAPPED;
1310fea9cb91Slq 	}
1311fea9cb91Slq }
1312fea9cb91Slq 
1313fea9cb91Slq static void
tem_safe_new_line(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1314aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_new_line(struct tem_vt_state *tem,
1315fea9cb91Slq     cred_t *credp, enum called_from called_from)
1316fea9cb91Slq {
1317aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_cr(tem);
1318aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_lf(tem, credp, called_from);
1319fea9cb91Slq }
1320fea9cb91Slq 
1321fea9cb91Slq static void
tem_safe_cr(struct tem_vt_state * tem)1322aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_cr(struct tem_vt_state *tem)
1323fea9cb91Slq {
1324aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = 0;
1325*d863b4c1SToomas Soome 	tem->tvs_stateflags &= ~TVS_WRAPPED;
1326aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
1327fea9cb91Slq }
1328fea9cb91Slq 
1329fea9cb91Slq static void
tem_safe_lf(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1330aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_lf(struct tem_vt_state *tem,
1331fea9cb91Slq     cred_t *credp, enum called_from called_from)
1332fea9cb91Slq {
1333fea9cb91Slq 	int row;
1334fea9cb91Slq 
1335fea9cb91Slq 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
1336aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
1337fea9cb91Slq 
1338*d863b4c1SToomas Soome 	tem->tvs_stateflags &= ~TVS_WRAPPED;
1339fea9cb91Slq 	/*
1340fea9cb91Slq 	 * Sanity checking notes:
1341fea9cb91Slq 	 * . a_nscroll was validated when it was set.
1342aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * . Regardless of that, tem_safe_scroll and tem_safe_mv_cursor
1343aecfc01dSrui zang - Sun Microsystems - Beijing China 	 *   will prevent anything bad from happening.
1344fea9cb91Slq 	 */
1345aecfc01dSrui zang - Sun Microsystems - Beijing China 	row = tem->tvs_c_cursor.row + 1;
1346fea9cb91Slq 
1347aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row >= tems.ts_c_dimension.height) {
1348aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_nscroll != 0) {
1349aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_scroll(tem, 0,
1350aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.height - 1,
1351aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_nscroll, TEM_SCROLL_UP,
1352fea9cb91Slq 			    credp, called_from);
1353aecfc01dSrui zang - Sun Microsystems - Beijing China 			row = tems.ts_c_dimension.height -
1354aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_nscroll;
1355fea9cb91Slq 		} else {	/* no scroll */
1356fea9cb91Slq 			/*
1357fea9cb91Slq 			 * implement Esc[#r when # is zero.  This means no
1358fea9cb91Slq 			 * scroll but just return cursor to top of screen,
1359fea9cb91Slq 			 * do not clear screen.
1360fea9cb91Slq 			 */
1361fea9cb91Slq 			row = 0;
1362fea9cb91Slq 		}
1363fea9cb91Slq 	}
1364fea9cb91Slq 
1365aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_mv_cursor(tem, row, tem->tvs_c_cursor.col,
1366c35aa225Smarx 	    credp, called_from);
1367fea9cb91Slq 
1368aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_nscroll == 0) {
1369fea9cb91Slq 		/* erase rest of cursor line */
1370aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem,
1371aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.width -
1372aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col,
1373aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
1374aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col,
1375fea9cb91Slq 		    credp, called_from);
1376fea9cb91Slq 
1377fea9cb91Slq 	}
1378fea9cb91Slq 
1379aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
1380fea9cb91Slq }
1381fea9cb91Slq 
1382fea9cb91Slq static void
tem_safe_send_data(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1383aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_send_data(struct tem_vt_state *tem, cred_t *credp,
1384fea9cb91Slq     enum called_from called_from)
1385fea9cb91Slq {
1386fea9cb91Slq 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
1387aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
1388fea9cb91Slq 
1389aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_outindex == 0) {
1390aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_align_cursor(tem);
1391aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1392aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1393fea9cb91Slq 
1394aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_virtual_display(tem,
1395aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tem->tvs_outbuf, tem->tvs_outindex,
1396cbc8e155SToomas Soome 	    tem->tvs_s_cursor.row, tem->tvs_s_cursor.col);
1397fea9cb91Slq 
1398aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_isactive) {
1399fea9cb91Slq 		/*
1400fea9cb91Slq 		 * Call the primitive to render this data.
1401fea9cb91Slq 		 */
1402aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_display(tem,
1403aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_outbuf, tem->tvs_outindex,
1404aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_s_cursor.row, tem->tvs_s_cursor.col,
1405c35aa225Smarx 		    credp, called_from);
1406fea9cb91Slq 	}
1407aecfc01dSrui zang - Sun Microsystems - Beijing China 
1408aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_outindex = 0;
1409aecfc01dSrui zang - Sun Microsystems - Beijing China 
1410aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
1411fea9cb91Slq }
1412fea9cb91Slq 
1413fea9cb91Slq 
1414fea9cb91Slq /*
1415fea9cb91Slq  * We have just done something to the current output point.  Reset the start
1416fea9cb91Slq  * point for the buffered data in a_outbuf.  There shouldn't be any data
1417fea9cb91Slq  * buffered yet.
1418fea9cb91Slq  */
1419aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_safe_align_cursor(struct tem_vt_state * tem)1420aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_align_cursor(struct tem_vt_state *tem)
1421fea9cb91Slq {
1422aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.row = tem->tvs_c_cursor.row;
1423aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.col = tem->tvs_c_cursor.col;
1424fea9cb91Slq }
1425fea9cb91Slq 
1426fea9cb91Slq /*
1427fea9cb91Slq  * State machine parser based on the current state and character input
1428fea9cb91Slq  * major terminations are to control character or normal character
1429fea9cb91Slq  */
1430fea9cb91Slq 
1431fea9cb91Slq static void
tem_safe_parse(struct tem_vt_state * tem,tem_char_t ch,cred_t * credp,enum called_from called_from)14320e3b7565SToomas Soome tem_safe_parse(struct tem_vt_state *tem, tem_char_t ch,
1433fea9cb91Slq     cred_t *credp, enum called_from called_from)
1434fea9cb91Slq {
1435fea9cb91Slq 	int	i;
1436fea9cb91Slq 
1437fea9cb91Slq 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
1438aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
1439fea9cb91Slq 
1440aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_state == A_STATE_START) {	/* Normal state? */
1441aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (ch == A_CSI || ch == A_ESC || ch < ' ') {
1442aecfc01dSrui zang - Sun Microsystems - Beijing China 			/* Control */
1443aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_control(tem, ch, credp, called_from);
1444aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else {
1445fea9cb91Slq 			/* Display */
1446aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_outch(tem, ch, credp, called_from);
1447aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1448fea9cb91Slq 		return;
1449fea9cb91Slq 	}
1450fea9cb91Slq 
1451fea9cb91Slq 	/* In <ESC> sequence */
1452aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_state != A_STATE_ESC) {	/* Need to get parameters? */
1453aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_state != A_STATE_CSI) {
1454aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_getparams(tem, ch, credp, called_from);
1455fea9cb91Slq 			return;
1456fea9cb91Slq 		}
1457fea9cb91Slq 
1458fea9cb91Slq 		switch (ch) {
1459fea9cb91Slq 		case '?':
1460aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_CSI_QMARK;
1461fea9cb91Slq 			return;
1462fea9cb91Slq 		case '=':
1463aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_CSI_EQUAL;
1464fea9cb91Slq 			return;
1465fea9cb91Slq 		case 's':
1466fea9cb91Slq 			/*
1467fea9cb91Slq 			 * As defined below, this sequence
1468fea9cb91Slq 			 * saves the cursor.  However, Sun
1469fea9cb91Slq 			 * defines ESC[s as reset.  We resolved
1470fea9cb91Slq 			 * the conflict by selecting reset as it
1471fea9cb91Slq 			 * is exported in the termcap file for
1472fea9cb91Slq 			 * sun-mon, while the "save cursor"
1473fea9cb91Slq 			 * definition does not exist anywhere in
1474fea9cb91Slq 			 * /etc/termcap.
1475fea9cb91Slq 			 * However, having no coherent
1476fea9cb91Slq 			 * definition of reset, we have not
1477fea9cb91Slq 			 * implemented it.
1478fea9cb91Slq 			 */
1479fea9cb91Slq 
1480fea9cb91Slq 			/*
1481fea9cb91Slq 			 * Original code
1482aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * tem->tvs_r_cursor.row = tem->tvs_c_cursor.row;
1483aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * tem->tvs_r_cursor.col = tem->tvs_c_cursor.col;
1484aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * tem->tvs_state = A_STATE_START;
1485fea9cb91Slq 			 */
1486fea9cb91Slq 
1487aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1488fea9cb91Slq 			return;
1489fea9cb91Slq 		case 'u':
1490aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_mv_cursor(tem, tem->tvs_r_cursor.row,
1491aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_r_cursor.col, credp, called_from);
1492aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1493fea9cb91Slq 			return;
1494a27563ebSToomas Soome 		case 'p':	/* sunbow */
1495aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_send_data(tem, credp, called_from);
1496fea9cb91Slq 			/*
1497fea9cb91Slq 			 * Don't set anything if we are
1498fea9cb91Slq 			 * already as we want to be.
1499fea9cb91Slq 			 */
1500aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
1501aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags &= ~TEM_ATTR_SCREEN_REVERSE;
1502fea9cb91Slq 				/*
1503fea9cb91Slq 				 * If we have switched the characters to be the
1504fea9cb91Slq 				 * inverse from the screen, then switch them as
1505fea9cb91Slq 				 * well to keep them the inverse of the screen.
1506fea9cb91Slq 				 */
1507aecfc01dSrui zang - Sun Microsystems - Beijing China 				if (tem->tvs_flags & TEM_ATTR_REVERSE)
1508aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags &= ~TEM_ATTR_REVERSE;
1509aecfc01dSrui zang - Sun Microsystems - Beijing China 				else
1510aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags |= TEM_ATTR_REVERSE;
1511fea9cb91Slq 			}
1512aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_cls(tem, credp, called_from);
1513aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1514fea9cb91Slq 			return;
1515a27563ebSToomas Soome 		case 'q':	/* sunwob */
1516aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_send_data(tem, credp, called_from);
1517fea9cb91Slq 			/*
1518fea9cb91Slq 			 * Don't set anything if we are
1519fea9cb91Slq 			 * already where as we want to be.
1520fea9cb91Slq 			 */
1521aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (!(tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE)) {
1522aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags |= TEM_ATTR_SCREEN_REVERSE;
1523fea9cb91Slq 				/*
1524fea9cb91Slq 				 * If we have switched the characters to be the
1525fea9cb91Slq 				 * inverse from the screen, then switch them as
1526fea9cb91Slq 				 * well to keep them the inverse of the screen.
1527fea9cb91Slq 				 */
1528aecfc01dSrui zang - Sun Microsystems - Beijing China 				if (!(tem->tvs_flags & TEM_ATTR_REVERSE))
1529aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags |= TEM_ATTR_REVERSE;
1530aecfc01dSrui zang - Sun Microsystems - Beijing China 				else
1531aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags &= ~TEM_ATTR_REVERSE;
1532fea9cb91Slq 			}
1533fea9cb91Slq 
1534aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_cls(tem, credp, called_from);
1535aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1536fea9cb91Slq 			return;
1537fea9cb91Slq 		case 'r':	/* sunscrl */
1538fea9cb91Slq 			/*
1539fea9cb91Slq 			 * Rule exception:  check for validity here.
1540fea9cb91Slq 			 */
1541aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_nscroll = tem->tvs_paramval;
1542aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_nscroll > tems.ts_c_dimension.height)
1543aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_nscroll = tems.ts_c_dimension.height;
1544aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_nscroll < 0)
1545aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_nscroll = 1;
1546aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1547fea9cb91Slq 			return;
1548fea9cb91Slq 		default:
1549aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_getparams(tem, ch, credp, called_from);
1550fea9cb91Slq 			return;
1551fea9cb91Slq 		}
1552fea9cb91Slq 	}
1553fea9cb91Slq 
1554fea9cb91Slq 	/* Previous char was <ESC> */
1555fea9cb91Slq 	if (ch == '[') {
1556aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_curparam = 0;
1557aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_paramval = 0;
1558aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_gotparam = B_FALSE;
1559fea9cb91Slq 		/* clear the parameters */
1560fea9cb91Slq 		for (i = 0; i < TEM_MAXPARAMS; i++)
1561aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_params[i] = -1;
1562aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_CSI;
1563fea9cb91Slq 	} else if (ch == 'Q') {	/* <ESC>Q ? */
1564aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1565fea9cb91Slq 	} else if (ch == 'C') {	/* <ESC>C ? */
1566aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1567fea9cb91Slq 	} else {
1568aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1569aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (ch == 'c') {
1570fea9cb91Slq 			/* ESC c resets display */
1571aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_reset_display(tem, credp, called_from,
1572aecfc01dSrui zang - Sun Microsystems - Beijing China 			    B_TRUE, B_TRUE);
1573aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch == 'H') {
1574fea9cb91Slq 			/* ESC H sets a tab */
1575aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_set_tab(tem);
1576aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch == '7') {
1577fea9cb91Slq 			/* ESC 7 Save Cursor position */
1578aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_r_cursor.row = tem->tvs_c_cursor.row;
1579aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_r_cursor.col = tem->tvs_c_cursor.col;
1580aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch == '8') {
1581fea9cb91Slq 			/* ESC 8 Restore Cursor position */
1582aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_mv_cursor(tem, tem->tvs_r_cursor.row,
1583aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_r_cursor.col, credp, called_from);
1584fea9cb91Slq 		/* check for control chars */
1585aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch < ' ') {
1586aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_control(tem, ch, credp, called_from);
1587aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else {
1588aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_outch(tem, ch, credp, called_from);
1589aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1590fea9cb91Slq 	}
1591fea9cb91Slq }
1592fea9cb91Slq 
1593fea9cb91Slq /* ARGSUSED */
1594fea9cb91Slq static void
tem_safe_bell(struct tem_vt_state * tem,enum called_from called_from)1595aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_bell(struct tem_vt_state *tem, enum called_from called_from)
1596fea9cb91Slq {
1597fea9cb91Slq 	if (called_from == CALLED_FROM_STANDALONE)
1598c35aa225Smarx 		(void) beep_polled(BEEP_CONSOLE);
1599fea9cb91Slq 	else
1600c35aa225Smarx 		(void) beep(BEEP_CONSOLE);
1601fea9cb91Slq }
1602fea9cb91Slq 
1603fea9cb91Slq 
1604fea9cb91Slq static void
tem_safe_scroll(struct tem_vt_state * tem,int start,int end,int count,int direction,cred_t * credp,enum called_from called_from)1605aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_scroll(struct tem_vt_state *tem, int start, int end, int count,
1606b6bd4f48SToomas Soome     int direction, cred_t *credp, enum called_from called_from)
1607fea9cb91Slq {
1608fea9cb91Slq 	int	row;
1609fea9cb91Slq 	int	lines_affected;
1610fea9cb91Slq 
1611aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1612aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1613fea9cb91Slq 
1614fea9cb91Slq 	lines_affected = end - start + 1;
1615fea9cb91Slq 	if (count > lines_affected)
1616fea9cb91Slq 		count = lines_affected;
1617fea9cb91Slq 	if (count <= 0)
1618fea9cb91Slq 		return;
1619fea9cb91Slq 
1620fea9cb91Slq 	switch (direction) {
1621fea9cb91Slq 	case TEM_SCROLL_UP:
1622fea9cb91Slq 		if (count < lines_affected) {
1623aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem, 0, start + count,
1624aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - 1, end,
1625fea9cb91Slq 			    0, start, credp, called_from);
1626fea9cb91Slq 		}
1627fea9cb91Slq 		for (row = (end - count) + 1; row <= end; row++) {
1628aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
1629fea9cb91Slq 			    row, 0, credp, called_from);
1630fea9cb91Slq 		}
1631fea9cb91Slq 		break;
1632fea9cb91Slq 
1633fea9cb91Slq 	case TEM_SCROLL_DOWN:
1634fea9cb91Slq 		if (count < lines_affected) {
1635aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem, 0, start,
1636aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - 1,
1637fea9cb91Slq 			    end - count, 0, start + count,
1638fea9cb91Slq 			    credp, called_from);
1639fea9cb91Slq 		}
1640fea9cb91Slq 		for (row = start; row < start + count; row++) {
1641aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
1642fea9cb91Slq 			    row, 0, credp, called_from);
1643fea9cb91Slq 		}
1644fea9cb91Slq 		break;
1645fea9cb91Slq 	}
1646fea9cb91Slq }
1647fea9cb91Slq 
1648f06e090aSToomas Soome static int
tem_copy_width(term_char_t * src,term_char_t * dst,int cols)1649f06e090aSToomas Soome tem_copy_width(term_char_t *src, term_char_t *dst, int cols)
1650f06e090aSToomas Soome {
1651f06e090aSToomas Soome 	int width = cols - 1;
1652f06e090aSToomas Soome 
1653f06e090aSToomas Soome 	while (width >= 0) {
16542e5d9c98SToomas Soome 		/* We can't compare images. */
16552e5d9c98SToomas Soome 		if (TEM_CHAR_ATTR(src[width].tc_char) == TEM_ATTR_IMAGE ||
16562e5d9c98SToomas Soome 		    TEM_CHAR_ATTR(dst[width].tc_char) == TEM_ATTR_IMAGE)
16572e5d9c98SToomas Soome 			break;
16582e5d9c98SToomas Soome 
1659f06e090aSToomas Soome 		/*
1660f06e090aSToomas Soome 		 * Find difference on line, compare char with its attributes
1661f06e090aSToomas Soome 		 * and colors.
1662f06e090aSToomas Soome 		 */
1663f06e090aSToomas Soome 		if (src[width].tc_char != dst[width].tc_char ||
1664fa9eb222SToomas Soome 		    src[width].tc_fg_color.n != dst[width].tc_fg_color.n ||
1665fa9eb222SToomas Soome 		    src[width].tc_bg_color.n != dst[width].tc_bg_color.n) {
1666f06e090aSToomas Soome 			break;
1667f06e090aSToomas Soome 		}
1668f06e090aSToomas Soome 		width--;
1669f06e090aSToomas Soome 	}
1670f06e090aSToomas Soome 	return (width + 1);
1671f06e090aSToomas Soome }
1672f06e090aSToomas Soome 
1673fea9cb91Slq static void
tem_safe_copy_area(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row,cred_t * credp,enum called_from called_from)1674aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_copy_area(struct tem_vt_state *tem,
1675b6bd4f48SToomas Soome     screen_pos_t s_col, screen_pos_t s_row,
1676b6bd4f48SToomas Soome     screen_pos_t e_col, screen_pos_t e_row,
1677b6bd4f48SToomas Soome     screen_pos_t t_col, screen_pos_t t_row,
1678b6bd4f48SToomas Soome     cred_t *credp, enum called_from called_from)
1679fea9cb91Slq {
1680f06e090aSToomas Soome 	size_t soffset, toffset;
1681f06e090aSToomas Soome 	term_char_t *src, *dst;
1682fea9cb91Slq 	int rows;
1683fea9cb91Slq 	int cols;
1684fea9cb91Slq 
1685aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1686aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1687fea9cb91Slq 
1688fea9cb91Slq 	if (s_col < 0 || s_row < 0 ||
1689fea9cb91Slq 	    e_col < 0 || e_row < 0 ||
1690fea9cb91Slq 	    t_col < 0 || t_row < 0 ||
1691aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col >= tems.ts_c_dimension.width ||
1692aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col >= tems.ts_c_dimension.width ||
1693aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col >= tems.ts_c_dimension.width ||
1694aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_row >= tems.ts_c_dimension.height ||
1695aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_row >= tems.ts_c_dimension.height ||
1696aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_row >= tems.ts_c_dimension.height)
1697fea9cb91Slq 		return;
1698fea9cb91Slq 
1699fea9cb91Slq 	if (s_row > e_row || s_col > e_col)
1700fea9cb91Slq 		return;
1701fea9cb91Slq 
1702fea9cb91Slq 	rows = e_row - s_row + 1;
1703fea9cb91Slq 	cols = e_col - s_col + 1;
1704aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (t_row + rows > tems.ts_c_dimension.height ||
1705aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col + cols > tems.ts_c_dimension.width)
1706aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1707aecfc01dSrui zang - Sun Microsystems - Beijing China 
1708f06e090aSToomas Soome 	soffset = s_col + s_row * tems.ts_c_dimension.width;
1709f06e090aSToomas Soome 	toffset = t_col + t_row * tems.ts_c_dimension.width;
1710f06e090aSToomas Soome 	src = tem->tvs_screen_buf + soffset;
1711f06e090aSToomas Soome 	dst = tem->tvs_screen_buf + toffset;
1712aecfc01dSrui zang - Sun Microsystems - Beijing China 
1713f06e090aSToomas Soome 	/*
1714f06e090aSToomas Soome 	 * Copy line by line. We determine the length by comparing the
1715f06e090aSToomas Soome 	 * screen content from cached text in tvs_screen_buf.
1716f06e090aSToomas Soome 	 */
1717f06e090aSToomas Soome 	if (toffset <= soffset) {
1718f06e090aSToomas Soome 		for (int i = 0; i < rows; i++) {
1719f06e090aSToomas Soome 			int increment = i * tems.ts_c_dimension.width;
1720f06e090aSToomas Soome 			int width;
1721f06e090aSToomas Soome 
1722f06e090aSToomas Soome 			width = tem_copy_width(src + increment,
1723f06e090aSToomas Soome 			    dst + increment, cols);
1724f06e090aSToomas Soome 
1725f06e090aSToomas Soome 			tem_safe_virtual_copy(tem, s_col, s_row + i,
1726f06e090aSToomas Soome 			    e_col  - cols + width, s_row + i,
1727f06e090aSToomas Soome 			    t_col, t_row + i);
1728f06e090aSToomas Soome 
1729f06e090aSToomas Soome 			if (tem->tvs_isactive) {
1730f06e090aSToomas Soome 				tem_safe_callback_copy(tem, s_col, s_row + i,
1731f06e090aSToomas Soome 				    e_col - cols + width, s_row + i,
1732f06e090aSToomas Soome 				    t_col, t_row + i, credp, called_from);
1733f06e090aSToomas Soome 			}
1734f06e090aSToomas Soome 		}
1735f06e090aSToomas Soome 	} else {
1736f06e090aSToomas Soome 		for (int i = rows - 1; i >= 0; i--) {
1737f06e090aSToomas Soome 			int increment = i * tems.ts_c_dimension.width;
1738f06e090aSToomas Soome 			int width;
1739fea9cb91Slq 
1740f06e090aSToomas Soome 			width = tem_copy_width(src + increment,
1741f06e090aSToomas Soome 			    dst + increment, cols);
1742f06e090aSToomas Soome 
1743f06e090aSToomas Soome 			tem_safe_virtual_copy(tem, s_col, s_row + i,
1744f06e090aSToomas Soome 			    e_col  - cols + width, s_row + i,
1745f06e090aSToomas Soome 			    t_col, t_row + i);
1746f06e090aSToomas Soome 
1747f06e090aSToomas Soome 			if (tem->tvs_isactive) {
1748f06e090aSToomas Soome 				tem_safe_callback_copy(tem, s_col, s_row + i,
1749f06e090aSToomas Soome 				    e_col - cols + width, s_row + i,
1750f06e090aSToomas Soome 				    t_col, t_row + i, credp, called_from);
1751f06e090aSToomas Soome 			}
1752f06e090aSToomas Soome 		}
1753f06e090aSToomas Soome 	}
1754fea9cb91Slq }
1755fea9cb91Slq 
1756fea9cb91Slq static void
tem_safe_clear_chars(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1757aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_clear_chars(struct tem_vt_state *tem, int count, screen_pos_t row,
1758b6bd4f48SToomas Soome     screen_pos_t col, cred_t *credp, enum called_from called_from)
1759fea9cb91Slq {
1760aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1761aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1762fea9cb91Slq 
1763aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row < 0 || row >= tems.ts_c_dimension.height ||
1764aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col < 0 || col >= tems.ts_c_dimension.width ||
1765fea9cb91Slq 	    count < 0)
1766fea9cb91Slq 		return;
1767fea9cb91Slq 
1768fea9cb91Slq 	/*
1769fea9cb91Slq 	 * Note that very large values of "count" could cause col+count
1770fea9cb91Slq 	 * to overflow, so we check "count" independently.
1771fea9cb91Slq 	 */
1772aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (count > tems.ts_c_dimension.width ||
1773aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col + count > tems.ts_c_dimension.width)
1774aecfc01dSrui zang - Sun Microsystems - Beijing China 		count = tems.ts_c_dimension.width - col;
1775fea9cb91Slq 
1776aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_virtual_cls(tem, count, row, col);
1777aecfc01dSrui zang - Sun Microsystems - Beijing China 
1778aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_isactive)
1779aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1780aecfc01dSrui zang - Sun Microsystems - Beijing China 
1781aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_cls(tem, count, row, col, credp, called_from);
1782fea9cb91Slq }
1783fea9cb91Slq 
1784aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
1785fea9cb91Slq void
tem_safe_text_display(struct tem_vt_state * tem,term_char_t * string,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1786cbc8e155SToomas Soome tem_safe_text_display(struct tem_vt_state *tem, term_char_t *string,
1787b6bd4f48SToomas Soome     int count, screen_pos_t row, screen_pos_t col,
1788b6bd4f48SToomas Soome     cred_t *credp, enum called_from called_from)
1789fea9cb91Slq {
1790fea9cb91Slq 	struct vis_consdisplay da;
17910e3b7565SToomas Soome 	int i;
1792cbc8e155SToomas Soome 	tem_char_t c;
1793fa9eb222SToomas Soome 	text_color_t bg, fg;
1794fea9cb91Slq 
1795aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1796aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1797aecfc01dSrui zang - Sun Microsystems - Beijing China 
1798cbc8e155SToomas Soome 	da.data = (uint8_t *)&c;
17990e3b7565SToomas Soome 	da.width = 1;
1800fea9cb91Slq 	da.row = row;
1801fea9cb91Slq 	da.col = col;
1802fea9cb91Slq 
18030e3b7565SToomas Soome 	for (i = 0; i < count; i++) {
1804fa9eb222SToomas Soome 		tem_safe_get_color(tem, &fg, &bg, &string[i]);
1805fa9eb222SToomas Soome 		tem_safe_set_color(&fg, &da.fg_color);
1806fa9eb222SToomas Soome 		tem_safe_set_color(&bg, &da.bg_color);
1807cbc8e155SToomas Soome 		c = TEM_CHAR(string[i].tc_char);
18080e3b7565SToomas Soome 		tems_safe_display(&da, credp, called_from);
18090e3b7565SToomas Soome 		da.col++;
18100e3b7565SToomas Soome 	}
1811fea9cb91Slq }
1812fea9cb91Slq 
1813e0721d5aSToomas Soome #if 0
1814fea9cb91Slq /*
1815fea9cb91Slq  * This function is used to blit a rectangular color image,
1816fea9cb91Slq  * unperturbed on the underlying framebuffer, to render
1817fea9cb91Slq  * icons and pictures.  The data is a pixel pattern that
1818fea9cb91Slq  * fills a rectangle bounded to the width and height parameters.
1819fea9cb91Slq  * The color pixel data must to be pre-adjusted by the caller
1820fea9cb91Slq  * for the current video depth.
1821fea9cb91Slq  *
1822fea9cb91Slq  * This function is unused now.
1823fea9cb91Slq  */
1824aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
1825aecfc01dSrui zang - Sun Microsystems - Beijing China static void
1826aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_image_display(struct tem_vt_state *tem, uchar_t *image,
1827b6bd4f48SToomas Soome     int height, int width, screen_pos_t row, screen_pos_t col,
1828b6bd4f48SToomas Soome     cred_t *credp, enum called_from called_from)
1829fea9cb91Slq {
1830fea9cb91Slq 	struct vis_consdisplay da;
1831fea9cb91Slq 
1832aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&tems.ts_lock);
1833aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&tem->tvs_lock);
1834aecfc01dSrui zang - Sun Microsystems - Beijing China 
1835fea9cb91Slq 	da.data = image;
1836aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.width = (screen_size_t)width;
1837aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.height = (screen_size_t)height;
1838fea9cb91Slq 	da.row = row;
1839fea9cb91Slq 	da.col = col;
1840fea9cb91Slq 
1841aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_display(&da, credp, called_from);
1842aecfc01dSrui zang - Sun Microsystems - Beijing China 
1843aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&tem->tvs_lock);
1844aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&tems.ts_lock);
1845fea9cb91Slq }
1846e0721d5aSToomas Soome #endif
1847fea9cb91Slq 
1848aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
1849fea9cb91Slq void
tem_safe_text_copy(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row,cred_t * credp,enum called_from called_from)1850aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_copy(struct tem_vt_state *tem,
1851b6bd4f48SToomas Soome     screen_pos_t s_col, screen_pos_t s_row,
1852b6bd4f48SToomas Soome     screen_pos_t e_col, screen_pos_t e_row,
1853b6bd4f48SToomas Soome     screen_pos_t t_col, screen_pos_t t_row,
1854b6bd4f48SToomas Soome     cred_t *credp, enum called_from called_from)
1855fea9cb91Slq {
1856fea9cb91Slq 	struct vis_conscopy da;
1857fea9cb91Slq 
1858aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1859aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1860aecfc01dSrui zang - Sun Microsystems - Beijing China 
1861fea9cb91Slq 	da.s_row = s_row;
1862fea9cb91Slq 	da.s_col = s_col;
1863fea9cb91Slq 	da.e_row = e_row;
1864fea9cb91Slq 	da.e_col = e_col;
1865fea9cb91Slq 	da.t_row = t_row;
1866fea9cb91Slq 	da.t_col = t_col;
1867fea9cb91Slq 
1868aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_copy(&da, credp, called_from);
1869fea9cb91Slq }
1870fea9cb91Slq 
1871fea9cb91Slq void
tem_safe_text_cls(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1872aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_cls(struct tem_vt_state *tem,
1873b6bd4f48SToomas Soome     int count, screen_pos_t row, screen_pos_t col, cred_t *credp,
1874b6bd4f48SToomas Soome     enum called_from called_from)
1875fea9cb91Slq {
1876cbc8e155SToomas Soome 	text_attr_t attr;
1877cbc8e155SToomas Soome 	term_char_t c;
1878cbc8e155SToomas Soome 	int i;
1879fea9cb91Slq 
1880aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1881aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1882aecfc01dSrui zang - Sun Microsystems - Beijing China 
1883cbc8e155SToomas Soome 	tem_safe_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
1884aecfc01dSrui zang - Sun Microsystems - Beijing China 	    TEM_ATTR_SCREEN_REVERSE);
1885cbc8e155SToomas Soome 	c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' ';
1886cbc8e155SToomas Soome 
1887cbc8e155SToomas Soome 	if (count > tems.ts_c_dimension.width ||
1888cbc8e155SToomas Soome 	    col + count > tems.ts_c_dimension.width)
1889cbc8e155SToomas Soome 		count = tems.ts_c_dimension.width - col;
1890cbc8e155SToomas Soome 
1891cbc8e155SToomas Soome 	for (i = 0; i < count; i++)
1892cbc8e155SToomas Soome 		tems.ts_blank_line[i] = c;
1893cbc8e155SToomas Soome 
1894cbc8e155SToomas Soome 	tem_safe_text_display(tem, tems.ts_blank_line, count, row, col,
1895cbc8e155SToomas Soome 	    credp, called_from);
1896fea9cb91Slq }
1897fea9cb91Slq 
1898fea9cb91Slq void
tem_safe_pix_display(struct tem_vt_state * tem,term_char_t * string,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1899aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_display(struct tem_vt_state *tem,
1900cbc8e155SToomas Soome     term_char_t *string, int count,
1901b6bd4f48SToomas Soome     screen_pos_t row, screen_pos_t col,
1902b6bd4f48SToomas Soome     cred_t *credp, enum called_from called_from)
1903fea9cb91Slq {
1904fea9cb91Slq 	struct vis_consdisplay da;
1905fea9cb91Slq 	int	i;
1906aecfc01dSrui zang - Sun Microsystems - Beijing China 
1907aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1908aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1909aecfc01dSrui zang - Sun Microsystems - Beijing China 
1910aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.data = (uchar_t *)tem->tvs_pix_data;
1911cbc8e155SToomas Soome 	da.width = (screen_size_t)tems.ts_font.vf_width;
1912cbc8e155SToomas Soome 	da.height = (screen_size_t)tems.ts_font.vf_height;
1913aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.row = (row * da.height) + tems.ts_p_offset.y;
1914aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.col = (col * da.width) + tems.ts_p_offset.x;
1915fea9cb91Slq 
1916fea9cb91Slq 	for (i = 0; i < count; i++) {
19172e5d9c98SToomas Soome 		/* Do not display image area */
19182e5d9c98SToomas Soome 		if (!TEM_ATTR_ISSET(string[i].tc_char, TEM_ATTR_IMAGE)) {
1919fa9eb222SToomas Soome 			tem_safe_callback_bit2pix(tem, &string[i]);
19202e5d9c98SToomas Soome 			tems_safe_display(&da, credp, called_from);
19212e5d9c98SToomas Soome 		}
1922fea9cb91Slq 		da.col += da.width;
1923fea9cb91Slq 	}
1924fea9cb91Slq }
1925fea9cb91Slq 
1926fea9cb91Slq void
tem_safe_pix_copy(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row,cred_t * credp,enum called_from called_from)1927aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_copy(struct tem_vt_state *tem,
1928b6bd4f48SToomas Soome     screen_pos_t s_col, screen_pos_t s_row,
1929b6bd4f48SToomas Soome     screen_pos_t e_col, screen_pos_t e_row,
1930b6bd4f48SToomas Soome     screen_pos_t t_col, screen_pos_t t_row,
1931b6bd4f48SToomas Soome     cred_t *credp,
1932b6bd4f48SToomas Soome     enum called_from called_from)
1933fea9cb91Slq {
1934fea9cb91Slq 	struct vis_conscopy ma;
1935fea9cb91Slq 	static boolean_t need_clear = B_TRUE;
1936fea9cb91Slq 
1937aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1938aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1939fea9cb91Slq 
1940aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (need_clear && tem->tvs_first_line > 0) {
1941fea9cb91Slq 		/*
1942fea9cb91Slq 		 * Clear OBP output above our kernel console term
1943fea9cb91Slq 		 * when our kernel console term begins to scroll up,
1944fea9cb91Slq 		 * we hope it is user friendly.
1945aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * (Also see comments on tem_safe_pix_clear_prom_output)
1946fea9cb91Slq 		 *
1947fea9cb91Slq 		 * This is only one time call.
1948fea9cb91Slq 		 */
1949aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_pix_clear_prom_output(tem, credp, called_from);
1950fea9cb91Slq 	}
1951fea9cb91Slq 	need_clear = B_FALSE;
1952fea9cb91Slq 
1953cbc8e155SToomas Soome 	ma.s_row = s_row * tems.ts_font.vf_height + tems.ts_p_offset.y;
1954cbc8e155SToomas Soome 	ma.e_row = (e_row + 1) * tems.ts_font.vf_height +
1955cbc8e155SToomas Soome 	    tems.ts_p_offset.y - 1;
1956cbc8e155SToomas Soome 	ma.t_row = t_row * tems.ts_font.vf_height + tems.ts_p_offset.y;
1957fea9cb91Slq 
1958fea9cb91Slq 	/*
1959fea9cb91Slq 	 * Check if we're in process of clearing OBP's columns area,
1960fea9cb91Slq 	 * which only happens when term scrolls up a whole line.
1961fea9cb91Slq 	 */
1962aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_first_line > 0 && t_row < s_row && t_col == 0 &&
1963aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col == tems.ts_c_dimension.width - 1) {
1964fea9cb91Slq 		/*
1965fea9cb91Slq 		 * We need to clear OBP's columns area outside our kernel
1966fea9cb91Slq 		 * console term. So that we set ma.e_col to entire row here.
1967fea9cb91Slq 		 */
1968cbc8e155SToomas Soome 		ma.s_col = s_col * tems.ts_font.vf_width;
1969aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.e_col = tems.ts_p_dimension.width - 1;
1970fea9cb91Slq 
1971cbc8e155SToomas Soome 		ma.t_col = t_col * tems.ts_font.vf_width;
1972fea9cb91Slq 	} else {
1973cbc8e155SToomas Soome 		ma.s_col = s_col * tems.ts_font.vf_width + tems.ts_p_offset.x;
1974cbc8e155SToomas Soome 		ma.e_col = (e_col + 1) * tems.ts_font.vf_width +
1975aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_p_offset.x - 1;
1976cbc8e155SToomas Soome 		ma.t_col = t_col * tems.ts_font.vf_width + tems.ts_p_offset.x;
1977fea9cb91Slq 	}
1978fea9cb91Slq 
1979aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_copy(&ma, credp, called_from);
1980fea9cb91Slq 
1981aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_first_line > 0 && t_row < s_row) {
1982fea9cb91Slq 		/* We have scrolled up (s_row - t_row) rows. */
1983aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_first_line -= (s_row - t_row);
1984aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_first_line <= 0) {
1985fea9cb91Slq 			/* All OBP rows have been cleared. */
1986aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_first_line = 0;
1987fea9cb91Slq 		}
1988fea9cb91Slq 	}
1989fea9cb91Slq 
1990fea9cb91Slq }
1991fea9cb91Slq 
1992aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_safe_pix_bit2pix(struct tem_vt_state * tem,term_char_t * c)1993fa9eb222SToomas Soome tem_safe_pix_bit2pix(struct tem_vt_state *tem, term_char_t *c)
1994aecfc01dSrui zang - Sun Microsystems - Beijing China {
1995cbc8e155SToomas Soome 	text_color_t fg, bg;
19960e3b7565SToomas Soome 	void (*fp)(struct tem_vt_state *, tem_char_t,
1997fa9eb222SToomas Soome 	    text_color_t, text_color_t);
1998aecfc01dSrui zang - Sun Microsystems - Beijing China 
1999fa9eb222SToomas Soome 	tem_safe_get_color(tem, &fg, &bg, c);
2000aecfc01dSrui zang - Sun Microsystems - Beijing China 	switch (tems.ts_pdepth) {
2001aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 4:
2002aecfc01dSrui zang - Sun Microsystems - Beijing China 		fp = bit_to_pix4;
2003aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
2004aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 8:
2005aecfc01dSrui zang - Sun Microsystems - Beijing China 		fp = bit_to_pix8;
2006aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
20075a801801SToomas Soome 	case 15:
20085a801801SToomas Soome 	case 16:
20095a801801SToomas Soome 		fp = bit_to_pix16;
20105a801801SToomas Soome 		break;
2011aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 24:
2012aecfc01dSrui zang - Sun Microsystems - Beijing China 		fp = bit_to_pix24;
20133e90f8d3SToomas Soome 		break;
20143e90f8d3SToomas Soome 	case 32:
20153e90f8d3SToomas Soome 		fp = bit_to_pix32;
20163e90f8d3SToomas Soome 		break;
20173e90f8d3SToomas Soome 	default:
20183e90f8d3SToomas Soome 		return;
2019aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2020aecfc01dSrui zang - Sun Microsystems - Beijing China 
2021fa9eb222SToomas Soome 	fp(tem, c->tc_char, fg, bg);
2022aecfc01dSrui zang - Sun Microsystems - Beijing China }
2023aecfc01dSrui zang - Sun Microsystems - Beijing China 
2024aecfc01dSrui zang - Sun Microsystems - Beijing China 
2025fea9cb91Slq /*
2026fea9cb91Slq  * This function only clears count of columns in one row
2027fea9cb91Slq  */
2028fea9cb91Slq void
tem_safe_pix_cls(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)2029aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cls(struct tem_vt_state *tem, int count,
2030b6bd4f48SToomas Soome     screen_pos_t row, screen_pos_t col, cred_t *credp,
2031b6bd4f48SToomas Soome     enum called_from called_from)
2032fea9cb91Slq {
2033aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2034aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2035fea9cb91Slq 
2036aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_pix_cls_range(tem, row, 1, tems.ts_p_offset.y,
2037aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col, count, tems.ts_p_offset.x, B_FALSE, credp, called_from);
2038fea9cb91Slq }
2039fea9cb91Slq 
2040fea9cb91Slq /*
2041fea9cb91Slq  * This function clears OBP output above our kernel console term area
2042fea9cb91Slq  * because OBP's term may have a bigger terminal window than that of
2043fea9cb91Slq  * our kernel console term. So we need to clear OBP output garbage outside
2044fea9cb91Slq  * of our kernel console term at a proper time, which is when the first
2045fea9cb91Slq  * row output of our kernel console term scrolls at the first screen line.
2046fea9cb91Slq  *
2047fea9cb91Slq  *	_________________________________
2048fea9cb91Slq  *	|   _____________________	|  ---> OBP's bigger term window
2049fea9cb91Slq  *	|   |			|	|
2050fea9cb91Slq  *	|___|			|	|
2051fea9cb91Slq  *	| | |			|	|
2052fea9cb91Slq  *	| | |			|	|
2053fea9cb91Slq  *	|_|_|___________________|_______|
2054fea9cb91Slq  *	  | |			|	   ---> first line
2055fea9cb91Slq  *	  | |___________________|---> our kernel console term window
2056fea9cb91Slq  *	  |
2057fea9cb91Slq  *	  |---> columns area to be cleared
2058fea9cb91Slq  *
2059fea9cb91Slq  * This function only takes care of the output above our kernel console term,
2060fea9cb91Slq  * and tem_prom_scroll_up takes care of columns area outside of our kernel
2061fea9cb91Slq  * console term.
2062fea9cb91Slq  */
2063fea9cb91Slq static void
tem_safe_pix_clear_prom_output(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2064aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_clear_prom_output(struct tem_vt_state *tem, cred_t *credp,
2065fea9cb91Slq     enum called_from called_from)
2066fea9cb91Slq {
206784a8796cSToomas Soome 	int	nrows, ncols, width, height, offset;
2068fea9cb91Slq 
2069aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2070aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2071fea9cb91Slq 
2072cbc8e155SToomas Soome 	width = tems.ts_font.vf_width;
2073cbc8e155SToomas Soome 	height = tems.ts_font.vf_height;
207484a8796cSToomas Soome 	offset = tems.ts_p_offset.y % height;
2075fea9cb91Slq 
207684a8796cSToomas Soome 	nrows = tems.ts_p_offset.y / height;
2077aecfc01dSrui zang - Sun Microsystems - Beijing China 	ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
2078fea9cb91Slq 
207984a8796cSToomas Soome 	if (nrows > 0)
208084a8796cSToomas Soome 		tem_safe_pix_cls_range(tem, 0, nrows, offset, 0, ncols, 0,
208184a8796cSToomas Soome 		    B_FALSE, credp, called_from);
2082fea9cb91Slq }
2083fea9cb91Slq 
2084fea9cb91Slq /*
2085aecfc01dSrui zang - Sun Microsystems - Beijing China  * clear the whole screen for pixel mode, just clear the
2086aecfc01dSrui zang - Sun Microsystems - Beijing China  * physical screen.
2087fea9cb91Slq  */
2088aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_safe_pix_clear_entire_screen(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2089aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_clear_entire_screen(struct tem_vt_state *tem, cred_t *credp,
2090fea9cb91Slq     enum called_from called_from)
2091fea9cb91Slq {
20925a801801SToomas Soome 	struct vis_consclear cl;
20935a801801SToomas Soome 	text_color_t fg_color;
20945a801801SToomas Soome 	text_color_t bg_color;
2095cbc8e155SToomas Soome 	text_attr_t attr;
2096cbc8e155SToomas Soome 	term_char_t c;
2097cbc8e155SToomas Soome 	int nrows, ncols, width, height;
2098fea9cb91Slq 
2099aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2100aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2101fea9cb91Slq 
21025a801801SToomas Soome 	/* call driver first, if error, clear terminal area */
2103cbc8e155SToomas Soome 	tem_safe_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
2104cbc8e155SToomas Soome 	    TEM_ATTR_SCREEN_REVERSE);
2105cbc8e155SToomas Soome 	c.tc_char = TEM_ATTR(attr);
2106cbc8e155SToomas Soome 
2107fa9eb222SToomas Soome 	tem_safe_get_color(tem, &fg_color, &bg_color, &c);
2108fa9eb222SToomas Soome 	tem_safe_set_color(&bg_color, &cl.bg_color);
21095a801801SToomas Soome 	if (tems_cls_layered(&cl, credp) == 0)
21105a801801SToomas Soome 		return;
21115a801801SToomas Soome 
2112cbc8e155SToomas Soome 	width = tems.ts_font.vf_width;
2113cbc8e155SToomas Soome 	height = tems.ts_font.vf_height;
2114fea9cb91Slq 
2115aecfc01dSrui zang - Sun Microsystems - Beijing China 	nrows = (tems.ts_p_dimension.height + (height - 1))/ height;
2116aecfc01dSrui zang - Sun Microsystems - Beijing China 	ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
2117fea9cb91Slq 
2118a27563ebSToomas Soome 	tem_safe_pix_cls_range(tem, 0, nrows, tems.ts_p_offset.y, 0, ncols,
2119a27563ebSToomas Soome 	    tems.ts_p_offset.x, B_FALSE, credp, called_from);
2120fea9cb91Slq 
2121fea9cb91Slq 	/*
2122fea9cb91Slq 	 * Since the whole screen is cleared, we don't need
2123fea9cb91Slq 	 * to clear OBP output later.
2124fea9cb91Slq 	 */
2125aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_first_line > 0)
2126aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_first_line = 0;
2127fea9cb91Slq }
2128fea9cb91Slq 
2129fea9cb91Slq /*
2130aecfc01dSrui zang - Sun Microsystems - Beijing China  * clear the whole screen, including the virtual screen buffer,
2131aecfc01dSrui zang - Sun Microsystems - Beijing China  * and reset the cursor to start point.
2132fea9cb91Slq  */
2133fea9cb91Slq static void
tem_safe_cls(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2134aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_cls(struct tem_vt_state *tem,
2135fea9cb91Slq     cred_t *credp, enum called_from called_from)
2136fea9cb91Slq {
2137fea9cb91Slq 	int	row;
2138fea9cb91Slq 
2139aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2140aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2141fea9cb91Slq 
2142aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_TEXT) {
2143aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (row = 0; row < tems.ts_c_dimension.height; row++) {
2144aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
2145c35aa225Smarx 			    row, 0, credp, called_from);
2146fea9cb91Slq 		}
2147aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.row = 0;
2148aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.col = 0;
2149aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_align_cursor(tem);
2150fea9cb91Slq 		return;
2151fea9cb91Slq 	}
2152fea9cb91Slq 
2153aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(tems.ts_display_mode == VIS_PIXEL);
2154aecfc01dSrui zang - Sun Microsystems - Beijing China 
2155aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_c_dimension.height; row++) {
2156aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_virtual_cls(tem, tems.ts_c_dimension.width, row, 0);
2157aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2158aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.row = 0;
2159aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = 0;
2160aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
2161aecfc01dSrui zang - Sun Microsystems - Beijing China 
2162aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_isactive)
2163aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2164fea9cb91Slq 
2165aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2166fea9cb91Slq }
2167fea9cb91Slq 
2168fea9cb91Slq static void
tem_safe_back_tab(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2169aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_back_tab(struct tem_vt_state *tem,
2170fea9cb91Slq     cred_t *credp, enum called_from called_from)
2171fea9cb91Slq {
2172fea9cb91Slq 	int	i;
2173fea9cb91Slq 	screen_pos_t	tabstop;
2174fea9cb91Slq 
2175aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2176aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2177fea9cb91Slq 
2178fea9cb91Slq 	tabstop = 0;
2179fea9cb91Slq 
2180aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = tem->tvs_ntabs - 1; i >= 0; i--) {
2181aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] < tem->tvs_c_cursor.col) {
2182aecfc01dSrui zang - Sun Microsystems - Beijing China 			tabstop = tem->tvs_tabs[i];
2183fea9cb91Slq 			break;
2184fea9cb91Slq 		}
2185fea9cb91Slq 	}
2186fea9cb91Slq 
2187aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_mv_cursor(tem, tem->tvs_c_cursor.row,
2188c35aa225Smarx 	    tabstop, credp, called_from);
2189fea9cb91Slq }
2190fea9cb91Slq 
2191fea9cb91Slq static void
tem_safe_tab(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2192aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_tab(struct tem_vt_state *tem,
2193fea9cb91Slq     cred_t *credp, enum called_from called_from)
2194fea9cb91Slq {
2195835b861bSToomas Soome 	size_t	i;
2196fea9cb91Slq 	screen_pos_t	tabstop;
2197fea9cb91Slq 
2198aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2199aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2200fea9cb91Slq 
2201aecfc01dSrui zang - Sun Microsystems - Beijing China 	tabstop = tems.ts_c_dimension.width - 1;
2202fea9cb91Slq 
2203aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = 0; i < tem->tvs_ntabs; i++) {
2204aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) {
2205aecfc01dSrui zang - Sun Microsystems - Beijing China 			tabstop = tem->tvs_tabs[i];
2206fea9cb91Slq 			break;
2207fea9cb91Slq 		}
2208fea9cb91Slq 	}
2209fea9cb91Slq 
2210aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_mv_cursor(tem, tem->tvs_c_cursor.row,
2211fea9cb91Slq 	    tabstop, credp, called_from);
2212fea9cb91Slq }
2213fea9cb91Slq 
2214fea9cb91Slq static void
tem_safe_set_tab(struct tem_vt_state * tem)2215aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_set_tab(struct tem_vt_state *tem)
2216fea9cb91Slq {
2217835b861bSToomas Soome 	size_t	i, j;
2218fea9cb91Slq 
2219835b861bSToomas Soome 	if (tem->tvs_ntabs == tem->tvs_maxtab)
2220c35aa225Smarx 		return;
2221aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_ntabs == 0 ||
2222aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tem->tvs_tabs[tem->tvs_ntabs] < tem->tvs_c_cursor.col) {
2223aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_tabs[tem->tvs_ntabs++] = tem->tvs_c_cursor.col;
2224aecfc01dSrui zang - Sun Microsystems - Beijing China 			return;
2225fea9cb91Slq 	}
2226aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = 0; i < tem->tvs_ntabs; i++) {
2227aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col)
2228fea9cb91Slq 			return;
2229aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) {
2230aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (j = tem->tvs_ntabs - 1; j >= i; j--)
2231aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_tabs[j+ 1] = tem->tvs_tabs[j];
2232aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_tabs[i] = tem->tvs_c_cursor.col;
2233aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_ntabs++;
2234fea9cb91Slq 			return;
2235fea9cb91Slq 		}
2236fea9cb91Slq 	}
2237fea9cb91Slq }
2238fea9cb91Slq 
2239fea9cb91Slq static void
tem_safe_clear_tabs(struct tem_vt_state * tem,int action)2240aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_clear_tabs(struct tem_vt_state *tem, int action)
2241fea9cb91Slq {
2242835b861bSToomas Soome 	size_t	i, j;
2243fea9cb91Slq 
2244fea9cb91Slq 	switch (action) {
2245fea9cb91Slq 	case 3: /* clear all tabs */
2246aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_ntabs = 0;
2247fea9cb91Slq 		break;
2248fea9cb91Slq 	case 0: /* clr tab at cursor */
2249fea9cb91Slq 
2250aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (i = 0; i < tem->tvs_ntabs; i++) {
2251aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col) {
2252aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_ntabs--;
2253aecfc01dSrui zang - Sun Microsystems - Beijing China 				for (j = i; j < tem->tvs_ntabs; j++)
2254aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_tabs[j] = tem->tvs_tabs[j + 1];
2255fea9cb91Slq 				return;
2256fea9cb91Slq 			}
2257fea9cb91Slq 		}
2258fea9cb91Slq 		break;
2259fea9cb91Slq 	}
2260fea9cb91Slq }
2261fea9cb91Slq 
2262fea9cb91Slq static void
tem_safe_mv_cursor(struct tem_vt_state * tem,int row,int col,cred_t * credp,enum called_from called_from)2263aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_mv_cursor(struct tem_vt_state *tem, int row, int col,
2264fea9cb91Slq     cred_t *credp, enum called_from called_from)
2265fea9cb91Slq {
2266aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2267aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2268fea9cb91Slq 
2269fea9cb91Slq 	/*
2270fea9cb91Slq 	 * Sanity check and bounds enforcement.  Out of bounds requests are
2271fea9cb91Slq 	 * clipped to the screen boundaries.  This seems to be what SPARC
2272fea9cb91Slq 	 * does.
2273fea9cb91Slq 	 */
2274fea9cb91Slq 	if (row < 0)
2275fea9cb91Slq 		row = 0;
2276aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row >= tems.ts_c_dimension.height)
2277aecfc01dSrui zang - Sun Microsystems - Beijing China 		row = tems.ts_c_dimension.height - 1;
2278fea9cb91Slq 	if (col < 0)
2279fea9cb91Slq 		col = 0;
2280*d863b4c1SToomas Soome 	if (col >= tems.ts_c_dimension.width) {
2281*d863b4c1SToomas Soome 		tem->tvs_stateflags |= TVS_WRAPPED;
2282aecfc01dSrui zang - Sun Microsystems - Beijing China 		col = tems.ts_c_dimension.width - 1;
2283*d863b4c1SToomas Soome 	} else {
2284*d863b4c1SToomas Soome 		tem->tvs_stateflags &= ~TVS_WRAPPED;
2285*d863b4c1SToomas Soome 	}
2286fea9cb91Slq 
2287aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_send_data(tem, credp, called_from);
2288aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.row = (screen_pos_t)row;
2289aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = (screen_pos_t)col;
2290aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
2291fea9cb91Slq }
2292fea9cb91Slq 
2293fea9cb91Slq /* ARGSUSED */
2294fea9cb91Slq void
tem_safe_reset_emulator(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from,boolean_t init_color)2295aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_reset_emulator(struct tem_vt_state *tem,
2296c9503a49Slq     cred_t *credp, enum called_from called_from,
2297aecfc01dSrui zang - Sun Microsystems - Beijing China     boolean_t init_color)
2298fea9cb91Slq {
2299fea9cb91Slq 	int j;
2300fea9cb91Slq 
2301aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2302aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2303aecfc01dSrui zang - Sun Microsystems - Beijing China 
2304aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.row = 0;
2305aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = 0;
2306aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_r_cursor.row = 0;
2307aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_r_cursor.col = 0;
2308aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.row = 0;
2309aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.col = 0;
2310aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_outindex = 0;
2311aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
2312aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_gotparam = B_FALSE;
2313aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_curparam = 0;
2314aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_paramval = 0;
2315aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_nscroll = 1;
2316aecfc01dSrui zang - Sun Microsystems - Beijing China 
2317aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (init_color) {
2318fa9eb222SToomas Soome 		tem->tvs_alpha = 0xff;
2319aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_fg_color = tems.ts_init_color.fg_color;
2320aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_bg_color = tems.ts_init_color.bg_color;
2321aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_flags = tems.ts_init_color.a_flags;
2322c9503a49Slq 	}
2323fea9cb91Slq 
2324fea9cb91Slq 	/*
2325fea9cb91Slq 	 * set up the initial tab stops
2326fea9cb91Slq 	 */
2327aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_ntabs = 0;
2328aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (j = 8; j < tems.ts_c_dimension.width; j += 8)
2329aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_tabs[tem->tvs_ntabs++] = (screen_pos_t)j;
2330fea9cb91Slq 
2331fea9cb91Slq 	for (j = 0; j < TEM_MAXPARAMS; j++)
2332aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_params[j] = 0;
2333fea9cb91Slq }
2334fea9cb91Slq 
2335fea9cb91Slq void
tem_safe_reset_display(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from,boolean_t clear_txt,boolean_t init_color)2336aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_reset_display(struct tem_vt_state *tem,
2337aecfc01dSrui zang - Sun Microsystems - Beijing China     cred_t *credp, enum called_from called_from,
2338aecfc01dSrui zang - Sun Microsystems - Beijing China     boolean_t clear_txt, boolean_t init_color)
2339fea9cb91Slq {
2340aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2341aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2342fea9cb91Slq 
2343aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_reset_emulator(tem, credp, called_from, init_color);
2344fea9cb91Slq 
2345fea9cb91Slq 	if (clear_txt) {
2346aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_isactive)
2347aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_callback_cursor(tem,
2348aecfc01dSrui zang - Sun Microsystems - Beijing China 			    VIS_HIDE_CURSOR, credp, called_from);
2349fea9cb91Slq 
2350aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_cls(tem, credp, called_from);
2351fea9cb91Slq 
2352aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_isactive)
2353aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_callback_cursor(tem,
2354aecfc01dSrui zang - Sun Microsystems - Beijing China 			    VIS_DISPLAY_CURSOR, credp, called_from);
2355fea9cb91Slq 	}
2356fea9cb91Slq }
2357fea9cb91Slq 
2358fea9cb91Slq static void
tem_safe_shift(struct tem_vt_state * tem,int count,int direction,cred_t * credp,enum called_from called_from)2359aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_shift(
2360aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem,
2361fea9cb91Slq 	int count,
2362fea9cb91Slq 	int direction,
2363fea9cb91Slq 	cred_t *credp,
2364fea9cb91Slq 	enum called_from called_from)
2365fea9cb91Slq {
2366fea9cb91Slq 	int rest_of_line;
2367fea9cb91Slq 
2368aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2369aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2370fea9cb91Slq 
2371aecfc01dSrui zang - Sun Microsystems - Beijing China 	rest_of_line = tems.ts_c_dimension.width - tem->tvs_c_cursor.col;
2372fea9cb91Slq 	if (count > rest_of_line)
2373fea9cb91Slq 		count = rest_of_line;
2374fea9cb91Slq 
2375fea9cb91Slq 	if (count <= 0)
2376fea9cb91Slq 		return;
2377fea9cb91Slq 
2378fea9cb91Slq 	switch (direction) {
2379fea9cb91Slq 	case TEM_SHIFT_LEFT:
2380fea9cb91Slq 		if (count < rest_of_line) {
2381aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem,
2382aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + count,
2383aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
2384aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - 1,
2385aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
2386aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
2387aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
2388c35aa225Smarx 			    credp, called_from);
2389fea9cb91Slq 		}
2390fea9cb91Slq 
2391aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem, count, tem->tvs_c_cursor.row,
2392aecfc01dSrui zang - Sun Microsystems - Beijing China 		    (tems.ts_c_dimension.width - count), credp,
2393c35aa225Smarx 		    called_from);
2394fea9cb91Slq 		break;
2395fea9cb91Slq 	case TEM_SHIFT_RIGHT:
2396fea9cb91Slq 		if (count < rest_of_line) {
2397aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem,
2398aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
2399aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
2400aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - count - 1,
2401aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
2402aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + count,
2403aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
2404c35aa225Smarx 			    credp, called_from);
2405fea9cb91Slq 		}
2406fea9cb91Slq 
2407aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem, count, tem->tvs_c_cursor.row,
2408aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col, credp, called_from);
2409fea9cb91Slq 		break;
2410fea9cb91Slq 	}
2411fea9cb91Slq }
2412fea9cb91Slq 
2413fea9cb91Slq void
tem_safe_text_cursor(struct tem_vt_state * tem,short action,cred_t * credp,enum called_from called_from)2414aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_cursor(struct tem_vt_state *tem, short action,
2415fea9cb91Slq     cred_t *credp, enum called_from called_from)
2416fea9cb91Slq {
2417fea9cb91Slq 	struct vis_conscursor	ca;
2418fea9cb91Slq 
2419aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2420aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2421fea9cb91Slq 
2422aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.row = tem->tvs_c_cursor.row;
2423aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.col = tem->tvs_c_cursor.col;
2424fea9cb91Slq 	ca.action = action;
2425fea9cb91Slq 
2426aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_cursor(&ca, credp, called_from);
2427fea9cb91Slq 
2428fea9cb91Slq 	if (action == VIS_GET_CURSOR) {
2429aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.row = ca.row;
2430aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.col = ca.col;
2431fea9cb91Slq 	}
2432fea9cb91Slq }
2433fea9cb91Slq 
2434fea9cb91Slq void
tem_safe_pix_cursor(struct tem_vt_state * tem,short action,cred_t * credp,enum called_from called_from)2435aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cursor(struct tem_vt_state *tem, short action,
2436fea9cb91Slq     cred_t *credp, enum called_from called_from)
2437fea9cb91Slq {
2438fea9cb91Slq 	struct vis_conscursor	ca;
24395a801801SToomas Soome 	text_color_t fg, bg;
2440cbc8e155SToomas Soome 	term_char_t c;
2441cbc8e155SToomas Soome 	text_attr_t attr;
2442fea9cb91Slq 
2443aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2444aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2445aecfc01dSrui zang - Sun Microsystems - Beijing China 
2446cbc8e155SToomas Soome 	ca.row = tem->tvs_c_cursor.row * tems.ts_font.vf_height +
2447aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tems.ts_p_offset.y;
2448cbc8e155SToomas Soome 	ca.col = tem->tvs_c_cursor.col * tems.ts_font.vf_width +
2449aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tems.ts_p_offset.x;
2450cbc8e155SToomas Soome 	ca.width = (screen_size_t)tems.ts_font.vf_width;
2451cbc8e155SToomas Soome 	ca.height = (screen_size_t)tems.ts_font.vf_height;
24525a801801SToomas Soome 
2453cbc8e155SToomas Soome 	tem_safe_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
2454cbc8e155SToomas Soome 	    TEM_ATTR_REVERSE);
2455cbc8e155SToomas Soome 	c.tc_char = TEM_ATTR(attr);
2456cbc8e155SToomas Soome 
2457fa9eb222SToomas Soome 	tem_safe_get_color(tem, &fg, &bg, &c);
2458fa9eb222SToomas Soome 	tem_safe_set_color(&fg, &ca.fg_color);
2459fa9eb222SToomas Soome 	tem_safe_set_color(&bg, &ca.bg_color);
2460fea9cb91Slq 
2461fea9cb91Slq 	ca.action = action;
2462fea9cb91Slq 
2463aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_cursor(&ca, credp, called_from);
246440d76caaSToomas Soome 
246540d76caaSToomas Soome 	if (action == VIS_GET_CURSOR) {
2466cbc8e155SToomas Soome 		tem->tvs_c_cursor.row = 0;
2467cbc8e155SToomas Soome 		tem->tvs_c_cursor.col = 0;
2468cbc8e155SToomas Soome 
2469cbc8e155SToomas Soome 		if (ca.row != 0) {
2470cbc8e155SToomas Soome 			tem->tvs_c_cursor.row = (ca.row - tems.ts_p_offset.y) /
2471cbc8e155SToomas Soome 			    tems.ts_font.vf_height;
2472cbc8e155SToomas Soome 		}
2473cbc8e155SToomas Soome 		if (ca.col != 0) {
2474cbc8e155SToomas Soome 			tem->tvs_c_cursor.col = (ca.col - tems.ts_p_offset.x) /
2475cbc8e155SToomas Soome 			    tems.ts_font.vf_width;
2476cbc8e155SToomas Soome 		}
247740d76caaSToomas Soome 	}
2478fea9cb91Slq }
2479fea9cb91Slq 
2480aecfc01dSrui zang - Sun Microsystems - Beijing China static void
bit_to_pix4(struct tem_vt_state * tem,tem_char_t c,text_color_t fg,text_color_t bg)2481fa9eb222SToomas Soome bit_to_pix4(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
2482fa9eb222SToomas Soome     text_color_t bg)
2483fea9cb91Slq {
2484898c3fecSToomas Soome 	uint8_t *dest = (uint8_t *)tem->tvs_pix_data;
2485fa9eb222SToomas Soome 
2486fa9eb222SToomas Soome 	font_bit_to_pix4(&tems.ts_font, dest, c, fg.n, bg.n);
2487fea9cb91Slq }
2488fea9cb91Slq 
2489aecfc01dSrui zang - Sun Microsystems - Beijing China static void
bit_to_pix8(struct tem_vt_state * tem,tem_char_t c,text_color_t fg,text_color_t bg)2490fa9eb222SToomas Soome bit_to_pix8(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
2491fa9eb222SToomas Soome     text_color_t bg)
2492fea9cb91Slq {
2493898c3fecSToomas Soome 	uint8_t *dest = (uint8_t *)tem->tvs_pix_data;
24944deedc8cSToomas Soome 
2495fa9eb222SToomas Soome 	font_bit_to_pix8(&tems.ts_font, dest, c, fg.n, bg.n);
2496fea9cb91Slq }
2497fea9cb91Slq 
24985a801801SToomas Soome static void
bit_to_pix16(struct tem_vt_state * tem,tem_char_t c,text_color_t fg,text_color_t bg)2499fa9eb222SToomas Soome bit_to_pix16(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
2500fa9eb222SToomas Soome     text_color_t bg)
25015a801801SToomas Soome {
25025a801801SToomas Soome 	uint16_t *dest;
25035a801801SToomas Soome 
25045a801801SToomas Soome 	dest = (uint16_t *)tem->tvs_pix_data;
2505fa9eb222SToomas Soome 	font_bit_to_pix16(&tems.ts_font, dest, c, fg.n, bg.n);
25065a801801SToomas Soome }
25075a801801SToomas Soome 
2508aecfc01dSrui zang - Sun Microsystems - Beijing China static void
bit_to_pix24(struct tem_vt_state * tem,tem_char_t c,text_color_t fg,text_color_t bg)2509fa9eb222SToomas Soome bit_to_pix24(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
2510fa9eb222SToomas Soome     text_color_t bg)
25113e90f8d3SToomas Soome {
25123e90f8d3SToomas Soome 	uint8_t *dest;
25133e90f8d3SToomas Soome 
25143e90f8d3SToomas Soome 	dest = (uint8_t *)tem->tvs_pix_data;
2515fa9eb222SToomas Soome 	font_bit_to_pix24(&tems.ts_font, dest, c, fg.n, bg.n);
25163e90f8d3SToomas Soome }
25173e90f8d3SToomas Soome 
25183e90f8d3SToomas Soome static void
bit_to_pix32(struct tem_vt_state * tem,tem_char_t c,text_color_t fg,text_color_t bg)2519fa9eb222SToomas Soome bit_to_pix32(struct tem_vt_state *tem, tem_char_t c, text_color_t fg,
2520fa9eb222SToomas Soome     text_color_t bg)
2521fea9cb91Slq {
2522fa9eb222SToomas Soome 	uint32_t *dest;
2523fea9cb91Slq 
2524898c3fecSToomas Soome 	dest = (uint32_t *)tem->tvs_pix_data;
2525fa9eb222SToomas Soome 	font_bit_to_pix32(&tems.ts_font, dest, c, fg.n, bg.n);
2526fea9cb91Slq }
2527fea9cb91Slq 
2528aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2529aecfc01dSrui zang - Sun Microsystems - Beijing China  * flag: TEM_ATTR_SCREEN_REVERSE or TEM_ATTR_REVERSE
2530aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2531aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_safe_get_attr(struct tem_vt_state * tem,text_color_t * fg,text_color_t * bg,text_attr_t * attr,uint8_t flag)2532cbc8e155SToomas Soome tem_safe_get_attr(struct tem_vt_state *tem, text_color_t *fg,
2533cbc8e155SToomas Soome     text_color_t *bg, text_attr_t *attr, uint8_t flag)
2534fea9cb91Slq {
2535aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_flags & flag) {
2536cbc8e155SToomas Soome 		*fg = tem->tvs_bg_color;
2537cbc8e155SToomas Soome 		*bg = tem->tvs_fg_color;
2538fea9cb91Slq 	} else {
2539cbc8e155SToomas Soome 		*fg = tem->tvs_fg_color;
2540cbc8e155SToomas Soome 		*bg = tem->tvs_bg_color;
2541fea9cb91Slq 	}
2542cbc8e155SToomas Soome 
2543fa9eb222SToomas Soome 	if (attr != NULL)
2544fa9eb222SToomas Soome 		*attr = tem->tvs_flags;
2545cbc8e155SToomas Soome }
2546cbc8e155SToomas Soome 
2547cbc8e155SToomas Soome static void
tem_safe_get_color(struct tem_vt_state * tem,text_color_t * fg,text_color_t * bg,term_char_t * c)2548fa9eb222SToomas Soome tem_safe_get_color(struct tem_vt_state *tem, text_color_t *fg,
2549fa9eb222SToomas Soome     text_color_t *bg, term_char_t *c)
2550cbc8e155SToomas Soome {
2551e0721d5aSToomas Soome 	boolean_t bold_font;
2552e0721d5aSToomas Soome 
2553fa9eb222SToomas Soome 	*fg = c->tc_fg_color;
2554fa9eb222SToomas Soome 	*bg = c->tc_bg_color;
2555a4e6b9b6SToomas Soome 
2556e0721d5aSToomas Soome 	bold_font = tems.ts_font.vf_map_count[VFNT_MAP_BOLD] != 0;
2557e0721d5aSToomas Soome 
2558e0721d5aSToomas Soome 	/*
2559e0721d5aSToomas Soome 	 * If we have both normal and bold font components,
2560e0721d5aSToomas Soome 	 * we use bold font for TEM_ATTR_BOLD.
2561e0721d5aSToomas Soome 	 * The bright color is traditionally used with TEM_ATTR_BOLD,
2562e0721d5aSToomas Soome 	 * in case there is no bold font.
2563e0721d5aSToomas Soome 	 */
2564fa9eb222SToomas Soome 	if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG) &&
2565fa9eb222SToomas Soome 	    c->tc_fg_color.n < XLATE_NCOLORS) {
2566fa9eb222SToomas Soome 		if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_FG) ||
2567fa9eb222SToomas Soome 		    (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BOLD) && !bold_font))
2568fa9eb222SToomas Soome 			fg->n = brt_xlate[c->tc_fg_color.n];
2569a4e6b9b6SToomas Soome 		else
2570fa9eb222SToomas Soome 			fg->n = dim_xlate[c->tc_fg_color.n];
2571a4e6b9b6SToomas Soome 	}
2572cbc8e155SToomas Soome 
2573fa9eb222SToomas Soome 	if (!TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG) &&
2574fa9eb222SToomas Soome 	    c->tc_bg_color.n < XLATE_NCOLORS) {
2575fa9eb222SToomas Soome 		if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_BRIGHT_BG))
2576fa9eb222SToomas Soome 			bg->n = brt_xlate[c->tc_bg_color.n];
2577a4e6b9b6SToomas Soome 		else
2578fa9eb222SToomas Soome 			bg->n = dim_xlate[c->tc_bg_color.n];
2579fa9eb222SToomas Soome 	}
2580fa9eb222SToomas Soome 
2581fa9eb222SToomas Soome 	if (tems.ts_display_mode == VIS_TEXT)
2582fa9eb222SToomas Soome 		return;
2583fa9eb222SToomas Soome 
2584fa9eb222SToomas Soome 	if (tems.ts_pdepth == 8) {
2585fa9eb222SToomas Soome 		/* 8-bit depth is using indexed colors. */
2586fa9eb222SToomas Soome #ifndef	_HAVE_TEM_FIRMWARE
2587fa9eb222SToomas Soome 		fg->n = tems.ts_color_map(fg->n);
2588fa9eb222SToomas Soome 		bg->n = tems.ts_color_map(bg->n);
2589fa9eb222SToomas Soome #endif
2590fa9eb222SToomas Soome 		return;
2591fa9eb222SToomas Soome 	}
2592fa9eb222SToomas Soome 
2593fa9eb222SToomas Soome 	/*
2594fa9eb222SToomas Soome 	 * Translate fg and bg to RGB colors.
2595fa9eb222SToomas Soome 	 */
2596fa9eb222SToomas Soome 	if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_FG)) {
2597fa9eb222SToomas Soome 		fg->n = rgb_to_color(&rgb_info,
2598fa9eb222SToomas Soome 		    fg->rgb.a, fg->rgb.r, fg->rgb.g, fg->rgb.b);
2599fa9eb222SToomas Soome 	} else {
2600fa9eb222SToomas Soome #ifdef _HAVE_TEM_FIRMWARE
2601fa9eb222SToomas Soome 		if (tems.ts_pdepth == 24 || tems.ts_pdepth == 32)
2602fa9eb222SToomas Soome 			fg->n = PIX4TO32(fg->n);
2603fa9eb222SToomas Soome #else
2604fa9eb222SToomas Soome 		fg->n = rgb_color_map(&rgb_info, fg->n, tem->tvs_alpha);
2605fa9eb222SToomas Soome #endif
2606fa9eb222SToomas Soome 	}
2607fa9eb222SToomas Soome 
2608fa9eb222SToomas Soome 	if (TEM_ATTR_ISSET(c->tc_char, TEM_ATTR_RGB_BG)) {
2609fa9eb222SToomas Soome 		bg->n = rgb_to_color(&rgb_info,
2610fa9eb222SToomas Soome 		    bg->rgb.a, bg->rgb.r, bg->rgb.g, bg->rgb.b);
2611fa9eb222SToomas Soome 	} else {
2612fa9eb222SToomas Soome #ifdef _HAVE_TEM_FIRMWARE
2613fa9eb222SToomas Soome 		if (tems.ts_pdepth == 24 || tems.ts_pdepth == 32)
2614fa9eb222SToomas Soome 			bg->n = PIX4TO32(bg->n);
2615fa9eb222SToomas Soome #else
2616fa9eb222SToomas Soome 		bg->n = rgb_color_map(&rgb_info, bg->n, tem->tvs_alpha);
2617fa9eb222SToomas Soome #endif
2618fa9eb222SToomas Soome 	}
2619fa9eb222SToomas Soome }
2620fa9eb222SToomas Soome 
2621fa9eb222SToomas Soome static void
tem_safe_set_color(text_color_t * t,color_t * c)2622fa9eb222SToomas Soome tem_safe_set_color(text_color_t *t, color_t *c)
2623fa9eb222SToomas Soome {
2624fa9eb222SToomas Soome 	switch (tems.ts_pdepth) {
2625fa9eb222SToomas Soome 	case 4:
2626fa9eb222SToomas Soome 		c->four = t->n & 0xFF;
2627fa9eb222SToomas Soome 		break;
2628fa9eb222SToomas Soome 	case 8:
2629fa9eb222SToomas Soome 		c->eight = t->n & 0xFF;
2630fa9eb222SToomas Soome 		break;
2631fa9eb222SToomas Soome 	case 15:
2632fa9eb222SToomas Soome 	case 16:
2633fa9eb222SToomas Soome 		c->sixteen[0] = (t->n >> 8) & 0xFF;
2634fa9eb222SToomas Soome 		c->sixteen[1] = t->n & 0xFF;
2635fa9eb222SToomas Soome 		break;
2636fa9eb222SToomas Soome 	case 24:
2637fa9eb222SToomas Soome 		c->twentyfour[0] = (t->n >> 16) & 0xFF;
2638fa9eb222SToomas Soome 		c->twentyfour[1] = (t->n >> 8) & 0xFF;
2639fa9eb222SToomas Soome 		c->twentyfour[2] = t->n & 0xFF;
2640fa9eb222SToomas Soome 		break;
2641fa9eb222SToomas Soome 	default:
2642fa9eb222SToomas Soome 		*(uint32_t *)c = t->n;
2643fa9eb222SToomas Soome 		break;
2644a4e6b9b6SToomas Soome 	}
2645fea9cb91Slq }
2646fea9cb91Slq 
2647fea9cb91Slq /*
2648fea9cb91Slq  * Clear a rectangle of screen for pixel mode.
2649fea9cb91Slq  *
2650fea9cb91Slq  * arguments:
2651fea9cb91Slq  *    row:	start row#
2652fea9cb91Slq  *    nrows:	the number of rows to clear
2653fea9cb91Slq  *    offset_y:	the offset of height in pixels to begin clear
2654fea9cb91Slq  *    col:	start col#
2655fea9cb91Slq  *    ncols:	the number of cols to clear
2656fea9cb91Slq  *    offset_x:	the offset of width in pixels to begin clear
2657fea9cb91Slq  *    scroll_up: whether this function is called during sroll up,
2658fea9cb91Slq  *		 which is called only once.
2659fea9cb91Slq  */
2660fea9cb91Slq void
tem_safe_pix_cls_range(struct tem_vt_state * tem,screen_pos_t row,int nrows,int offset_y,screen_pos_t col,int ncols,int offset_x,boolean_t sroll_up,cred_t * credp,enum called_from called_from)2661aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cls_range(struct tem_vt_state *tem,
2662b6bd4f48SToomas Soome     screen_pos_t row, int nrows, int offset_y,
2663b6bd4f48SToomas Soome     screen_pos_t col, int ncols, int offset_x,
2664b6bd4f48SToomas Soome     boolean_t sroll_up, cred_t *credp,
2665b6bd4f48SToomas Soome     enum called_from called_from)
2666fea9cb91Slq {
2667fea9cb91Slq 	struct vis_consdisplay da;
2668fea9cb91Slq 	int	i, j;
2669fea9cb91Slq 	int	row_add = 0;
2670cbc8e155SToomas Soome 	term_char_t c;
2671cbc8e155SToomas Soome 	text_attr_t attr;
2672fea9cb91Slq 
2673aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2674aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2675fea9cb91Slq 
2676fea9cb91Slq 	if (sroll_up)
2677aecfc01dSrui zang - Sun Microsystems - Beijing China 		row_add = tems.ts_c_dimension.height - 1;
2678fea9cb91Slq 
2679cbc8e155SToomas Soome 	da.width = (screen_size_t)tems.ts_font.vf_width;
2680cbc8e155SToomas Soome 	da.height = (screen_size_t)tems.ts_font.vf_height;
2681fea9cb91Slq 
2682cbc8e155SToomas Soome 	tem_safe_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
2683cbc8e155SToomas Soome 	    TEM_ATTR_SCREEN_REVERSE);
2684cbc8e155SToomas Soome 	/* Make sure we will not draw underlines */
2685cbc8e155SToomas Soome 	c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' ';
2686fea9cb91Slq 
2687fa9eb222SToomas Soome 	tem_safe_callback_bit2pix(tem, &c);
2688aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.data = (uchar_t *)tem->tvs_pix_data;
2689fea9cb91Slq 
2690fea9cb91Slq 	for (i = 0; i < nrows; i++, row++) {
2691fea9cb91Slq 		da.row = (row + row_add) * da.height + offset_y;
2692fea9cb91Slq 		da.col = col * da.width + offset_x;
2693fea9cb91Slq 		for (j = 0; j < ncols; j++) {
2694aecfc01dSrui zang - Sun Microsystems - Beijing China 			tems_safe_display(&da, credp, called_from);
2695fea9cb91Slq 			da.col += da.width;
2696fea9cb91Slq 		}
2697fea9cb91Slq 	}
2698fea9cb91Slq }
2699aecfc01dSrui zang - Sun Microsystems - Beijing China 
2700aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2701aecfc01dSrui zang - Sun Microsystems - Beijing China  * virtual screen operations
2702aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2703aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_safe_virtual_display(struct tem_vt_state * tem,term_char_t * string,int count,screen_pos_t row,screen_pos_t col)2704cbc8e155SToomas Soome tem_safe_virtual_display(struct tem_vt_state *tem, term_char_t *string,
2705cbc8e155SToomas Soome     int count, screen_pos_t row, screen_pos_t col)
2706aecfc01dSrui zang - Sun Microsystems - Beijing China {
2707aecfc01dSrui zang - Sun Microsystems - Beijing China 	int i, width;
2708cbc8e155SToomas Soome 	term_char_t *addr;
2709aecfc01dSrui zang - Sun Microsystems - Beijing China 
2710aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row < 0 || row >= tems.ts_c_dimension.height ||
2711aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col < 0 || col >= tems.ts_c_dimension.width ||
2712aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col + count > tems.ts_c_dimension.width)
2713aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2714aecfc01dSrui zang - Sun Microsystems - Beijing China 
2715aecfc01dSrui zang - Sun Microsystems - Beijing China 	width = tems.ts_c_dimension.width;
2716cbc8e155SToomas Soome 	addr = tem->tvs_screen_buf + (row * width + col);
2717aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = 0; i < count; i++) {
2718aecfc01dSrui zang - Sun Microsystems - Beijing China 		*addr++ = string[i];
2719aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2720aecfc01dSrui zang - Sun Microsystems - Beijing China }
2721aecfc01dSrui zang - Sun Microsystems - Beijing China 
2722aecfc01dSrui zang - Sun Microsystems - Beijing China static void
i_virtual_copy_tem_chars(term_char_t * base,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row)2723cbc8e155SToomas Soome i_virtual_copy_tem_chars(term_char_t *base,
27240e3b7565SToomas Soome     screen_pos_t s_col, screen_pos_t s_row,
27250e3b7565SToomas Soome     screen_pos_t e_col, screen_pos_t e_row,
27260e3b7565SToomas Soome     screen_pos_t t_col, screen_pos_t t_row)
27270e3b7565SToomas Soome {
2728cbc8e155SToomas Soome 	term_char_t	*from;
2729cbc8e155SToomas Soome 	term_char_t	*to;
27300e3b7565SToomas Soome 	int		cnt;
27310e3b7565SToomas Soome 	screen_size_t chars_per_row;
2732cbc8e155SToomas Soome 	term_char_t	*to_row_start;
2733cbc8e155SToomas Soome 	term_char_t	*from_row_start;
2734aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t   rows_to_move;
2735aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		cols = tems.ts_c_dimension.width;
2736aecfc01dSrui zang - Sun Microsystems - Beijing China 
2737aecfc01dSrui zang - Sun Microsystems - Beijing China 	chars_per_row = e_col - s_col + 1;
2738aecfc01dSrui zang - Sun Microsystems - Beijing China 	rows_to_move = e_row - s_row + 1;
2739aecfc01dSrui zang - Sun Microsystems - Beijing China 
2740aecfc01dSrui zang - Sun Microsystems - Beijing China 	to_row_start = base + ((t_row * cols) + t_col);
2741aecfc01dSrui zang - Sun Microsystems - Beijing China 	from_row_start = base + ((s_row * cols) + s_col);
2742aecfc01dSrui zang - Sun Microsystems - Beijing China 
2743aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (to_row_start < from_row_start) {
2744aecfc01dSrui zang - Sun Microsystems - Beijing China 		while (rows_to_move-- > 0) {
2745aecfc01dSrui zang - Sun Microsystems - Beijing China 			to = to_row_start;
2746aecfc01dSrui zang - Sun Microsystems - Beijing China 			from = from_row_start;
2747aecfc01dSrui zang - Sun Microsystems - Beijing China 			to_row_start += cols;
2748aecfc01dSrui zang - Sun Microsystems - Beijing China 			from_row_start += cols;
2749aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (cnt = chars_per_row; cnt-- > 0; )
2750aecfc01dSrui zang - Sun Microsystems - Beijing China 				*to++ = *from++;
2751aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
2752aecfc01dSrui zang - Sun Microsystems - Beijing China 	} else {
2753aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
2754aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Offset to the end of the region and copy backwards.
2755aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
2756aecfc01dSrui zang - Sun Microsystems - Beijing China 		cnt = rows_to_move * cols + chars_per_row;
2757aecfc01dSrui zang - Sun Microsystems - Beijing China 		to_row_start += cnt;
2758aecfc01dSrui zang - Sun Microsystems - Beijing China 		from_row_start += cnt;
2759aecfc01dSrui zang - Sun Microsystems - Beijing China 
2760aecfc01dSrui zang - Sun Microsystems - Beijing China 		while (rows_to_move-- > 0) {
2761aecfc01dSrui zang - Sun Microsystems - Beijing China 			to_row_start -= cols;
2762aecfc01dSrui zang - Sun Microsystems - Beijing China 			from_row_start -= cols;
2763aecfc01dSrui zang - Sun Microsystems - Beijing China 			to = to_row_start;
2764aecfc01dSrui zang - Sun Microsystems - Beijing China 			from = from_row_start;
2765aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (cnt = chars_per_row; cnt-- > 0; )
2766aecfc01dSrui zang - Sun Microsystems - Beijing China 				*--to = *--from;
2767aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
2768aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2769aecfc01dSrui zang - Sun Microsystems - Beijing China }
2770aecfc01dSrui zang - Sun Microsystems - Beijing China 
2771aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_safe_virtual_copy(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row)2772aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_virtual_copy(struct tem_vt_state *tem,
2773b6bd4f48SToomas Soome     screen_pos_t s_col, screen_pos_t s_row,
2774b6bd4f48SToomas Soome     screen_pos_t e_col, screen_pos_t e_row,
2775b6bd4f48SToomas Soome     screen_pos_t t_col, screen_pos_t t_row)
2776aecfc01dSrui zang - Sun Microsystems - Beijing China {
2777aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t chars_per_row;
2778aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t   rows_to_move;
2779aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		rows = tems.ts_c_dimension.height;
2780aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		cols = tems.ts_c_dimension.width;
2781aecfc01dSrui zang - Sun Microsystems - Beijing China 
2782aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (s_col < 0 || s_col >= cols ||
2783aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_row < 0 || s_row >= rows ||
2784aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col < 0 || e_col >= cols ||
2785aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_row < 0 || e_row >= rows ||
2786aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col < 0 || t_col >= cols ||
2787aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_row < 0 || t_row >= rows ||
2788aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col > e_col ||
2789aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_row > e_row)
2790aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2791aecfc01dSrui zang - Sun Microsystems - Beijing China 
2792aecfc01dSrui zang - Sun Microsystems - Beijing China 	chars_per_row = e_col - s_col + 1;
2793aecfc01dSrui zang - Sun Microsystems - Beijing China 	rows_to_move = e_row - s_row + 1;
2794aecfc01dSrui zang - Sun Microsystems - Beijing China 
2795aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* More sanity checks. */
2796aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (t_row + rows_to_move > rows ||
2797aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col + chars_per_row > cols)
2798aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2799aecfc01dSrui zang - Sun Microsystems - Beijing China 
28000e3b7565SToomas Soome 	i_virtual_copy_tem_chars(tem->tvs_screen_buf, s_col, s_row,
2801aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col, e_row, t_col, t_row);
2802aecfc01dSrui zang - Sun Microsystems - Beijing China }
2803aecfc01dSrui zang - Sun Microsystems - Beijing China 
2804aecfc01dSrui zang - Sun Microsystems - Beijing China static void
tem_safe_virtual_cls(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col)2805aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_virtual_cls(struct tem_vt_state *tem,
2806b6bd4f48SToomas Soome     int count, screen_pos_t row, screen_pos_t col)
2807aecfc01dSrui zang - Sun Microsystems - Beijing China {
2808cbc8e155SToomas Soome 	int i;
2809cbc8e155SToomas Soome 	text_attr_t attr;
2810cbc8e155SToomas Soome 	term_char_t c;
2811cbc8e155SToomas Soome 
2812cbc8e155SToomas Soome 	tem_safe_get_attr(tem, &c.tc_fg_color, &c.tc_bg_color, &attr,
2813cbc8e155SToomas Soome 	    TEM_ATTR_SCREEN_REVERSE);
2814cbc8e155SToomas Soome 	c.tc_char = TEM_ATTR(attr & ~TEM_ATTR_UNDERLINE) | ' ';
2815aecfc01dSrui zang - Sun Microsystems - Beijing China 
2816cbc8e155SToomas Soome 	for (i = 0; i < tems.ts_c_dimension.width; i++)
2817cbc8e155SToomas Soome 		tems.ts_blank_line[i] = c;
2818cbc8e155SToomas Soome 
2819cbc8e155SToomas Soome 	tem_safe_virtual_display(tem, tems.ts_blank_line, count, row, col);
2820aecfc01dSrui zang - Sun Microsystems - Beijing China }
2821aecfc01dSrui zang - Sun Microsystems - Beijing China 
2822aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2823aecfc01dSrui zang - Sun Microsystems - Beijing China  * only blank screen, not clear our screen buffer
2824aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2825aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_safe_blank_screen(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2826aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_blank_screen(struct tem_vt_state *tem, cred_t *credp,
2827b6bd4f48SToomas Soome     enum called_from called_from)
2828aecfc01dSrui zang - Sun Microsystems - Beijing China {
2829aecfc01dSrui zang - Sun Microsystems - Beijing China 	int	row;
2830aecfc01dSrui zang - Sun Microsystems - Beijing China 
2831aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2832aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2833aecfc01dSrui zang - Sun Microsystems - Beijing China 
2834aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_PIXEL) {
2835aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2836aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2837aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2838aecfc01dSrui zang - Sun Microsystems - Beijing China 
2839aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_c_dimension.height; row++) {
2840aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_cls(tem,
2841aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.width,
2842aecfc01dSrui zang - Sun Microsystems - Beijing China 		    row, 0, credp, called_from);
2843aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2844aecfc01dSrui zang - Sun Microsystems - Beijing China }
2845aecfc01dSrui zang - Sun Microsystems - Beijing China 
2846aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2847aecfc01dSrui zang - Sun Microsystems - Beijing China  * unblank screen with associated tem from its screen buffer
2848aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2849aecfc01dSrui zang - Sun Microsystems - Beijing China void
tem_safe_unblank_screen(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2850aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_unblank_screen(struct tem_vt_state *tem, cred_t *credp,
2851b6bd4f48SToomas Soome     enum called_from called_from)
2852aecfc01dSrui zang - Sun Microsystems - Beijing China {
2853cbc8e155SToomas Soome 	int	row;
2854aecfc01dSrui zang - Sun Microsystems - Beijing China 
2855aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2856aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2857aecfc01dSrui zang - Sun Microsystems - Beijing China 
2858aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_PIXEL)
2859aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2860aecfc01dSrui zang - Sun Microsystems - Beijing China 
2861aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_cursor(tem, VIS_HIDE_CURSOR, credp, called_from);
2862aecfc01dSrui zang - Sun Microsystems - Beijing China 
2863aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
2864aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Display data in tvs_screen_buf to the actual framebuffer in a
2865aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * row by row way.
2866aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * When dealing with one row, output data with the same foreground
2867aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * and background color all together.
2868aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
2869aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_c_dimension.height; row++) {
2870cbc8e155SToomas Soome 		tem_safe_callback_display(tem, tem->tvs_screen_rows[row],
2871cbc8e155SToomas Soome 		    tems.ts_c_dimension.width, row, 0, credp, called_from);
2872aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2873aecfc01dSrui zang - Sun Microsystems - Beijing China 
2874aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_cursor(tem, VIS_DISPLAY_CURSOR, credp, called_from);
2875aecfc01dSrui zang - Sun Microsystems - Beijing China }
2876