xref: /titanic_52/usr/src/uts/common/io/tem_safe.c (revision aecfc01d1bad84e66649703f7fc2926ef70b34ba)
1fea9cb91Slq150181 /*
2fea9cb91Slq150181  * CDDL HEADER START
3fea9cb91Slq150181  *
4fea9cb91Slq150181  * The contents of this file are subject to the terms of the
5fea9cb91Slq150181  * Common Development and Distribution License (the "License").
6fea9cb91Slq150181  * You may not use this file except in compliance with the License.
7fea9cb91Slq150181  *
8fea9cb91Slq150181  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fea9cb91Slq150181  * or http://www.opensolaris.org/os/licensing.
10fea9cb91Slq150181  * See the License for the specific language governing permissions
11fea9cb91Slq150181  * and limitations under the License.
12fea9cb91Slq150181  *
13fea9cb91Slq150181  * When distributing Covered Code, include this CDDL HEADER in each
14fea9cb91Slq150181  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fea9cb91Slq150181  * If applicable, add the following below this CDDL HEADER, with the
16fea9cb91Slq150181  * fields enclosed by brackets "[]" replaced with your own identifying
17fea9cb91Slq150181  * information: Portions Copyright [yyyy] [name of copyright owner]
18fea9cb91Slq150181  *
19fea9cb91Slq150181  * CDDL HEADER END
20fea9cb91Slq150181  */
21fea9cb91Slq150181 
22fea9cb91Slq150181 /*
23*aecfc01dSrui zang - Sun Microsystems - Beijing China  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24fea9cb91Slq150181  * Use is subject to license terms.
25fea9cb91Slq150181  */
26fea9cb91Slq150181 
27fea9cb91Slq150181 /*
28fea9cb91Slq150181  * Polled I/O safe ANSI terminal emulator module;
29fea9cb91Slq150181  * Supporting TERM types 'sun' and 'sun-color, parsing
30fea9cb91Slq150181  * ANSI x3.64 escape sequences, and the like.  (See wscons(7d)
31fea9cb91Slq150181  * for more information).
32fea9cb91Slq150181  *
33fea9cb91Slq150181  * IMPORTANT:
34fea9cb91Slq150181  *
35fea9cb91Slq150181  *   The functions in this file *must* be able to function in
36fea9cb91Slq150181  *   standalone mode, ie. on a quiesced system.   In that state,
37fea9cb91Slq150181  *   access is single threaded, only one CPU is running.
38fea9cb91Slq150181  *   System services are NOT available.
39fea9cb91Slq150181  *
40fea9cb91Slq150181  * The following restrictions pertain to every function
41fea9cb91Slq150181  * in this file:
42fea9cb91Slq150181  *
43fea9cb91Slq150181  *     - CANNOT use the DDI or LDI interfaces
44fea9cb91Slq150181  *     - CANNOT call system services
45fea9cb91Slq150181  *     - CANNOT use mutexes
46fea9cb91Slq150181  *     - CANNOT wait for interrupts
47fea9cb91Slq150181  *     - CANNOT allocate memory
48fea9cb91Slq150181  *
49*aecfc01dSrui zang - Sun Microsystems - Beijing China  * All non-static functions in this file which:
50*aecfc01dSrui zang - Sun Microsystems - Beijing China  *     - Operates on tems and tem_vt_state
51*aecfc01dSrui zang - Sun Microsystems - Beijing China  *     - Not only called from standalone mode, i.e. has
52*aecfc01dSrui zang - Sun Microsystems - Beijing China  *       a "calledfrom" argument
53*aecfc01dSrui zang - Sun Microsystems - Beijing China  * should assert this at the beginning:
54*aecfc01dSrui zang - Sun Microsystems - Beijing China  *
55*aecfc01dSrui zang - Sun Microsystems - Beijing China  *    ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
56*aecfc01dSrui zang - Sun Microsystems - Beijing China  *        called_from == CALLED_FROM_STANDALONE);
57fea9cb91Slq150181  */
58fea9cb91Slq150181 
59fea9cb91Slq150181 #include <sys/types.h>
60fea9cb91Slq150181 #include <sys/ascii.h>
61fea9cb91Slq150181 #include <sys/visual_io.h>
62fea9cb91Slq150181 #include <sys/font.h>
63fea9cb91Slq150181 #include <sys/tem.h>
64fea9cb91Slq150181 #include <sys/tem_impl.h>
65fea9cb91Slq150181 #include <sys/ksynch.h>
66fea9cb91Slq150181 #include <sys/sysmacros.h>
67fea9cb91Slq150181 #include <sys/mutex.h>
68*aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/note.h>
69*aecfc01dSrui zang - Sun Microsystems - Beijing China #include <sys/t_lock.h>
70fea9cb91Slq150181 
71*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_callbacks_t tem_safe_text_callbacks = {
72*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_display,
73*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_copy,
74*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_cursor,
75*aecfc01dSrui zang - Sun Microsystems - Beijing China 	NULL,
76*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_text_cls
77*aecfc01dSrui zang - Sun Microsystems - Beijing China };
78*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_callbacks_t tem_safe_pix_callbacks = {
79*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_display,
80*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_copy,
81*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_cursor,
82*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_bit2pix,
83*aecfc01dSrui zang - Sun Microsystems - Beijing China 	&tem_safe_pix_cls
84*aecfc01dSrui zang - Sun Microsystems - Beijing China };
85*aecfc01dSrui zang - Sun Microsystems - Beijing China 
86*aecfc01dSrui zang - Sun Microsystems - Beijing China 
87*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_control(struct tem_vt_state *, uchar_t,
88fea9cb91Slq150181 			cred_t *, enum called_from);
89*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_setparam(struct tem_vt_state *, int, int);
90*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_selgraph(struct tem_vt_state *);
91*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_chkparam(struct tem_vt_state *, uchar_t,
92fea9cb91Slq150181 			cred_t *, enum called_from);
93*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_getparams(struct tem_vt_state *, uchar_t,
94fea9cb91Slq150181 			cred_t *, enum called_from);
95*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_outch(struct tem_vt_state *, uchar_t,
96fea9cb91Slq150181 			cred_t *, enum called_from);
97*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_parse(struct tem_vt_state *, uchar_t,
98fea9cb91Slq150181 			cred_t *, enum called_from);
99fea9cb91Slq150181 
100*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_new_line(struct tem_vt_state *,
101fea9cb91Slq150181 			cred_t *, enum called_from);
102*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_cr(struct tem_vt_state *);
103*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_lf(struct tem_vt_state *,
104fea9cb91Slq150181 			cred_t *, enum called_from);
105*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_send_data(struct tem_vt_state *, cred_t *,
106fea9cb91Slq150181 			enum called_from);
107*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_cls(struct tem_vt_state *,
108fea9cb91Slq150181 			cred_t *, enum called_from);
109*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_tab(struct tem_vt_state *,
110fea9cb91Slq150181 			cred_t *, enum called_from);
111*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_back_tab(struct tem_vt_state *,
112fea9cb91Slq150181 			cred_t *, enum called_from);
113*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_clear_tabs(struct tem_vt_state *, int);
114*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_set_tab(struct tem_vt_state *);
115*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_mv_cursor(struct tem_vt_state *, int, int,
116fea9cb91Slq150181 			cred_t *, enum called_from);
117*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_shift(struct tem_vt_state *, int, int,
118fea9cb91Slq150181 			cred_t *, enum called_from);
119*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_scroll(struct tem_vt_state *, int, int,
120fea9cb91Slq150181 			int, int, cred_t *, enum called_from);
121*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_clear_chars(struct tem_vt_state *tem,
122fea9cb91Slq150181 			int count, screen_pos_t row, screen_pos_t col,
123fea9cb91Slq150181 			cred_t *credp, enum called_from called_from);
124*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_copy_area(struct tem_vt_state *tem,
125fea9cb91Slq150181 			screen_pos_t s_col, screen_pos_t s_row,
126fea9cb91Slq150181 			screen_pos_t e_col, screen_pos_t e_row,
127fea9cb91Slq150181 			screen_pos_t t_col, screen_pos_t t_row,
128fea9cb91Slq150181 			cred_t *credp, enum called_from called_from);
129*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_image_display(struct tem_vt_state *, uchar_t *,
130fea9cb91Slq150181 			int, int, screen_pos_t, screen_pos_t,
131fea9cb91Slq150181 			cred_t *, enum called_from);
132*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_bell(struct tem_vt_state *tem,
133fea9cb91Slq150181 			enum called_from called_from);
134*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_pix_clear_prom_output(struct tem_vt_state *tem,
135fea9cb91Slq150181 			cred_t *credp, enum called_from called_from);
136fea9cb91Slq150181 
137*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_virtual_cls(struct tem_vt_state *, int, screen_pos_t,
138*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    screen_pos_t);
139*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_virtual_display(struct tem_vt_state *,
140*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    unsigned char *, int, screen_pos_t, screen_pos_t,
141*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t, text_color_t);
142*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_virtual_copy(struct tem_vt_state *, screen_pos_t,
143*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    screen_pos_t, screen_pos_t, screen_pos_t,
144*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    screen_pos_t, screen_pos_t);
145*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	tem_safe_align_cursor(struct tem_vt_state *tem);
146*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	bit_to_pix4(struct tem_vt_state *tem, uchar_t c,
147*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t fg_color, text_color_t bg_color);
148*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	bit_to_pix8(struct tem_vt_state *tem, uchar_t c,
149*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t fg_color, text_color_t bg_color);
150*aecfc01dSrui zang - Sun Microsystems - Beijing China static void	bit_to_pix24(struct tem_vt_state *tem, uchar_t c,
151*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    text_color_t fg_color, text_color_t bg_color);
152*aecfc01dSrui zang - Sun Microsystems - Beijing China 
153fea9cb91Slq150181 /* BEGIN CSTYLED */
154fea9cb91Slq150181 /*                                      Bk  Rd  Gr  Br  Bl  Mg  Cy  Wh */
155fea9cb91Slq150181 static text_color_t fg_dim_xlate[] = {  1,  5,  3,  7,  2,  6,  4,  8 };
156fea9cb91Slq150181 static text_color_t fg_brt_xlate[] = {  9, 13, 11, 15, 10, 14, 12,  0 };
157fea9cb91Slq150181 static text_color_t bg_xlate[] = {      1,  5,  3,  7,  2,  6,  4,  0 };
158fea9cb91Slq150181 /* END CSTYLED */
159fea9cb91Slq150181 
160fea9cb91Slq150181 
161fea9cb91Slq150181 text_cmap_t cmap4_to_24 = {
162fea9cb91Slq150181 /* BEGIN CSTYLED */
163fea9cb91Slq150181 /* 0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15
164fea9cb91Slq150181   Wh+  Bk   Bl   Gr   Cy   Rd   Mg   Br   Wh   Bk+  Bl+  Gr+  Cy+  Rd+  Mg+  Yw */
165fea9cb91Slq150181   0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff,
166fea9cb91Slq150181   0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff,
167fea9cb91Slq150181   0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00
168fea9cb91Slq150181 /* END CSTYLED */
169fea9cb91Slq150181 };
170fea9cb91Slq150181 
171fea9cb91Slq150181 #define	PIX4TO32(pix4) (pixel32_t)(  \
172fea9cb91Slq150181     cmap4_to_24.red[pix4] << 16 |  \
173fea9cb91Slq150181     cmap4_to_24.green[pix4] << 8 | \
174fea9cb91Slq150181     cmap4_to_24.blue[pix4])
175fea9cb91Slq150181 
176fea9cb91Slq150181 /*
177fea9cb91Slq150181  * Fonts are statically linked with this module. At some point an
178fea9cb91Slq150181  * RFE might be desireable to allow dynamic font loading.  The
179fea9cb91Slq150181  * original intention to facilitate dynamic fonts can be seen
180fea9cb91Slq150181  * by examining the data structures and set_font().  As much of
181fea9cb91Slq150181  * the original code is retained but modified to be suited to
182fea9cb91Slq150181  * traversing a list of static fonts.
183fea9cb91Slq150181  */
184fea9cb91Slq150181 extern struct fontlist fonts[];
185fea9cb91Slq150181 
186fea9cb91Slq150181 #define	DEFAULT_FONT_DATA font_data_12x22
187fea9cb91Slq150181 
188fea9cb91Slq150181 extern bitmap_data_t font_data_12x22;
189fea9cb91Slq150181 extern bitmap_data_t font_data_7x14;
190fea9cb91Slq150181 extern bitmap_data_t font_data_6x10;
191fea9cb91Slq150181 /*
192fea9cb91Slq150181  * Must be sorted by font size in descending order
193fea9cb91Slq150181  */
194fea9cb91Slq150181 struct fontlist fonts[] = {
195fea9cb91Slq150181 	{  &font_data_12x22,	NULL  },
196fea9cb91Slq150181 	{  &font_data_7x14,	NULL  },
197fea9cb91Slq150181 	{  &font_data_6x10,	NULL  },
198fea9cb91Slq150181 	{  NULL, NULL  }
199fea9cb91Slq150181 };
200fea9cb91Slq150181 
201fea9cb91Slq150181 #define	INVERSE(ch) (ch ^ 0xff)
202fea9cb91Slq150181 
203*aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_display	(*tems.ts_callbacks->tsc_display)
204*aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_copy		(*tems.ts_callbacks->tsc_copy)
205*aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_cursor	(*tems.ts_callbacks->tsc_cursor)
206*aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_cls		(*tems.ts_callbacks->tsc_cls)
207*aecfc01dSrui zang - Sun Microsystems - Beijing China #define	tem_safe_callback_bit2pix(tem, c, fg, bg)	{		\
208*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(tems.ts_callbacks->tsc_bit2pix != NULL);			\
209*aecfc01dSrui zang - Sun Microsystems - Beijing China 	(void) (*tems.ts_callbacks->tsc_bit2pix)((tem), (c), (fg), (bg));\
210fea9cb91Slq150181 }
211fea9cb91Slq150181 
212fea9cb91Slq150181 void
213*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_check_first_time(
214*aecfc01dSrui zang - Sun Microsystems - Beijing China     struct tem_vt_state *tem,
215fea9cb91Slq150181     cred_t *credp,
216fea9cb91Slq150181     enum called_from called_from)
217fea9cb91Slq150181 {
218fea9cb91Slq150181 	static int first_time = 1;
219fea9cb91Slq150181 
220*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
221*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
222*aecfc01dSrui zang - Sun Microsystems - Beijing China 
223fea9cb91Slq150181 	/*
224fea9cb91Slq150181 	 * Realign the console cursor. We did this in tem_init().
225fea9cb91Slq150181 	 * However, drivers in the console stream may emit additional
226fea9cb91Slq150181 	 * messages before we are ready. This causes text overwrite
227fea9cb91Slq150181 	 * on the screen. This is a workaround.
228fea9cb91Slq150181 	 */
229*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!first_time)
230*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
231fea9cb91Slq150181 
232*aecfc01dSrui zang - Sun Microsystems - Beijing China 	first_time = 0;
233*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_TEXT) {
234*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_text_cursor(tem, VIS_GET_CURSOR, credp, called_from);
235*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_align_cursor(tem);
236*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
237fea9cb91Slq150181 }
238fea9cb91Slq150181 
239fea9cb91Slq150181 /*
240fea9cb91Slq150181  * This entry point handles output requests from restricted contexts like
241fea9cb91Slq150181  * kmdb, where services like mutexes are not available. This function
242fea9cb91Slq150181  * is entered when OBP or when a kernel debugger (such as kmdb)
243fea9cb91Slq150181  * are generating console output.  In those cases, power management
244fea9cb91Slq150181  * concerns are handled by the abort sequence initiation (ie. when
245fea9cb91Slq150181  * the user hits L1+A or the equivalent to enter OBP or the debugger.).
246fea9cb91Slq150181  * It is also entered when the kernel is panicing.
247fea9cb91Slq150181  */
248fea9cb91Slq150181 void
249*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_polled_write(
250*aecfc01dSrui zang - Sun Microsystems - Beijing China     tem_vt_state_t tem_arg,
251fea9cb91Slq150181     uchar_t *buf,
252fea9cb91Slq150181     int len)
253fea9cb91Slq150181 {
254*aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
255fea9cb91Slq150181 
256*aecfc01dSrui zang - Sun Microsystems - Beijing China #ifdef	__lock_lint
257*aecfc01dSrui zang - Sun Microsystems - Beijing China 	_NOTE(NO_COMPETING_THREADS_NOW)
258*aecfc01dSrui zang - Sun Microsystems - Beijing China 	_NOTE(NO_COMPETING_THREADS_AS_SIDE_EFFECT)
259*aecfc01dSrui zang - Sun Microsystems - Beijing China #endif
260fea9cb91Slq150181 
261*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_initialized) {
262*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
263*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
264*aecfc01dSrui zang - Sun Microsystems - Beijing China 
265*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_check_first_time(tem, kcred, CALLED_FROM_STANDALONE);
266*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_terminal_emulate(tem, buf, len, NULL, CALLED_FROM_STANDALONE);
267fea9cb91Slq150181 }
268fea9cb91Slq150181 
269fea9cb91Slq150181 
270fea9cb91Slq150181 /*
271fea9cb91Slq150181  * This is the main entry point into the terminal emulator.
272fea9cb91Slq150181  *
273fea9cb91Slq150181  * For each data message coming downstream, ANSI assumes that it is composed
274fea9cb91Slq150181  * of ASCII characters, which are treated as a byte-stream input to the
275fea9cb91Slq150181  * parsing state machine. All data is parsed immediately -- there is
276fea9cb91Slq150181  * no enqueing.
277fea9cb91Slq150181  */
278fea9cb91Slq150181 void
279*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_terminal_emulate(
280*aecfc01dSrui zang - Sun Microsystems - Beijing China     struct tem_vt_state *tem,
281fea9cb91Slq150181     uchar_t *buf,
282fea9cb91Slq150181     int len,
283fea9cb91Slq150181     cred_t *credp,
284fea9cb91Slq150181     enum called_from called_from)
285fea9cb91Slq150181 {
286fea9cb91Slq150181 
287*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
288*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
289fea9cb91Slq150181 
290*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_isactive)
291*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_cursor(tem,
292*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    VIS_HIDE_CURSOR, credp, called_from);
293fea9cb91Slq150181 
294*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (; len > 0; len--, buf++)
295*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_parse(tem, *buf, credp, called_from);
296fea9cb91Slq150181 
297fea9cb91Slq150181 	/*
298fea9cb91Slq150181 	 * Send the data we just got to the framebuffer.
299fea9cb91Slq150181 	 */
300*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_send_data(tem, credp, called_from);
301fea9cb91Slq150181 
302*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_isactive)
303*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_cursor(tem,
304*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    VIS_DISPLAY_CURSOR, credp, called_from);
305fea9cb91Slq150181 }
306fea9cb91Slq150181 
307fea9cb91Slq150181 /*
308fea9cb91Slq150181  * Display an rectangular image on the frame buffer using the
309fea9cb91Slq150181  * mechanism appropriate for the system state being called
310fea9cb91Slq150181  * from quiesced or normal (ie. use polled I/O vs. layered ioctls)
311fea9cb91Slq150181  */
312fea9cb91Slq150181 static void
313*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_safe_display(
314fea9cb91Slq150181 	struct vis_consdisplay *pda,
315fea9cb91Slq150181 	cred_t *credp,
316fea9cb91Slq150181 	enum called_from called_from)
317fea9cb91Slq150181 {
318fea9cb91Slq150181 	if (called_from == CALLED_FROM_STANDALONE)
319*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems.ts_fb_polledio->display(tems.ts_fb_polledio->arg, pda);
320fea9cb91Slq150181 	else
321*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_display_layered(pda, credp);
322fea9cb91Slq150181 }
323fea9cb91Slq150181 
324fea9cb91Slq150181 /*
325fea9cb91Slq150181  * Copy a rectangle from one location to another on the frame buffer
326fea9cb91Slq150181  * using the mechanism appropriate for the system state being called
327fea9cb91Slq150181  * from, quiesced or normal (ie. use polled I/O vs. layered ioctls)
328fea9cb91Slq150181  */
329fea9cb91Slq150181 void
330*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_safe_copy(
331fea9cb91Slq150181 	struct vis_conscopy *pca,
332fea9cb91Slq150181 	cred_t *credp,
333fea9cb91Slq150181 	enum called_from called_from)
334fea9cb91Slq150181 {
335fea9cb91Slq150181 	if (called_from == CALLED_FROM_STANDALONE)
336*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems.ts_fb_polledio->copy(tems.ts_fb_polledio->arg, pca);
337fea9cb91Slq150181 	else
338*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_copy_layered(pca, credp);
339fea9cb91Slq150181 }
340fea9cb91Slq150181 
341fea9cb91Slq150181 /*
342fea9cb91Slq150181  * Display or hide a rectangular block text cursor of a specificsize
343fea9cb91Slq150181  * at a specific location on frame buffer* using the mechanism
344fea9cb91Slq150181  * appropriate for the system state being called from, quisced or
345fea9cb91Slq150181  * normal (ie. use polled I/O vs. layered ioctls).
346fea9cb91Slq150181  */
347fea9cb91Slq150181 static void
348*aecfc01dSrui zang - Sun Microsystems - Beijing China tems_safe_cursor(
349fea9cb91Slq150181 	struct vis_conscursor *pca,
350fea9cb91Slq150181 	cred_t *credp,
351fea9cb91Slq150181 	enum called_from called_from)
352fea9cb91Slq150181 {
353fea9cb91Slq150181 	if (called_from == CALLED_FROM_STANDALONE)
354*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems.ts_fb_polledio->cursor(tems.ts_fb_polledio->arg, pca);
355fea9cb91Slq150181 	else
356*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_cursor_layered(pca, credp);
357fea9cb91Slq150181 }
358fea9cb91Slq150181 
359fea9cb91Slq150181 /*
360fea9cb91Slq150181  * send the appropriate control message or set state based on the
361fea9cb91Slq150181  * value of the control character ch
362fea9cb91Slq150181  */
363fea9cb91Slq150181 
364fea9cb91Slq150181 static void
365*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_control(
366*aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem,
367fea9cb91Slq150181 	uchar_t ch,
368fea9cb91Slq150181 	cred_t *credp,
369fea9cb91Slq150181 	enum called_from called_from)
370fea9cb91Slq150181 {
371*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
372fea9cb91Slq150181 	switch (ch) {
373fea9cb91Slq150181 	case A_BEL:
374*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_bell(tem, called_from);
375fea9cb91Slq150181 		break;
376fea9cb91Slq150181 
377fea9cb91Slq150181 	case A_BS:
378*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem,
379*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
380*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col - 1,
381fea9cb91Slq150181 		    credp, called_from);
382fea9cb91Slq150181 		break;
383fea9cb91Slq150181 
384fea9cb91Slq150181 	case A_HT:
385*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_tab(tem, credp, called_from);
386fea9cb91Slq150181 		break;
387fea9cb91Slq150181 
388fea9cb91Slq150181 	case A_NL:
389fea9cb91Slq150181 		/*
390*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * tem_safe_send_data(tem, credp, called_from);
391*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * tem_safe_new_line(tem, credp, called_from);
392fea9cb91Slq150181 		 * break;
393fea9cb91Slq150181 		 */
394fea9cb91Slq150181 
395fea9cb91Slq150181 	case A_VT:
396*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
397*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_lf(tem, credp, called_from);
398fea9cb91Slq150181 		break;
399fea9cb91Slq150181 
400fea9cb91Slq150181 	case A_FF:
401*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
402*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_cls(tem, credp, called_from);
403fea9cb91Slq150181 		break;
404fea9cb91Slq150181 
405fea9cb91Slq150181 	case A_CR:
406*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
407*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_cr(tem);
408fea9cb91Slq150181 		break;
409fea9cb91Slq150181 
410fea9cb91Slq150181 	case A_ESC:
411*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_ESC;
412fea9cb91Slq150181 		break;
413fea9cb91Slq150181 
414fea9cb91Slq150181 	case A_CSI:
415fea9cb91Slq150181 		{
416fea9cb91Slq150181 			int i;
417*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_curparam = 0;
418*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_paramval = 0;
419*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_gotparam = B_FALSE;
420fea9cb91Slq150181 			/* clear the parameters */
421fea9cb91Slq150181 			for (i = 0; i < TEM_MAXPARAMS; i++)
422*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_params[i] = -1;
423*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_CSI;
424fea9cb91Slq150181 		}
425fea9cb91Slq150181 		break;
426fea9cb91Slq150181 
427fea9cb91Slq150181 	case A_GS:
428*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_back_tab(tem, credp, called_from);
429fea9cb91Slq150181 		break;
430fea9cb91Slq150181 
431fea9cb91Slq150181 	default:
432fea9cb91Slq150181 		break;
433fea9cb91Slq150181 	}
434fea9cb91Slq150181 }
435fea9cb91Slq150181 
436fea9cb91Slq150181 
437fea9cb91Slq150181 /*
438fea9cb91Slq150181  * if parameters [0..count - 1] are not set, set them to the value
439fea9cb91Slq150181  * of newparam.
440fea9cb91Slq150181  */
441fea9cb91Slq150181 
442fea9cb91Slq150181 static void
443*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_setparam(struct tem_vt_state *tem, int count, int newparam)
444fea9cb91Slq150181 {
445fea9cb91Slq150181 	int i;
446fea9cb91Slq150181 
447fea9cb91Slq150181 	for (i = 0; i < count; i++) {
448*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_params[i] == -1)
449*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_params[i] = newparam;
450fea9cb91Slq150181 	}
451fea9cb91Slq150181 }
452fea9cb91Slq150181 
453fea9cb91Slq150181 
454fea9cb91Slq150181 /*
455fea9cb91Slq150181  * select graphics mode based on the param vals stored in a_params
456fea9cb91Slq150181  */
457fea9cb91Slq150181 static void
458*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_selgraph(struct tem_vt_state *tem)
459fea9cb91Slq150181 {
460fea9cb91Slq150181 	int curparam;
461fea9cb91Slq150181 	int count = 0;
462fea9cb91Slq150181 	int param;
463fea9cb91Slq150181 
464*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
465*aecfc01dSrui zang - Sun Microsystems - Beijing China 
466*aecfc01dSrui zang - Sun Microsystems - Beijing China 	curparam = tem->tvs_curparam;
467fea9cb91Slq150181 	do {
468*aecfc01dSrui zang - Sun Microsystems - Beijing China 		param = tem->tvs_params[count];
469fea9cb91Slq150181 
470fea9cb91Slq150181 		switch (param) {
471fea9cb91Slq150181 		case -1:
472fea9cb91Slq150181 		case 0:
473*aecfc01dSrui zang - Sun Microsystems - Beijing China 			/* reset to initial normal settings */
474*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_fg_color = tems.ts_init_color.fg_color;
475*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_bg_color = tems.ts_init_color.bg_color;
476*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags = tems.ts_init_color.a_flags;
477fea9cb91Slq150181 			break;
478fea9cb91Slq150181 
479fea9cb91Slq150181 		case 1: /* Bold Intense */
480*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags |= TEM_ATTR_BOLD;
481fea9cb91Slq150181 			break;
482fea9cb91Slq150181 
483c9503a49Slq150181 		case 2: /* Faint Intense */
484*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags &= ~TEM_ATTR_BOLD;
485c9503a49Slq150181 			break;
486c9503a49Slq150181 
487fea9cb91Slq150181 		case 5: /* Blink */
488*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_flags |= TEM_ATTR_BLINK;
489fea9cb91Slq150181 			break;
490fea9cb91Slq150181 
491fea9cb91Slq150181 		case 7: /* Reverse video */
492*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
493*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags &= ~TEM_ATTR_REVERSE;
494fea9cb91Slq150181 			} else {
495*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags |= TEM_ATTR_REVERSE;
496fea9cb91Slq150181 			}
497fea9cb91Slq150181 			break;
498fea9cb91Slq150181 
499fea9cb91Slq150181 		case 30: /* black	(grey) 		foreground */
500fea9cb91Slq150181 		case 31: /* red		(light red) 	foreground */
501fea9cb91Slq150181 		case 32: /* green	(light green) 	foreground */
502fea9cb91Slq150181 		case 33: /* brown	(yellow) 	foreground */
503fea9cb91Slq150181 		case 34: /* blue	(light blue) 	foreground */
504fea9cb91Slq150181 		case 35: /* magenta	(light magenta) foreground */
505fea9cb91Slq150181 		case 36: /* cyan	(light cyan) 	foreground */
506fea9cb91Slq150181 		case 37: /* white	(bright white) 	foreground */
507*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_fg_color = param - 30;
508fea9cb91Slq150181 			break;
509fea9cb91Slq150181 
510fea9cb91Slq150181 		case 40: /* black	(grey) 		background */
511fea9cb91Slq150181 		case 41: /* red		(light red) 	background */
512fea9cb91Slq150181 		case 42: /* green	(light green) 	background */
513fea9cb91Slq150181 		case 43: /* brown	(yellow) 	background */
514fea9cb91Slq150181 		case 44: /* blue	(light blue) 	background */
515fea9cb91Slq150181 		case 45: /* magenta	(light magenta) background */
516fea9cb91Slq150181 		case 46: /* cyan	(light cyan) 	background */
517fea9cb91Slq150181 		case 47: /* white	(bright white) 	background */
518*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_bg_color = param - 40;
519fea9cb91Slq150181 			break;
520fea9cb91Slq150181 
521fea9cb91Slq150181 		default:
522fea9cb91Slq150181 			break;
523fea9cb91Slq150181 		}
524fea9cb91Slq150181 		count++;
525fea9cb91Slq150181 		curparam--;
526fea9cb91Slq150181 
527fea9cb91Slq150181 	} while (curparam > 0);
528fea9cb91Slq150181 }
529fea9cb91Slq150181 
530fea9cb91Slq150181 /*
531fea9cb91Slq150181  * perform the appropriate action for the escape sequence
532fea9cb91Slq150181  *
533fea9cb91Slq150181  * General rule:  This code does not validate the arguments passed.
534fea9cb91Slq150181  *                It assumes that the next lower level will do so.
535fea9cb91Slq150181  */
536fea9cb91Slq150181 static void
537*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_chkparam(
538*aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem,
539fea9cb91Slq150181 	uchar_t ch,
540fea9cb91Slq150181 	cred_t *credp,
541fea9cb91Slq150181 	enum called_from called_from)
542fea9cb91Slq150181 {
543fea9cb91Slq150181 	int	i;
544fea9cb91Slq150181 	int	row;
545fea9cb91Slq150181 	int	col;
546fea9cb91Slq150181 
547fea9cb91Slq150181 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
548*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
549fea9cb91Slq150181 
550*aecfc01dSrui zang - Sun Microsystems - Beijing China 	row = tem->tvs_c_cursor.row;
551*aecfc01dSrui zang - Sun Microsystems - Beijing China 	col = tem->tvs_c_cursor.col;
552fea9cb91Slq150181 
553fea9cb91Slq150181 	switch (ch) {
554fea9cb91Slq150181 
555fea9cb91Slq150181 	case 'm': /* select terminal graphics mode */
556*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
557*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_selgraph(tem);
558fea9cb91Slq150181 		break;
559fea9cb91Slq150181 
560fea9cb91Slq150181 	case '@':		/* insert char */
561*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
562*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_shift(tem, tem->tvs_params[0], TEM_SHIFT_RIGHT,
563fea9cb91Slq150181 		    credp, called_from);
564fea9cb91Slq150181 		break;
565fea9cb91Slq150181 
566fea9cb91Slq150181 	case 'A':		/* cursor up */
567*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
568*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row - tem->tvs_params[0], col,
569fea9cb91Slq150181 		    credp, called_from);
570fea9cb91Slq150181 		break;
571fea9cb91Slq150181 
572fea9cb91Slq150181 	case 'd':		/* VPA - vertical position absolute */
573*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
574*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, tem->tvs_params[0] - 1, col,
575fea9cb91Slq150181 		    credp, called_from);
576fea9cb91Slq150181 		break;
577fea9cb91Slq150181 
578fea9cb91Slq150181 	case 'e':		/* VPR - vertical position relative */
579fea9cb91Slq150181 	case 'B':		/* cursor down */
580*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
581*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row + tem->tvs_params[0], col,
582fea9cb91Slq150181 		    credp, called_from);
583fea9cb91Slq150181 		break;
584fea9cb91Slq150181 
585fea9cb91Slq150181 	case 'a':		/* HPR - horizontal position relative */
586fea9cb91Slq150181 	case 'C':		/* cursor right */
587*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
588*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, col + tem->tvs_params[0],
589fea9cb91Slq150181 		    credp, called_from);
590fea9cb91Slq150181 		break;
591fea9cb91Slq150181 
592fea9cb91Slq150181 	case '`':		/* HPA - horizontal position absolute */
593*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
594*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, tem->tvs_params[0] - 1,
595fea9cb91Slq150181 		    credp, called_from);
596fea9cb91Slq150181 		break;
597fea9cb91Slq150181 
598fea9cb91Slq150181 	case 'D':		/* cursor left */
599*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
600*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, col - tem->tvs_params[0],
601fea9cb91Slq150181 		    credp, called_from);
602fea9cb91Slq150181 		break;
603fea9cb91Slq150181 
604fea9cb91Slq150181 	case 'E':		/* CNL cursor next line */
605*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
606*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row + tem->tvs_params[0], 0,
607fea9cb91Slq150181 		    credp, called_from);
608fea9cb91Slq150181 		break;
609fea9cb91Slq150181 
610fea9cb91Slq150181 	case 'F':		/* CPL cursor previous line */
611*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
612*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row - tem->tvs_params[0], 0,
613fea9cb91Slq150181 		    credp, called_from);
614fea9cb91Slq150181 		break;
615fea9cb91Slq150181 
616fea9cb91Slq150181 	case 'G':		/* cursor horizontal position */
617*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
618*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem, row, tem->tvs_params[0] - 1,
619fea9cb91Slq150181 		    credp, called_from);
620fea9cb91Slq150181 		break;
621fea9cb91Slq150181 
622fea9cb91Slq150181 	case 'g':		/* clear tabs */
623*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 0);
624*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_tabs(tem, tem->tvs_params[0]);
625fea9cb91Slq150181 		break;
626fea9cb91Slq150181 
627fea9cb91Slq150181 	case 'f':		/* HVP Horizontal and Vertical Position */
628fea9cb91Slq150181 	case 'H':		/* CUP position cursor */
629*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 2, 1);
630*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_mv_cursor(tem,
631*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0] - 1,
632*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[1] - 1,
633fea9cb91Slq150181 		    credp, called_from);
634fea9cb91Slq150181 		break;
635fea9cb91Slq150181 
636fea9cb91Slq150181 	case 'I':		/* CHT - Cursor Horizontal Tab */
637fea9cb91Slq150181 		/* Not implemented */
638fea9cb91Slq150181 		break;
639fea9cb91Slq150181 
640fea9cb91Slq150181 	case 'J':		/* ED - Erase in Display */
641*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
642*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 0);
643*aecfc01dSrui zang - Sun Microsystems - Beijing China 		switch (tem->tvs_params[0]) {
644fea9cb91Slq150181 		case 0:
645fea9cb91Slq150181 			/* erase cursor to end of screen */
646fea9cb91Slq150181 			/* FIRST erase cursor to end of line */
647*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
648*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width -
649*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
650*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
651*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col, credp, called_from);
652fea9cb91Slq150181 
653fea9cb91Slq150181 			/* THEN erase lines below the cursor */
654*aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (row = tem->tvs_c_cursor.row + 1;
655*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    row < tems.ts_c_dimension.height;
656fea9cb91Slq150181 			    row++) {
657*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_clear_chars(tem,
658*aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tems.ts_c_dimension.width,
659fea9cb91Slq150181 				    row, 0, credp, called_from);
660fea9cb91Slq150181 			}
661fea9cb91Slq150181 			break;
662fea9cb91Slq150181 
663fea9cb91Slq150181 		case 1:
664fea9cb91Slq150181 			/* erase beginning of screen to cursor */
665fea9cb91Slq150181 			/* FIRST erase lines above the cursor */
666fea9cb91Slq150181 			for (row = 0;
667*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    row < tem->tvs_c_cursor.row;
668fea9cb91Slq150181 			    row++) {
669*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_clear_chars(tem,
670*aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tems.ts_c_dimension.width,
671fea9cb91Slq150181 				    row, 0, credp, called_from);
672fea9cb91Slq150181 			}
673fea9cb91Slq150181 			/* THEN erase beginning of line to cursor */
674*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
675*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + 1,
676*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
677fea9cb91Slq150181 			    0, credp, called_from);
678fea9cb91Slq150181 			break;
679fea9cb91Slq150181 
680fea9cb91Slq150181 		case 2:
681fea9cb91Slq150181 			/* erase whole screen */
682fea9cb91Slq150181 			for (row = 0;
683*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    row < tems.ts_c_dimension.height;
684fea9cb91Slq150181 			    row++) {
685*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_clear_chars(tem,
686*aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tems.ts_c_dimension.width,
687fea9cb91Slq150181 				    row, 0, credp, called_from);
688fea9cb91Slq150181 			}
689fea9cb91Slq150181 			break;
690fea9cb91Slq150181 		}
691fea9cb91Slq150181 		break;
692fea9cb91Slq150181 
693fea9cb91Slq150181 	case 'K':		/* EL - Erase in Line */
694*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
695*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 0);
696*aecfc01dSrui zang - Sun Microsystems - Beijing China 		switch (tem->tvs_params[0]) {
697fea9cb91Slq150181 		case 0:
698fea9cb91Slq150181 			/* erase cursor to end of line */
699*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
700*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    (tems.ts_c_dimension.width -
701*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col),
702*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
703*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
704fea9cb91Slq150181 			    credp, called_from);
705fea9cb91Slq150181 			break;
706fea9cb91Slq150181 
707fea9cb91Slq150181 		case 1:
708fea9cb91Slq150181 			/* erase beginning of line to cursor */
709*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
710*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + 1,
711*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
712fea9cb91Slq150181 			    0, credp, called_from);
713fea9cb91Slq150181 			break;
714fea9cb91Slq150181 
715fea9cb91Slq150181 		case 2:
716fea9cb91Slq150181 			/* erase whole line */
717*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem,
718*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width,
719*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
720fea9cb91Slq150181 			    0, credp, called_from);
721fea9cb91Slq150181 			break;
722fea9cb91Slq150181 		}
723fea9cb91Slq150181 		break;
724fea9cb91Slq150181 
725fea9cb91Slq150181 	case 'L':		/* insert line */
726*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
727*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
728*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem,
729*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
730*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
731*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_DOWN,
732fea9cb91Slq150181 		    credp, called_from);
733fea9cb91Slq150181 		break;
734fea9cb91Slq150181 
735fea9cb91Slq150181 	case 'M':		/* delete line */
736*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
737*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
738*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem,
739*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
740*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
741*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_UP,
742fea9cb91Slq150181 		    credp, called_from);
743fea9cb91Slq150181 		break;
744fea9cb91Slq150181 
745fea9cb91Slq150181 	case 'P':		/* DCH - delete char */
746*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
747*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_shift(tem, tem->tvs_params[0], TEM_SHIFT_LEFT,
748fea9cb91Slq150181 		    credp, called_from);
749fea9cb91Slq150181 		break;
750fea9cb91Slq150181 
751fea9cb91Slq150181 	case 'S':		/* scroll up */
752*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
753*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
754*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem, 0,
755*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
756*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_UP,
757fea9cb91Slq150181 		    credp, called_from);
758fea9cb91Slq150181 		break;
759fea9cb91Slq150181 
760fea9cb91Slq150181 	case 'T':		/* scroll down */
761*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
762*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
763*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_scroll(tem, 0,
764*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.height - 1,
765*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0], TEM_SCROLL_DOWN,
766fea9cb91Slq150181 		    credp, called_from);
767fea9cb91Slq150181 		break;
768fea9cb91Slq150181 
769fea9cb91Slq150181 	case 'X':		/* erase char */
770*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
771*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem,
772*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_params[0],
773*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
774*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col,
775fea9cb91Slq150181 		    credp, called_from);
776fea9cb91Slq150181 		break;
777fea9cb91Slq150181 
778fea9cb91Slq150181 	case 'Z':		/* cursor backward tabulation */
779*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_setparam(tem, 1, 1);
780fea9cb91Slq150181 
781fea9cb91Slq150181 		/*
782fea9cb91Slq150181 		 * Rule exception - We do sanity checking here.
783fea9cb91Slq150181 		 *
784fea9cb91Slq150181 		 * Restrict the count to a sane value to keep from
785fea9cb91Slq150181 		 * looping for a long time.  There can't be more than one
786fea9cb91Slq150181 		 * tab stop per column, so use that as a limit.
787fea9cb91Slq150181 		 */
788*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_params[0] > tems.ts_c_dimension.width)
789*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_params[0] = tems.ts_c_dimension.width;
790fea9cb91Slq150181 
791*aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (i = 0; i < tem->tvs_params[0]; i++)
792*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_back_tab(tem, credp, called_from);
793fea9cb91Slq150181 		break;
794fea9cb91Slq150181 	}
795*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
796fea9cb91Slq150181 }
797fea9cb91Slq150181 
798fea9cb91Slq150181 
799fea9cb91Slq150181 /*
800fea9cb91Slq150181  * Gather the parameters of an ANSI escape sequence
801fea9cb91Slq150181  */
802fea9cb91Slq150181 static void
803*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_getparams(struct tem_vt_state *tem, uchar_t ch,
804fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
805fea9cb91Slq150181 {
806fea9cb91Slq150181 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
807*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
808fea9cb91Slq150181 
80951fd4921Slt200341 	if (ch >= '0' && ch <= '9') {
810*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_paramval = ((tem->tvs_paramval * 10) + (ch - '0'));
811*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_gotparam = B_TRUE;  /* Remember got parameter */
812fea9cb91Slq150181 		return; /* Return immediately */
813*aecfc01dSrui zang - Sun Microsystems - Beijing China 	} else if (tem->tvs_state == A_STATE_CSI_EQUAL ||
814*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tem->tvs_state == A_STATE_CSI_QMARK) {
815*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
81651fd4921Slt200341 	} else {
817*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_curparam < TEM_MAXPARAMS) {
818*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_gotparam) {
81951fd4921Slt200341 				/* get the parameter value */
820*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_params[tem->tvs_curparam] =
821*aecfc01dSrui zang - Sun Microsystems - Beijing China 				    tem->tvs_paramval;
82251fd4921Slt200341 			}
823*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_curparam++;
824fea9cb91Slq150181 		}
825fea9cb91Slq150181 
826fea9cb91Slq150181 		if (ch == ';') {
827fea9cb91Slq150181 			/* Restart parameter search */
828*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_gotparam = B_FALSE;
829*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_paramval = 0; /* No parame value yet */
83051fd4921Slt200341 		} else {
831fea9cb91Slq150181 			/* Handle escape sequence */
832*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_chkparam(tem, ch, credp, called_from);
83351fd4921Slt200341 		}
834fea9cb91Slq150181 	}
835fea9cb91Slq150181 }
836fea9cb91Slq150181 
837fea9cb91Slq150181 /*
838fea9cb91Slq150181  * Add character to internal buffer.
839fea9cb91Slq150181  * When its full, send it to the next layer.
840fea9cb91Slq150181  */
841fea9cb91Slq150181 
842fea9cb91Slq150181 static void
843*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_outch(struct tem_vt_state *tem, uchar_t ch,
844fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
845fea9cb91Slq150181 {
846fea9cb91Slq150181 
847*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
848*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
849fea9cb91Slq150181 
850fea9cb91Slq150181 	/* buffer up the character until later */
851fea9cb91Slq150181 
852*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_outbuf[tem->tvs_outindex++] = ch;
853*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col++;
854*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_c_cursor.col >= tems.ts_c_dimension.width) {
855*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_send_data(tem, credp, called_from);
856*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_new_line(tem, credp, called_from);
857fea9cb91Slq150181 	}
858fea9cb91Slq150181 }
859fea9cb91Slq150181 
860fea9cb91Slq150181 static void
861*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_new_line(struct tem_vt_state *tem,
862fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
863fea9cb91Slq150181 {
864*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_cr(tem);
865*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_lf(tem, credp, called_from);
866fea9cb91Slq150181 }
867fea9cb91Slq150181 
868fea9cb91Slq150181 static void
869*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_cr(struct tem_vt_state *tem)
870fea9cb91Slq150181 {
871*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = 0;
872*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
873fea9cb91Slq150181 }
874fea9cb91Slq150181 
875fea9cb91Slq150181 static void
876*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_lf(struct tem_vt_state *tem,
877fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
878fea9cb91Slq150181 {
879fea9cb91Slq150181 	int row;
880fea9cb91Slq150181 
881fea9cb91Slq150181 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
882*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
883fea9cb91Slq150181 
884fea9cb91Slq150181 	/*
885fea9cb91Slq150181 	 * Sanity checking notes:
886fea9cb91Slq150181 	 * . a_nscroll was validated when it was set.
887*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * . Regardless of that, tem_safe_scroll and tem_safe_mv_cursor
888*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 *   will prevent anything bad from happening.
889fea9cb91Slq150181 	 */
890*aecfc01dSrui zang - Sun Microsystems - Beijing China 	row = tem->tvs_c_cursor.row + 1;
891fea9cb91Slq150181 
892*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row >= tems.ts_c_dimension.height) {
893*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_nscroll != 0) {
894*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_scroll(tem, 0,
895*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.height - 1,
896*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_nscroll, TEM_SCROLL_UP,
897fea9cb91Slq150181 			    credp, called_from);
898*aecfc01dSrui zang - Sun Microsystems - Beijing China 			row = tems.ts_c_dimension.height -
899*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_nscroll;
900fea9cb91Slq150181 		} else {	/* no scroll */
901fea9cb91Slq150181 			/*
902fea9cb91Slq150181 			 * implement Esc[#r when # is zero.  This means no
903fea9cb91Slq150181 			 * scroll but just return cursor to top of screen,
904fea9cb91Slq150181 			 * do not clear screen.
905fea9cb91Slq150181 			 */
906fea9cb91Slq150181 			row = 0;
907fea9cb91Slq150181 		}
908fea9cb91Slq150181 	}
909fea9cb91Slq150181 
910*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_mv_cursor(tem, row, tem->tvs_c_cursor.col,
911fea9cb91Slq150181 	    credp, called_from);
912fea9cb91Slq150181 
913*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_nscroll == 0) {
914fea9cb91Slq150181 		/* erase rest of cursor line */
915*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem,
916*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.width -
917*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col,
918*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.row,
919*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col,
920fea9cb91Slq150181 		    credp, called_from);
921fea9cb91Slq150181 
922fea9cb91Slq150181 	}
923fea9cb91Slq150181 
924*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
925fea9cb91Slq150181 }
926fea9cb91Slq150181 
927fea9cb91Slq150181 static void
928*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_send_data(struct tem_vt_state *tem, cred_t *credp,
929fea9cb91Slq150181     enum called_from called_from)
930fea9cb91Slq150181 {
931fea9cb91Slq150181 	text_color_t fg_color;
932fea9cb91Slq150181 	text_color_t bg_color;
933fea9cb91Slq150181 
934fea9cb91Slq150181 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
935*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
936fea9cb91Slq150181 
937*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_outindex == 0) {
938*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_align_cursor(tem);
939*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
940fea9cb91Slq150181 	}
941fea9cb91Slq150181 
942*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_get_color(tem, &fg_color, &bg_color, TEM_ATTR_REVERSE);
943*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_virtual_display(tem,
944*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tem->tvs_outbuf, tem->tvs_outindex,
945*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tem->tvs_s_cursor.row, tem->tvs_s_cursor.col,
946*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    fg_color, bg_color);
947*aecfc01dSrui zang - Sun Microsystems - Beijing China 
948*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_isactive) {
949fea9cb91Slq150181 		/*
950fea9cb91Slq150181 		 * Call the primitive to render this data.
951fea9cb91Slq150181 		 */
952*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_display(tem,
953*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_outbuf, tem->tvs_outindex,
954*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_s_cursor.row, tem->tvs_s_cursor.col,
955fea9cb91Slq150181 		    fg_color, bg_color,
956fea9cb91Slq150181 		    credp, called_from);
957fea9cb91Slq150181 	}
958*aecfc01dSrui zang - Sun Microsystems - Beijing China 
959*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_outindex = 0;
960*aecfc01dSrui zang - Sun Microsystems - Beijing China 
961*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
962fea9cb91Slq150181 }
963fea9cb91Slq150181 
964fea9cb91Slq150181 
965fea9cb91Slq150181 /*
966fea9cb91Slq150181  * We have just done something to the current output point.  Reset the start
967fea9cb91Slq150181  * point for the buffered data in a_outbuf.  There shouldn't be any data
968fea9cb91Slq150181  * buffered yet.
969fea9cb91Slq150181  */
970*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
971*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_align_cursor(struct tem_vt_state *tem)
972fea9cb91Slq150181 {
973*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.row = tem->tvs_c_cursor.row;
974*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.col = tem->tvs_c_cursor.col;
975fea9cb91Slq150181 }
976fea9cb91Slq150181 
977fea9cb91Slq150181 /*
978fea9cb91Slq150181  * State machine parser based on the current state and character input
979fea9cb91Slq150181  * major terminations are to control character or normal character
980fea9cb91Slq150181  */
981fea9cb91Slq150181 
982fea9cb91Slq150181 static void
983*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_parse(struct tem_vt_state *tem, uchar_t ch,
984fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
985fea9cb91Slq150181 {
986fea9cb91Slq150181 	int	i;
987fea9cb91Slq150181 
988fea9cb91Slq150181 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
989*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    MUTEX_HELD(&tem->tvs_lock));
990fea9cb91Slq150181 
991*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_state == A_STATE_START) {	/* Normal state? */
992*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (ch == A_CSI || ch == A_ESC || ch < ' ') {
993*aecfc01dSrui zang - Sun Microsystems - Beijing China 			/* Control */
994*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_control(tem, ch, credp, called_from);
995*aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else {
996fea9cb91Slq150181 			/* Display */
997*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_outch(tem, ch, credp, called_from);
998*aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
999fea9cb91Slq150181 		return;
1000fea9cb91Slq150181 	}
1001fea9cb91Slq150181 
1002fea9cb91Slq150181 	/* In <ESC> sequence */
1003*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_state != A_STATE_ESC) {	/* Need to get parameters? */
1004*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_state != A_STATE_CSI) {
1005*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_getparams(tem, ch, credp, called_from);
1006fea9cb91Slq150181 			return;
1007fea9cb91Slq150181 		}
1008fea9cb91Slq150181 
1009fea9cb91Slq150181 		switch (ch) {
1010fea9cb91Slq150181 		case '?':
1011*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_CSI_QMARK;
1012fea9cb91Slq150181 			return;
1013fea9cb91Slq150181 		case '=':
1014*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_CSI_EQUAL;
1015fea9cb91Slq150181 			return;
1016fea9cb91Slq150181 		case 's':
1017fea9cb91Slq150181 			/*
1018fea9cb91Slq150181 			 * As defined below, this sequence
1019fea9cb91Slq150181 			 * saves the cursor.  However, Sun
1020fea9cb91Slq150181 			 * defines ESC[s as reset.  We resolved
1021fea9cb91Slq150181 			 * the conflict by selecting reset as it
1022fea9cb91Slq150181 			 * is exported in the termcap file for
1023fea9cb91Slq150181 			 * sun-mon, while the "save cursor"
1024fea9cb91Slq150181 			 * definition does not exist anywhere in
1025fea9cb91Slq150181 			 * /etc/termcap.
1026fea9cb91Slq150181 			 * However, having no coherent
1027fea9cb91Slq150181 			 * definition of reset, we have not
1028fea9cb91Slq150181 			 * implemented it.
1029fea9cb91Slq150181 			 */
1030fea9cb91Slq150181 
1031fea9cb91Slq150181 			/*
1032fea9cb91Slq150181 			 * Original code
1033*aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * tem->tvs_r_cursor.row = tem->tvs_c_cursor.row;
1034*aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * tem->tvs_r_cursor.col = tem->tvs_c_cursor.col;
1035*aecfc01dSrui zang - Sun Microsystems - Beijing China 			 * tem->tvs_state = A_STATE_START;
1036fea9cb91Slq150181 			 */
1037fea9cb91Slq150181 
1038*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1039fea9cb91Slq150181 			return;
1040fea9cb91Slq150181 		case 'u':
1041*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_mv_cursor(tem, tem->tvs_r_cursor.row,
1042*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_r_cursor.col, credp, called_from);
1043*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1044fea9cb91Slq150181 			return;
1045fea9cb91Slq150181 		case 'p': 	/* sunbow */
1046*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_send_data(tem, credp, called_from);
1047fea9cb91Slq150181 			/*
1048fea9cb91Slq150181 			 * Don't set anything if we are
1049fea9cb91Slq150181 			 * already as we want to be.
1050fea9cb91Slq150181 			 */
1051*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
1052*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags &= ~TEM_ATTR_SCREEN_REVERSE;
1053fea9cb91Slq150181 				/*
1054fea9cb91Slq150181 				 * If we have switched the characters to be the
1055fea9cb91Slq150181 				 * inverse from the screen, then switch them as
1056fea9cb91Slq150181 				 * well to keep them the inverse of the screen.
1057fea9cb91Slq150181 				 */
1058*aecfc01dSrui zang - Sun Microsystems - Beijing China 				if (tem->tvs_flags & TEM_ATTR_REVERSE)
1059*aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags &= ~TEM_ATTR_REVERSE;
1060*aecfc01dSrui zang - Sun Microsystems - Beijing China 				else
1061*aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags |= TEM_ATTR_REVERSE;
1062fea9cb91Slq150181 			}
1063*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_cls(tem, credp, called_from);
1064*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1065fea9cb91Slq150181 			return;
1066fea9cb91Slq150181 		case 'q':  	/* sunwob */
1067*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_send_data(tem, credp, called_from);
1068fea9cb91Slq150181 			/*
1069fea9cb91Slq150181 			 * Don't set anything if we are
1070fea9cb91Slq150181 			 * already where as we want to be.
1071fea9cb91Slq150181 			 */
1072*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (!(tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE)) {
1073*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_flags |= TEM_ATTR_SCREEN_REVERSE;
1074fea9cb91Slq150181 				/*
1075fea9cb91Slq150181 				 * If we have switched the characters to be the
1076fea9cb91Slq150181 				 * inverse from the screen, then switch them as
1077fea9cb91Slq150181 				 * well to keep them the inverse of the screen.
1078fea9cb91Slq150181 				 */
1079*aecfc01dSrui zang - Sun Microsystems - Beijing China 				if (!(tem->tvs_flags & TEM_ATTR_REVERSE))
1080*aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags |= TEM_ATTR_REVERSE;
1081*aecfc01dSrui zang - Sun Microsystems - Beijing China 				else
1082*aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_flags &= ~TEM_ATTR_REVERSE;
1083fea9cb91Slq150181 			}
1084fea9cb91Slq150181 
1085*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_cls(tem, credp, called_from);
1086*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1087fea9cb91Slq150181 			return;
1088fea9cb91Slq150181 		case 'r':	/* sunscrl */
1089fea9cb91Slq150181 			/*
1090fea9cb91Slq150181 			 * Rule exception:  check for validity here.
1091fea9cb91Slq150181 			 */
1092*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_nscroll = tem->tvs_paramval;
1093*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_nscroll > tems.ts_c_dimension.height)
1094*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_nscroll = tems.ts_c_dimension.height;
1095*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_nscroll < 0)
1096*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_nscroll = 1;
1097*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_state = A_STATE_START;
1098fea9cb91Slq150181 			return;
1099fea9cb91Slq150181 		default:
1100*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_getparams(tem, ch, credp, called_from);
1101fea9cb91Slq150181 			return;
1102fea9cb91Slq150181 		}
1103fea9cb91Slq150181 	}
1104fea9cb91Slq150181 
1105fea9cb91Slq150181 	/* Previous char was <ESC> */
1106fea9cb91Slq150181 	if (ch == '[') {
1107*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_curparam = 0;
1108*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_paramval = 0;
1109*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_gotparam = B_FALSE;
1110fea9cb91Slq150181 		/* clear the parameters */
1111fea9cb91Slq150181 		for (i = 0; i < TEM_MAXPARAMS; i++)
1112*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_params[i] = -1;
1113*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_CSI;
1114fea9cb91Slq150181 	} else if (ch == 'Q') {	/* <ESC>Q ? */
1115*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1116fea9cb91Slq150181 	} else if (ch == 'C') {	/* <ESC>C ? */
1117*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1118fea9cb91Slq150181 	} else {
1119*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_state = A_STATE_START;
1120*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (ch == 'c') {
1121fea9cb91Slq150181 			/* ESC c resets display */
1122*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_reset_display(tem, credp, called_from,
1123*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    B_TRUE, B_TRUE);
1124*aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch == 'H') {
1125fea9cb91Slq150181 			/* ESC H sets a tab */
1126*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_set_tab(tem);
1127*aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch == '7') {
1128fea9cb91Slq150181 			/* ESC 7 Save Cursor position */
1129*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_r_cursor.row = tem->tvs_c_cursor.row;
1130*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_r_cursor.col = tem->tvs_c_cursor.col;
1131*aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch == '8') {
1132fea9cb91Slq150181 			/* ESC 8 Restore Cursor position */
1133*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_mv_cursor(tem, tem->tvs_r_cursor.row,
1134*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_r_cursor.col, credp, called_from);
1135fea9cb91Slq150181 		/* check for control chars */
1136*aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else if (ch < ' ') {
1137*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_control(tem, ch, credp, called_from);
1138*aecfc01dSrui zang - Sun Microsystems - Beijing China 		} else {
1139*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_outch(tem, ch, credp, called_from);
1140*aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
1141fea9cb91Slq150181 	}
1142fea9cb91Slq150181 }
1143fea9cb91Slq150181 
1144fea9cb91Slq150181 /* ARGSUSED */
1145fea9cb91Slq150181 static void
1146*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_bell(struct tem_vt_state *tem, enum called_from called_from)
1147fea9cb91Slq150181 {
1148fea9cb91Slq150181 	if (called_from == CALLED_FROM_STANDALONE)
1149c35aa225Smarx 		(void) beep_polled(BEEP_CONSOLE);
1150fea9cb91Slq150181 	else
1151c35aa225Smarx 		(void) beep(BEEP_CONSOLE);
1152fea9cb91Slq150181 }
1153fea9cb91Slq150181 
1154fea9cb91Slq150181 
1155fea9cb91Slq150181 static void
1156*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_scroll(struct tem_vt_state *tem, int start, int end, int count,
1157*aecfc01dSrui zang - Sun Microsystems - Beijing China     int direction,
1158fea9cb91Slq150181 	cred_t *credp, enum called_from called_from)
1159fea9cb91Slq150181 {
1160fea9cb91Slq150181 	int	row;
1161fea9cb91Slq150181 	int	lines_affected;
1162fea9cb91Slq150181 
1163*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1164*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1165fea9cb91Slq150181 
1166fea9cb91Slq150181 	lines_affected = end - start + 1;
1167fea9cb91Slq150181 	if (count > lines_affected)
1168fea9cb91Slq150181 		count = lines_affected;
1169fea9cb91Slq150181 	if (count <= 0)
1170fea9cb91Slq150181 		return;
1171fea9cb91Slq150181 
1172fea9cb91Slq150181 	switch (direction) {
1173fea9cb91Slq150181 	case TEM_SCROLL_UP:
1174fea9cb91Slq150181 		if (count < lines_affected) {
1175*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem, 0, start + count,
1176*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - 1, end,
1177fea9cb91Slq150181 			    0, start, credp, called_from);
1178fea9cb91Slq150181 		}
1179fea9cb91Slq150181 		for (row = (end - count) + 1; row <= end; row++) {
1180*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
1181fea9cb91Slq150181 			    row, 0, credp, called_from);
1182fea9cb91Slq150181 		}
1183fea9cb91Slq150181 		break;
1184fea9cb91Slq150181 
1185fea9cb91Slq150181 	case TEM_SCROLL_DOWN:
1186fea9cb91Slq150181 		if (count < lines_affected) {
1187*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem, 0, start,
1188*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - 1,
1189fea9cb91Slq150181 			    end - count, 0, start + count,
1190fea9cb91Slq150181 			    credp, called_from);
1191fea9cb91Slq150181 		}
1192fea9cb91Slq150181 		for (row = start; row < start + count; row++) {
1193*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
1194fea9cb91Slq150181 			    row, 0, credp, called_from);
1195fea9cb91Slq150181 		}
1196fea9cb91Slq150181 		break;
1197fea9cb91Slq150181 	}
1198fea9cb91Slq150181 }
1199fea9cb91Slq150181 
1200fea9cb91Slq150181 static void
1201*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_copy_area(struct tem_vt_state *tem,
1202fea9cb91Slq150181 	screen_pos_t s_col, screen_pos_t s_row,
1203fea9cb91Slq150181 	screen_pos_t e_col, screen_pos_t e_row,
1204fea9cb91Slq150181 	screen_pos_t t_col, screen_pos_t t_row,
1205fea9cb91Slq150181 	cred_t *credp, enum called_from called_from)
1206fea9cb91Slq150181 {
1207fea9cb91Slq150181 	int rows;
1208fea9cb91Slq150181 	int cols;
1209fea9cb91Slq150181 
1210*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1211*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1212fea9cb91Slq150181 
1213fea9cb91Slq150181 	if (s_col < 0 || s_row < 0 ||
1214fea9cb91Slq150181 	    e_col < 0 || e_row < 0 ||
1215fea9cb91Slq150181 	    t_col < 0 || t_row < 0 ||
1216*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col >= tems.ts_c_dimension.width ||
1217*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col >= tems.ts_c_dimension.width ||
1218*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col >= tems.ts_c_dimension.width ||
1219*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_row >= tems.ts_c_dimension.height ||
1220*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_row >= tems.ts_c_dimension.height ||
1221*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_row >= tems.ts_c_dimension.height)
1222fea9cb91Slq150181 		return;
1223fea9cb91Slq150181 
1224fea9cb91Slq150181 	if (s_row > e_row || s_col > e_col)
1225fea9cb91Slq150181 		return;
1226fea9cb91Slq150181 
1227fea9cb91Slq150181 	rows = e_row - s_row + 1;
1228fea9cb91Slq150181 	cols = e_col - s_col + 1;
1229*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (t_row + rows > tems.ts_c_dimension.height ||
1230*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col + cols > tems.ts_c_dimension.width)
1231fea9cb91Slq150181 		return;
1232fea9cb91Slq150181 
1233*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_virtual_copy(tem,
1234*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col, s_row,
1235*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col, e_row,
1236*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col, t_row);
1237*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1238*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_isactive)
1239*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1240*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1241*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_copy(tem, s_col, s_row,
1242fea9cb91Slq150181 	    e_col, e_row, t_col, t_row, credp, called_from);
1243fea9cb91Slq150181 }
1244fea9cb91Slq150181 
1245fea9cb91Slq150181 static void
1246*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_clear_chars(struct tem_vt_state *tem, int count, screen_pos_t row,
1247fea9cb91Slq150181 	screen_pos_t col, cred_t *credp, enum called_from called_from)
1248fea9cb91Slq150181 {
1249*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1250*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1251fea9cb91Slq150181 
1252*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row < 0 || row >= tems.ts_c_dimension.height ||
1253*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col < 0 || col >= tems.ts_c_dimension.width ||
1254fea9cb91Slq150181 	    count < 0)
1255fea9cb91Slq150181 		return;
1256fea9cb91Slq150181 
1257fea9cb91Slq150181 	/*
1258fea9cb91Slq150181 	 * Note that very large values of "count" could cause col+count
1259fea9cb91Slq150181 	 * to overflow, so we check "count" independently.
1260fea9cb91Slq150181 	 */
1261*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (count > tems.ts_c_dimension.width ||
1262*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col + count > tems.ts_c_dimension.width)
1263*aecfc01dSrui zang - Sun Microsystems - Beijing China 		count = tems.ts_c_dimension.width - col;
1264fea9cb91Slq150181 
1265*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_virtual_cls(tem, count, row, col);
1266*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1267*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_isactive)
1268*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1269*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1270*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_cls(tem, count, row, col, credp, called_from);
1271fea9cb91Slq150181 }
1272fea9cb91Slq150181 
1273*aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
1274fea9cb91Slq150181 void
1275*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_display(struct tem_vt_state *tem, uchar_t *string,
1276fea9cb91Slq150181 	int count, screen_pos_t row, screen_pos_t col,
1277fea9cb91Slq150181 	text_color_t fg_color, text_color_t bg_color,
1278fea9cb91Slq150181 	cred_t *credp, enum called_from called_from)
1279fea9cb91Slq150181 {
1280fea9cb91Slq150181 	struct vis_consdisplay da;
1281fea9cb91Slq150181 
1282*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1283*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1284*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1285fea9cb91Slq150181 	da.data = string;
1286*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.width = (screen_size_t)count;
1287fea9cb91Slq150181 	da.row = row;
1288fea9cb91Slq150181 	da.col = col;
1289fea9cb91Slq150181 
1290fea9cb91Slq150181 	da.fg_color = fg_color;
1291fea9cb91Slq150181 	da.bg_color = bg_color;
1292fea9cb91Slq150181 
1293*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_display(&da, credp, called_from);
1294fea9cb91Slq150181 }
1295fea9cb91Slq150181 
1296fea9cb91Slq150181 /*
1297fea9cb91Slq150181  * This function is used to blit a rectangular color image,
1298fea9cb91Slq150181  * unperturbed on the underlying framebuffer, to render
1299fea9cb91Slq150181  * icons and pictures.  The data is a pixel pattern that
1300fea9cb91Slq150181  * fills a rectangle bounded to the width and height parameters.
1301fea9cb91Slq150181  * The color pixel data must to be pre-adjusted by the caller
1302fea9cb91Slq150181  * for the current video depth.
1303fea9cb91Slq150181  *
1304fea9cb91Slq150181  * This function is unused now.
1305fea9cb91Slq150181  */
1306*aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
1307*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
1308*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_image_display(struct tem_vt_state *tem, uchar_t *image,
1309fea9cb91Slq150181 	int height, int width, screen_pos_t row, screen_pos_t col,
1310fea9cb91Slq150181 	cred_t *credp, enum called_from called_from)
1311fea9cb91Slq150181 {
1312fea9cb91Slq150181 	struct vis_consdisplay da;
1313fea9cb91Slq150181 
1314*aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&tems.ts_lock);
1315*aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_enter(&tem->tvs_lock);
1316*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1317fea9cb91Slq150181 	da.data = image;
1318*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.width = (screen_size_t)width;
1319*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.height = (screen_size_t)height;
1320fea9cb91Slq150181 	da.row = row;
1321fea9cb91Slq150181 	da.col = col;
1322fea9cb91Slq150181 
1323*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_display(&da, credp, called_from);
1324*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1325*aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&tem->tvs_lock);
1326*aecfc01dSrui zang - Sun Microsystems - Beijing China 	mutex_exit(&tems.ts_lock);
1327fea9cb91Slq150181 }
1328fea9cb91Slq150181 
1329fea9cb91Slq150181 
1330*aecfc01dSrui zang - Sun Microsystems - Beijing China /*ARGSUSED*/
1331fea9cb91Slq150181 void
1332*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_copy(struct tem_vt_state *tem,
1333fea9cb91Slq150181 	screen_pos_t s_col, screen_pos_t s_row,
1334fea9cb91Slq150181 	screen_pos_t e_col, screen_pos_t e_row,
1335fea9cb91Slq150181 	screen_pos_t t_col, screen_pos_t t_row,
1336fea9cb91Slq150181 	cred_t *credp, enum called_from called_from)
1337fea9cb91Slq150181 {
1338fea9cb91Slq150181 	struct vis_conscopy da;
1339fea9cb91Slq150181 
1340*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1341*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1342*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1343fea9cb91Slq150181 	da.s_row = s_row;
1344fea9cb91Slq150181 	da.s_col = s_col;
1345fea9cb91Slq150181 	da.e_row = e_row;
1346fea9cb91Slq150181 	da.e_col = e_col;
1347fea9cb91Slq150181 	da.t_row = t_row;
1348fea9cb91Slq150181 	da.t_col = t_col;
1349fea9cb91Slq150181 
1350*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_copy(&da, credp, called_from);
1351fea9cb91Slq150181 }
1352fea9cb91Slq150181 
1353fea9cb91Slq150181 void
1354*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_cls(struct tem_vt_state *tem,
1355fea9cb91Slq150181 	int count, screen_pos_t row, screen_pos_t col, cred_t *credp,
1356fea9cb91Slq150181 	enum called_from called_from)
1357fea9cb91Slq150181 {
1358fea9cb91Slq150181 	struct vis_consdisplay da;
1359fea9cb91Slq150181 
1360*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1361*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1362*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1363*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.data = tems.ts_blank_line;
1364*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.width = (screen_size_t)count;
1365fea9cb91Slq150181 	da.row = row;
1366fea9cb91Slq150181 	da.col = col;
1367fea9cb91Slq150181 
1368*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_get_color(tem, &da.fg_color, &da.bg_color,
1369*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    TEM_ATTR_SCREEN_REVERSE);
1370*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_display(&da, credp, called_from);
1371fea9cb91Slq150181 }
1372fea9cb91Slq150181 
1373fea9cb91Slq150181 
1374fea9cb91Slq150181 
1375fea9cb91Slq150181 void
1376*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_display(struct tem_vt_state *tem,
1377fea9cb91Slq150181 	uchar_t *string, int count,
1378fea9cb91Slq150181 	screen_pos_t row, screen_pos_t col,
1379fea9cb91Slq150181 	text_color_t fg_color, text_color_t bg_color,
1380fea9cb91Slq150181 	cred_t *credp, enum called_from called_from)
1381fea9cb91Slq150181 {
1382fea9cb91Slq150181 	struct vis_consdisplay da;
1383fea9cb91Slq150181 	int	i;
1384*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1385*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1386*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1387*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1388*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.data = (uchar_t *)tem->tvs_pix_data;
1389*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.width = tems.ts_font.width;
1390*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.height = tems.ts_font.height;
1391*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.row = (row * da.height) + tems.ts_p_offset.y;
1392*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.col = (col * da.width) + tems.ts_p_offset.x;
1393fea9cb91Slq150181 
1394fea9cb91Slq150181 	for (i = 0; i < count; i++) {
1395*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_bit2pix(tem, string[i], fg_color, bg_color);
1396*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tems_safe_display(&da, credp, called_from);
1397fea9cb91Slq150181 		da.col += da.width;
1398fea9cb91Slq150181 	}
1399fea9cb91Slq150181 }
1400fea9cb91Slq150181 
1401fea9cb91Slq150181 void
1402*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_copy(struct tem_vt_state *tem,
1403fea9cb91Slq150181 	screen_pos_t s_col, screen_pos_t s_row,
1404fea9cb91Slq150181 	screen_pos_t e_col, screen_pos_t e_row,
1405fea9cb91Slq150181 	screen_pos_t t_col, screen_pos_t t_row,
1406fea9cb91Slq150181 	cred_t *credp,
1407fea9cb91Slq150181 	enum called_from called_from)
1408fea9cb91Slq150181 {
1409fea9cb91Slq150181 	struct vis_conscopy ma;
1410fea9cb91Slq150181 	static boolean_t need_clear = B_TRUE;
1411fea9cb91Slq150181 
1412*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1413*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1414fea9cb91Slq150181 
1415*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (need_clear && tem->tvs_first_line > 0) {
1416fea9cb91Slq150181 		/*
1417fea9cb91Slq150181 		 * Clear OBP output above our kernel console term
1418fea9cb91Slq150181 		 * when our kernel console term begins to scroll up,
1419fea9cb91Slq150181 		 * we hope it is user friendly.
1420*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * (Also see comments on tem_safe_pix_clear_prom_output)
1421fea9cb91Slq150181 		 *
1422fea9cb91Slq150181 		 * This is only one time call.
1423fea9cb91Slq150181 		 */
1424*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_pix_clear_prom_output(tem, credp, called_from);
1425fea9cb91Slq150181 	}
1426fea9cb91Slq150181 	need_clear = B_FALSE;
1427fea9cb91Slq150181 
1428*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ma.s_row = s_row * tems.ts_font.height + tems.ts_p_offset.y;
1429*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ma.e_row = (e_row + 1) * tems.ts_font.height + tems.ts_p_offset.y - 1;
1430*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ma.t_row = t_row * tems.ts_font.height + tems.ts_p_offset.y;
1431fea9cb91Slq150181 
1432fea9cb91Slq150181 	/*
1433fea9cb91Slq150181 	 * Check if we're in process of clearing OBP's columns area,
1434fea9cb91Slq150181 	 * which only happens when term scrolls up a whole line.
1435fea9cb91Slq150181 	 */
1436*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_first_line > 0 && t_row < s_row && t_col == 0 &&
1437*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col == tems.ts_c_dimension.width - 1) {
1438fea9cb91Slq150181 		/*
1439fea9cb91Slq150181 		 * We need to clear OBP's columns area outside our kernel
1440fea9cb91Slq150181 		 * console term. So that we set ma.e_col to entire row here.
1441fea9cb91Slq150181 		 */
1442*aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.s_col = s_col * tems.ts_font.width;
1443*aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.e_col = tems.ts_p_dimension.width - 1;
1444fea9cb91Slq150181 
1445*aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.t_col = t_col * tems.ts_font.width;
1446fea9cb91Slq150181 	} else {
1447*aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.s_col = s_col * tems.ts_font.width + tems.ts_p_offset.x;
1448*aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.e_col = (e_col + 1) * tems.ts_font.width +
1449*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_p_offset.x - 1;
1450*aecfc01dSrui zang - Sun Microsystems - Beijing China 		ma.t_col = t_col * tems.ts_font.width + tems.ts_p_offset.x;
1451fea9cb91Slq150181 	}
1452fea9cb91Slq150181 
1453*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_copy(&ma, credp, called_from);
1454fea9cb91Slq150181 
1455*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_first_line > 0 && t_row < s_row) {
1456fea9cb91Slq150181 		/* We have scrolled up (s_row - t_row) rows. */
1457*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_first_line -= (s_row - t_row);
1458*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_first_line <= 0) {
1459fea9cb91Slq150181 			/* All OBP rows have been cleared. */
1460*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_first_line = 0;
1461fea9cb91Slq150181 		}
1462fea9cb91Slq150181 	}
1463fea9cb91Slq150181 
1464fea9cb91Slq150181 }
1465fea9cb91Slq150181 
1466*aecfc01dSrui zang - Sun Microsystems - Beijing China void
1467*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_bit2pix(struct tem_vt_state *tem, unsigned char c,
1468*aecfc01dSrui zang - Sun Microsystems - Beijing China     unsigned char fg, unsigned char bg)
1469*aecfc01dSrui zang - Sun Microsystems - Beijing China {
1470*aecfc01dSrui zang - Sun Microsystems - Beijing China 	void (*fp)(struct tem_vt_state *, unsigned char,
1471*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    unsigned char, unsigned char);
1472*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1473*aecfc01dSrui zang - Sun Microsystems - Beijing China 	switch (tems.ts_pdepth) {
1474*aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 4:
1475*aecfc01dSrui zang - Sun Microsystems - Beijing China 		fp = bit_to_pix4;
1476*aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1477*aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 8:
1478*aecfc01dSrui zang - Sun Microsystems - Beijing China 		fp = bit_to_pix8;
1479*aecfc01dSrui zang - Sun Microsystems - Beijing China 		break;
1480*aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 24:
1481*aecfc01dSrui zang - Sun Microsystems - Beijing China 	case 32:
1482*aecfc01dSrui zang - Sun Microsystems - Beijing China 		fp = bit_to_pix24;
1483*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1484*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1485*aecfc01dSrui zang - Sun Microsystems - Beijing China 	fp(tem, c, fg, bg);
1486*aecfc01dSrui zang - Sun Microsystems - Beijing China }
1487*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1488*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1489fea9cb91Slq150181 /*
1490fea9cb91Slq150181  * This function only clears count of columns in one row
1491fea9cb91Slq150181  */
1492fea9cb91Slq150181 void
1493*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cls(struct tem_vt_state *tem, int count,
1494fea9cb91Slq150181 	screen_pos_t row, screen_pos_t col, cred_t *credp,
1495fea9cb91Slq150181 	enum called_from called_from)
1496fea9cb91Slq150181 {
1497*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1498*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1499fea9cb91Slq150181 
1500*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_pix_cls_range(tem, row, 1, tems.ts_p_offset.y,
1501*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col, count, tems.ts_p_offset.x, B_FALSE, credp, called_from);
1502fea9cb91Slq150181 }
1503fea9cb91Slq150181 
1504fea9cb91Slq150181 /*
1505fea9cb91Slq150181  * This function clears OBP output above our kernel console term area
1506fea9cb91Slq150181  * because OBP's term may have a bigger terminal window than that of
1507fea9cb91Slq150181  * our kernel console term. So we need to clear OBP output garbage outside
1508fea9cb91Slq150181  * of our kernel console term at a proper time, which is when the first
1509fea9cb91Slq150181  * row output of our kernel console term scrolls at the first screen line.
1510fea9cb91Slq150181  *
1511fea9cb91Slq150181  *	_________________________________
1512fea9cb91Slq150181  *	|   _____________________	|  ---> OBP's bigger term window
1513fea9cb91Slq150181  *	|   |			|	|
1514fea9cb91Slq150181  *	|___|			|	|
1515fea9cb91Slq150181  *	| | |			|	|
1516fea9cb91Slq150181  *	| | |			|	|
1517fea9cb91Slq150181  *	|_|_|___________________|_______|
1518fea9cb91Slq150181  *	  | |			|	   ---> first line
1519fea9cb91Slq150181  *	  | |___________________|---> our kernel console term window
1520fea9cb91Slq150181  *	  |
1521fea9cb91Slq150181  *	  |---> columns area to be cleared
1522fea9cb91Slq150181  *
1523fea9cb91Slq150181  * This function only takes care of the output above our kernel console term,
1524fea9cb91Slq150181  * and tem_prom_scroll_up takes care of columns area outside of our kernel
1525fea9cb91Slq150181  * console term.
1526fea9cb91Slq150181  */
1527fea9cb91Slq150181 static void
1528*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_clear_prom_output(struct tem_vt_state *tem, cred_t *credp,
1529fea9cb91Slq150181     enum called_from called_from)
1530fea9cb91Slq150181 {
1531fea9cb91Slq150181 	int	nrows, ncols, width, height;
1532fea9cb91Slq150181 
1533*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1534*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1535fea9cb91Slq150181 
1536*aecfc01dSrui zang - Sun Microsystems - Beijing China 	width = tems.ts_font.width;
1537*aecfc01dSrui zang - Sun Microsystems - Beijing China 	height = tems.ts_font.height;
1538fea9cb91Slq150181 
1539*aecfc01dSrui zang - Sun Microsystems - Beijing China 	nrows = (tems.ts_p_offset.y + (height - 1))/ height;
1540*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
1541fea9cb91Slq150181 
1542*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_pix_cls_range(tem, 0, nrows, 0, 0, ncols, 0,
1543fea9cb91Slq150181 	    B_FALSE, credp, called_from);
1544fea9cb91Slq150181 }
1545fea9cb91Slq150181 
1546fea9cb91Slq150181 /*
1547*aecfc01dSrui zang - Sun Microsystems - Beijing China  * clear the whole screen for pixel mode, just clear the
1548*aecfc01dSrui zang - Sun Microsystems - Beijing China  * physical screen.
1549fea9cb91Slq150181  */
1550*aecfc01dSrui zang - Sun Microsystems - Beijing China void
1551*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_clear_entire_screen(struct tem_vt_state *tem, cred_t *credp,
1552fea9cb91Slq150181     enum called_from called_from)
1553fea9cb91Slq150181 {
1554fea9cb91Slq150181 	int	nrows, ncols, width, height;
1555fea9cb91Slq150181 
1556*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1557*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1558fea9cb91Slq150181 
1559*aecfc01dSrui zang - Sun Microsystems - Beijing China 	width = tems.ts_font.width;
1560*aecfc01dSrui zang - Sun Microsystems - Beijing China 	height = tems.ts_font.height;
1561fea9cb91Slq150181 
1562*aecfc01dSrui zang - Sun Microsystems - Beijing China 	nrows = (tems.ts_p_dimension.height + (height - 1))/ height;
1563*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
1564fea9cb91Slq150181 
1565*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_pix_cls_range(tem, 0, nrows, 0, 0, ncols, 0,
1566fea9cb91Slq150181 	    B_FALSE, credp, called_from);
1567fea9cb91Slq150181 
1568fea9cb91Slq150181 	/*
1569fea9cb91Slq150181 	 * Since the whole screen is cleared, we don't need
1570fea9cb91Slq150181 	 * to clear OBP output later.
1571fea9cb91Slq150181 	 */
1572*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_first_line > 0)
1573*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_first_line = 0;
1574fea9cb91Slq150181 }
1575fea9cb91Slq150181 
1576fea9cb91Slq150181 /*
1577*aecfc01dSrui zang - Sun Microsystems - Beijing China  * clear the whole screen, including the virtual screen buffer,
1578*aecfc01dSrui zang - Sun Microsystems - Beijing China  * and reset the cursor to start point.
1579fea9cb91Slq150181  */
1580fea9cb91Slq150181 static void
1581*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_cls(struct tem_vt_state *tem,
1582fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
1583fea9cb91Slq150181 {
1584fea9cb91Slq150181 	int	row;
1585fea9cb91Slq150181 
1586*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1587*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1588fea9cb91Slq150181 
1589*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_TEXT) {
1590*aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (row = 0; row < tems.ts_c_dimension.height; row++) {
1591*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
1592fea9cb91Slq150181 			    row, 0, credp, called_from);
1593fea9cb91Slq150181 		}
1594*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.row = 0;
1595*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.col = 0;
1596*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_align_cursor(tem);
1597fea9cb91Slq150181 		return;
1598fea9cb91Slq150181 	}
1599fea9cb91Slq150181 
1600*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT(tems.ts_display_mode == VIS_PIXEL);
1601fea9cb91Slq150181 
1602*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_c_dimension.height; row++) {
1603*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_virtual_cls(tem, tems.ts_c_dimension.width, row, 0);
1604*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
1605*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.row = 0;
1606*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = 0;
1607*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
1608*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1609*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (!tem->tvs_isactive)
1610*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
1611*aecfc01dSrui zang - Sun Microsystems - Beijing China 
1612*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_pix_clear_entire_screen(tem, credp, called_from);
1613fea9cb91Slq150181 }
1614fea9cb91Slq150181 
1615fea9cb91Slq150181 static void
1616*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_back_tab(struct tem_vt_state *tem,
1617fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
1618fea9cb91Slq150181 {
1619fea9cb91Slq150181 	int	i;
1620fea9cb91Slq150181 	screen_pos_t	tabstop;
1621fea9cb91Slq150181 
1622*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1623*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1624fea9cb91Slq150181 
1625fea9cb91Slq150181 	tabstop = 0;
1626fea9cb91Slq150181 
1627*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = tem->tvs_ntabs - 1; i >= 0; i--) {
1628*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] < tem->tvs_c_cursor.col) {
1629*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tabstop = tem->tvs_tabs[i];
1630fea9cb91Slq150181 			break;
1631fea9cb91Slq150181 		}
1632fea9cb91Slq150181 	}
1633fea9cb91Slq150181 
1634*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_mv_cursor(tem, tem->tvs_c_cursor.row,
1635fea9cb91Slq150181 	    tabstop, credp, called_from);
1636fea9cb91Slq150181 }
1637fea9cb91Slq150181 
1638fea9cb91Slq150181 static void
1639*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_tab(struct tem_vt_state *tem,
1640fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
1641fea9cb91Slq150181 {
1642fea9cb91Slq150181 	int	i;
1643fea9cb91Slq150181 	screen_pos_t	tabstop;
1644fea9cb91Slq150181 
1645*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1646*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1647fea9cb91Slq150181 
1648*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tabstop = tems.ts_c_dimension.width - 1;
1649fea9cb91Slq150181 
1650*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = 0; i < tem->tvs_ntabs; i++) {
1651*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) {
1652*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tabstop = tem->tvs_tabs[i];
1653fea9cb91Slq150181 			break;
1654fea9cb91Slq150181 		}
1655fea9cb91Slq150181 	}
1656fea9cb91Slq150181 
1657*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_mv_cursor(tem, tem->tvs_c_cursor.row,
1658fea9cb91Slq150181 	    tabstop, credp, called_from);
1659fea9cb91Slq150181 }
1660fea9cb91Slq150181 
1661fea9cb91Slq150181 static void
1662*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_set_tab(struct tem_vt_state *tem)
1663fea9cb91Slq150181 {
1664fea9cb91Slq150181 	int	i;
1665fea9cb91Slq150181 	int	j;
1666fea9cb91Slq150181 
1667*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_ntabs == TEM_MAXTAB)
1668fea9cb91Slq150181 		return;
1669*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_ntabs == 0 ||
1670*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tem->tvs_tabs[tem->tvs_ntabs] < tem->tvs_c_cursor.col) {
1671*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_tabs[tem->tvs_ntabs++] = tem->tvs_c_cursor.col;
1672fea9cb91Slq150181 			return;
1673fea9cb91Slq150181 	}
1674*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = 0; i < tem->tvs_ntabs; i++) {
1675*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col)
1676fea9cb91Slq150181 			return;
1677*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) {
1678*aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (j = tem->tvs_ntabs - 1; j >= i; j--)
1679*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_tabs[j+ 1] = tem->tvs_tabs[j];
1680*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_tabs[i] = tem->tvs_c_cursor.col;
1681*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem->tvs_ntabs++;
1682fea9cb91Slq150181 			return;
1683fea9cb91Slq150181 		}
1684fea9cb91Slq150181 	}
1685fea9cb91Slq150181 }
1686fea9cb91Slq150181 
1687fea9cb91Slq150181 static void
1688*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_clear_tabs(struct tem_vt_state *tem, int action)
1689fea9cb91Slq150181 {
1690fea9cb91Slq150181 	int	i;
1691fea9cb91Slq150181 	int	j;
1692fea9cb91Slq150181 
1693fea9cb91Slq150181 	switch (action) {
1694fea9cb91Slq150181 	case 3: /* clear all tabs */
1695*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_ntabs = 0;
1696fea9cb91Slq150181 		break;
1697fea9cb91Slq150181 	case 0: /* clr tab at cursor */
1698fea9cb91Slq150181 
1699*aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (i = 0; i < tem->tvs_ntabs; i++) {
1700*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col) {
1701*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem->tvs_ntabs--;
1702*aecfc01dSrui zang - Sun Microsystems - Beijing China 				for (j = i; j < tem->tvs_ntabs; j++)
1703*aecfc01dSrui zang - Sun Microsystems - Beijing China 					tem->tvs_tabs[j] = tem->tvs_tabs[j + 1];
1704fea9cb91Slq150181 				return;
1705fea9cb91Slq150181 			}
1706fea9cb91Slq150181 		}
1707fea9cb91Slq150181 		break;
1708fea9cb91Slq150181 	}
1709fea9cb91Slq150181 }
1710fea9cb91Slq150181 
1711fea9cb91Slq150181 static void
1712*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_mv_cursor(struct tem_vt_state *tem, int row, int col,
1713fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
1714fea9cb91Slq150181 {
1715*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1716*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1717fea9cb91Slq150181 
1718fea9cb91Slq150181 	/*
1719fea9cb91Slq150181 	 * Sanity check and bounds enforcement.  Out of bounds requests are
1720fea9cb91Slq150181 	 * clipped to the screen boundaries.  This seems to be what SPARC
1721fea9cb91Slq150181 	 * does.
1722fea9cb91Slq150181 	 */
1723fea9cb91Slq150181 	if (row < 0)
1724fea9cb91Slq150181 		row = 0;
1725*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row >= tems.ts_c_dimension.height)
1726*aecfc01dSrui zang - Sun Microsystems - Beijing China 		row = tems.ts_c_dimension.height - 1;
1727fea9cb91Slq150181 	if (col < 0)
1728fea9cb91Slq150181 		col = 0;
1729*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (col >= tems.ts_c_dimension.width)
1730*aecfc01dSrui zang - Sun Microsystems - Beijing China 		col = tems.ts_c_dimension.width - 1;
1731fea9cb91Slq150181 
1732*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_send_data(tem, credp, called_from);
1733*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.row = (screen_pos_t)row;
1734*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = (screen_pos_t)col;
1735*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_align_cursor(tem);
1736fea9cb91Slq150181 }
1737fea9cb91Slq150181 
1738fea9cb91Slq150181 /* ARGSUSED */
1739fea9cb91Slq150181 void
1740*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_reset_emulator(struct tem_vt_state *tem,
1741c9503a49Slq150181     cred_t *credp, enum called_from called_from,
1742*aecfc01dSrui zang - Sun Microsystems - Beijing China     boolean_t init_color)
1743fea9cb91Slq150181 {
1744fea9cb91Slq150181 	int j;
1745fea9cb91Slq150181 
1746*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1747*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1748fea9cb91Slq150181 
1749*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.row = 0;
1750*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_c_cursor.col = 0;
1751*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_r_cursor.row = 0;
1752*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_r_cursor.col = 0;
1753*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.row = 0;
1754*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_s_cursor.col = 0;
1755*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_outindex = 0;
1756*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_state = A_STATE_START;
1757*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_gotparam = B_FALSE;
1758*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_curparam = 0;
1759*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_paramval = 0;
1760*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_nscroll = 1;
1761c9503a49Slq150181 
1762*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (init_color) {
1763c9503a49Slq150181 		/* use initial settings */
1764*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_fg_color = tems.ts_init_color.fg_color;
1765*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_bg_color = tems.ts_init_color.bg_color;
1766*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_flags = tems.ts_init_color.a_flags;
1767c9503a49Slq150181 	}
1768fea9cb91Slq150181 
1769fea9cb91Slq150181 	/*
1770fea9cb91Slq150181 	 * set up the initial tab stops
1771fea9cb91Slq150181 	 */
1772*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem->tvs_ntabs = 0;
1773*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (j = 8; j < tems.ts_c_dimension.width; j += 8)
1774*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_tabs[tem->tvs_ntabs++] = (screen_pos_t)j;
1775fea9cb91Slq150181 
1776fea9cb91Slq150181 	for (j = 0; j < TEM_MAXPARAMS; j++)
1777*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_params[j] = 0;
1778fea9cb91Slq150181 }
1779fea9cb91Slq150181 
1780fea9cb91Slq150181 void
1781*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_reset_display(struct tem_vt_state *tem,
1782*aecfc01dSrui zang - Sun Microsystems - Beijing China     cred_t *credp, enum called_from called_from,
1783*aecfc01dSrui zang - Sun Microsystems - Beijing China     boolean_t clear_txt, boolean_t init_color)
1784fea9cb91Slq150181 {
1785*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1786*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1787fea9cb91Slq150181 
1788*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_reset_emulator(tem, credp, called_from, init_color);
1789fea9cb91Slq150181 
1790fea9cb91Slq150181 	if (clear_txt) {
1791*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_isactive)
1792*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_callback_cursor(tem,
1793fea9cb91Slq150181 			    VIS_HIDE_CURSOR, credp, called_from);
1794fea9cb91Slq150181 
1795*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_cls(tem, credp, called_from);
1796fea9cb91Slq150181 
1797*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_isactive)
1798*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_callback_cursor(tem,
1799fea9cb91Slq150181 			    VIS_DISPLAY_CURSOR, credp, called_from);
1800fea9cb91Slq150181 	}
1801fea9cb91Slq150181 }
1802fea9cb91Slq150181 
1803fea9cb91Slq150181 static void
1804*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_shift(
1805*aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem,
1806fea9cb91Slq150181 	int count,
1807fea9cb91Slq150181 	int direction,
1808fea9cb91Slq150181 	cred_t *credp,
1809fea9cb91Slq150181 	enum called_from called_from)
1810fea9cb91Slq150181 {
1811fea9cb91Slq150181 	int rest_of_line;
1812fea9cb91Slq150181 
1813*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1814*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1815fea9cb91Slq150181 
1816*aecfc01dSrui zang - Sun Microsystems - Beijing China 	rest_of_line = tems.ts_c_dimension.width - tem->tvs_c_cursor.col;
1817fea9cb91Slq150181 	if (count > rest_of_line)
1818fea9cb91Slq150181 		count = rest_of_line;
1819fea9cb91Slq150181 
1820fea9cb91Slq150181 	if (count <= 0)
1821fea9cb91Slq150181 		return;
1822fea9cb91Slq150181 
1823fea9cb91Slq150181 	switch (direction) {
1824fea9cb91Slq150181 	case TEM_SHIFT_LEFT:
1825fea9cb91Slq150181 		if (count < rest_of_line) {
1826*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem,
1827*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + count,
1828*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1829*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - 1,
1830*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1831*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
1832*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1833fea9cb91Slq150181 			    credp, called_from);
1834fea9cb91Slq150181 		}
1835fea9cb91Slq150181 
1836*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem, count, tem->tvs_c_cursor.row,
1837*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    (tems.ts_c_dimension.width - count), credp,
1838fea9cb91Slq150181 		    called_from);
1839fea9cb91Slq150181 		break;
1840fea9cb91Slq150181 	case TEM_SHIFT_RIGHT:
1841fea9cb91Slq150181 		if (count < rest_of_line) {
1842*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tem_safe_copy_area(tem,
1843*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col,
1844*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1845*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tems.ts_c_dimension.width - count - 1,
1846*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1847*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.col + count,
1848*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_c_cursor.row,
1849fea9cb91Slq150181 			    credp, called_from);
1850fea9cb91Slq150181 		}
1851fea9cb91Slq150181 
1852*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_clear_chars(tem, count, tem->tvs_c_cursor.row,
1853*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_c_cursor.col, credp, called_from);
1854fea9cb91Slq150181 		break;
1855fea9cb91Slq150181 	}
1856fea9cb91Slq150181 }
1857fea9cb91Slq150181 
1858fea9cb91Slq150181 void
1859*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_text_cursor(struct tem_vt_state *tem, short action,
1860fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
1861fea9cb91Slq150181 {
1862fea9cb91Slq150181 	struct vis_conscursor	ca;
1863fea9cb91Slq150181 
1864*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1865*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1866fea9cb91Slq150181 
1867*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.row = tem->tvs_c_cursor.row;
1868*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.col = tem->tvs_c_cursor.col;
1869fea9cb91Slq150181 	ca.action = action;
1870fea9cb91Slq150181 
1871*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_cursor(&ca, credp, called_from);
1872fea9cb91Slq150181 
1873fea9cb91Slq150181 	if (action == VIS_GET_CURSOR) {
1874*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.row = ca.row;
1875*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem->tvs_c_cursor.col = ca.col;
1876fea9cb91Slq150181 	}
1877fea9cb91Slq150181 }
1878fea9cb91Slq150181 
1879fea9cb91Slq150181 void
1880*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cursor(struct tem_vt_state *tem, short action,
1881fea9cb91Slq150181     cred_t *credp, enum called_from called_from)
1882fea9cb91Slq150181 {
1883fea9cb91Slq150181 	struct vis_conscursor	ca;
1884fea9cb91Slq150181 
1885*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1886*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
1887fea9cb91Slq150181 
1888*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.row = tem->tvs_c_cursor.row * tems.ts_font.height +
1889*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tems.ts_p_offset.y;
1890*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.col = tem->tvs_c_cursor.col * tems.ts_font.width +
1891*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    tems.ts_p_offset.x;
1892*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.width = tems.ts_font.width;
1893*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ca.height = tems.ts_font.height;
1894*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_pdepth == 8 || tems.ts_pdepth == 4) {
1895*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_flags & TEM_ATTR_REVERSE) {
1896fea9cb91Slq150181 			ca.fg_color.mono = TEM_TEXT_WHITE;
1897fea9cb91Slq150181 			ca.bg_color.mono = TEM_TEXT_BLACK;
1898fea9cb91Slq150181 		} else {
1899fea9cb91Slq150181 			ca.fg_color.mono = TEM_TEXT_BLACK;
1900fea9cb91Slq150181 			ca.bg_color.mono = TEM_TEXT_WHITE;
1901fea9cb91Slq150181 		}
1902*aecfc01dSrui zang - Sun Microsystems - Beijing China 	} else if (tems.ts_pdepth == 24 || tems.ts_pdepth == 32) {
1903*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (tem->tvs_flags & TEM_ATTR_REVERSE) {
1904fea9cb91Slq150181 			ca.fg_color.twentyfour[0] = TEM_TEXT_WHITE24_RED;
1905fea9cb91Slq150181 			ca.fg_color.twentyfour[1] = TEM_TEXT_WHITE24_GREEN;
1906fea9cb91Slq150181 			ca.fg_color.twentyfour[2] = TEM_TEXT_WHITE24_BLUE;
1907fea9cb91Slq150181 
1908fea9cb91Slq150181 			ca.bg_color.twentyfour[0] = TEM_TEXT_BLACK24_RED;
1909fea9cb91Slq150181 			ca.bg_color.twentyfour[1] = TEM_TEXT_BLACK24_GREEN;
1910fea9cb91Slq150181 			ca.bg_color.twentyfour[2] = TEM_TEXT_BLACK24_BLUE;
1911fea9cb91Slq150181 		} else {
1912fea9cb91Slq150181 			ca.fg_color.twentyfour[0] = TEM_TEXT_BLACK24_RED;
1913fea9cb91Slq150181 			ca.fg_color.twentyfour[1] = TEM_TEXT_BLACK24_GREEN;
1914fea9cb91Slq150181 			ca.fg_color.twentyfour[2] = TEM_TEXT_BLACK24_BLUE;
1915fea9cb91Slq150181 
1916fea9cb91Slq150181 			ca.bg_color.twentyfour[0] = TEM_TEXT_WHITE24_RED;
1917fea9cb91Slq150181 			ca.bg_color.twentyfour[1] = TEM_TEXT_WHITE24_GREEN;
1918fea9cb91Slq150181 			ca.bg_color.twentyfour[2] = TEM_TEXT_WHITE24_BLUE;
1919fea9cb91Slq150181 		}
1920fea9cb91Slq150181 	}
1921fea9cb91Slq150181 
1922fea9cb91Slq150181 	ca.action = action;
1923fea9cb91Slq150181 
1924*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tems_safe_cursor(&ca, credp, called_from);
1925fea9cb91Slq150181 }
1926fea9cb91Slq150181 
1927fea9cb91Slq150181 #define	BORDER_PIXELS 10
1928fea9cb91Slq150181 void
1929fea9cb91Slq150181 set_font(struct font *f, short *rows, short *cols, short height, short width)
1930fea9cb91Slq150181 {
1931fea9cb91Slq150181 	bitmap_data_t	*font_selected = NULL;
1932fea9cb91Slq150181 	struct fontlist	*fl;
1933fea9cb91Slq150181 
1934fea9cb91Slq150181 	/*
1935fea9cb91Slq150181 	 * Find best font for these dimensions, or use default
1936fea9cb91Slq150181 	 *
1937fea9cb91Slq150181 	 * A 1 pixel border is the absolute minimum we could have
1938fea9cb91Slq150181 	 * as a border around the text window (BORDER_PIXELS = 2),
1939fea9cb91Slq150181 	 * however a slightly larger border not only looks better
1940fea9cb91Slq150181 	 * but for the fonts currently statically built into the
1941fea9cb91Slq150181 	 * emulator causes much better font selection for the
1942fea9cb91Slq150181 	 * normal range of screen resolutions.
1943fea9cb91Slq150181 	 */
1944fea9cb91Slq150181 	for (fl = fonts; fl->data; fl++) {
1945fea9cb91Slq150181 		if ((((*rows * fl->data->height) + BORDER_PIXELS) <= height) &&
1946fea9cb91Slq150181 		    (((*cols * fl->data->width) + BORDER_PIXELS) <= width)) {
1947fea9cb91Slq150181 			font_selected = fl->data;
1948fea9cb91Slq150181 			break;
1949fea9cb91Slq150181 		}
1950fea9cb91Slq150181 	}
1951fea9cb91Slq150181 	/*
1952fea9cb91Slq150181 	 * The minus 2 is to make sure we have at least a 1 pixel
1953fea9cb91Slq150181 	 * boarder around the entire screen.
1954fea9cb91Slq150181 	 */
1955fea9cb91Slq150181 	if (font_selected == NULL) {
1956fea9cb91Slq150181 		if (((*rows * DEFAULT_FONT_DATA.height) > height) ||
1957fea9cb91Slq150181 		    ((*cols * DEFAULT_FONT_DATA.width) > width)) {
1958fea9cb91Slq150181 			*rows = (height - 2) / DEFAULT_FONT_DATA.height;
1959fea9cb91Slq150181 			*cols = (width - 2) / DEFAULT_FONT_DATA.width;
1960fea9cb91Slq150181 		}
1961fea9cb91Slq150181 		font_selected = &DEFAULT_FONT_DATA;
1962fea9cb91Slq150181 	}
1963fea9cb91Slq150181 
1964fea9cb91Slq150181 	f->width = font_selected->width;
1965fea9cb91Slq150181 	f->height = font_selected->height;
1966fea9cb91Slq150181 	bcopy((caddr_t)font_selected->encoding, (caddr_t)f->char_ptr,
1967fea9cb91Slq150181 	    sizeof (f->char_ptr));
1968fea9cb91Slq150181 	f->image_data = font_selected->image;
1969fea9cb91Slq150181 
1970fea9cb91Slq150181 }
1971fea9cb91Slq150181 
1972fea9cb91Slq150181 /*
1973fea9cb91Slq150181  * bit_to_pix4 is for 4-bit frame buffers.  It will write one output byte
1974fea9cb91Slq150181  * for each 2 bits of input bitmap.  It inverts the input bits before
1975fea9cb91Slq150181  * doing the output translation, for reverse video.
1976fea9cb91Slq150181  *
1977fea9cb91Slq150181  * Assuming foreground is 0001 and background is 0000...
1978fea9cb91Slq150181  * An input data byte of 0x53 will output the bit pattern
1979fea9cb91Slq150181  * 00000001 00000001 00000000 00010001.
1980fea9cb91Slq150181  */
1981fea9cb91Slq150181 
1982*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
1983fea9cb91Slq150181 bit_to_pix4(
1984*aecfc01dSrui zang - Sun Microsystems - Beijing China     struct tem_vt_state *tem,
1985fea9cb91Slq150181     uchar_t c,
1986fea9cb91Slq150181     text_color_t fg_color,
1987fea9cb91Slq150181     text_color_t bg_color)
1988fea9cb91Slq150181 {
1989fea9cb91Slq150181 	int	row;
1990fea9cb91Slq150181 	int	byte;
1991fea9cb91Slq150181 	int	i;
1992fea9cb91Slq150181 	uint8_t	*cp;
1993fea9cb91Slq150181 	uint8_t	data;
1994fea9cb91Slq150181 	uint8_t	nibblett;
1995fea9cb91Slq150181 	int	bytes_wide;
1996fea9cb91Slq150181 	uint8_t *dest;
1997fea9cb91Slq150181 
1998*aecfc01dSrui zang - Sun Microsystems - Beijing China 	dest = (uint8_t *)tem->tvs_pix_data;
1999fea9cb91Slq150181 
2000*aecfc01dSrui zang - Sun Microsystems - Beijing China 	cp = tems.ts_font.char_ptr[c];
2001*aecfc01dSrui zang - Sun Microsystems - Beijing China 	bytes_wide = (tems.ts_font.width + 7) / 8;
2002fea9cb91Slq150181 
2003*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_font.height; row++) {
2004fea9cb91Slq150181 		for (byte = 0; byte < bytes_wide; byte++) {
2005fea9cb91Slq150181 			data = *cp++;
2006fea9cb91Slq150181 			for (i = 0; i < 4; i++) {
2007fea9cb91Slq150181 				nibblett = (data >> ((3-i) * 2)) & 0x3;
2008fea9cb91Slq150181 				switch (nibblett) {
2009fea9cb91Slq150181 				case 0x0:
2010fea9cb91Slq150181 					*dest++ = bg_color << 4 | bg_color;
2011fea9cb91Slq150181 					break;
2012fea9cb91Slq150181 				case 0x1:
2013fea9cb91Slq150181 					*dest++ = bg_color << 4 | fg_color;
2014fea9cb91Slq150181 					break;
2015fea9cb91Slq150181 				case 0x2:
2016fea9cb91Slq150181 					*dest++ = fg_color << 4 | bg_color;
2017fea9cb91Slq150181 					break;
2018fea9cb91Slq150181 				case 0x3:
2019fea9cb91Slq150181 					*dest++ = fg_color << 4 | fg_color;
2020fea9cb91Slq150181 					break;
2021fea9cb91Slq150181 				}
2022fea9cb91Slq150181 			}
2023fea9cb91Slq150181 		}
2024fea9cb91Slq150181 	}
2025fea9cb91Slq150181 }
2026fea9cb91Slq150181 
2027fea9cb91Slq150181 /*
2028fea9cb91Slq150181  * bit_to_pix8 is for 8-bit frame buffers.  It will write one output byte
2029fea9cb91Slq150181  * for each bit of input bitmap.  It inverts the input bits before
2030fea9cb91Slq150181  * doing the output translation, for reverse video.
2031fea9cb91Slq150181  *
2032fea9cb91Slq150181  * Assuming foreground is 00000001 and background is 00000000...
2033fea9cb91Slq150181  * An input data byte of 0x53 will output the bit pattern
2034fea9cb91Slq150181  * 0000000 000000001 00000000 00000001 00000000 00000000 00000001 00000001.
2035fea9cb91Slq150181  */
2036fea9cb91Slq150181 
2037*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
2038fea9cb91Slq150181 bit_to_pix8(
2039*aecfc01dSrui zang - Sun Microsystems - Beijing China     struct tem_vt_state *tem,
2040fea9cb91Slq150181     uchar_t c,
2041fea9cb91Slq150181     text_color_t fg_color,
2042fea9cb91Slq150181     text_color_t bg_color)
2043fea9cb91Slq150181 {
2044fea9cb91Slq150181 	int	row;
2045fea9cb91Slq150181 	int	byte;
2046fea9cb91Slq150181 	int	i;
2047fea9cb91Slq150181 	uint8_t	*cp;
2048fea9cb91Slq150181 	uint8_t	data;
2049fea9cb91Slq150181 	int	bytes_wide;
2050fea9cb91Slq150181 	uint8_t	mask;
2051fea9cb91Slq150181 	int	bitsleft, nbits;
2052fea9cb91Slq150181 	uint8_t *dest;
2053fea9cb91Slq150181 
2054*aecfc01dSrui zang - Sun Microsystems - Beijing China 	dest = (uint8_t *)tem->tvs_pix_data;
2055fea9cb91Slq150181 
2056*aecfc01dSrui zang - Sun Microsystems - Beijing China 	cp = tems.ts_font.char_ptr[c];
2057*aecfc01dSrui zang - Sun Microsystems - Beijing China 	bytes_wide = (tems.ts_font.width + 7) / 8;
2058fea9cb91Slq150181 
2059*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_font.height; row++) {
2060*aecfc01dSrui zang - Sun Microsystems - Beijing China 		bitsleft = tems.ts_font.width;
2061fea9cb91Slq150181 		for (byte = 0; byte < bytes_wide; byte++) {
2062fea9cb91Slq150181 			data = *cp++;
2063fea9cb91Slq150181 			mask = 0x80;
2064fea9cb91Slq150181 			nbits = MIN(8, bitsleft);
2065fea9cb91Slq150181 			bitsleft -= nbits;
2066fea9cb91Slq150181 			for (i = 0; i < nbits; i++) {
2067fea9cb91Slq150181 				*dest++ = (data & mask ? fg_color: bg_color);
2068fea9cb91Slq150181 				mask = mask >> 1;
2069fea9cb91Slq150181 			}
2070fea9cb91Slq150181 		}
2071fea9cb91Slq150181 	}
2072fea9cb91Slq150181 }
2073fea9cb91Slq150181 
2074fea9cb91Slq150181 /*
2075fea9cb91Slq150181  * bit_to_pix24 is for 24-bit frame buffers.  It will write four output bytes
2076fea9cb91Slq150181  * for each bit of input bitmap.  It inverts the input bits before
2077fea9cb91Slq150181  * doing the output translation, for reverse video.  Note that each
2078fea9cb91Slq150181  * 24-bit RGB value is finally stored in a 32-bit unsigned int, with the
2079fea9cb91Slq150181  * high-order byte set to zero.
2080fea9cb91Slq150181  *
2081fea9cb91Slq150181  * Assuming foreground is 00000000 11111111 11111111 11111111
2082fea9cb91Slq150181  * and background is 00000000 00000000 00000000 00000000
2083fea9cb91Slq150181  * An input data byte of 0x53 will output the bit pattern
2084fea9cb91Slq150181  *
2085fea9cb91Slq150181  * 00000000 00000000 00000000 00000000
2086fea9cb91Slq150181  * 00000000 11111111 11111111 11111111
2087fea9cb91Slq150181  * 00000000 00000000 00000000 00000000
2088fea9cb91Slq150181  * 00000000 11111111 11111111 11111111
2089fea9cb91Slq150181  * 00000000 00000000 00000000 00000000
2090fea9cb91Slq150181  * 00000000 00000000 00000000 00000000
2091fea9cb91Slq150181  * 00000000 11111111 11111111 11111111
2092fea9cb91Slq150181  * 00000000 11111111 11111111 11111111
2093fea9cb91Slq150181  *
2094fea9cb91Slq150181  */
2095fea9cb91Slq150181 typedef uint32_t pixel32_t;
2096fea9cb91Slq150181 
2097*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
2098fea9cb91Slq150181 bit_to_pix24(
2099*aecfc01dSrui zang - Sun Microsystems - Beijing China 	struct tem_vt_state *tem,
2100fea9cb91Slq150181 	uchar_t c,
2101fea9cb91Slq150181 	text_color_t fg_color4,
2102fea9cb91Slq150181 	text_color_t bg_color4)
2103fea9cb91Slq150181 {
2104fea9cb91Slq150181 	int	row;
2105fea9cb91Slq150181 	int	byte;
2106fea9cb91Slq150181 	int	i;
2107fea9cb91Slq150181 	uint8_t	*cp;
2108fea9cb91Slq150181 	uint8_t	data;
2109fea9cb91Slq150181 	int	bytes_wide;
2110fea9cb91Slq150181 	int	bitsleft, nbits;
2111fea9cb91Slq150181 
2112fea9cb91Slq150181 	pixel32_t fg_color32, bg_color32, *destp;
2113fea9cb91Slq150181 
2114fea9cb91Slq150181 	ASSERT(fg_color4 < 16 && bg_color4 < 16);
2115fea9cb91Slq150181 
2116fea9cb91Slq150181 	fg_color32 = PIX4TO32(fg_color4);
2117fea9cb91Slq150181 	bg_color32 = PIX4TO32(bg_color4);
2118fea9cb91Slq150181 
2119*aecfc01dSrui zang - Sun Microsystems - Beijing China 	destp = (pixel32_t *)tem->tvs_pix_data;
2120*aecfc01dSrui zang - Sun Microsystems - Beijing China 	cp = tems.ts_font.char_ptr[c];
2121*aecfc01dSrui zang - Sun Microsystems - Beijing China 	bytes_wide = (tems.ts_font.width + 7) / 8;
2122fea9cb91Slq150181 
2123*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_font.height; row++) {
2124*aecfc01dSrui zang - Sun Microsystems - Beijing China 		bitsleft = tems.ts_font.width;
2125fea9cb91Slq150181 		for (byte = 0; byte < bytes_wide; byte++) {
2126fea9cb91Slq150181 			data = *cp++;
2127fea9cb91Slq150181 			nbits = MIN(8, bitsleft);
2128fea9cb91Slq150181 			bitsleft -= nbits;
2129fea9cb91Slq150181 			for (i = 0; i < nbits; i++) {
2130fea9cb91Slq150181 				*destp++ = ((data << i) & 0x80 ?
2131fea9cb91Slq150181 				    fg_color32 : bg_color32);
2132fea9cb91Slq150181 			}
2133fea9cb91Slq150181 		}
2134fea9cb91Slq150181 	}
2135fea9cb91Slq150181 }
2136fea9cb91Slq150181 
2137fea9cb91Slq150181 /* ARGSUSED */
2138*aecfc01dSrui zang - Sun Microsystems - Beijing China static text_color_t
2139*aecfc01dSrui zang - Sun Microsystems - Beijing China ansi_bg_to_solaris(struct tem_vt_state *tem, int ansi)
2140fea9cb91Slq150181 {
2141fea9cb91Slq150181 	return (bg_xlate[ansi]);
2142fea9cb91Slq150181 }
2143fea9cb91Slq150181 
2144*aecfc01dSrui zang - Sun Microsystems - Beijing China static text_color_t
2145*aecfc01dSrui zang - Sun Microsystems - Beijing China ansi_fg_to_solaris(struct tem_vt_state *tem, int ansi)
2146fea9cb91Slq150181 {
2147*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_flags & TEM_ATTR_BOLD)
2148fea9cb91Slq150181 		return (fg_brt_xlate[ansi]);
2149fea9cb91Slq150181 	else
2150fea9cb91Slq150181 		return (fg_dim_xlate[ansi]);
2151fea9cb91Slq150181 }
2152fea9cb91Slq150181 
2153*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2154*aecfc01dSrui zang - Sun Microsystems - Beijing China  * flag: TEM_ATTR_SCREEN_REVERSE or TEM_ATTR_REVERSE
2155*aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2156*aecfc01dSrui zang - Sun Microsystems - Beijing China void
2157*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_get_color(struct tem_vt_state *tem, text_color_t *fg,
2158*aecfc01dSrui zang - Sun Microsystems - Beijing China     text_color_t *bg, uint8_t flag)
2159fea9cb91Slq150181 {
2160*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tem->tvs_flags & flag) {
2161fea9cb91Slq150181 		*fg = ansi_fg_to_solaris(tem,
2162*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_bg_color);
2163fea9cb91Slq150181 		*bg = ansi_bg_to_solaris(tem,
2164*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_fg_color);
2165fea9cb91Slq150181 	} else {
2166fea9cb91Slq150181 		*fg = ansi_fg_to_solaris(tem,
2167*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_fg_color);
2168fea9cb91Slq150181 		*bg = ansi_bg_to_solaris(tem,
2169*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tem->tvs_bg_color);
2170fea9cb91Slq150181 	}
2171fea9cb91Slq150181 }
2172fea9cb91Slq150181 
2173fea9cb91Slq150181 /*
2174fea9cb91Slq150181  * Clear a rectangle of screen for pixel mode.
2175fea9cb91Slq150181  *
2176fea9cb91Slq150181  * arguments:
2177fea9cb91Slq150181  *    row:	start row#
2178fea9cb91Slq150181  *    nrows:	the number of rows to clear
2179fea9cb91Slq150181  *    offset_y:	the offset of height in pixels to begin clear
2180fea9cb91Slq150181  *    col:	start col#
2181fea9cb91Slq150181  *    ncols:	the number of cols to clear
2182fea9cb91Slq150181  *    offset_x:	the offset of width in pixels to begin clear
2183fea9cb91Slq150181  *    scroll_up: whether this function is called during sroll up,
2184fea9cb91Slq150181  *		 which is called only once.
2185fea9cb91Slq150181  */
2186fea9cb91Slq150181 void
2187*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_pix_cls_range(struct tem_vt_state *tem,
2188fea9cb91Slq150181 	screen_pos_t row, int nrows, int offset_y,
2189fea9cb91Slq150181 	screen_pos_t col, int ncols, int offset_x,
2190fea9cb91Slq150181 	boolean_t sroll_up, cred_t *credp,
2191fea9cb91Slq150181 	enum called_from called_from)
2192fea9cb91Slq150181 {
2193fea9cb91Slq150181 	struct vis_consdisplay da;
2194fea9cb91Slq150181 	int	i, j;
2195fea9cb91Slq150181 	int	row_add = 0;
2196fea9cb91Slq150181 	text_color_t fg_color;
2197fea9cb91Slq150181 	text_color_t bg_color;
2198fea9cb91Slq150181 
2199*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2200*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2201fea9cb91Slq150181 
2202fea9cb91Slq150181 	if (sroll_up)
2203*aecfc01dSrui zang - Sun Microsystems - Beijing China 		row_add = tems.ts_c_dimension.height - 1;
2204fea9cb91Slq150181 
2205*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.width = tems.ts_font.width;
2206*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.height = tems.ts_font.height;
2207fea9cb91Slq150181 
2208*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_get_color(tem, &fg_color, &bg_color, TEM_ATTR_SCREEN_REVERSE);
2209fea9cb91Slq150181 
2210*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_bit2pix(tem, ' ', fg_color, bg_color);
2211*aecfc01dSrui zang - Sun Microsystems - Beijing China 	da.data = (uchar_t *)tem->tvs_pix_data;
2212fea9cb91Slq150181 
2213fea9cb91Slq150181 	for (i = 0; i < nrows; i++, row++) {
2214fea9cb91Slq150181 		da.row = (row + row_add) * da.height + offset_y;
2215fea9cb91Slq150181 		da.col = col * da.width + offset_x;
2216fea9cb91Slq150181 		for (j = 0; j < ncols; j++) {
2217*aecfc01dSrui zang - Sun Microsystems - Beijing China 			tems_safe_display(&da, credp, called_from);
2218fea9cb91Slq150181 			da.col += da.width;
2219fea9cb91Slq150181 		}
2220fea9cb91Slq150181 	}
2221fea9cb91Slq150181 }
2222*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2223*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2224*aecfc01dSrui zang - Sun Microsystems - Beijing China  * virtual screen operations
2225*aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2226*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
2227*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_virtual_display(struct tem_vt_state *tem, unsigned char *string,
2228*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int count, screen_pos_t row, screen_pos_t col,
2229*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t fg_color, text_color_t bg_color)
2230*aecfc01dSrui zang - Sun Microsystems - Beijing China {
2231*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int i, width;
2232*aecfc01dSrui zang - Sun Microsystems - Beijing China 	unsigned char *addr;
2233*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t *pfgcolor;
2234*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t *pbgcolor;
2235*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2236*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (row < 0 || row >= tems.ts_c_dimension.height ||
2237*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col < 0 || col >= tems.ts_c_dimension.width ||
2238*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    col + count > tems.ts_c_dimension.width)
2239*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2240*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2241*aecfc01dSrui zang - Sun Microsystems - Beijing China 	width = tems.ts_c_dimension.width;
2242*aecfc01dSrui zang - Sun Microsystems - Beijing China 	addr = tem->tvs_screen_buf +  (row * width + col);
2243*aecfc01dSrui zang - Sun Microsystems - Beijing China 	pfgcolor = tem->tvs_fg_buf + (row * width + col);
2244*aecfc01dSrui zang - Sun Microsystems - Beijing China 	pbgcolor = tem->tvs_bg_buf + (row * width + col);
2245*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (i = 0; i < count; i++) {
2246*aecfc01dSrui zang - Sun Microsystems - Beijing China 		*addr++ = string[i];
2247*aecfc01dSrui zang - Sun Microsystems - Beijing China 		*pfgcolor++ = fg_color;
2248*aecfc01dSrui zang - Sun Microsystems - Beijing China 		*pbgcolor++ = bg_color;
2249*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2250*aecfc01dSrui zang - Sun Microsystems - Beijing China }
2251*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2252*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
2253*aecfc01dSrui zang - Sun Microsystems - Beijing China i_virtual_copy(unsigned char *base,
2254*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_pos_t s_col, screen_pos_t s_row,
2255*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_pos_t e_col, screen_pos_t e_row,
2256*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_pos_t t_col, screen_pos_t t_row)
2257*aecfc01dSrui zang - Sun Microsystems - Beijing China {
2258*aecfc01dSrui zang - Sun Microsystems - Beijing China 	unsigned char   *from;
2259*aecfc01dSrui zang - Sun Microsystems - Beijing China 	unsigned char   *to;
2260*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		cnt;
2261*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t chars_per_row;
2262*aecfc01dSrui zang - Sun Microsystems - Beijing China 	unsigned char   *to_row_start;
2263*aecfc01dSrui zang - Sun Microsystems - Beijing China 	unsigned char   *from_row_start;
2264*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t   rows_to_move;
2265*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		cols = tems.ts_c_dimension.width;
2266*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2267*aecfc01dSrui zang - Sun Microsystems - Beijing China 	chars_per_row = e_col - s_col + 1;
2268*aecfc01dSrui zang - Sun Microsystems - Beijing China 	rows_to_move = e_row - s_row + 1;
2269*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2270*aecfc01dSrui zang - Sun Microsystems - Beijing China 	to_row_start = base + ((t_row * cols) + t_col);
2271*aecfc01dSrui zang - Sun Microsystems - Beijing China 	from_row_start = base + ((s_row * cols) + s_col);
2272*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2273*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (to_row_start < from_row_start) {
2274*aecfc01dSrui zang - Sun Microsystems - Beijing China 		while (rows_to_move-- > 0) {
2275*aecfc01dSrui zang - Sun Microsystems - Beijing China 			to = to_row_start;
2276*aecfc01dSrui zang - Sun Microsystems - Beijing China 			from = from_row_start;
2277*aecfc01dSrui zang - Sun Microsystems - Beijing China 			to_row_start += cols;
2278*aecfc01dSrui zang - Sun Microsystems - Beijing China 			from_row_start += cols;
2279*aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (cnt = chars_per_row; cnt-- > 0; )
2280*aecfc01dSrui zang - Sun Microsystems - Beijing China 				*to++ = *from++;
2281*aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
2282*aecfc01dSrui zang - Sun Microsystems - Beijing China 	} else {
2283*aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
2284*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Offset to the end of the region and copy backwards.
2285*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
2286*aecfc01dSrui zang - Sun Microsystems - Beijing China 		cnt = rows_to_move * cols + chars_per_row;
2287*aecfc01dSrui zang - Sun Microsystems - Beijing China 		to_row_start += cnt;
2288*aecfc01dSrui zang - Sun Microsystems - Beijing China 		from_row_start += cnt;
2289*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2290*aecfc01dSrui zang - Sun Microsystems - Beijing China 		while (rows_to_move-- > 0) {
2291*aecfc01dSrui zang - Sun Microsystems - Beijing China 			to_row_start -= cols;
2292*aecfc01dSrui zang - Sun Microsystems - Beijing China 			from_row_start -= cols;
2293*aecfc01dSrui zang - Sun Microsystems - Beijing China 			to = to_row_start;
2294*aecfc01dSrui zang - Sun Microsystems - Beijing China 			from = from_row_start;
2295*aecfc01dSrui zang - Sun Microsystems - Beijing China 			for (cnt = chars_per_row; cnt-- > 0; )
2296*aecfc01dSrui zang - Sun Microsystems - Beijing China 				*--to = *--from;
2297*aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
2298*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2299*aecfc01dSrui zang - Sun Microsystems - Beijing China }
2300*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2301*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
2302*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_virtual_copy(struct tem_vt_state *tem,
2303*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_pos_t s_col, screen_pos_t s_row,
2304*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_pos_t e_col, screen_pos_t e_row,
2305*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_pos_t t_col, screen_pos_t t_row)
2306*aecfc01dSrui zang - Sun Microsystems - Beijing China {
2307*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t chars_per_row;
2308*aecfc01dSrui zang - Sun Microsystems - Beijing China 	screen_size_t   rows_to_move;
2309*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		rows = tems.ts_c_dimension.height;
2310*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int		cols = tems.ts_c_dimension.width;
2311*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2312*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (s_col < 0 || s_col >= cols ||
2313*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_row < 0 || s_row >= rows ||
2314*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col < 0 || e_col >= cols ||
2315*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_row < 0 || e_row >= rows ||
2316*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col < 0 || t_col >= cols ||
2317*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_row < 0 || t_row >= rows ||
2318*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col > e_col ||
2319*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_row > e_row)
2320*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2321*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2322*aecfc01dSrui zang - Sun Microsystems - Beijing China 	chars_per_row = e_col - s_col + 1;
2323*aecfc01dSrui zang - Sun Microsystems - Beijing China 	rows_to_move = e_row - s_row + 1;
2324*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2325*aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* More sanity checks. */
2326*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (t_row + rows_to_move > rows ||
2327*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    t_col + chars_per_row > cols)
2328*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2329*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2330*aecfc01dSrui zang - Sun Microsystems - Beijing China 	i_virtual_copy(tem->tvs_screen_buf, s_col, s_row,
2331*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    e_col, e_row, t_col, t_row);
2332*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2333*aecfc01dSrui zang - Sun Microsystems - Beijing China 	/* text_color_t is the same size as char */
2334*aecfc01dSrui zang - Sun Microsystems - Beijing China 	i_virtual_copy((unsigned char *)tem->tvs_fg_buf,
2335*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col, s_row, e_col, e_row, t_col, t_row);
2336*aecfc01dSrui zang - Sun Microsystems - Beijing China 	i_virtual_copy((unsigned char *)tem->tvs_bg_buf,
2337*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    s_col, s_row, e_col, e_row, t_col, t_row);
2338*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2339*aecfc01dSrui zang - Sun Microsystems - Beijing China }
2340*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2341*aecfc01dSrui zang - Sun Microsystems - Beijing China static void
2342*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_virtual_cls(struct tem_vt_state *tem,
2343*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int count, screen_pos_t row, screen_pos_t col)
2344*aecfc01dSrui zang - Sun Microsystems - Beijing China {
2345*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t fg_color;
2346*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t bg_color;
2347*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2348*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_get_color(tem, &fg_color, &bg_color, TEM_ATTR_SCREEN_REVERSE);
2349*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_virtual_display(tem, tems.ts_blank_line, count, row, col,
2350*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    fg_color, bg_color);
2351*aecfc01dSrui zang - Sun Microsystems - Beijing China }
2352*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2353*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2354*aecfc01dSrui zang - Sun Microsystems - Beijing China  * only blank screen, not clear our screen buffer
2355*aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2356*aecfc01dSrui zang - Sun Microsystems - Beijing China void
2357*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_blank_screen(struct tem_vt_state *tem, cred_t *credp,
2358*aecfc01dSrui zang - Sun Microsystems - Beijing China 	enum called_from called_from)
2359*aecfc01dSrui zang - Sun Microsystems - Beijing China {
2360*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int	row;
2361*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2362*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2363*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2364*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2365*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_PIXEL) {
2366*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2367*aecfc01dSrui zang - Sun Microsystems - Beijing China 		return;
2368*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2369*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2370*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_c_dimension.height; row++) {
2371*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_cls(tem,
2372*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    tems.ts_c_dimension.width,
2373*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    row, 0, credp, called_from);
2374*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2375*aecfc01dSrui zang - Sun Microsystems - Beijing China }
2376*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2377*aecfc01dSrui zang - Sun Microsystems - Beijing China /*
2378*aecfc01dSrui zang - Sun Microsystems - Beijing China  * unblank screen with associated tem from its screen buffer
2379*aecfc01dSrui zang - Sun Microsystems - Beijing China  */
2380*aecfc01dSrui zang - Sun Microsystems - Beijing China void
2381*aecfc01dSrui zang - Sun Microsystems - Beijing China tem_safe_unblank_screen(struct tem_vt_state *tem, cred_t *credp,
2382*aecfc01dSrui zang - Sun Microsystems - Beijing China 	enum called_from called_from)
2383*aecfc01dSrui zang - Sun Microsystems - Beijing China {
2384*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t fg_color, fg_last;
2385*aecfc01dSrui zang - Sun Microsystems - Beijing China 	text_color_t bg_color, bg_last;
2386*aecfc01dSrui zang - Sun Microsystems - Beijing China 	size_t	tc_size = sizeof (text_color_t);
2387*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int	row, col, count, col_start;
2388*aecfc01dSrui zang - Sun Microsystems - Beijing China 	int	width;
2389*aecfc01dSrui zang - Sun Microsystems - Beijing China 	unsigned char *buf;
2390*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2391*aecfc01dSrui zang - Sun Microsystems - Beijing China 	ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2392*aecfc01dSrui zang - Sun Microsystems - Beijing China 	    called_from == CALLED_FROM_STANDALONE);
2393*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2394*aecfc01dSrui zang - Sun Microsystems - Beijing China 	if (tems.ts_display_mode == VIS_PIXEL)
2395*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2396*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2397*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_cursor(tem, VIS_HIDE_CURSOR, credp, called_from);
2398*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2399*aecfc01dSrui zang - Sun Microsystems - Beijing China 	width = tems.ts_c_dimension.width;
2400*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2401*aecfc01dSrui zang - Sun Microsystems - Beijing China 	/*
2402*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * Display data in tvs_screen_buf to the actual framebuffer in a
2403*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * row by row way.
2404*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * When dealing with one row, output data with the same foreground
2405*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 * and background color all together.
2406*aecfc01dSrui zang - Sun Microsystems - Beijing China 	 */
2407*aecfc01dSrui zang - Sun Microsystems - Beijing China 	for (row = 0; row < tems.ts_c_dimension.height; row++) {
2408*aecfc01dSrui zang - Sun Microsystems - Beijing China 		buf = tem->tvs_screen_buf + (row * width);
2409*aecfc01dSrui zang - Sun Microsystems - Beijing China 		count = col_start = 0;
2410*aecfc01dSrui zang - Sun Microsystems - Beijing China 		for (col = 0; col < width; col++) {
2411*aecfc01dSrui zang - Sun Microsystems - Beijing China 			fg_color =
2412*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_fg_buf[(row * width + col) * tc_size];
2413*aecfc01dSrui zang - Sun Microsystems - Beijing China 			bg_color =
2414*aecfc01dSrui zang - Sun Microsystems - Beijing China 			    tem->tvs_bg_buf[(row * width + col) * tc_size];
2415*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if (col == 0) {
2416*aecfc01dSrui zang - Sun Microsystems - Beijing China 				fg_last = fg_color;
2417*aecfc01dSrui zang - Sun Microsystems - Beijing China 				bg_last = bg_color;
2418*aecfc01dSrui zang - Sun Microsystems - Beijing China 			}
2419*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2420*aecfc01dSrui zang - Sun Microsystems - Beijing China 			if ((fg_color != fg_last) || (bg_color != bg_last)) {
2421*aecfc01dSrui zang - Sun Microsystems - Beijing China 				/*
2422*aecfc01dSrui zang - Sun Microsystems - Beijing China 				 * Call the primitive to render this data.
2423*aecfc01dSrui zang - Sun Microsystems - Beijing China 				 */
2424*aecfc01dSrui zang - Sun Microsystems - Beijing China 				tem_safe_callback_display(tem,
2425*aecfc01dSrui zang - Sun Microsystems - Beijing China 				    buf, count, row, col_start,
2426*aecfc01dSrui zang - Sun Microsystems - Beijing China 				    fg_last, bg_last, credp, called_from);
2427*aecfc01dSrui zang - Sun Microsystems - Beijing China 				buf += count;
2428*aecfc01dSrui zang - Sun Microsystems - Beijing China 				count = 1;
2429*aecfc01dSrui zang - Sun Microsystems - Beijing China 				col_start = col;
2430*aecfc01dSrui zang - Sun Microsystems - Beijing China 				fg_last = fg_color;
2431*aecfc01dSrui zang - Sun Microsystems - Beijing China 				bg_last = bg_color;
2432*aecfc01dSrui zang - Sun Microsystems - Beijing China 			} else {
2433*aecfc01dSrui zang - Sun Microsystems - Beijing China 				count++;
2434*aecfc01dSrui zang - Sun Microsystems - Beijing China 			}
2435*aecfc01dSrui zang - Sun Microsystems - Beijing China 		}
2436*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2437*aecfc01dSrui zang - Sun Microsystems - Beijing China 		if (col_start == (width - 1))
2438*aecfc01dSrui zang - Sun Microsystems - Beijing China 			continue;
2439*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2440*aecfc01dSrui zang - Sun Microsystems - Beijing China 		/*
2441*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 * Call the primitive to render this data.
2442*aecfc01dSrui zang - Sun Microsystems - Beijing China 		 */
2443*aecfc01dSrui zang - Sun Microsystems - Beijing China 		tem_safe_callback_display(tem,
2444*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    buf, count, row, col_start,
2445*aecfc01dSrui zang - Sun Microsystems - Beijing China 		    fg_last, bg_last, credp, called_from);
2446*aecfc01dSrui zang - Sun Microsystems - Beijing China 	}
2447*aecfc01dSrui zang - Sun Microsystems - Beijing China 
2448*aecfc01dSrui zang - Sun Microsystems - Beijing China 	tem_safe_callback_cursor(tem, VIS_DISPLAY_CURSOR, credp, called_from);
2449*aecfc01dSrui zang - Sun Microsystems - Beijing China }
2450