11253Slq150181 /*
21253Slq150181 * CDDL HEADER START
31253Slq150181 *
41253Slq150181 * The contents of this file are subject to the terms of the
51253Slq150181 * Common Development and Distribution License (the "License").
61253Slq150181 * You may not use this file except in compliance with the License.
71253Slq150181 *
81253Slq150181 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91253Slq150181 * or http://www.opensolaris.org/os/licensing.
101253Slq150181 * See the License for the specific language governing permissions
111253Slq150181 * and limitations under the License.
121253Slq150181 *
131253Slq150181 * When distributing Covered Code, include this CDDL HEADER in each
141253Slq150181 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151253Slq150181 * If applicable, add the following below this CDDL HEADER, with the
161253Slq150181 * fields enclosed by brackets "[]" replaced with your own identifying
171253Slq150181 * information: Portions Copyright [yyyy] [name of copyright owner]
181253Slq150181 *
191253Slq150181 * CDDL HEADER END
201253Slq150181 */
211253Slq150181
221253Slq150181 /*
23*7688SAaron.Zang@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
241253Slq150181 * Use is subject to license terms.
251253Slq150181 */
261253Slq150181
271253Slq150181 /*
281253Slq150181 * Polled I/O safe ANSI terminal emulator module;
291253Slq150181 * Supporting TERM types 'sun' and 'sun-color, parsing
301253Slq150181 * ANSI x3.64 escape sequences, and the like. (See wscons(7d)
311253Slq150181 * for more information).
321253Slq150181 *
331253Slq150181 * IMPORTANT:
341253Slq150181 *
351253Slq150181 * The functions in this file *must* be able to function in
361253Slq150181 * standalone mode, ie. on a quiesced system. In that state,
371253Slq150181 * access is single threaded, only one CPU is running.
381253Slq150181 * System services are NOT available.
391253Slq150181 *
401253Slq150181 * The following restrictions pertain to every function
411253Slq150181 * in this file:
421253Slq150181 *
431253Slq150181 * - CANNOT use the DDI or LDI interfaces
441253Slq150181 * - CANNOT call system services
451253Slq150181 * - CANNOT use mutexes
461253Slq150181 * - CANNOT wait for interrupts
471253Slq150181 * - CANNOT allocate memory
481253Slq150181 *
49*7688SAaron.Zang@Sun.COM * All non-static functions in this file which:
50*7688SAaron.Zang@Sun.COM * - Operates on tems and tem_vt_state
51*7688SAaron.Zang@Sun.COM * - Not only called from standalone mode, i.e. has
52*7688SAaron.Zang@Sun.COM * a "calledfrom" argument
53*7688SAaron.Zang@Sun.COM * should assert this at the beginning:
54*7688SAaron.Zang@Sun.COM *
55*7688SAaron.Zang@Sun.COM * ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
56*7688SAaron.Zang@Sun.COM * called_from == CALLED_FROM_STANDALONE);
571253Slq150181 */
581253Slq150181
591253Slq150181 #include <sys/types.h>
601253Slq150181 #include <sys/ascii.h>
611253Slq150181 #include <sys/visual_io.h>
621253Slq150181 #include <sys/font.h>
631253Slq150181 #include <sys/tem.h>
641253Slq150181 #include <sys/tem_impl.h>
651253Slq150181 #include <sys/ksynch.h>
661253Slq150181 #include <sys/sysmacros.h>
671253Slq150181 #include <sys/mutex.h>
68*7688SAaron.Zang@Sun.COM #include <sys/note.h>
69*7688SAaron.Zang@Sun.COM #include <sys/t_lock.h>
701253Slq150181
71*7688SAaron.Zang@Sun.COM tem_safe_callbacks_t tem_safe_text_callbacks = {
72*7688SAaron.Zang@Sun.COM &tem_safe_text_display,
73*7688SAaron.Zang@Sun.COM &tem_safe_text_copy,
74*7688SAaron.Zang@Sun.COM &tem_safe_text_cursor,
75*7688SAaron.Zang@Sun.COM NULL,
76*7688SAaron.Zang@Sun.COM &tem_safe_text_cls
77*7688SAaron.Zang@Sun.COM };
78*7688SAaron.Zang@Sun.COM tem_safe_callbacks_t tem_safe_pix_callbacks = {
79*7688SAaron.Zang@Sun.COM &tem_safe_pix_display,
80*7688SAaron.Zang@Sun.COM &tem_safe_pix_copy,
81*7688SAaron.Zang@Sun.COM &tem_safe_pix_cursor,
82*7688SAaron.Zang@Sun.COM &tem_safe_pix_bit2pix,
83*7688SAaron.Zang@Sun.COM &tem_safe_pix_cls
84*7688SAaron.Zang@Sun.COM };
85*7688SAaron.Zang@Sun.COM
86*7688SAaron.Zang@Sun.COM
87*7688SAaron.Zang@Sun.COM static void tem_safe_control(struct tem_vt_state *, uchar_t,
881253Slq150181 cred_t *, enum called_from);
89*7688SAaron.Zang@Sun.COM static void tem_safe_setparam(struct tem_vt_state *, int, int);
90*7688SAaron.Zang@Sun.COM static void tem_safe_selgraph(struct tem_vt_state *);
91*7688SAaron.Zang@Sun.COM static void tem_safe_chkparam(struct tem_vt_state *, uchar_t,
921253Slq150181 cred_t *, enum called_from);
93*7688SAaron.Zang@Sun.COM static void tem_safe_getparams(struct tem_vt_state *, uchar_t,
941253Slq150181 cred_t *, enum called_from);
95*7688SAaron.Zang@Sun.COM static void tem_safe_outch(struct tem_vt_state *, uchar_t,
961253Slq150181 cred_t *, enum called_from);
97*7688SAaron.Zang@Sun.COM static void tem_safe_parse(struct tem_vt_state *, uchar_t,
981253Slq150181 cred_t *, enum called_from);
991253Slq150181
100*7688SAaron.Zang@Sun.COM static void tem_safe_new_line(struct tem_vt_state *,
1011253Slq150181 cred_t *, enum called_from);
102*7688SAaron.Zang@Sun.COM static void tem_safe_cr(struct tem_vt_state *);
103*7688SAaron.Zang@Sun.COM static void tem_safe_lf(struct tem_vt_state *,
1041253Slq150181 cred_t *, enum called_from);
105*7688SAaron.Zang@Sun.COM static void tem_safe_send_data(struct tem_vt_state *, cred_t *,
1061253Slq150181 enum called_from);
107*7688SAaron.Zang@Sun.COM static void tem_safe_cls(struct tem_vt_state *,
1081253Slq150181 cred_t *, enum called_from);
109*7688SAaron.Zang@Sun.COM static void tem_safe_tab(struct tem_vt_state *,
1101253Slq150181 cred_t *, enum called_from);
111*7688SAaron.Zang@Sun.COM static void tem_safe_back_tab(struct tem_vt_state *,
1121253Slq150181 cred_t *, enum called_from);
113*7688SAaron.Zang@Sun.COM static void tem_safe_clear_tabs(struct tem_vt_state *, int);
114*7688SAaron.Zang@Sun.COM static void tem_safe_set_tab(struct tem_vt_state *);
115*7688SAaron.Zang@Sun.COM static void tem_safe_mv_cursor(struct tem_vt_state *, int, int,
1161253Slq150181 cred_t *, enum called_from);
117*7688SAaron.Zang@Sun.COM static void tem_safe_shift(struct tem_vt_state *, int, int,
1181253Slq150181 cred_t *, enum called_from);
119*7688SAaron.Zang@Sun.COM static void tem_safe_scroll(struct tem_vt_state *, int, int,
1201253Slq150181 int, int, cred_t *, enum called_from);
121*7688SAaron.Zang@Sun.COM static void tem_safe_clear_chars(struct tem_vt_state *tem,
1221253Slq150181 int count, screen_pos_t row, screen_pos_t col,
1231253Slq150181 cred_t *credp, enum called_from called_from);
124*7688SAaron.Zang@Sun.COM static void tem_safe_copy_area(struct tem_vt_state *tem,
1251253Slq150181 screen_pos_t s_col, screen_pos_t s_row,
1261253Slq150181 screen_pos_t e_col, screen_pos_t e_row,
1271253Slq150181 screen_pos_t t_col, screen_pos_t t_row,
1281253Slq150181 cred_t *credp, enum called_from called_from);
129*7688SAaron.Zang@Sun.COM static void tem_safe_image_display(struct tem_vt_state *, uchar_t *,
1301253Slq150181 int, int, screen_pos_t, screen_pos_t,
1311253Slq150181 cred_t *, enum called_from);
132*7688SAaron.Zang@Sun.COM static void tem_safe_bell(struct tem_vt_state *tem,
1331253Slq150181 enum called_from called_from);
134*7688SAaron.Zang@Sun.COM static void tem_safe_pix_clear_prom_output(struct tem_vt_state *tem,
1351253Slq150181 cred_t *credp, enum called_from called_from);
1361253Slq150181
137*7688SAaron.Zang@Sun.COM static void tem_safe_virtual_cls(struct tem_vt_state *, int, screen_pos_t,
138*7688SAaron.Zang@Sun.COM screen_pos_t);
139*7688SAaron.Zang@Sun.COM static void tem_safe_virtual_display(struct tem_vt_state *,
140*7688SAaron.Zang@Sun.COM unsigned char *, int, screen_pos_t, screen_pos_t,
141*7688SAaron.Zang@Sun.COM text_color_t, text_color_t);
142*7688SAaron.Zang@Sun.COM static void tem_safe_virtual_copy(struct tem_vt_state *, screen_pos_t,
143*7688SAaron.Zang@Sun.COM screen_pos_t, screen_pos_t, screen_pos_t,
144*7688SAaron.Zang@Sun.COM screen_pos_t, screen_pos_t);
145*7688SAaron.Zang@Sun.COM static void tem_safe_align_cursor(struct tem_vt_state *tem);
146*7688SAaron.Zang@Sun.COM static void bit_to_pix4(struct tem_vt_state *tem, uchar_t c,
147*7688SAaron.Zang@Sun.COM text_color_t fg_color, text_color_t bg_color);
148*7688SAaron.Zang@Sun.COM static void bit_to_pix8(struct tem_vt_state *tem, uchar_t c,
149*7688SAaron.Zang@Sun.COM text_color_t fg_color, text_color_t bg_color);
150*7688SAaron.Zang@Sun.COM static void bit_to_pix24(struct tem_vt_state *tem, uchar_t c,
151*7688SAaron.Zang@Sun.COM text_color_t fg_color, text_color_t bg_color);
152*7688SAaron.Zang@Sun.COM
1531253Slq150181 /* BEGIN CSTYLED */
1541253Slq150181 /* Bk Rd Gr Br Bl Mg Cy Wh */
1551253Slq150181 static text_color_t fg_dim_xlate[] = { 1, 5, 3, 7, 2, 6, 4, 8 };
1561253Slq150181 static text_color_t fg_brt_xlate[] = { 9, 13, 11, 15, 10, 14, 12, 0 };
1571253Slq150181 static text_color_t bg_xlate[] = { 1, 5, 3, 7, 2, 6, 4, 0 };
1581253Slq150181 /* END CSTYLED */
1591253Slq150181
1601253Slq150181
1611253Slq150181 text_cmap_t cmap4_to_24 = {
1621253Slq150181 /* BEGIN CSTYLED */
1631253Slq150181 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1641253Slq150181 Wh+ Bk Bl Gr Cy Rd Mg Br Wh Bk+ Bl+ Gr+ Cy+ Rd+ Mg+ Yw */
1651253Slq150181 0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff,
1661253Slq150181 0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff,
1671253Slq150181 0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00
1681253Slq150181 /* END CSTYLED */
1691253Slq150181 };
1701253Slq150181
1711253Slq150181 #define PIX4TO32(pix4) (pixel32_t)( \
1721253Slq150181 cmap4_to_24.red[pix4] << 16 | \
1731253Slq150181 cmap4_to_24.green[pix4] << 8 | \
1741253Slq150181 cmap4_to_24.blue[pix4])
1751253Slq150181
1761253Slq150181 /*
1771253Slq150181 * Fonts are statically linked with this module. At some point an
1781253Slq150181 * RFE might be desireable to allow dynamic font loading. The
1791253Slq150181 * original intention to facilitate dynamic fonts can be seen
1801253Slq150181 * by examining the data structures and set_font(). As much of
1811253Slq150181 * the original code is retained but modified to be suited to
1821253Slq150181 * traversing a list of static fonts.
1831253Slq150181 */
1841253Slq150181 extern struct fontlist fonts[];
1851253Slq150181
1861253Slq150181 #define DEFAULT_FONT_DATA font_data_12x22
1871253Slq150181
1881253Slq150181 extern bitmap_data_t font_data_12x22;
1891253Slq150181 extern bitmap_data_t font_data_7x14;
1901253Slq150181 extern bitmap_data_t font_data_6x10;
1911253Slq150181 /*
1921253Slq150181 * Must be sorted by font size in descending order
1931253Slq150181 */
1941253Slq150181 struct fontlist fonts[] = {
1951253Slq150181 { &font_data_12x22, NULL },
1961253Slq150181 { &font_data_7x14, NULL },
1971253Slq150181 { &font_data_6x10, NULL },
1981253Slq150181 { NULL, NULL }
1991253Slq150181 };
2001253Slq150181
2011253Slq150181 #define INVERSE(ch) (ch ^ 0xff)
2021253Slq150181
203*7688SAaron.Zang@Sun.COM #define tem_safe_callback_display (*tems.ts_callbacks->tsc_display)
204*7688SAaron.Zang@Sun.COM #define tem_safe_callback_copy (*tems.ts_callbacks->tsc_copy)
205*7688SAaron.Zang@Sun.COM #define tem_safe_callback_cursor (*tems.ts_callbacks->tsc_cursor)
206*7688SAaron.Zang@Sun.COM #define tem_safe_callback_cls (*tems.ts_callbacks->tsc_cls)
207*7688SAaron.Zang@Sun.COM #define tem_safe_callback_bit2pix(tem, c, fg, bg) { \
208*7688SAaron.Zang@Sun.COM ASSERT(tems.ts_callbacks->tsc_bit2pix != NULL); \
209*7688SAaron.Zang@Sun.COM (void) (*tems.ts_callbacks->tsc_bit2pix)((tem), (c), (fg), (bg));\
2101253Slq150181 }
2111253Slq150181
2121253Slq150181 void
tem_safe_check_first_time(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)213*7688SAaron.Zang@Sun.COM tem_safe_check_first_time(
214*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
2151253Slq150181 cred_t *credp,
2161253Slq150181 enum called_from called_from)
2171253Slq150181 {
2181253Slq150181 static int first_time = 1;
2191253Slq150181
220*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
221*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
222*7688SAaron.Zang@Sun.COM
2231253Slq150181 /*
2241253Slq150181 * Realign the console cursor. We did this in tem_init().
2251253Slq150181 * However, drivers in the console stream may emit additional
2261253Slq150181 * messages before we are ready. This causes text overwrite
2271253Slq150181 * on the screen. This is a workaround.
2281253Slq150181 */
229*7688SAaron.Zang@Sun.COM if (!first_time)
230*7688SAaron.Zang@Sun.COM return;
231*7688SAaron.Zang@Sun.COM
232*7688SAaron.Zang@Sun.COM first_time = 0;
233*7688SAaron.Zang@Sun.COM if (tems.ts_display_mode == VIS_TEXT) {
234*7688SAaron.Zang@Sun.COM tem_safe_text_cursor(tem, VIS_GET_CURSOR, credp, called_from);
235*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
2361253Slq150181 }
2371253Slq150181 }
2381253Slq150181
2391253Slq150181 /*
2401253Slq150181 * This entry point handles output requests from restricted contexts like
2411253Slq150181 * kmdb, where services like mutexes are not available. This function
2421253Slq150181 * is entered when OBP or when a kernel debugger (such as kmdb)
2431253Slq150181 * are generating console output. In those cases, power management
2441253Slq150181 * concerns are handled by the abort sequence initiation (ie. when
2451253Slq150181 * the user hits L1+A or the equivalent to enter OBP or the debugger.).
2461253Slq150181 * It is also entered when the kernel is panicing.
2471253Slq150181 */
2481253Slq150181 void
tem_safe_polled_write(tem_vt_state_t tem_arg,uchar_t * buf,int len)249*7688SAaron.Zang@Sun.COM tem_safe_polled_write(
250*7688SAaron.Zang@Sun.COM tem_vt_state_t tem_arg,
2511253Slq150181 uchar_t *buf,
2521253Slq150181 int len)
2531253Slq150181 {
254*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem = (struct tem_vt_state *)tem_arg;
2551253Slq150181
256*7688SAaron.Zang@Sun.COM #ifdef __lock_lint
257*7688SAaron.Zang@Sun.COM _NOTE(NO_COMPETING_THREADS_NOW)
258*7688SAaron.Zang@Sun.COM _NOTE(NO_COMPETING_THREADS_AS_SIDE_EFFECT)
259*7688SAaron.Zang@Sun.COM #endif
2601253Slq150181
261*7688SAaron.Zang@Sun.COM if (!tem->tvs_initialized) {
262*7688SAaron.Zang@Sun.COM return;
263*7688SAaron.Zang@Sun.COM }
264*7688SAaron.Zang@Sun.COM
265*7688SAaron.Zang@Sun.COM tem_safe_check_first_time(tem, kcred, CALLED_FROM_STANDALONE);
266*7688SAaron.Zang@Sun.COM tem_safe_terminal_emulate(tem, buf, len, NULL, CALLED_FROM_STANDALONE);
2671253Slq150181 }
2681253Slq150181
2691253Slq150181
2701253Slq150181 /*
2711253Slq150181 * This is the main entry point into the terminal emulator.
2721253Slq150181 *
2731253Slq150181 * For each data message coming downstream, ANSI assumes that it is composed
2741253Slq150181 * of ASCII characters, which are treated as a byte-stream input to the
2751253Slq150181 * parsing state machine. All data is parsed immediately -- there is
2761253Slq150181 * no enqueing.
2771253Slq150181 */
2781253Slq150181 void
tem_safe_terminal_emulate(struct tem_vt_state * tem,uchar_t * buf,int len,cred_t * credp,enum called_from called_from)279*7688SAaron.Zang@Sun.COM tem_safe_terminal_emulate(
280*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
2811253Slq150181 uchar_t *buf,
2821253Slq150181 int len,
2831253Slq150181 cred_t *credp,
2841253Slq150181 enum called_from called_from)
2851253Slq150181 {
2861253Slq150181
287*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
288*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
2891253Slq150181
290*7688SAaron.Zang@Sun.COM if (tem->tvs_isactive)
291*7688SAaron.Zang@Sun.COM tem_safe_callback_cursor(tem,
292*7688SAaron.Zang@Sun.COM VIS_HIDE_CURSOR, credp, called_from);
2931253Slq150181
294*7688SAaron.Zang@Sun.COM for (; len > 0; len--, buf++)
295*7688SAaron.Zang@Sun.COM tem_safe_parse(tem, *buf, credp, called_from);
2961253Slq150181
2971253Slq150181 /*
2981253Slq150181 * Send the data we just got to the framebuffer.
2991253Slq150181 */
300*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
3011253Slq150181
302*7688SAaron.Zang@Sun.COM if (tem->tvs_isactive)
303*7688SAaron.Zang@Sun.COM tem_safe_callback_cursor(tem,
304*7688SAaron.Zang@Sun.COM VIS_DISPLAY_CURSOR, credp, called_from);
3051253Slq150181 }
3061253Slq150181
3071253Slq150181 /*
3081253Slq150181 * Display an rectangular image on the frame buffer using the
3091253Slq150181 * mechanism appropriate for the system state being called
3101253Slq150181 * from quiesced or normal (ie. use polled I/O vs. layered ioctls)
3111253Slq150181 */
3121253Slq150181 static void
tems_safe_display(struct vis_consdisplay * pda,cred_t * credp,enum called_from called_from)313*7688SAaron.Zang@Sun.COM tems_safe_display(
3141253Slq150181 struct vis_consdisplay *pda,
3151253Slq150181 cred_t *credp,
3161253Slq150181 enum called_from called_from)
3171253Slq150181 {
3181253Slq150181 if (called_from == CALLED_FROM_STANDALONE)
319*7688SAaron.Zang@Sun.COM tems.ts_fb_polledio->display(tems.ts_fb_polledio->arg, pda);
3201253Slq150181 else
321*7688SAaron.Zang@Sun.COM tems_display_layered(pda, credp);
3221253Slq150181 }
3231253Slq150181
3241253Slq150181 /*
3251253Slq150181 * Copy a rectangle from one location to another on the frame buffer
3261253Slq150181 * using the mechanism appropriate for the system state being called
3271253Slq150181 * from, quiesced or normal (ie. use polled I/O vs. layered ioctls)
3281253Slq150181 */
3291253Slq150181 void
tems_safe_copy(struct vis_conscopy * pca,cred_t * credp,enum called_from called_from)330*7688SAaron.Zang@Sun.COM tems_safe_copy(
3311253Slq150181 struct vis_conscopy *pca,
3321253Slq150181 cred_t *credp,
3331253Slq150181 enum called_from called_from)
3341253Slq150181 {
3351253Slq150181 if (called_from == CALLED_FROM_STANDALONE)
336*7688SAaron.Zang@Sun.COM tems.ts_fb_polledio->copy(tems.ts_fb_polledio->arg, pca);
3371253Slq150181 else
338*7688SAaron.Zang@Sun.COM tems_copy_layered(pca, credp);
3391253Slq150181 }
3401253Slq150181
3411253Slq150181 /*
3421253Slq150181 * Display or hide a rectangular block text cursor of a specificsize
3431253Slq150181 * at a specific location on frame buffer* using the mechanism
3441253Slq150181 * appropriate for the system state being called from, quisced or
3451253Slq150181 * normal (ie. use polled I/O vs. layered ioctls).
3461253Slq150181 */
3471253Slq150181 static void
tems_safe_cursor(struct vis_conscursor * pca,cred_t * credp,enum called_from called_from)348*7688SAaron.Zang@Sun.COM tems_safe_cursor(
3491253Slq150181 struct vis_conscursor *pca,
3501253Slq150181 cred_t *credp,
3511253Slq150181 enum called_from called_from)
3521253Slq150181 {
3531253Slq150181 if (called_from == CALLED_FROM_STANDALONE)
354*7688SAaron.Zang@Sun.COM tems.ts_fb_polledio->cursor(tems.ts_fb_polledio->arg, pca);
3551253Slq150181 else
356*7688SAaron.Zang@Sun.COM tems_cursor_layered(pca, credp);
3571253Slq150181 }
3581253Slq150181
3591253Slq150181 /*
3601253Slq150181 * send the appropriate control message or set state based on the
3611253Slq150181 * value of the control character ch
3621253Slq150181 */
3631253Slq150181
3641253Slq150181 static void
tem_safe_control(struct tem_vt_state * tem,uchar_t ch,cred_t * credp,enum called_from called_from)365*7688SAaron.Zang@Sun.COM tem_safe_control(
366*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
3671253Slq150181 uchar_t ch,
3681253Slq150181 cred_t *credp,
3691253Slq150181 enum called_from called_from)
3701253Slq150181 {
371*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
3721253Slq150181 switch (ch) {
3731253Slq150181 case A_BEL:
374*7688SAaron.Zang@Sun.COM tem_safe_bell(tem, called_from);
3751253Slq150181 break;
3761253Slq150181
3771253Slq150181 case A_BS:
378*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem,
379*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
380*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col - 1,
3811253Slq150181 credp, called_from);
3821253Slq150181 break;
3831253Slq150181
3841253Slq150181 case A_HT:
385*7688SAaron.Zang@Sun.COM tem_safe_tab(tem, credp, called_from);
3861253Slq150181 break;
3871253Slq150181
3881253Slq150181 case A_NL:
3891253Slq150181 /*
390*7688SAaron.Zang@Sun.COM * tem_safe_send_data(tem, credp, called_from);
391*7688SAaron.Zang@Sun.COM * tem_safe_new_line(tem, credp, called_from);
3921253Slq150181 * break;
3931253Slq150181 */
3941253Slq150181
3951253Slq150181 case A_VT:
396*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
397*7688SAaron.Zang@Sun.COM tem_safe_lf(tem, credp, called_from);
3981253Slq150181 break;
3991253Slq150181
4001253Slq150181 case A_FF:
401*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
402*7688SAaron.Zang@Sun.COM tem_safe_cls(tem, credp, called_from);
4031253Slq150181 break;
4041253Slq150181
4051253Slq150181 case A_CR:
406*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
407*7688SAaron.Zang@Sun.COM tem_safe_cr(tem);
4081253Slq150181 break;
4091253Slq150181
4101253Slq150181 case A_ESC:
411*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_ESC;
4121253Slq150181 break;
4131253Slq150181
4141253Slq150181 case A_CSI:
4151253Slq150181 {
4161253Slq150181 int i;
417*7688SAaron.Zang@Sun.COM tem->tvs_curparam = 0;
418*7688SAaron.Zang@Sun.COM tem->tvs_paramval = 0;
419*7688SAaron.Zang@Sun.COM tem->tvs_gotparam = B_FALSE;
4201253Slq150181 /* clear the parameters */
4211253Slq150181 for (i = 0; i < TEM_MAXPARAMS; i++)
422*7688SAaron.Zang@Sun.COM tem->tvs_params[i] = -1;
423*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_CSI;
4241253Slq150181 }
4251253Slq150181 break;
4261253Slq150181
4271253Slq150181 case A_GS:
428*7688SAaron.Zang@Sun.COM tem_safe_back_tab(tem, credp, called_from);
4291253Slq150181 break;
4301253Slq150181
4311253Slq150181 default:
4321253Slq150181 break;
4331253Slq150181 }
4341253Slq150181 }
4351253Slq150181
4361253Slq150181
4371253Slq150181 /*
4381253Slq150181 * if parameters [0..count - 1] are not set, set them to the value
4391253Slq150181 * of newparam.
4401253Slq150181 */
4411253Slq150181
4421253Slq150181 static void
tem_safe_setparam(struct tem_vt_state * tem,int count,int newparam)443*7688SAaron.Zang@Sun.COM tem_safe_setparam(struct tem_vt_state *tem, int count, int newparam)
4441253Slq150181 {
4451253Slq150181 int i;
4461253Slq150181
4471253Slq150181 for (i = 0; i < count; i++) {
448*7688SAaron.Zang@Sun.COM if (tem->tvs_params[i] == -1)
449*7688SAaron.Zang@Sun.COM tem->tvs_params[i] = newparam;
4501253Slq150181 }
4511253Slq150181 }
4521253Slq150181
4531253Slq150181
4541253Slq150181 /*
4551253Slq150181 * select graphics mode based on the param vals stored in a_params
4561253Slq150181 */
4571253Slq150181 static void
tem_safe_selgraph(struct tem_vt_state * tem)458*7688SAaron.Zang@Sun.COM tem_safe_selgraph(struct tem_vt_state *tem)
4591253Slq150181 {
4601253Slq150181 int curparam;
4611253Slq150181 int count = 0;
4621253Slq150181 int param;
4631253Slq150181
464*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
465*7688SAaron.Zang@Sun.COM
466*7688SAaron.Zang@Sun.COM curparam = tem->tvs_curparam;
4671253Slq150181 do {
468*7688SAaron.Zang@Sun.COM param = tem->tvs_params[count];
4691253Slq150181
4701253Slq150181 switch (param) {
4711253Slq150181 case -1:
4721253Slq150181 case 0:
473*7688SAaron.Zang@Sun.COM /* reset to initial normal settings */
474*7688SAaron.Zang@Sun.COM tem->tvs_fg_color = tems.ts_init_color.fg_color;
475*7688SAaron.Zang@Sun.COM tem->tvs_bg_color = tems.ts_init_color.bg_color;
476*7688SAaron.Zang@Sun.COM tem->tvs_flags = tems.ts_init_color.a_flags;
4771253Slq150181 break;
4781253Slq150181
4791253Slq150181 case 1: /* Bold Intense */
480*7688SAaron.Zang@Sun.COM tem->tvs_flags |= TEM_ATTR_BOLD;
4811253Slq150181 break;
4821253Slq150181
4833994Slq150181 case 2: /* Faint Intense */
484*7688SAaron.Zang@Sun.COM tem->tvs_flags &= ~TEM_ATTR_BOLD;
4853994Slq150181 break;
4863994Slq150181
4871253Slq150181 case 5: /* Blink */
488*7688SAaron.Zang@Sun.COM tem->tvs_flags |= TEM_ATTR_BLINK;
4891253Slq150181 break;
4901253Slq150181
4911253Slq150181 case 7: /* Reverse video */
492*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
493*7688SAaron.Zang@Sun.COM tem->tvs_flags &= ~TEM_ATTR_REVERSE;
4941253Slq150181 } else {
495*7688SAaron.Zang@Sun.COM tem->tvs_flags |= TEM_ATTR_REVERSE;
4961253Slq150181 }
4971253Slq150181 break;
4981253Slq150181
4991253Slq150181 case 30: /* black (grey) foreground */
5001253Slq150181 case 31: /* red (light red) foreground */
5011253Slq150181 case 32: /* green (light green) foreground */
5021253Slq150181 case 33: /* brown (yellow) foreground */
5031253Slq150181 case 34: /* blue (light blue) foreground */
5041253Slq150181 case 35: /* magenta (light magenta) foreground */
5051253Slq150181 case 36: /* cyan (light cyan) foreground */
5061253Slq150181 case 37: /* white (bright white) foreground */
507*7688SAaron.Zang@Sun.COM tem->tvs_fg_color = param - 30;
5081253Slq150181 break;
5091253Slq150181
5101253Slq150181 case 40: /* black (grey) background */
5111253Slq150181 case 41: /* red (light red) background */
5121253Slq150181 case 42: /* green (light green) background */
5131253Slq150181 case 43: /* brown (yellow) background */
5141253Slq150181 case 44: /* blue (light blue) background */
5151253Slq150181 case 45: /* magenta (light magenta) background */
5161253Slq150181 case 46: /* cyan (light cyan) background */
5171253Slq150181 case 47: /* white (bright white) background */
518*7688SAaron.Zang@Sun.COM tem->tvs_bg_color = param - 40;
5191253Slq150181 break;
5201253Slq150181
5211253Slq150181 default:
5221253Slq150181 break;
5231253Slq150181 }
5241253Slq150181 count++;
5251253Slq150181 curparam--;
5261253Slq150181
5271253Slq150181 } while (curparam > 0);
5281253Slq150181 }
5291253Slq150181
5301253Slq150181 /*
5311253Slq150181 * perform the appropriate action for the escape sequence
5321253Slq150181 *
5331253Slq150181 * General rule: This code does not validate the arguments passed.
5341253Slq150181 * It assumes that the next lower level will do so.
5351253Slq150181 */
5361253Slq150181 static void
tem_safe_chkparam(struct tem_vt_state * tem,uchar_t ch,cred_t * credp,enum called_from called_from)537*7688SAaron.Zang@Sun.COM tem_safe_chkparam(
538*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
5391253Slq150181 uchar_t ch,
5401253Slq150181 cred_t *credp,
5411253Slq150181 enum called_from called_from)
5421253Slq150181 {
5431253Slq150181 int i;
5441253Slq150181 int row;
5451253Slq150181 int col;
5461253Slq150181
5471253Slq150181 ASSERT((called_from == CALLED_FROM_STANDALONE) ||
548*7688SAaron.Zang@Sun.COM MUTEX_HELD(&tem->tvs_lock));
5491253Slq150181
550*7688SAaron.Zang@Sun.COM row = tem->tvs_c_cursor.row;
551*7688SAaron.Zang@Sun.COM col = tem->tvs_c_cursor.col;
5521253Slq150181
5531253Slq150181 switch (ch) {
5541253Slq150181
5551253Slq150181 case 'm': /* select terminal graphics mode */
556*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
557*7688SAaron.Zang@Sun.COM tem_safe_selgraph(tem);
5581253Slq150181 break;
5591253Slq150181
5601253Slq150181 case '@': /* insert char */
561*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
562*7688SAaron.Zang@Sun.COM tem_safe_shift(tem, tem->tvs_params[0], TEM_SHIFT_RIGHT,
5631253Slq150181 credp, called_from);
5641253Slq150181 break;
5651253Slq150181
5661253Slq150181 case 'A': /* cursor up */
567*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
568*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row - tem->tvs_params[0], col,
5691253Slq150181 credp, called_from);
5701253Slq150181 break;
5711253Slq150181
5721253Slq150181 case 'd': /* VPA - vertical position absolute */
573*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
574*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, tem->tvs_params[0] - 1, col,
5751253Slq150181 credp, called_from);
5761253Slq150181 break;
5771253Slq150181
5781253Slq150181 case 'e': /* VPR - vertical position relative */
5791253Slq150181 case 'B': /* cursor down */
580*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
581*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row + tem->tvs_params[0], col,
5821253Slq150181 credp, called_from);
5831253Slq150181 break;
5841253Slq150181
5851253Slq150181 case 'a': /* HPR - horizontal position relative */
5861253Slq150181 case 'C': /* cursor right */
587*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
588*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row, col + tem->tvs_params[0],
5891253Slq150181 credp, called_from);
5901253Slq150181 break;
5911253Slq150181
5921253Slq150181 case '`': /* HPA - horizontal position absolute */
593*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
594*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row, tem->tvs_params[0] - 1,
5951253Slq150181 credp, called_from);
5961253Slq150181 break;
5971253Slq150181
5981253Slq150181 case 'D': /* cursor left */
599*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
600*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row, col - tem->tvs_params[0],
6011253Slq150181 credp, called_from);
6021253Slq150181 break;
6031253Slq150181
6041253Slq150181 case 'E': /* CNL cursor next line */
605*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
606*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row + tem->tvs_params[0], 0,
6071253Slq150181 credp, called_from);
6081253Slq150181 break;
6091253Slq150181
6101253Slq150181 case 'F': /* CPL cursor previous line */
611*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
612*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row - tem->tvs_params[0], 0,
6131253Slq150181 credp, called_from);
6141253Slq150181 break;
6151253Slq150181
6161253Slq150181 case 'G': /* cursor horizontal position */
617*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
618*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row, tem->tvs_params[0] - 1,
6191253Slq150181 credp, called_from);
6201253Slq150181 break;
6211253Slq150181
6221253Slq150181 case 'g': /* clear tabs */
623*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 0);
624*7688SAaron.Zang@Sun.COM tem_safe_clear_tabs(tem, tem->tvs_params[0]);
6251253Slq150181 break;
6261253Slq150181
6271253Slq150181 case 'f': /* HVP Horizontal and Vertical Position */
6281253Slq150181 case 'H': /* CUP position cursor */
629*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 2, 1);
630*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem,
631*7688SAaron.Zang@Sun.COM tem->tvs_params[0] - 1,
632*7688SAaron.Zang@Sun.COM tem->tvs_params[1] - 1,
6331253Slq150181 credp, called_from);
6341253Slq150181 break;
6351253Slq150181
6361253Slq150181 case 'I': /* CHT - Cursor Horizontal Tab */
6371253Slq150181 /* Not implemented */
6381253Slq150181 break;
6391253Slq150181
6401253Slq150181 case 'J': /* ED - Erase in Display */
641*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
642*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 0);
643*7688SAaron.Zang@Sun.COM switch (tem->tvs_params[0]) {
6441253Slq150181 case 0:
6451253Slq150181 /* erase cursor to end of screen */
6461253Slq150181 /* FIRST erase cursor to end of line */
647*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
648*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width -
649*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
650*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
651*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col, credp, called_from);
6521253Slq150181
6531253Slq150181 /* THEN erase lines below the cursor */
654*7688SAaron.Zang@Sun.COM for (row = tem->tvs_c_cursor.row + 1;
655*7688SAaron.Zang@Sun.COM row < tems.ts_c_dimension.height;
6565129Smarx row++) {
657*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
658*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width,
6591253Slq150181 row, 0, credp, called_from);
6601253Slq150181 }
6611253Slq150181 break;
6621253Slq150181
6631253Slq150181 case 1:
6641253Slq150181 /* erase beginning of screen to cursor */
6651253Slq150181 /* FIRST erase lines above the cursor */
6661253Slq150181 for (row = 0;
667*7688SAaron.Zang@Sun.COM row < tem->tvs_c_cursor.row;
6685129Smarx row++) {
669*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
670*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width,
6711253Slq150181 row, 0, credp, called_from);
6721253Slq150181 }
6731253Slq150181 /* THEN erase beginning of line to cursor */
674*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
675*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col + 1,
676*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
6775129Smarx 0, credp, called_from);
6781253Slq150181 break;
6791253Slq150181
6801253Slq150181 case 2:
6811253Slq150181 /* erase whole screen */
6821253Slq150181 for (row = 0;
683*7688SAaron.Zang@Sun.COM row < tems.ts_c_dimension.height;
6841253Slq150181 row++) {
685*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
686*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width,
6875129Smarx row, 0, credp, called_from);
6881253Slq150181 }
6891253Slq150181 break;
6901253Slq150181 }
6911253Slq150181 break;
6921253Slq150181
6931253Slq150181 case 'K': /* EL - Erase in Line */
694*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
695*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 0);
696*7688SAaron.Zang@Sun.COM switch (tem->tvs_params[0]) {
6971253Slq150181 case 0:
6981253Slq150181 /* erase cursor to end of line */
699*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
700*7688SAaron.Zang@Sun.COM (tems.ts_c_dimension.width -
701*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col),
702*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
703*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
7041253Slq150181 credp, called_from);
7051253Slq150181 break;
7061253Slq150181
7071253Slq150181 case 1:
7081253Slq150181 /* erase beginning of line to cursor */
709*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
710*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col + 1,
711*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
7121253Slq150181 0, credp, called_from);
7131253Slq150181 break;
7141253Slq150181
7151253Slq150181 case 2:
7161253Slq150181 /* erase whole line */
717*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
718*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width,
719*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
7201253Slq150181 0, credp, called_from);
7211253Slq150181 break;
7221253Slq150181 }
7231253Slq150181 break;
7241253Slq150181
7251253Slq150181 case 'L': /* insert line */
726*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
727*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
728*7688SAaron.Zang@Sun.COM tem_safe_scroll(tem,
729*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
730*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.height - 1,
731*7688SAaron.Zang@Sun.COM tem->tvs_params[0], TEM_SCROLL_DOWN,
7325129Smarx credp, called_from);
7331253Slq150181 break;
7341253Slq150181
7351253Slq150181 case 'M': /* delete line */
736*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
737*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
738*7688SAaron.Zang@Sun.COM tem_safe_scroll(tem,
739*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
740*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.height - 1,
741*7688SAaron.Zang@Sun.COM tem->tvs_params[0], TEM_SCROLL_UP,
7425129Smarx credp, called_from);
7431253Slq150181 break;
7441253Slq150181
7451253Slq150181 case 'P': /* DCH - delete char */
746*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
747*7688SAaron.Zang@Sun.COM tem_safe_shift(tem, tem->tvs_params[0], TEM_SHIFT_LEFT,
7481253Slq150181 credp, called_from);
7491253Slq150181 break;
7501253Slq150181
7511253Slq150181 case 'S': /* scroll up */
752*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
753*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
754*7688SAaron.Zang@Sun.COM tem_safe_scroll(tem, 0,
755*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.height - 1,
756*7688SAaron.Zang@Sun.COM tem->tvs_params[0], TEM_SCROLL_UP,
7575129Smarx credp, called_from);
7581253Slq150181 break;
7591253Slq150181
7601253Slq150181 case 'T': /* scroll down */
761*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
762*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
763*7688SAaron.Zang@Sun.COM tem_safe_scroll(tem, 0,
764*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.height - 1,
765*7688SAaron.Zang@Sun.COM tem->tvs_params[0], TEM_SCROLL_DOWN,
7665129Smarx credp, called_from);
7671253Slq150181 break;
7681253Slq150181
7691253Slq150181 case 'X': /* erase char */
770*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
771*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
772*7688SAaron.Zang@Sun.COM tem->tvs_params[0],
773*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
774*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
7755129Smarx credp, called_from);
7761253Slq150181 break;
7771253Slq150181
7781253Slq150181 case 'Z': /* cursor backward tabulation */
779*7688SAaron.Zang@Sun.COM tem_safe_setparam(tem, 1, 1);
7801253Slq150181
7811253Slq150181 /*
7821253Slq150181 * Rule exception - We do sanity checking here.
7831253Slq150181 *
7841253Slq150181 * Restrict the count to a sane value to keep from
7851253Slq150181 * looping for a long time. There can't be more than one
7861253Slq150181 * tab stop per column, so use that as a limit.
7871253Slq150181 */
788*7688SAaron.Zang@Sun.COM if (tem->tvs_params[0] > tems.ts_c_dimension.width)
789*7688SAaron.Zang@Sun.COM tem->tvs_params[0] = tems.ts_c_dimension.width;
7901253Slq150181
791*7688SAaron.Zang@Sun.COM for (i = 0; i < tem->tvs_params[0]; i++)
792*7688SAaron.Zang@Sun.COM tem_safe_back_tab(tem, credp, called_from);
7931253Slq150181 break;
7941253Slq150181 }
795*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
7961253Slq150181 }
7971253Slq150181
7981253Slq150181
7991253Slq150181 /*
8001253Slq150181 * Gather the parameters of an ANSI escape sequence
8011253Slq150181 */
8021253Slq150181 static void
tem_safe_getparams(struct tem_vt_state * tem,uchar_t ch,cred_t * credp,enum called_from called_from)803*7688SAaron.Zang@Sun.COM tem_safe_getparams(struct tem_vt_state *tem, uchar_t ch,
8041253Slq150181 cred_t *credp, enum called_from called_from)
8051253Slq150181 {
8061253Slq150181 ASSERT((called_from == CALLED_FROM_STANDALONE) ||
807*7688SAaron.Zang@Sun.COM MUTEX_HELD(&tem->tvs_lock));
8081253Slq150181
8092216Slt200341 if (ch >= '0' && ch <= '9') {
810*7688SAaron.Zang@Sun.COM tem->tvs_paramval = ((tem->tvs_paramval * 10) + (ch - '0'));
811*7688SAaron.Zang@Sun.COM tem->tvs_gotparam = B_TRUE; /* Remember got parameter */
8121253Slq150181 return; /* Return immediately */
813*7688SAaron.Zang@Sun.COM } else if (tem->tvs_state == A_STATE_CSI_EQUAL ||
814*7688SAaron.Zang@Sun.COM tem->tvs_state == A_STATE_CSI_QMARK) {
815*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
8162216Slt200341 } else {
817*7688SAaron.Zang@Sun.COM if (tem->tvs_curparam < TEM_MAXPARAMS) {
818*7688SAaron.Zang@Sun.COM if (tem->tvs_gotparam) {
8192216Slt200341 /* get the parameter value */
820*7688SAaron.Zang@Sun.COM tem->tvs_params[tem->tvs_curparam] =
821*7688SAaron.Zang@Sun.COM tem->tvs_paramval;
8221253Slq150181 }
823*7688SAaron.Zang@Sun.COM tem->tvs_curparam++;
8241253Slq150181 }
8251253Slq150181
8261253Slq150181 if (ch == ';') {
8271253Slq150181 /* Restart parameter search */
828*7688SAaron.Zang@Sun.COM tem->tvs_gotparam = B_FALSE;
829*7688SAaron.Zang@Sun.COM tem->tvs_paramval = 0; /* No parame value yet */
8302216Slt200341 } else {
8311253Slq150181 /* Handle escape sequence */
832*7688SAaron.Zang@Sun.COM tem_safe_chkparam(tem, ch, credp, called_from);
8332216Slt200341 }
8341253Slq150181 }
8351253Slq150181 }
8361253Slq150181
8371253Slq150181 /*
8381253Slq150181 * Add character to internal buffer.
8391253Slq150181 * When its full, send it to the next layer.
8401253Slq150181 */
8411253Slq150181
8421253Slq150181 static void
tem_safe_outch(struct tem_vt_state * tem,uchar_t ch,cred_t * credp,enum called_from called_from)843*7688SAaron.Zang@Sun.COM tem_safe_outch(struct tem_vt_state *tem, uchar_t ch,
8441253Slq150181 cred_t *credp, enum called_from called_from)
8451253Slq150181 {
8461253Slq150181
847*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
848*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
8491253Slq150181
8501253Slq150181 /* buffer up the character until later */
8511253Slq150181
852*7688SAaron.Zang@Sun.COM tem->tvs_outbuf[tem->tvs_outindex++] = ch;
853*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col++;
854*7688SAaron.Zang@Sun.COM if (tem->tvs_c_cursor.col >= tems.ts_c_dimension.width) {
855*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
856*7688SAaron.Zang@Sun.COM tem_safe_new_line(tem, credp, called_from);
8571253Slq150181 }
8581253Slq150181 }
8591253Slq150181
8601253Slq150181 static void
tem_safe_new_line(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)861*7688SAaron.Zang@Sun.COM tem_safe_new_line(struct tem_vt_state *tem,
8621253Slq150181 cred_t *credp, enum called_from called_from)
8631253Slq150181 {
864*7688SAaron.Zang@Sun.COM tem_safe_cr(tem);
865*7688SAaron.Zang@Sun.COM tem_safe_lf(tem, credp, called_from);
8661253Slq150181 }
8671253Slq150181
8681253Slq150181 static void
tem_safe_cr(struct tem_vt_state * tem)869*7688SAaron.Zang@Sun.COM tem_safe_cr(struct tem_vt_state *tem)
8701253Slq150181 {
871*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col = 0;
872*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
8731253Slq150181 }
8741253Slq150181
8751253Slq150181 static void
tem_safe_lf(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)876*7688SAaron.Zang@Sun.COM tem_safe_lf(struct tem_vt_state *tem,
8771253Slq150181 cred_t *credp, enum called_from called_from)
8781253Slq150181 {
8791253Slq150181 int row;
8801253Slq150181
8811253Slq150181 ASSERT((called_from == CALLED_FROM_STANDALONE) ||
882*7688SAaron.Zang@Sun.COM MUTEX_HELD(&tem->tvs_lock));
8831253Slq150181
8841253Slq150181 /*
8851253Slq150181 * Sanity checking notes:
8861253Slq150181 * . a_nscroll was validated when it was set.
887*7688SAaron.Zang@Sun.COM * . Regardless of that, tem_safe_scroll and tem_safe_mv_cursor
888*7688SAaron.Zang@Sun.COM * will prevent anything bad from happening.
8891253Slq150181 */
890*7688SAaron.Zang@Sun.COM row = tem->tvs_c_cursor.row + 1;
8911253Slq150181
892*7688SAaron.Zang@Sun.COM if (row >= tems.ts_c_dimension.height) {
893*7688SAaron.Zang@Sun.COM if (tem->tvs_nscroll != 0) {
894*7688SAaron.Zang@Sun.COM tem_safe_scroll(tem, 0,
895*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.height - 1,
896*7688SAaron.Zang@Sun.COM tem->tvs_nscroll, TEM_SCROLL_UP,
8971253Slq150181 credp, called_from);
898*7688SAaron.Zang@Sun.COM row = tems.ts_c_dimension.height -
899*7688SAaron.Zang@Sun.COM tem->tvs_nscroll;
9001253Slq150181 } else { /* no scroll */
9011253Slq150181 /*
9021253Slq150181 * implement Esc[#r when # is zero. This means no
9031253Slq150181 * scroll but just return cursor to top of screen,
9041253Slq150181 * do not clear screen.
9051253Slq150181 */
9061253Slq150181 row = 0;
9071253Slq150181 }
9081253Slq150181 }
9091253Slq150181
910*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, row, tem->tvs_c_cursor.col,
9115129Smarx credp, called_from);
9121253Slq150181
913*7688SAaron.Zang@Sun.COM if (tem->tvs_nscroll == 0) {
9141253Slq150181 /* erase rest of cursor line */
915*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem,
916*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width -
917*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
918*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
919*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
9201253Slq150181 credp, called_from);
9211253Slq150181
9221253Slq150181 }
9231253Slq150181
924*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
9251253Slq150181 }
9261253Slq150181
9271253Slq150181 static void
tem_safe_send_data(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)928*7688SAaron.Zang@Sun.COM tem_safe_send_data(struct tem_vt_state *tem, cred_t *credp,
9291253Slq150181 enum called_from called_from)
9301253Slq150181 {
9311253Slq150181 text_color_t fg_color;
9321253Slq150181 text_color_t bg_color;
9331253Slq150181
9341253Slq150181 ASSERT((called_from == CALLED_FROM_STANDALONE) ||
935*7688SAaron.Zang@Sun.COM MUTEX_HELD(&tem->tvs_lock));
9361253Slq150181
937*7688SAaron.Zang@Sun.COM if (tem->tvs_outindex == 0) {
938*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
939*7688SAaron.Zang@Sun.COM return;
940*7688SAaron.Zang@Sun.COM }
9411253Slq150181
942*7688SAaron.Zang@Sun.COM tem_safe_get_color(tem, &fg_color, &bg_color, TEM_ATTR_REVERSE);
943*7688SAaron.Zang@Sun.COM tem_safe_virtual_display(tem,
944*7688SAaron.Zang@Sun.COM tem->tvs_outbuf, tem->tvs_outindex,
945*7688SAaron.Zang@Sun.COM tem->tvs_s_cursor.row, tem->tvs_s_cursor.col,
946*7688SAaron.Zang@Sun.COM fg_color, bg_color);
9471253Slq150181
948*7688SAaron.Zang@Sun.COM if (tem->tvs_isactive) {
9491253Slq150181 /*
9501253Slq150181 * Call the primitive to render this data.
9511253Slq150181 */
952*7688SAaron.Zang@Sun.COM tem_safe_callback_display(tem,
953*7688SAaron.Zang@Sun.COM tem->tvs_outbuf, tem->tvs_outindex,
954*7688SAaron.Zang@Sun.COM tem->tvs_s_cursor.row, tem->tvs_s_cursor.col,
9555129Smarx fg_color, bg_color,
9565129Smarx credp, called_from);
9571253Slq150181 }
958*7688SAaron.Zang@Sun.COM
959*7688SAaron.Zang@Sun.COM tem->tvs_outindex = 0;
960*7688SAaron.Zang@Sun.COM
961*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
9621253Slq150181 }
9631253Slq150181
9641253Slq150181
9651253Slq150181 /*
9661253Slq150181 * We have just done something to the current output point. Reset the start
9671253Slq150181 * point for the buffered data in a_outbuf. There shouldn't be any data
9681253Slq150181 * buffered yet.
9691253Slq150181 */
970*7688SAaron.Zang@Sun.COM static void
tem_safe_align_cursor(struct tem_vt_state * tem)971*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(struct tem_vt_state *tem)
9721253Slq150181 {
973*7688SAaron.Zang@Sun.COM tem->tvs_s_cursor.row = tem->tvs_c_cursor.row;
974*7688SAaron.Zang@Sun.COM tem->tvs_s_cursor.col = tem->tvs_c_cursor.col;
9751253Slq150181 }
9761253Slq150181
9771253Slq150181 /*
9781253Slq150181 * State machine parser based on the current state and character input
9791253Slq150181 * major terminations are to control character or normal character
9801253Slq150181 */
9811253Slq150181
9821253Slq150181 static void
tem_safe_parse(struct tem_vt_state * tem,uchar_t ch,cred_t * credp,enum called_from called_from)983*7688SAaron.Zang@Sun.COM tem_safe_parse(struct tem_vt_state *tem, uchar_t ch,
9841253Slq150181 cred_t *credp, enum called_from called_from)
9851253Slq150181 {
9861253Slq150181 int i;
9871253Slq150181
9881253Slq150181 ASSERT((called_from == CALLED_FROM_STANDALONE) ||
989*7688SAaron.Zang@Sun.COM MUTEX_HELD(&tem->tvs_lock));
9901253Slq150181
991*7688SAaron.Zang@Sun.COM if (tem->tvs_state == A_STATE_START) { /* Normal state? */
992*7688SAaron.Zang@Sun.COM if (ch == A_CSI || ch == A_ESC || ch < ' ') {
993*7688SAaron.Zang@Sun.COM /* Control */
994*7688SAaron.Zang@Sun.COM tem_safe_control(tem, ch, credp, called_from);
995*7688SAaron.Zang@Sun.COM } else {
9961253Slq150181 /* Display */
997*7688SAaron.Zang@Sun.COM tem_safe_outch(tem, ch, credp, called_from);
998*7688SAaron.Zang@Sun.COM }
9991253Slq150181 return;
10001253Slq150181 }
10011253Slq150181
10021253Slq150181 /* In <ESC> sequence */
1003*7688SAaron.Zang@Sun.COM if (tem->tvs_state != A_STATE_ESC) { /* Need to get parameters? */
1004*7688SAaron.Zang@Sun.COM if (tem->tvs_state != A_STATE_CSI) {
1005*7688SAaron.Zang@Sun.COM tem_safe_getparams(tem, ch, credp, called_from);
10061253Slq150181 return;
10071253Slq150181 }
10081253Slq150181
10091253Slq150181 switch (ch) {
10101253Slq150181 case '?':
1011*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_CSI_QMARK;
10121253Slq150181 return;
10131253Slq150181 case '=':
1014*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_CSI_EQUAL;
10151253Slq150181 return;
10161253Slq150181 case 's':
10171253Slq150181 /*
10181253Slq150181 * As defined below, this sequence
10191253Slq150181 * saves the cursor. However, Sun
10201253Slq150181 * defines ESC[s as reset. We resolved
10211253Slq150181 * the conflict by selecting reset as it
10221253Slq150181 * is exported in the termcap file for
10231253Slq150181 * sun-mon, while the "save cursor"
10241253Slq150181 * definition does not exist anywhere in
10251253Slq150181 * /etc/termcap.
10261253Slq150181 * However, having no coherent
10271253Slq150181 * definition of reset, we have not
10281253Slq150181 * implemented it.
10291253Slq150181 */
10301253Slq150181
10311253Slq150181 /*
10321253Slq150181 * Original code
1033*7688SAaron.Zang@Sun.COM * tem->tvs_r_cursor.row = tem->tvs_c_cursor.row;
1034*7688SAaron.Zang@Sun.COM * tem->tvs_r_cursor.col = tem->tvs_c_cursor.col;
1035*7688SAaron.Zang@Sun.COM * tem->tvs_state = A_STATE_START;
10361253Slq150181 */
10371253Slq150181
1038*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
10391253Slq150181 return;
10401253Slq150181 case 'u':
1041*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, tem->tvs_r_cursor.row,
1042*7688SAaron.Zang@Sun.COM tem->tvs_r_cursor.col, credp, called_from);
1043*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
10441253Slq150181 return;
10451253Slq150181 case 'p': /* sunbow */
1046*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
10471253Slq150181 /*
10481253Slq150181 * Don't set anything if we are
10491253Slq150181 * already as we want to be.
10501253Slq150181 */
1051*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE) {
1052*7688SAaron.Zang@Sun.COM tem->tvs_flags &= ~TEM_ATTR_SCREEN_REVERSE;
10531253Slq150181 /*
10541253Slq150181 * If we have switched the characters to be the
10551253Slq150181 * inverse from the screen, then switch them as
10561253Slq150181 * well to keep them the inverse of the screen.
10571253Slq150181 */
1058*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & TEM_ATTR_REVERSE)
1059*7688SAaron.Zang@Sun.COM tem->tvs_flags &= ~TEM_ATTR_REVERSE;
1060*7688SAaron.Zang@Sun.COM else
1061*7688SAaron.Zang@Sun.COM tem->tvs_flags |= TEM_ATTR_REVERSE;
10621253Slq150181 }
1063*7688SAaron.Zang@Sun.COM tem_safe_cls(tem, credp, called_from);
1064*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
10651253Slq150181 return;
10661253Slq150181 case 'q': /* sunwob */
1067*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
10681253Slq150181 /*
10691253Slq150181 * Don't set anything if we are
10701253Slq150181 * already where as we want to be.
10711253Slq150181 */
1072*7688SAaron.Zang@Sun.COM if (!(tem->tvs_flags & TEM_ATTR_SCREEN_REVERSE)) {
1073*7688SAaron.Zang@Sun.COM tem->tvs_flags |= TEM_ATTR_SCREEN_REVERSE;
10741253Slq150181 /*
10751253Slq150181 * If we have switched the characters to be the
10761253Slq150181 * inverse from the screen, then switch them as
10771253Slq150181 * well to keep them the inverse of the screen.
10781253Slq150181 */
1079*7688SAaron.Zang@Sun.COM if (!(tem->tvs_flags & TEM_ATTR_REVERSE))
1080*7688SAaron.Zang@Sun.COM tem->tvs_flags |= TEM_ATTR_REVERSE;
1081*7688SAaron.Zang@Sun.COM else
1082*7688SAaron.Zang@Sun.COM tem->tvs_flags &= ~TEM_ATTR_REVERSE;
10831253Slq150181 }
10841253Slq150181
1085*7688SAaron.Zang@Sun.COM tem_safe_cls(tem, credp, called_from);
1086*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
10871253Slq150181 return;
10881253Slq150181 case 'r': /* sunscrl */
10891253Slq150181 /*
10901253Slq150181 * Rule exception: check for validity here.
10911253Slq150181 */
1092*7688SAaron.Zang@Sun.COM tem->tvs_nscroll = tem->tvs_paramval;
1093*7688SAaron.Zang@Sun.COM if (tem->tvs_nscroll > tems.ts_c_dimension.height)
1094*7688SAaron.Zang@Sun.COM tem->tvs_nscroll = tems.ts_c_dimension.height;
1095*7688SAaron.Zang@Sun.COM if (tem->tvs_nscroll < 0)
1096*7688SAaron.Zang@Sun.COM tem->tvs_nscroll = 1;
1097*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
10981253Slq150181 return;
10991253Slq150181 default:
1100*7688SAaron.Zang@Sun.COM tem_safe_getparams(tem, ch, credp, called_from);
11011253Slq150181 return;
11021253Slq150181 }
11031253Slq150181 }
11041253Slq150181
11051253Slq150181 /* Previous char was <ESC> */
11061253Slq150181 if (ch == '[') {
1107*7688SAaron.Zang@Sun.COM tem->tvs_curparam = 0;
1108*7688SAaron.Zang@Sun.COM tem->tvs_paramval = 0;
1109*7688SAaron.Zang@Sun.COM tem->tvs_gotparam = B_FALSE;
11101253Slq150181 /* clear the parameters */
11111253Slq150181 for (i = 0; i < TEM_MAXPARAMS; i++)
1112*7688SAaron.Zang@Sun.COM tem->tvs_params[i] = -1;
1113*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_CSI;
11141253Slq150181 } else if (ch == 'Q') { /* <ESC>Q ? */
1115*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
11161253Slq150181 } else if (ch == 'C') { /* <ESC>C ? */
1117*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
11181253Slq150181 } else {
1119*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
1120*7688SAaron.Zang@Sun.COM if (ch == 'c') {
11211253Slq150181 /* ESC c resets display */
1122*7688SAaron.Zang@Sun.COM tem_safe_reset_display(tem, credp, called_from,
1123*7688SAaron.Zang@Sun.COM B_TRUE, B_TRUE);
1124*7688SAaron.Zang@Sun.COM } else if (ch == 'H') {
11251253Slq150181 /* ESC H sets a tab */
1126*7688SAaron.Zang@Sun.COM tem_safe_set_tab(tem);
1127*7688SAaron.Zang@Sun.COM } else if (ch == '7') {
11281253Slq150181 /* ESC 7 Save Cursor position */
1129*7688SAaron.Zang@Sun.COM tem->tvs_r_cursor.row = tem->tvs_c_cursor.row;
1130*7688SAaron.Zang@Sun.COM tem->tvs_r_cursor.col = tem->tvs_c_cursor.col;
1131*7688SAaron.Zang@Sun.COM } else if (ch == '8') {
11321253Slq150181 /* ESC 8 Restore Cursor position */
1133*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, tem->tvs_r_cursor.row,
1134*7688SAaron.Zang@Sun.COM tem->tvs_r_cursor.col, credp, called_from);
11351253Slq150181 /* check for control chars */
1136*7688SAaron.Zang@Sun.COM } else if (ch < ' ') {
1137*7688SAaron.Zang@Sun.COM tem_safe_control(tem, ch, credp, called_from);
1138*7688SAaron.Zang@Sun.COM } else {
1139*7688SAaron.Zang@Sun.COM tem_safe_outch(tem, ch, credp, called_from);
1140*7688SAaron.Zang@Sun.COM }
11411253Slq150181 }
11421253Slq150181 }
11431253Slq150181
11441253Slq150181 /* ARGSUSED */
11451253Slq150181 static void
tem_safe_bell(struct tem_vt_state * tem,enum called_from called_from)1146*7688SAaron.Zang@Sun.COM tem_safe_bell(struct tem_vt_state *tem, enum called_from called_from)
11471253Slq150181 {
11481253Slq150181 if (called_from == CALLED_FROM_STANDALONE)
11495129Smarx (void) beep_polled(BEEP_CONSOLE);
11501253Slq150181 else
11515129Smarx (void) beep(BEEP_CONSOLE);
11521253Slq150181 }
11531253Slq150181
11541253Slq150181
11551253Slq150181 static void
tem_safe_scroll(struct tem_vt_state * tem,int start,int end,int count,int direction,cred_t * credp,enum called_from called_from)1156*7688SAaron.Zang@Sun.COM tem_safe_scroll(struct tem_vt_state *tem, int start, int end, int count,
1157*7688SAaron.Zang@Sun.COM int direction,
11581253Slq150181 cred_t *credp, enum called_from called_from)
11591253Slq150181 {
11601253Slq150181 int row;
11611253Slq150181 int lines_affected;
11621253Slq150181
1163*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1164*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
11651253Slq150181
11661253Slq150181 lines_affected = end - start + 1;
11671253Slq150181 if (count > lines_affected)
11681253Slq150181 count = lines_affected;
11691253Slq150181 if (count <= 0)
11701253Slq150181 return;
11711253Slq150181
11721253Slq150181 switch (direction) {
11731253Slq150181 case TEM_SCROLL_UP:
11741253Slq150181 if (count < lines_affected) {
1175*7688SAaron.Zang@Sun.COM tem_safe_copy_area(tem, 0, start + count,
1176*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width - 1, end,
11771253Slq150181 0, start, credp, called_from);
11781253Slq150181 }
11791253Slq150181 for (row = (end - count) + 1; row <= end; row++) {
1180*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
11811253Slq150181 row, 0, credp, called_from);
11821253Slq150181 }
11831253Slq150181 break;
11841253Slq150181
11851253Slq150181 case TEM_SCROLL_DOWN:
11861253Slq150181 if (count < lines_affected) {
1187*7688SAaron.Zang@Sun.COM tem_safe_copy_area(tem, 0, start,
1188*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width - 1,
11891253Slq150181 end - count, 0, start + count,
11901253Slq150181 credp, called_from);
11911253Slq150181 }
11921253Slq150181 for (row = start; row < start + count; row++) {
1193*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
11941253Slq150181 row, 0, credp, called_from);
11951253Slq150181 }
11961253Slq150181 break;
11971253Slq150181 }
11981253Slq150181 }
11991253Slq150181
12001253Slq150181 static void
tem_safe_copy_area(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row,cred_t * credp,enum called_from called_from)1201*7688SAaron.Zang@Sun.COM tem_safe_copy_area(struct tem_vt_state *tem,
12021253Slq150181 screen_pos_t s_col, screen_pos_t s_row,
12031253Slq150181 screen_pos_t e_col, screen_pos_t e_row,
12041253Slq150181 screen_pos_t t_col, screen_pos_t t_row,
12051253Slq150181 cred_t *credp, enum called_from called_from)
12061253Slq150181 {
12071253Slq150181 int rows;
12081253Slq150181 int cols;
12091253Slq150181
1210*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1211*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
12121253Slq150181
12131253Slq150181 if (s_col < 0 || s_row < 0 ||
12141253Slq150181 e_col < 0 || e_row < 0 ||
12151253Slq150181 t_col < 0 || t_row < 0 ||
1216*7688SAaron.Zang@Sun.COM s_col >= tems.ts_c_dimension.width ||
1217*7688SAaron.Zang@Sun.COM e_col >= tems.ts_c_dimension.width ||
1218*7688SAaron.Zang@Sun.COM t_col >= tems.ts_c_dimension.width ||
1219*7688SAaron.Zang@Sun.COM s_row >= tems.ts_c_dimension.height ||
1220*7688SAaron.Zang@Sun.COM e_row >= tems.ts_c_dimension.height ||
1221*7688SAaron.Zang@Sun.COM t_row >= tems.ts_c_dimension.height)
12221253Slq150181 return;
12231253Slq150181
12241253Slq150181 if (s_row > e_row || s_col > e_col)
12251253Slq150181 return;
12261253Slq150181
12271253Slq150181 rows = e_row - s_row + 1;
12281253Slq150181 cols = e_col - s_col + 1;
1229*7688SAaron.Zang@Sun.COM if (t_row + rows > tems.ts_c_dimension.height ||
1230*7688SAaron.Zang@Sun.COM t_col + cols > tems.ts_c_dimension.width)
12311253Slq150181 return;
12321253Slq150181
1233*7688SAaron.Zang@Sun.COM tem_safe_virtual_copy(tem,
1234*7688SAaron.Zang@Sun.COM s_col, s_row,
1235*7688SAaron.Zang@Sun.COM e_col, e_row,
1236*7688SAaron.Zang@Sun.COM t_col, t_row);
1237*7688SAaron.Zang@Sun.COM
1238*7688SAaron.Zang@Sun.COM if (!tem->tvs_isactive)
1239*7688SAaron.Zang@Sun.COM return;
1240*7688SAaron.Zang@Sun.COM
1241*7688SAaron.Zang@Sun.COM tem_safe_callback_copy(tem, s_col, s_row,
12425129Smarx e_col, e_row, t_col, t_row, credp, called_from);
12431253Slq150181 }
12441253Slq150181
12451253Slq150181 static void
tem_safe_clear_chars(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1246*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(struct tem_vt_state *tem, int count, screen_pos_t row,
12471253Slq150181 screen_pos_t col, cred_t *credp, enum called_from called_from)
12481253Slq150181 {
1249*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1250*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
12511253Slq150181
1252*7688SAaron.Zang@Sun.COM if (row < 0 || row >= tems.ts_c_dimension.height ||
1253*7688SAaron.Zang@Sun.COM col < 0 || col >= tems.ts_c_dimension.width ||
12541253Slq150181 count < 0)
12551253Slq150181 return;
12561253Slq150181
12571253Slq150181 /*
12581253Slq150181 * Note that very large values of "count" could cause col+count
12591253Slq150181 * to overflow, so we check "count" independently.
12601253Slq150181 */
1261*7688SAaron.Zang@Sun.COM if (count > tems.ts_c_dimension.width ||
1262*7688SAaron.Zang@Sun.COM col + count > tems.ts_c_dimension.width)
1263*7688SAaron.Zang@Sun.COM count = tems.ts_c_dimension.width - col;
12641253Slq150181
1265*7688SAaron.Zang@Sun.COM tem_safe_virtual_cls(tem, count, row, col);
1266*7688SAaron.Zang@Sun.COM
1267*7688SAaron.Zang@Sun.COM if (!tem->tvs_isactive)
1268*7688SAaron.Zang@Sun.COM return;
1269*7688SAaron.Zang@Sun.COM
1270*7688SAaron.Zang@Sun.COM tem_safe_callback_cls(tem, count, row, col, credp, called_from);
12711253Slq150181 }
12721253Slq150181
1273*7688SAaron.Zang@Sun.COM /*ARGSUSED*/
12741253Slq150181 void
tem_safe_text_display(struct tem_vt_state * tem,uchar_t * string,int count,screen_pos_t row,screen_pos_t col,text_color_t fg_color,text_color_t bg_color,cred_t * credp,enum called_from called_from)1275*7688SAaron.Zang@Sun.COM tem_safe_text_display(struct tem_vt_state *tem, uchar_t *string,
12761253Slq150181 int count, screen_pos_t row, screen_pos_t col,
12771253Slq150181 text_color_t fg_color, text_color_t bg_color,
12781253Slq150181 cred_t *credp, enum called_from called_from)
12791253Slq150181 {
12801253Slq150181 struct vis_consdisplay da;
12811253Slq150181
1282*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1283*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
1284*7688SAaron.Zang@Sun.COM
12851253Slq150181 da.data = string;
1286*7688SAaron.Zang@Sun.COM da.width = (screen_size_t)count;
12871253Slq150181 da.row = row;
12881253Slq150181 da.col = col;
12891253Slq150181
12901253Slq150181 da.fg_color = fg_color;
12911253Slq150181 da.bg_color = bg_color;
12921253Slq150181
1293*7688SAaron.Zang@Sun.COM tems_safe_display(&da, credp, called_from);
12941253Slq150181 }
12951253Slq150181
12961253Slq150181 /*
12971253Slq150181 * This function is used to blit a rectangular color image,
12981253Slq150181 * unperturbed on the underlying framebuffer, to render
12991253Slq150181 * icons and pictures. The data is a pixel pattern that
13001253Slq150181 * fills a rectangle bounded to the width and height parameters.
13011253Slq150181 * The color pixel data must to be pre-adjusted by the caller
13021253Slq150181 * for the current video depth.
13031253Slq150181 *
13041253Slq150181 * This function is unused now.
13051253Slq150181 */
1306*7688SAaron.Zang@Sun.COM /*ARGSUSED*/
1307*7688SAaron.Zang@Sun.COM static void
tem_safe_image_display(struct tem_vt_state * tem,uchar_t * image,int height,int width,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1308*7688SAaron.Zang@Sun.COM tem_safe_image_display(struct tem_vt_state *tem, uchar_t *image,
13091253Slq150181 int height, int width, screen_pos_t row, screen_pos_t col,
13101253Slq150181 cred_t *credp, enum called_from called_from)
13111253Slq150181 {
13121253Slq150181 struct vis_consdisplay da;
13131253Slq150181
1314*7688SAaron.Zang@Sun.COM mutex_enter(&tems.ts_lock);
1315*7688SAaron.Zang@Sun.COM mutex_enter(&tem->tvs_lock);
1316*7688SAaron.Zang@Sun.COM
13171253Slq150181 da.data = image;
1318*7688SAaron.Zang@Sun.COM da.width = (screen_size_t)width;
1319*7688SAaron.Zang@Sun.COM da.height = (screen_size_t)height;
13201253Slq150181 da.row = row;
13211253Slq150181 da.col = col;
13221253Slq150181
1323*7688SAaron.Zang@Sun.COM tems_safe_display(&da, credp, called_from);
1324*7688SAaron.Zang@Sun.COM
1325*7688SAaron.Zang@Sun.COM mutex_exit(&tem->tvs_lock);
1326*7688SAaron.Zang@Sun.COM mutex_exit(&tems.ts_lock);
13271253Slq150181 }
13281253Slq150181
13291253Slq150181
1330*7688SAaron.Zang@Sun.COM /*ARGSUSED*/
13311253Slq150181 void
tem_safe_text_copy(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row,cred_t * credp,enum called_from called_from)1332*7688SAaron.Zang@Sun.COM tem_safe_text_copy(struct tem_vt_state *tem,
13331253Slq150181 screen_pos_t s_col, screen_pos_t s_row,
13341253Slq150181 screen_pos_t e_col, screen_pos_t e_row,
13351253Slq150181 screen_pos_t t_col, screen_pos_t t_row,
13361253Slq150181 cred_t *credp, enum called_from called_from)
13371253Slq150181 {
13381253Slq150181 struct vis_conscopy da;
13391253Slq150181
1340*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1341*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
1342*7688SAaron.Zang@Sun.COM
13431253Slq150181 da.s_row = s_row;
13441253Slq150181 da.s_col = s_col;
13451253Slq150181 da.e_row = e_row;
13461253Slq150181 da.e_col = e_col;
13471253Slq150181 da.t_row = t_row;
13481253Slq150181 da.t_col = t_col;
13491253Slq150181
1350*7688SAaron.Zang@Sun.COM tems_safe_copy(&da, credp, called_from);
13511253Slq150181 }
13521253Slq150181
13531253Slq150181 void
tem_safe_text_cls(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1354*7688SAaron.Zang@Sun.COM tem_safe_text_cls(struct tem_vt_state *tem,
13551253Slq150181 int count, screen_pos_t row, screen_pos_t col, cred_t *credp,
13561253Slq150181 enum called_from called_from)
13571253Slq150181 {
13581253Slq150181 struct vis_consdisplay da;
13591253Slq150181
1360*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1361*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
1362*7688SAaron.Zang@Sun.COM
1363*7688SAaron.Zang@Sun.COM da.data = tems.ts_blank_line;
1364*7688SAaron.Zang@Sun.COM da.width = (screen_size_t)count;
13651253Slq150181 da.row = row;
13661253Slq150181 da.col = col;
13671253Slq150181
1368*7688SAaron.Zang@Sun.COM tem_safe_get_color(tem, &da.fg_color, &da.bg_color,
1369*7688SAaron.Zang@Sun.COM TEM_ATTR_SCREEN_REVERSE);
1370*7688SAaron.Zang@Sun.COM tems_safe_display(&da, credp, called_from);
13711253Slq150181 }
13721253Slq150181
13731253Slq150181
13741253Slq150181
13751253Slq150181 void
tem_safe_pix_display(struct tem_vt_state * tem,uchar_t * string,int count,screen_pos_t row,screen_pos_t col,text_color_t fg_color,text_color_t bg_color,cred_t * credp,enum called_from called_from)1376*7688SAaron.Zang@Sun.COM tem_safe_pix_display(struct tem_vt_state *tem,
13771253Slq150181 uchar_t *string, int count,
13781253Slq150181 screen_pos_t row, screen_pos_t col,
13791253Slq150181 text_color_t fg_color, text_color_t bg_color,
13801253Slq150181 cred_t *credp, enum called_from called_from)
13811253Slq150181 {
13821253Slq150181 struct vis_consdisplay da;
13831253Slq150181 int i;
1384*7688SAaron.Zang@Sun.COM
1385*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1386*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
1387*7688SAaron.Zang@Sun.COM
1388*7688SAaron.Zang@Sun.COM da.data = (uchar_t *)tem->tvs_pix_data;
1389*7688SAaron.Zang@Sun.COM da.width = tems.ts_font.width;
1390*7688SAaron.Zang@Sun.COM da.height = tems.ts_font.height;
1391*7688SAaron.Zang@Sun.COM da.row = (row * da.height) + tems.ts_p_offset.y;
1392*7688SAaron.Zang@Sun.COM da.col = (col * da.width) + tems.ts_p_offset.x;
13931253Slq150181
13941253Slq150181 for (i = 0; i < count; i++) {
1395*7688SAaron.Zang@Sun.COM tem_safe_callback_bit2pix(tem, string[i], fg_color, bg_color);
1396*7688SAaron.Zang@Sun.COM tems_safe_display(&da, credp, called_from);
13971253Slq150181 da.col += da.width;
13981253Slq150181 }
13991253Slq150181 }
14001253Slq150181
14011253Slq150181 void
tem_safe_pix_copy(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row,cred_t * credp,enum called_from called_from)1402*7688SAaron.Zang@Sun.COM tem_safe_pix_copy(struct tem_vt_state *tem,
14031253Slq150181 screen_pos_t s_col, screen_pos_t s_row,
14041253Slq150181 screen_pos_t e_col, screen_pos_t e_row,
14051253Slq150181 screen_pos_t t_col, screen_pos_t t_row,
14061253Slq150181 cred_t *credp,
14071253Slq150181 enum called_from called_from)
14081253Slq150181 {
14091253Slq150181 struct vis_conscopy ma;
14101253Slq150181 static boolean_t need_clear = B_TRUE;
14111253Slq150181
1412*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1413*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
14141253Slq150181
1415*7688SAaron.Zang@Sun.COM if (need_clear && tem->tvs_first_line > 0) {
14161253Slq150181 /*
14171253Slq150181 * Clear OBP output above our kernel console term
14181253Slq150181 * when our kernel console term begins to scroll up,
14191253Slq150181 * we hope it is user friendly.
1420*7688SAaron.Zang@Sun.COM * (Also see comments on tem_safe_pix_clear_prom_output)
14211253Slq150181 *
14221253Slq150181 * This is only one time call.
14231253Slq150181 */
1424*7688SAaron.Zang@Sun.COM tem_safe_pix_clear_prom_output(tem, credp, called_from);
14251253Slq150181 }
14261253Slq150181 need_clear = B_FALSE;
14271253Slq150181
1428*7688SAaron.Zang@Sun.COM ma.s_row = s_row * tems.ts_font.height + tems.ts_p_offset.y;
1429*7688SAaron.Zang@Sun.COM ma.e_row = (e_row + 1) * tems.ts_font.height + tems.ts_p_offset.y - 1;
1430*7688SAaron.Zang@Sun.COM ma.t_row = t_row * tems.ts_font.height + tems.ts_p_offset.y;
14311253Slq150181
14321253Slq150181 /*
14331253Slq150181 * Check if we're in process of clearing OBP's columns area,
14341253Slq150181 * which only happens when term scrolls up a whole line.
14351253Slq150181 */
1436*7688SAaron.Zang@Sun.COM if (tem->tvs_first_line > 0 && t_row < s_row && t_col == 0 &&
1437*7688SAaron.Zang@Sun.COM e_col == tems.ts_c_dimension.width - 1) {
14381253Slq150181 /*
14391253Slq150181 * We need to clear OBP's columns area outside our kernel
14401253Slq150181 * console term. So that we set ma.e_col to entire row here.
14411253Slq150181 */
1442*7688SAaron.Zang@Sun.COM ma.s_col = s_col * tems.ts_font.width;
1443*7688SAaron.Zang@Sun.COM ma.e_col = tems.ts_p_dimension.width - 1;
14441253Slq150181
1445*7688SAaron.Zang@Sun.COM ma.t_col = t_col * tems.ts_font.width;
14461253Slq150181 } else {
1447*7688SAaron.Zang@Sun.COM ma.s_col = s_col * tems.ts_font.width + tems.ts_p_offset.x;
1448*7688SAaron.Zang@Sun.COM ma.e_col = (e_col + 1) * tems.ts_font.width +
1449*7688SAaron.Zang@Sun.COM tems.ts_p_offset.x - 1;
1450*7688SAaron.Zang@Sun.COM ma.t_col = t_col * tems.ts_font.width + tems.ts_p_offset.x;
14511253Slq150181 }
14521253Slq150181
1453*7688SAaron.Zang@Sun.COM tems_safe_copy(&ma, credp, called_from);
14541253Slq150181
1455*7688SAaron.Zang@Sun.COM if (tem->tvs_first_line > 0 && t_row < s_row) {
14561253Slq150181 /* We have scrolled up (s_row - t_row) rows. */
1457*7688SAaron.Zang@Sun.COM tem->tvs_first_line -= (s_row - t_row);
1458*7688SAaron.Zang@Sun.COM if (tem->tvs_first_line <= 0) {
14591253Slq150181 /* All OBP rows have been cleared. */
1460*7688SAaron.Zang@Sun.COM tem->tvs_first_line = 0;
14611253Slq150181 }
14621253Slq150181 }
14631253Slq150181
14641253Slq150181 }
14651253Slq150181
1466*7688SAaron.Zang@Sun.COM void
tem_safe_pix_bit2pix(struct tem_vt_state * tem,unsigned char c,unsigned char fg,unsigned char bg)1467*7688SAaron.Zang@Sun.COM tem_safe_pix_bit2pix(struct tem_vt_state *tem, unsigned char c,
1468*7688SAaron.Zang@Sun.COM unsigned char fg, unsigned char bg)
1469*7688SAaron.Zang@Sun.COM {
1470*7688SAaron.Zang@Sun.COM void (*fp)(struct tem_vt_state *, unsigned char,
1471*7688SAaron.Zang@Sun.COM unsigned char, unsigned char);
1472*7688SAaron.Zang@Sun.COM
1473*7688SAaron.Zang@Sun.COM switch (tems.ts_pdepth) {
1474*7688SAaron.Zang@Sun.COM case 4:
1475*7688SAaron.Zang@Sun.COM fp = bit_to_pix4;
1476*7688SAaron.Zang@Sun.COM break;
1477*7688SAaron.Zang@Sun.COM case 8:
1478*7688SAaron.Zang@Sun.COM fp = bit_to_pix8;
1479*7688SAaron.Zang@Sun.COM break;
1480*7688SAaron.Zang@Sun.COM case 24:
1481*7688SAaron.Zang@Sun.COM case 32:
1482*7688SAaron.Zang@Sun.COM fp = bit_to_pix24;
1483*7688SAaron.Zang@Sun.COM }
1484*7688SAaron.Zang@Sun.COM
1485*7688SAaron.Zang@Sun.COM fp(tem, c, fg, bg);
1486*7688SAaron.Zang@Sun.COM }
1487*7688SAaron.Zang@Sun.COM
1488*7688SAaron.Zang@Sun.COM
14891253Slq150181 /*
14901253Slq150181 * This function only clears count of columns in one row
14911253Slq150181 */
14921253Slq150181 void
tem_safe_pix_cls(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col,cred_t * credp,enum called_from called_from)1493*7688SAaron.Zang@Sun.COM tem_safe_pix_cls(struct tem_vt_state *tem, int count,
14941253Slq150181 screen_pos_t row, screen_pos_t col, cred_t *credp,
14951253Slq150181 enum called_from called_from)
14961253Slq150181 {
1497*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1498*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
14991253Slq150181
1500*7688SAaron.Zang@Sun.COM tem_safe_pix_cls_range(tem, row, 1, tems.ts_p_offset.y,
1501*7688SAaron.Zang@Sun.COM col, count, tems.ts_p_offset.x, B_FALSE, credp, called_from);
15021253Slq150181 }
15031253Slq150181
15041253Slq150181 /*
15051253Slq150181 * This function clears OBP output above our kernel console term area
15061253Slq150181 * because OBP's term may have a bigger terminal window than that of
15071253Slq150181 * our kernel console term. So we need to clear OBP output garbage outside
15081253Slq150181 * of our kernel console term at a proper time, which is when the first
15091253Slq150181 * row output of our kernel console term scrolls at the first screen line.
15101253Slq150181 *
15111253Slq150181 * _________________________________
15121253Slq150181 * | _____________________ | ---> OBP's bigger term window
15131253Slq150181 * | | | |
15141253Slq150181 * |___| | |
15151253Slq150181 * | | | | |
15161253Slq150181 * | | | | |
15171253Slq150181 * |_|_|___________________|_______|
15181253Slq150181 * | | | ---> first line
15191253Slq150181 * | |___________________|---> our kernel console term window
15201253Slq150181 * |
15211253Slq150181 * |---> columns area to be cleared
15221253Slq150181 *
15231253Slq150181 * This function only takes care of the output above our kernel console term,
15241253Slq150181 * and tem_prom_scroll_up takes care of columns area outside of our kernel
15251253Slq150181 * console term.
15261253Slq150181 */
15271253Slq150181 static void
tem_safe_pix_clear_prom_output(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1528*7688SAaron.Zang@Sun.COM tem_safe_pix_clear_prom_output(struct tem_vt_state *tem, cred_t *credp,
15291253Slq150181 enum called_from called_from)
15301253Slq150181 {
15311253Slq150181 int nrows, ncols, width, height;
15321253Slq150181
1533*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1534*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
15351253Slq150181
1536*7688SAaron.Zang@Sun.COM width = tems.ts_font.width;
1537*7688SAaron.Zang@Sun.COM height = tems.ts_font.height;
15381253Slq150181
1539*7688SAaron.Zang@Sun.COM nrows = (tems.ts_p_offset.y + (height - 1))/ height;
1540*7688SAaron.Zang@Sun.COM ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
15411253Slq150181
1542*7688SAaron.Zang@Sun.COM tem_safe_pix_cls_range(tem, 0, nrows, 0, 0, ncols, 0,
15431253Slq150181 B_FALSE, credp, called_from);
15441253Slq150181 }
15451253Slq150181
15461253Slq150181 /*
1547*7688SAaron.Zang@Sun.COM * clear the whole screen for pixel mode, just clear the
1548*7688SAaron.Zang@Sun.COM * physical screen.
15491253Slq150181 */
1550*7688SAaron.Zang@Sun.COM void
tem_safe_pix_clear_entire_screen(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1551*7688SAaron.Zang@Sun.COM tem_safe_pix_clear_entire_screen(struct tem_vt_state *tem, cred_t *credp,
15521253Slq150181 enum called_from called_from)
15531253Slq150181 {
15541253Slq150181 int nrows, ncols, width, height;
15551253Slq150181
1556*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1557*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
15581253Slq150181
1559*7688SAaron.Zang@Sun.COM width = tems.ts_font.width;
1560*7688SAaron.Zang@Sun.COM height = tems.ts_font.height;
15611253Slq150181
1562*7688SAaron.Zang@Sun.COM nrows = (tems.ts_p_dimension.height + (height - 1))/ height;
1563*7688SAaron.Zang@Sun.COM ncols = (tems.ts_p_dimension.width + (width - 1))/ width;
15641253Slq150181
1565*7688SAaron.Zang@Sun.COM tem_safe_pix_cls_range(tem, 0, nrows, 0, 0, ncols, 0,
15661253Slq150181 B_FALSE, credp, called_from);
15671253Slq150181
15681253Slq150181 /*
15691253Slq150181 * Since the whole screen is cleared, we don't need
15701253Slq150181 * to clear OBP output later.
15711253Slq150181 */
1572*7688SAaron.Zang@Sun.COM if (tem->tvs_first_line > 0)
1573*7688SAaron.Zang@Sun.COM tem->tvs_first_line = 0;
15741253Slq150181 }
15751253Slq150181
15761253Slq150181 /*
1577*7688SAaron.Zang@Sun.COM * clear the whole screen, including the virtual screen buffer,
1578*7688SAaron.Zang@Sun.COM * and reset the cursor to start point.
15791253Slq150181 */
15801253Slq150181 static void
tem_safe_cls(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1581*7688SAaron.Zang@Sun.COM tem_safe_cls(struct tem_vt_state *tem,
15821253Slq150181 cred_t *credp, enum called_from called_from)
15831253Slq150181 {
15841253Slq150181 int row;
15851253Slq150181
1586*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1587*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
15881253Slq150181
1589*7688SAaron.Zang@Sun.COM if (tems.ts_display_mode == VIS_TEXT) {
1590*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_c_dimension.height; row++) {
1591*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem, tems.ts_c_dimension.width,
15925129Smarx row, 0, credp, called_from);
15931253Slq150181 }
1594*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row = 0;
1595*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col = 0;
1596*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
15971253Slq150181 return;
15981253Slq150181 }
15991253Slq150181
1600*7688SAaron.Zang@Sun.COM ASSERT(tems.ts_display_mode == VIS_PIXEL);
16011253Slq150181
1602*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_c_dimension.height; row++) {
1603*7688SAaron.Zang@Sun.COM tem_safe_virtual_cls(tem, tems.ts_c_dimension.width, row, 0);
1604*7688SAaron.Zang@Sun.COM }
1605*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row = 0;
1606*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col = 0;
1607*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
1608*7688SAaron.Zang@Sun.COM
1609*7688SAaron.Zang@Sun.COM if (!tem->tvs_isactive)
1610*7688SAaron.Zang@Sun.COM return;
1611*7688SAaron.Zang@Sun.COM
1612*7688SAaron.Zang@Sun.COM tem_safe_pix_clear_entire_screen(tem, credp, called_from);
16131253Slq150181 }
16141253Slq150181
16151253Slq150181 static void
tem_safe_back_tab(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1616*7688SAaron.Zang@Sun.COM tem_safe_back_tab(struct tem_vt_state *tem,
16171253Slq150181 cred_t *credp, enum called_from called_from)
16181253Slq150181 {
16191253Slq150181 int i;
16201253Slq150181 screen_pos_t tabstop;
16211253Slq150181
1622*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1623*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
16241253Slq150181
16251253Slq150181 tabstop = 0;
16261253Slq150181
1627*7688SAaron.Zang@Sun.COM for (i = tem->tvs_ntabs - 1; i >= 0; i--) {
1628*7688SAaron.Zang@Sun.COM if (tem->tvs_tabs[i] < tem->tvs_c_cursor.col) {
1629*7688SAaron.Zang@Sun.COM tabstop = tem->tvs_tabs[i];
16301253Slq150181 break;
16311253Slq150181 }
16321253Slq150181 }
16331253Slq150181
1634*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, tem->tvs_c_cursor.row,
16355129Smarx tabstop, credp, called_from);
16361253Slq150181 }
16371253Slq150181
16381253Slq150181 static void
tem_safe_tab(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)1639*7688SAaron.Zang@Sun.COM tem_safe_tab(struct tem_vt_state *tem,
16401253Slq150181 cred_t *credp, enum called_from called_from)
16411253Slq150181 {
16421253Slq150181 int i;
16431253Slq150181 screen_pos_t tabstop;
16441253Slq150181
1645*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1646*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
16471253Slq150181
1648*7688SAaron.Zang@Sun.COM tabstop = tems.ts_c_dimension.width - 1;
16491253Slq150181
1650*7688SAaron.Zang@Sun.COM for (i = 0; i < tem->tvs_ntabs; i++) {
1651*7688SAaron.Zang@Sun.COM if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) {
1652*7688SAaron.Zang@Sun.COM tabstop = tem->tvs_tabs[i];
16531253Slq150181 break;
16541253Slq150181 }
16551253Slq150181 }
16561253Slq150181
1657*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(tem, tem->tvs_c_cursor.row,
16581253Slq150181 tabstop, credp, called_from);
16591253Slq150181 }
16601253Slq150181
16611253Slq150181 static void
tem_safe_set_tab(struct tem_vt_state * tem)1662*7688SAaron.Zang@Sun.COM tem_safe_set_tab(struct tem_vt_state *tem)
16631253Slq150181 {
16641253Slq150181 int i;
16651253Slq150181 int j;
16661253Slq150181
1667*7688SAaron.Zang@Sun.COM if (tem->tvs_ntabs == TEM_MAXTAB)
16681253Slq150181 return;
1669*7688SAaron.Zang@Sun.COM if (tem->tvs_ntabs == 0 ||
1670*7688SAaron.Zang@Sun.COM tem->tvs_tabs[tem->tvs_ntabs] < tem->tvs_c_cursor.col) {
1671*7688SAaron.Zang@Sun.COM tem->tvs_tabs[tem->tvs_ntabs++] = tem->tvs_c_cursor.col;
1672*7688SAaron.Zang@Sun.COM return;
16731253Slq150181 }
1674*7688SAaron.Zang@Sun.COM for (i = 0; i < tem->tvs_ntabs; i++) {
1675*7688SAaron.Zang@Sun.COM if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col)
16761253Slq150181 return;
1677*7688SAaron.Zang@Sun.COM if (tem->tvs_tabs[i] > tem->tvs_c_cursor.col) {
1678*7688SAaron.Zang@Sun.COM for (j = tem->tvs_ntabs - 1; j >= i; j--)
1679*7688SAaron.Zang@Sun.COM tem->tvs_tabs[j+ 1] = tem->tvs_tabs[j];
1680*7688SAaron.Zang@Sun.COM tem->tvs_tabs[i] = tem->tvs_c_cursor.col;
1681*7688SAaron.Zang@Sun.COM tem->tvs_ntabs++;
16821253Slq150181 return;
16831253Slq150181 }
16841253Slq150181 }
16851253Slq150181 }
16861253Slq150181
16871253Slq150181 static void
tem_safe_clear_tabs(struct tem_vt_state * tem,int action)1688*7688SAaron.Zang@Sun.COM tem_safe_clear_tabs(struct tem_vt_state *tem, int action)
16891253Slq150181 {
16901253Slq150181 int i;
16911253Slq150181 int j;
16921253Slq150181
16931253Slq150181 switch (action) {
16941253Slq150181 case 3: /* clear all tabs */
1695*7688SAaron.Zang@Sun.COM tem->tvs_ntabs = 0;
16961253Slq150181 break;
16971253Slq150181 case 0: /* clr tab at cursor */
16981253Slq150181
1699*7688SAaron.Zang@Sun.COM for (i = 0; i < tem->tvs_ntabs; i++) {
1700*7688SAaron.Zang@Sun.COM if (tem->tvs_tabs[i] == tem->tvs_c_cursor.col) {
1701*7688SAaron.Zang@Sun.COM tem->tvs_ntabs--;
1702*7688SAaron.Zang@Sun.COM for (j = i; j < tem->tvs_ntabs; j++)
1703*7688SAaron.Zang@Sun.COM tem->tvs_tabs[j] = tem->tvs_tabs[j + 1];
17041253Slq150181 return;
17051253Slq150181 }
17061253Slq150181 }
17071253Slq150181 break;
17081253Slq150181 }
17091253Slq150181 }
17101253Slq150181
17111253Slq150181 static void
tem_safe_mv_cursor(struct tem_vt_state * tem,int row,int col,cred_t * credp,enum called_from called_from)1712*7688SAaron.Zang@Sun.COM tem_safe_mv_cursor(struct tem_vt_state *tem, int row, int col,
17131253Slq150181 cred_t *credp, enum called_from called_from)
17141253Slq150181 {
1715*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1716*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
17171253Slq150181
17181253Slq150181 /*
17191253Slq150181 * Sanity check and bounds enforcement. Out of bounds requests are
17201253Slq150181 * clipped to the screen boundaries. This seems to be what SPARC
17211253Slq150181 * does.
17221253Slq150181 */
17231253Slq150181 if (row < 0)
17241253Slq150181 row = 0;
1725*7688SAaron.Zang@Sun.COM if (row >= tems.ts_c_dimension.height)
1726*7688SAaron.Zang@Sun.COM row = tems.ts_c_dimension.height - 1;
17271253Slq150181 if (col < 0)
17281253Slq150181 col = 0;
1729*7688SAaron.Zang@Sun.COM if (col >= tems.ts_c_dimension.width)
1730*7688SAaron.Zang@Sun.COM col = tems.ts_c_dimension.width - 1;
17311253Slq150181
1732*7688SAaron.Zang@Sun.COM tem_safe_send_data(tem, credp, called_from);
1733*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row = (screen_pos_t)row;
1734*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col = (screen_pos_t)col;
1735*7688SAaron.Zang@Sun.COM tem_safe_align_cursor(tem);
17361253Slq150181 }
17371253Slq150181
17381253Slq150181 /* ARGSUSED */
17391253Slq150181 void
tem_safe_reset_emulator(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from,boolean_t init_color)1740*7688SAaron.Zang@Sun.COM tem_safe_reset_emulator(struct tem_vt_state *tem,
17413994Slq150181 cred_t *credp, enum called_from called_from,
1742*7688SAaron.Zang@Sun.COM boolean_t init_color)
17431253Slq150181 {
17441253Slq150181 int j;
17451253Slq150181
1746*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1747*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
17481253Slq150181
1749*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row = 0;
1750*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col = 0;
1751*7688SAaron.Zang@Sun.COM tem->tvs_r_cursor.row = 0;
1752*7688SAaron.Zang@Sun.COM tem->tvs_r_cursor.col = 0;
1753*7688SAaron.Zang@Sun.COM tem->tvs_s_cursor.row = 0;
1754*7688SAaron.Zang@Sun.COM tem->tvs_s_cursor.col = 0;
1755*7688SAaron.Zang@Sun.COM tem->tvs_outindex = 0;
1756*7688SAaron.Zang@Sun.COM tem->tvs_state = A_STATE_START;
1757*7688SAaron.Zang@Sun.COM tem->tvs_gotparam = B_FALSE;
1758*7688SAaron.Zang@Sun.COM tem->tvs_curparam = 0;
1759*7688SAaron.Zang@Sun.COM tem->tvs_paramval = 0;
1760*7688SAaron.Zang@Sun.COM tem->tvs_nscroll = 1;
17613994Slq150181
1762*7688SAaron.Zang@Sun.COM if (init_color) {
17633994Slq150181 /* use initial settings */
1764*7688SAaron.Zang@Sun.COM tem->tvs_fg_color = tems.ts_init_color.fg_color;
1765*7688SAaron.Zang@Sun.COM tem->tvs_bg_color = tems.ts_init_color.bg_color;
1766*7688SAaron.Zang@Sun.COM tem->tvs_flags = tems.ts_init_color.a_flags;
17673994Slq150181 }
17681253Slq150181
17691253Slq150181 /*
17701253Slq150181 * set up the initial tab stops
17711253Slq150181 */
1772*7688SAaron.Zang@Sun.COM tem->tvs_ntabs = 0;
1773*7688SAaron.Zang@Sun.COM for (j = 8; j < tems.ts_c_dimension.width; j += 8)
1774*7688SAaron.Zang@Sun.COM tem->tvs_tabs[tem->tvs_ntabs++] = (screen_pos_t)j;
17751253Slq150181
17761253Slq150181 for (j = 0; j < TEM_MAXPARAMS; j++)
1777*7688SAaron.Zang@Sun.COM tem->tvs_params[j] = 0;
17781253Slq150181 }
17791253Slq150181
17801253Slq150181 void
tem_safe_reset_display(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from,boolean_t clear_txt,boolean_t init_color)1781*7688SAaron.Zang@Sun.COM tem_safe_reset_display(struct tem_vt_state *tem,
1782*7688SAaron.Zang@Sun.COM cred_t *credp, enum called_from called_from,
1783*7688SAaron.Zang@Sun.COM boolean_t clear_txt, boolean_t init_color)
17841253Slq150181 {
1785*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1786*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
17871253Slq150181
1788*7688SAaron.Zang@Sun.COM tem_safe_reset_emulator(tem, credp, called_from, init_color);
17891253Slq150181
17901253Slq150181 if (clear_txt) {
1791*7688SAaron.Zang@Sun.COM if (tem->tvs_isactive)
1792*7688SAaron.Zang@Sun.COM tem_safe_callback_cursor(tem,
1793*7688SAaron.Zang@Sun.COM VIS_HIDE_CURSOR, credp, called_from);
17941253Slq150181
1795*7688SAaron.Zang@Sun.COM tem_safe_cls(tem, credp, called_from);
1796*7688SAaron.Zang@Sun.COM
1797*7688SAaron.Zang@Sun.COM if (tem->tvs_isactive)
1798*7688SAaron.Zang@Sun.COM tem_safe_callback_cursor(tem,
1799*7688SAaron.Zang@Sun.COM VIS_DISPLAY_CURSOR, credp, called_from);
18001253Slq150181 }
18011253Slq150181 }
18021253Slq150181
18031253Slq150181 static void
tem_safe_shift(struct tem_vt_state * tem,int count,int direction,cred_t * credp,enum called_from called_from)1804*7688SAaron.Zang@Sun.COM tem_safe_shift(
1805*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
18061253Slq150181 int count,
18071253Slq150181 int direction,
18081253Slq150181 cred_t *credp,
18091253Slq150181 enum called_from called_from)
18101253Slq150181 {
18111253Slq150181 int rest_of_line;
18121253Slq150181
1813*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1814*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
18151253Slq150181
1816*7688SAaron.Zang@Sun.COM rest_of_line = tems.ts_c_dimension.width - tem->tvs_c_cursor.col;
18171253Slq150181 if (count > rest_of_line)
18181253Slq150181 count = rest_of_line;
18191253Slq150181
18201253Slq150181 if (count <= 0)
18211253Slq150181 return;
18221253Slq150181
18231253Slq150181 switch (direction) {
18241253Slq150181 case TEM_SHIFT_LEFT:
18251253Slq150181 if (count < rest_of_line) {
1826*7688SAaron.Zang@Sun.COM tem_safe_copy_area(tem,
1827*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col + count,
1828*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
1829*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width - 1,
1830*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
1831*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
1832*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
18335129Smarx credp, called_from);
18341253Slq150181 }
18351253Slq150181
1836*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem, count, tem->tvs_c_cursor.row,
1837*7688SAaron.Zang@Sun.COM (tems.ts_c_dimension.width - count), credp,
18385129Smarx called_from);
18391253Slq150181 break;
18401253Slq150181 case TEM_SHIFT_RIGHT:
18411253Slq150181 if (count < rest_of_line) {
1842*7688SAaron.Zang@Sun.COM tem_safe_copy_area(tem,
1843*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col,
1844*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
1845*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width - count - 1,
1846*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
1847*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col + count,
1848*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row,
18495129Smarx credp, called_from);
18501253Slq150181 }
18511253Slq150181
1852*7688SAaron.Zang@Sun.COM tem_safe_clear_chars(tem, count, tem->tvs_c_cursor.row,
1853*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col, credp, called_from);
18541253Slq150181 break;
18551253Slq150181 }
18561253Slq150181 }
18571253Slq150181
18581253Slq150181 void
tem_safe_text_cursor(struct tem_vt_state * tem,short action,cred_t * credp,enum called_from called_from)1859*7688SAaron.Zang@Sun.COM tem_safe_text_cursor(struct tem_vt_state *tem, short action,
18601253Slq150181 cred_t *credp, enum called_from called_from)
18611253Slq150181 {
18621253Slq150181 struct vis_conscursor ca;
18631253Slq150181
1864*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1865*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
18661253Slq150181
1867*7688SAaron.Zang@Sun.COM ca.row = tem->tvs_c_cursor.row;
1868*7688SAaron.Zang@Sun.COM ca.col = tem->tvs_c_cursor.col;
18691253Slq150181 ca.action = action;
18701253Slq150181
1871*7688SAaron.Zang@Sun.COM tems_safe_cursor(&ca, credp, called_from);
18721253Slq150181
18731253Slq150181 if (action == VIS_GET_CURSOR) {
1874*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.row = ca.row;
1875*7688SAaron.Zang@Sun.COM tem->tvs_c_cursor.col = ca.col;
18761253Slq150181 }
18771253Slq150181 }
18781253Slq150181
18791253Slq150181 void
tem_safe_pix_cursor(struct tem_vt_state * tem,short action,cred_t * credp,enum called_from called_from)1880*7688SAaron.Zang@Sun.COM tem_safe_pix_cursor(struct tem_vt_state *tem, short action,
18811253Slq150181 cred_t *credp, enum called_from called_from)
18821253Slq150181 {
18831253Slq150181 struct vis_conscursor ca;
18841253Slq150181
1885*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
1886*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
18871253Slq150181
1888*7688SAaron.Zang@Sun.COM ca.row = tem->tvs_c_cursor.row * tems.ts_font.height +
1889*7688SAaron.Zang@Sun.COM tems.ts_p_offset.y;
1890*7688SAaron.Zang@Sun.COM ca.col = tem->tvs_c_cursor.col * tems.ts_font.width +
1891*7688SAaron.Zang@Sun.COM tems.ts_p_offset.x;
1892*7688SAaron.Zang@Sun.COM ca.width = tems.ts_font.width;
1893*7688SAaron.Zang@Sun.COM ca.height = tems.ts_font.height;
1894*7688SAaron.Zang@Sun.COM if (tems.ts_pdepth == 8 || tems.ts_pdepth == 4) {
1895*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & TEM_ATTR_REVERSE) {
18961253Slq150181 ca.fg_color.mono = TEM_TEXT_WHITE;
18971253Slq150181 ca.bg_color.mono = TEM_TEXT_BLACK;
18981253Slq150181 } else {
18991253Slq150181 ca.fg_color.mono = TEM_TEXT_BLACK;
19001253Slq150181 ca.bg_color.mono = TEM_TEXT_WHITE;
19011253Slq150181 }
1902*7688SAaron.Zang@Sun.COM } else if (tems.ts_pdepth == 24 || tems.ts_pdepth == 32) {
1903*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & TEM_ATTR_REVERSE) {
19041253Slq150181 ca.fg_color.twentyfour[0] = TEM_TEXT_WHITE24_RED;
19051253Slq150181 ca.fg_color.twentyfour[1] = TEM_TEXT_WHITE24_GREEN;
19061253Slq150181 ca.fg_color.twentyfour[2] = TEM_TEXT_WHITE24_BLUE;
19071253Slq150181
19081253Slq150181 ca.bg_color.twentyfour[0] = TEM_TEXT_BLACK24_RED;
19091253Slq150181 ca.bg_color.twentyfour[1] = TEM_TEXT_BLACK24_GREEN;
19101253Slq150181 ca.bg_color.twentyfour[2] = TEM_TEXT_BLACK24_BLUE;
19111253Slq150181 } else {
19121253Slq150181 ca.fg_color.twentyfour[0] = TEM_TEXT_BLACK24_RED;
19131253Slq150181 ca.fg_color.twentyfour[1] = TEM_TEXT_BLACK24_GREEN;
19141253Slq150181 ca.fg_color.twentyfour[2] = TEM_TEXT_BLACK24_BLUE;
19151253Slq150181
19161253Slq150181 ca.bg_color.twentyfour[0] = TEM_TEXT_WHITE24_RED;
19171253Slq150181 ca.bg_color.twentyfour[1] = TEM_TEXT_WHITE24_GREEN;
19181253Slq150181 ca.bg_color.twentyfour[2] = TEM_TEXT_WHITE24_BLUE;
19191253Slq150181 }
19201253Slq150181 }
19211253Slq150181
19221253Slq150181 ca.action = action;
19231253Slq150181
1924*7688SAaron.Zang@Sun.COM tems_safe_cursor(&ca, credp, called_from);
19251253Slq150181 }
19261253Slq150181
19271253Slq150181 #define BORDER_PIXELS 10
19281253Slq150181 void
set_font(struct font * f,short * rows,short * cols,short height,short width)19291253Slq150181 set_font(struct font *f, short *rows, short *cols, short height, short width)
19301253Slq150181 {
19311253Slq150181 bitmap_data_t *font_selected = NULL;
19321253Slq150181 struct fontlist *fl;
19331253Slq150181
19341253Slq150181 /*
19351253Slq150181 * Find best font for these dimensions, or use default
19361253Slq150181 *
19371253Slq150181 * A 1 pixel border is the absolute minimum we could have
19381253Slq150181 * as a border around the text window (BORDER_PIXELS = 2),
19391253Slq150181 * however a slightly larger border not only looks better
19401253Slq150181 * but for the fonts currently statically built into the
19411253Slq150181 * emulator causes much better font selection for the
19421253Slq150181 * normal range of screen resolutions.
19431253Slq150181 */
19441253Slq150181 for (fl = fonts; fl->data; fl++) {
19451253Slq150181 if ((((*rows * fl->data->height) + BORDER_PIXELS) <= height) &&
19461253Slq150181 (((*cols * fl->data->width) + BORDER_PIXELS) <= width)) {
19471253Slq150181 font_selected = fl->data;
19481253Slq150181 break;
19491253Slq150181 }
19501253Slq150181 }
19511253Slq150181 /*
19521253Slq150181 * The minus 2 is to make sure we have at least a 1 pixel
19531253Slq150181 * boarder around the entire screen.
19541253Slq150181 */
19551253Slq150181 if (font_selected == NULL) {
19561253Slq150181 if (((*rows * DEFAULT_FONT_DATA.height) > height) ||
19571253Slq150181 ((*cols * DEFAULT_FONT_DATA.width) > width)) {
19581253Slq150181 *rows = (height - 2) / DEFAULT_FONT_DATA.height;
19591253Slq150181 *cols = (width - 2) / DEFAULT_FONT_DATA.width;
19601253Slq150181 }
19611253Slq150181 font_selected = &DEFAULT_FONT_DATA;
19621253Slq150181 }
19631253Slq150181
19641253Slq150181 f->width = font_selected->width;
19651253Slq150181 f->height = font_selected->height;
19661253Slq150181 bcopy((caddr_t)font_selected->encoding, (caddr_t)f->char_ptr,
19675129Smarx sizeof (f->char_ptr));
19681253Slq150181 f->image_data = font_selected->image;
19691253Slq150181
19701253Slq150181 }
19711253Slq150181
19721253Slq150181 /*
19731253Slq150181 * bit_to_pix4 is for 4-bit frame buffers. It will write one output byte
19741253Slq150181 * for each 2 bits of input bitmap. It inverts the input bits before
19751253Slq150181 * doing the output translation, for reverse video.
19761253Slq150181 *
19771253Slq150181 * Assuming foreground is 0001 and background is 0000...
19781253Slq150181 * An input data byte of 0x53 will output the bit pattern
19791253Slq150181 * 00000001 00000001 00000000 00010001.
19801253Slq150181 */
19811253Slq150181
1982*7688SAaron.Zang@Sun.COM static void
bit_to_pix4(struct tem_vt_state * tem,uchar_t c,text_color_t fg_color,text_color_t bg_color)19831253Slq150181 bit_to_pix4(
1984*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
19851253Slq150181 uchar_t c,
19861253Slq150181 text_color_t fg_color,
19871253Slq150181 text_color_t bg_color)
19881253Slq150181 {
19891253Slq150181 int row;
19901253Slq150181 int byte;
19911253Slq150181 int i;
19921253Slq150181 uint8_t *cp;
19931253Slq150181 uint8_t data;
19941253Slq150181 uint8_t nibblett;
19951253Slq150181 int bytes_wide;
19961253Slq150181 uint8_t *dest;
19971253Slq150181
1998*7688SAaron.Zang@Sun.COM dest = (uint8_t *)tem->tvs_pix_data;
19991253Slq150181
2000*7688SAaron.Zang@Sun.COM cp = tems.ts_font.char_ptr[c];
2001*7688SAaron.Zang@Sun.COM bytes_wide = (tems.ts_font.width + 7) / 8;
20021253Slq150181
2003*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_font.height; row++) {
20041253Slq150181 for (byte = 0; byte < bytes_wide; byte++) {
20051253Slq150181 data = *cp++;
20061253Slq150181 for (i = 0; i < 4; i++) {
20071253Slq150181 nibblett = (data >> ((3-i) * 2)) & 0x3;
20081253Slq150181 switch (nibblett) {
20091253Slq150181 case 0x0:
20101253Slq150181 *dest++ = bg_color << 4 | bg_color;
20111253Slq150181 break;
20121253Slq150181 case 0x1:
20131253Slq150181 *dest++ = bg_color << 4 | fg_color;
20141253Slq150181 break;
20151253Slq150181 case 0x2:
20161253Slq150181 *dest++ = fg_color << 4 | bg_color;
20171253Slq150181 break;
20181253Slq150181 case 0x3:
20191253Slq150181 *dest++ = fg_color << 4 | fg_color;
20201253Slq150181 break;
20211253Slq150181 }
20221253Slq150181 }
20231253Slq150181 }
20241253Slq150181 }
20251253Slq150181 }
20261253Slq150181
20271253Slq150181 /*
20281253Slq150181 * bit_to_pix8 is for 8-bit frame buffers. It will write one output byte
20291253Slq150181 * for each bit of input bitmap. It inverts the input bits before
20301253Slq150181 * doing the output translation, for reverse video.
20311253Slq150181 *
20321253Slq150181 * Assuming foreground is 00000001 and background is 00000000...
20331253Slq150181 * An input data byte of 0x53 will output the bit pattern
20341253Slq150181 * 0000000 000000001 00000000 00000001 00000000 00000000 00000001 00000001.
20351253Slq150181 */
20361253Slq150181
2037*7688SAaron.Zang@Sun.COM static void
bit_to_pix8(struct tem_vt_state * tem,uchar_t c,text_color_t fg_color,text_color_t bg_color)20381253Slq150181 bit_to_pix8(
2039*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
20401253Slq150181 uchar_t c,
20411253Slq150181 text_color_t fg_color,
20421253Slq150181 text_color_t bg_color)
20431253Slq150181 {
20441253Slq150181 int row;
20451253Slq150181 int byte;
20461253Slq150181 int i;
20471253Slq150181 uint8_t *cp;
20481253Slq150181 uint8_t data;
20491253Slq150181 int bytes_wide;
20501253Slq150181 uint8_t mask;
20511253Slq150181 int bitsleft, nbits;
20521253Slq150181 uint8_t *dest;
20531253Slq150181
2054*7688SAaron.Zang@Sun.COM dest = (uint8_t *)tem->tvs_pix_data;
20551253Slq150181
2056*7688SAaron.Zang@Sun.COM cp = tems.ts_font.char_ptr[c];
2057*7688SAaron.Zang@Sun.COM bytes_wide = (tems.ts_font.width + 7) / 8;
20581253Slq150181
2059*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_font.height; row++) {
2060*7688SAaron.Zang@Sun.COM bitsleft = tems.ts_font.width;
20611253Slq150181 for (byte = 0; byte < bytes_wide; byte++) {
20621253Slq150181 data = *cp++;
20631253Slq150181 mask = 0x80;
20641253Slq150181 nbits = MIN(8, bitsleft);
20651253Slq150181 bitsleft -= nbits;
20661253Slq150181 for (i = 0; i < nbits; i++) {
20671253Slq150181 *dest++ = (data & mask ? fg_color: bg_color);
20681253Slq150181 mask = mask >> 1;
20691253Slq150181 }
20701253Slq150181 }
20711253Slq150181 }
20721253Slq150181 }
20731253Slq150181
20741253Slq150181 /*
20751253Slq150181 * bit_to_pix24 is for 24-bit frame buffers. It will write four output bytes
20761253Slq150181 * for each bit of input bitmap. It inverts the input bits before
20771253Slq150181 * doing the output translation, for reverse video. Note that each
20781253Slq150181 * 24-bit RGB value is finally stored in a 32-bit unsigned int, with the
20791253Slq150181 * high-order byte set to zero.
20801253Slq150181 *
20811253Slq150181 * Assuming foreground is 00000000 11111111 11111111 11111111
20821253Slq150181 * and background is 00000000 00000000 00000000 00000000
20831253Slq150181 * An input data byte of 0x53 will output the bit pattern
20841253Slq150181 *
20851253Slq150181 * 00000000 00000000 00000000 00000000
20861253Slq150181 * 00000000 11111111 11111111 11111111
20871253Slq150181 * 00000000 00000000 00000000 00000000
20881253Slq150181 * 00000000 11111111 11111111 11111111
20891253Slq150181 * 00000000 00000000 00000000 00000000
20901253Slq150181 * 00000000 00000000 00000000 00000000
20911253Slq150181 * 00000000 11111111 11111111 11111111
20921253Slq150181 * 00000000 11111111 11111111 11111111
20931253Slq150181 *
20941253Slq150181 */
20951253Slq150181 typedef uint32_t pixel32_t;
20961253Slq150181
2097*7688SAaron.Zang@Sun.COM static void
bit_to_pix24(struct tem_vt_state * tem,uchar_t c,text_color_t fg_color4,text_color_t bg_color4)20981253Slq150181 bit_to_pix24(
2099*7688SAaron.Zang@Sun.COM struct tem_vt_state *tem,
21001253Slq150181 uchar_t c,
21011253Slq150181 text_color_t fg_color4,
21021253Slq150181 text_color_t bg_color4)
21031253Slq150181 {
21041253Slq150181 int row;
21051253Slq150181 int byte;
21061253Slq150181 int i;
21071253Slq150181 uint8_t *cp;
21081253Slq150181 uint8_t data;
21091253Slq150181 int bytes_wide;
21101253Slq150181 int bitsleft, nbits;
21111253Slq150181
21121253Slq150181 pixel32_t fg_color32, bg_color32, *destp;
21131253Slq150181
21141253Slq150181 ASSERT(fg_color4 < 16 && bg_color4 < 16);
21151253Slq150181
21161253Slq150181 fg_color32 = PIX4TO32(fg_color4);
21171253Slq150181 bg_color32 = PIX4TO32(bg_color4);
21181253Slq150181
2119*7688SAaron.Zang@Sun.COM destp = (pixel32_t *)tem->tvs_pix_data;
2120*7688SAaron.Zang@Sun.COM cp = tems.ts_font.char_ptr[c];
2121*7688SAaron.Zang@Sun.COM bytes_wide = (tems.ts_font.width + 7) / 8;
21221253Slq150181
2123*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_font.height; row++) {
2124*7688SAaron.Zang@Sun.COM bitsleft = tems.ts_font.width;
21251253Slq150181 for (byte = 0; byte < bytes_wide; byte++) {
21261253Slq150181 data = *cp++;
21271253Slq150181 nbits = MIN(8, bitsleft);
21281253Slq150181 bitsleft -= nbits;
21291253Slq150181 for (i = 0; i < nbits; i++) {
21305129Smarx *destp++ = ((data << i) & 0x80 ?
21315129Smarx fg_color32 : bg_color32);
21321253Slq150181 }
21331253Slq150181 }
21341253Slq150181 }
21351253Slq150181 }
21361253Slq150181
21371253Slq150181 /* ARGSUSED */
2138*7688SAaron.Zang@Sun.COM static text_color_t
ansi_bg_to_solaris(struct tem_vt_state * tem,int ansi)2139*7688SAaron.Zang@Sun.COM ansi_bg_to_solaris(struct tem_vt_state *tem, int ansi)
21401253Slq150181 {
21411253Slq150181 return (bg_xlate[ansi]);
21421253Slq150181 }
21431253Slq150181
2144*7688SAaron.Zang@Sun.COM static text_color_t
ansi_fg_to_solaris(struct tem_vt_state * tem,int ansi)2145*7688SAaron.Zang@Sun.COM ansi_fg_to_solaris(struct tem_vt_state *tem, int ansi)
21461253Slq150181 {
2147*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & TEM_ATTR_BOLD)
21485129Smarx return (fg_brt_xlate[ansi]);
21491253Slq150181 else
21505129Smarx return (fg_dim_xlate[ansi]);
21511253Slq150181 }
21521253Slq150181
2153*7688SAaron.Zang@Sun.COM /*
2154*7688SAaron.Zang@Sun.COM * flag: TEM_ATTR_SCREEN_REVERSE or TEM_ATTR_REVERSE
2155*7688SAaron.Zang@Sun.COM */
2156*7688SAaron.Zang@Sun.COM void
tem_safe_get_color(struct tem_vt_state * tem,text_color_t * fg,text_color_t * bg,uint8_t flag)2157*7688SAaron.Zang@Sun.COM tem_safe_get_color(struct tem_vt_state *tem, text_color_t *fg,
2158*7688SAaron.Zang@Sun.COM text_color_t *bg, uint8_t flag)
21591253Slq150181 {
2160*7688SAaron.Zang@Sun.COM if (tem->tvs_flags & flag) {
21611253Slq150181 *fg = ansi_fg_to_solaris(tem,
2162*7688SAaron.Zang@Sun.COM tem->tvs_bg_color);
21631253Slq150181 *bg = ansi_bg_to_solaris(tem,
2164*7688SAaron.Zang@Sun.COM tem->tvs_fg_color);
21651253Slq150181 } else {
21661253Slq150181 *fg = ansi_fg_to_solaris(tem,
2167*7688SAaron.Zang@Sun.COM tem->tvs_fg_color);
21681253Slq150181 *bg = ansi_bg_to_solaris(tem,
2169*7688SAaron.Zang@Sun.COM tem->tvs_bg_color);
21701253Slq150181 }
21711253Slq150181 }
21721253Slq150181
21731253Slq150181 /*
21741253Slq150181 * Clear a rectangle of screen for pixel mode.
21751253Slq150181 *
21761253Slq150181 * arguments:
21771253Slq150181 * row: start row#
21781253Slq150181 * nrows: the number of rows to clear
21791253Slq150181 * offset_y: the offset of height in pixels to begin clear
21801253Slq150181 * col: start col#
21811253Slq150181 * ncols: the number of cols to clear
21821253Slq150181 * offset_x: the offset of width in pixels to begin clear
21831253Slq150181 * scroll_up: whether this function is called during sroll up,
21841253Slq150181 * which is called only once.
21851253Slq150181 */
21861253Slq150181 void
tem_safe_pix_cls_range(struct tem_vt_state * tem,screen_pos_t row,int nrows,int offset_y,screen_pos_t col,int ncols,int offset_x,boolean_t sroll_up,cred_t * credp,enum called_from called_from)2187*7688SAaron.Zang@Sun.COM tem_safe_pix_cls_range(struct tem_vt_state *tem,
21881253Slq150181 screen_pos_t row, int nrows, int offset_y,
21891253Slq150181 screen_pos_t col, int ncols, int offset_x,
21901253Slq150181 boolean_t sroll_up, cred_t *credp,
21911253Slq150181 enum called_from called_from)
21921253Slq150181 {
21931253Slq150181 struct vis_consdisplay da;
21941253Slq150181 int i, j;
21951253Slq150181 int row_add = 0;
21961253Slq150181 text_color_t fg_color;
21971253Slq150181 text_color_t bg_color;
21981253Slq150181
2199*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2200*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
22011253Slq150181
22021253Slq150181 if (sroll_up)
2203*7688SAaron.Zang@Sun.COM row_add = tems.ts_c_dimension.height - 1;
22041253Slq150181
2205*7688SAaron.Zang@Sun.COM da.width = tems.ts_font.width;
2206*7688SAaron.Zang@Sun.COM da.height = tems.ts_font.height;
22071253Slq150181
2208*7688SAaron.Zang@Sun.COM tem_safe_get_color(tem, &fg_color, &bg_color, TEM_ATTR_SCREEN_REVERSE);
22091253Slq150181
2210*7688SAaron.Zang@Sun.COM tem_safe_callback_bit2pix(tem, ' ', fg_color, bg_color);
2211*7688SAaron.Zang@Sun.COM da.data = (uchar_t *)tem->tvs_pix_data;
22121253Slq150181
22131253Slq150181 for (i = 0; i < nrows; i++, row++) {
22141253Slq150181 da.row = (row + row_add) * da.height + offset_y;
22151253Slq150181 da.col = col * da.width + offset_x;
22161253Slq150181 for (j = 0; j < ncols; j++) {
2217*7688SAaron.Zang@Sun.COM tems_safe_display(&da, credp, called_from);
22181253Slq150181 da.col += da.width;
22191253Slq150181 }
22201253Slq150181 }
22211253Slq150181 }
2222*7688SAaron.Zang@Sun.COM
2223*7688SAaron.Zang@Sun.COM /*
2224*7688SAaron.Zang@Sun.COM * virtual screen operations
2225*7688SAaron.Zang@Sun.COM */
2226*7688SAaron.Zang@Sun.COM static void
tem_safe_virtual_display(struct tem_vt_state * tem,unsigned char * string,int count,screen_pos_t row,screen_pos_t col,text_color_t fg_color,text_color_t bg_color)2227*7688SAaron.Zang@Sun.COM tem_safe_virtual_display(struct tem_vt_state *tem, unsigned char *string,
2228*7688SAaron.Zang@Sun.COM int count, screen_pos_t row, screen_pos_t col,
2229*7688SAaron.Zang@Sun.COM text_color_t fg_color, text_color_t bg_color)
2230*7688SAaron.Zang@Sun.COM {
2231*7688SAaron.Zang@Sun.COM int i, width;
2232*7688SAaron.Zang@Sun.COM unsigned char *addr;
2233*7688SAaron.Zang@Sun.COM text_color_t *pfgcolor;
2234*7688SAaron.Zang@Sun.COM text_color_t *pbgcolor;
2235*7688SAaron.Zang@Sun.COM
2236*7688SAaron.Zang@Sun.COM if (row < 0 || row >= tems.ts_c_dimension.height ||
2237*7688SAaron.Zang@Sun.COM col < 0 || col >= tems.ts_c_dimension.width ||
2238*7688SAaron.Zang@Sun.COM col + count > tems.ts_c_dimension.width)
2239*7688SAaron.Zang@Sun.COM return;
2240*7688SAaron.Zang@Sun.COM
2241*7688SAaron.Zang@Sun.COM width = tems.ts_c_dimension.width;
2242*7688SAaron.Zang@Sun.COM addr = tem->tvs_screen_buf + (row * width + col);
2243*7688SAaron.Zang@Sun.COM pfgcolor = tem->tvs_fg_buf + (row * width + col);
2244*7688SAaron.Zang@Sun.COM pbgcolor = tem->tvs_bg_buf + (row * width + col);
2245*7688SAaron.Zang@Sun.COM for (i = 0; i < count; i++) {
2246*7688SAaron.Zang@Sun.COM *addr++ = string[i];
2247*7688SAaron.Zang@Sun.COM *pfgcolor++ = fg_color;
2248*7688SAaron.Zang@Sun.COM *pbgcolor++ = bg_color;
2249*7688SAaron.Zang@Sun.COM }
2250*7688SAaron.Zang@Sun.COM }
2251*7688SAaron.Zang@Sun.COM
2252*7688SAaron.Zang@Sun.COM static void
i_virtual_copy(unsigned char * base,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row)2253*7688SAaron.Zang@Sun.COM i_virtual_copy(unsigned char *base,
2254*7688SAaron.Zang@Sun.COM screen_pos_t s_col, screen_pos_t s_row,
2255*7688SAaron.Zang@Sun.COM screen_pos_t e_col, screen_pos_t e_row,
2256*7688SAaron.Zang@Sun.COM screen_pos_t t_col, screen_pos_t t_row)
2257*7688SAaron.Zang@Sun.COM {
2258*7688SAaron.Zang@Sun.COM unsigned char *from;
2259*7688SAaron.Zang@Sun.COM unsigned char *to;
2260*7688SAaron.Zang@Sun.COM int cnt;
2261*7688SAaron.Zang@Sun.COM screen_size_t chars_per_row;
2262*7688SAaron.Zang@Sun.COM unsigned char *to_row_start;
2263*7688SAaron.Zang@Sun.COM unsigned char *from_row_start;
2264*7688SAaron.Zang@Sun.COM screen_size_t rows_to_move;
2265*7688SAaron.Zang@Sun.COM int cols = tems.ts_c_dimension.width;
2266*7688SAaron.Zang@Sun.COM
2267*7688SAaron.Zang@Sun.COM chars_per_row = e_col - s_col + 1;
2268*7688SAaron.Zang@Sun.COM rows_to_move = e_row - s_row + 1;
2269*7688SAaron.Zang@Sun.COM
2270*7688SAaron.Zang@Sun.COM to_row_start = base + ((t_row * cols) + t_col);
2271*7688SAaron.Zang@Sun.COM from_row_start = base + ((s_row * cols) + s_col);
2272*7688SAaron.Zang@Sun.COM
2273*7688SAaron.Zang@Sun.COM if (to_row_start < from_row_start) {
2274*7688SAaron.Zang@Sun.COM while (rows_to_move-- > 0) {
2275*7688SAaron.Zang@Sun.COM to = to_row_start;
2276*7688SAaron.Zang@Sun.COM from = from_row_start;
2277*7688SAaron.Zang@Sun.COM to_row_start += cols;
2278*7688SAaron.Zang@Sun.COM from_row_start += cols;
2279*7688SAaron.Zang@Sun.COM for (cnt = chars_per_row; cnt-- > 0; )
2280*7688SAaron.Zang@Sun.COM *to++ = *from++;
2281*7688SAaron.Zang@Sun.COM }
2282*7688SAaron.Zang@Sun.COM } else {
2283*7688SAaron.Zang@Sun.COM /*
2284*7688SAaron.Zang@Sun.COM * Offset to the end of the region and copy backwards.
2285*7688SAaron.Zang@Sun.COM */
2286*7688SAaron.Zang@Sun.COM cnt = rows_to_move * cols + chars_per_row;
2287*7688SAaron.Zang@Sun.COM to_row_start += cnt;
2288*7688SAaron.Zang@Sun.COM from_row_start += cnt;
2289*7688SAaron.Zang@Sun.COM
2290*7688SAaron.Zang@Sun.COM while (rows_to_move-- > 0) {
2291*7688SAaron.Zang@Sun.COM to_row_start -= cols;
2292*7688SAaron.Zang@Sun.COM from_row_start -= cols;
2293*7688SAaron.Zang@Sun.COM to = to_row_start;
2294*7688SAaron.Zang@Sun.COM from = from_row_start;
2295*7688SAaron.Zang@Sun.COM for (cnt = chars_per_row; cnt-- > 0; )
2296*7688SAaron.Zang@Sun.COM *--to = *--from;
2297*7688SAaron.Zang@Sun.COM }
2298*7688SAaron.Zang@Sun.COM }
2299*7688SAaron.Zang@Sun.COM }
2300*7688SAaron.Zang@Sun.COM
2301*7688SAaron.Zang@Sun.COM static void
tem_safe_virtual_copy(struct tem_vt_state * tem,screen_pos_t s_col,screen_pos_t s_row,screen_pos_t e_col,screen_pos_t e_row,screen_pos_t t_col,screen_pos_t t_row)2302*7688SAaron.Zang@Sun.COM tem_safe_virtual_copy(struct tem_vt_state *tem,
2303*7688SAaron.Zang@Sun.COM screen_pos_t s_col, screen_pos_t s_row,
2304*7688SAaron.Zang@Sun.COM screen_pos_t e_col, screen_pos_t e_row,
2305*7688SAaron.Zang@Sun.COM screen_pos_t t_col, screen_pos_t t_row)
2306*7688SAaron.Zang@Sun.COM {
2307*7688SAaron.Zang@Sun.COM screen_size_t chars_per_row;
2308*7688SAaron.Zang@Sun.COM screen_size_t rows_to_move;
2309*7688SAaron.Zang@Sun.COM int rows = tems.ts_c_dimension.height;
2310*7688SAaron.Zang@Sun.COM int cols = tems.ts_c_dimension.width;
2311*7688SAaron.Zang@Sun.COM
2312*7688SAaron.Zang@Sun.COM if (s_col < 0 || s_col >= cols ||
2313*7688SAaron.Zang@Sun.COM s_row < 0 || s_row >= rows ||
2314*7688SAaron.Zang@Sun.COM e_col < 0 || e_col >= cols ||
2315*7688SAaron.Zang@Sun.COM e_row < 0 || e_row >= rows ||
2316*7688SAaron.Zang@Sun.COM t_col < 0 || t_col >= cols ||
2317*7688SAaron.Zang@Sun.COM t_row < 0 || t_row >= rows ||
2318*7688SAaron.Zang@Sun.COM s_col > e_col ||
2319*7688SAaron.Zang@Sun.COM s_row > e_row)
2320*7688SAaron.Zang@Sun.COM return;
2321*7688SAaron.Zang@Sun.COM
2322*7688SAaron.Zang@Sun.COM chars_per_row = e_col - s_col + 1;
2323*7688SAaron.Zang@Sun.COM rows_to_move = e_row - s_row + 1;
2324*7688SAaron.Zang@Sun.COM
2325*7688SAaron.Zang@Sun.COM /* More sanity checks. */
2326*7688SAaron.Zang@Sun.COM if (t_row + rows_to_move > rows ||
2327*7688SAaron.Zang@Sun.COM t_col + chars_per_row > cols)
2328*7688SAaron.Zang@Sun.COM return;
2329*7688SAaron.Zang@Sun.COM
2330*7688SAaron.Zang@Sun.COM i_virtual_copy(tem->tvs_screen_buf, s_col, s_row,
2331*7688SAaron.Zang@Sun.COM e_col, e_row, t_col, t_row);
2332*7688SAaron.Zang@Sun.COM
2333*7688SAaron.Zang@Sun.COM /* text_color_t is the same size as char */
2334*7688SAaron.Zang@Sun.COM i_virtual_copy((unsigned char *)tem->tvs_fg_buf,
2335*7688SAaron.Zang@Sun.COM s_col, s_row, e_col, e_row, t_col, t_row);
2336*7688SAaron.Zang@Sun.COM i_virtual_copy((unsigned char *)tem->tvs_bg_buf,
2337*7688SAaron.Zang@Sun.COM s_col, s_row, e_col, e_row, t_col, t_row);
2338*7688SAaron.Zang@Sun.COM
2339*7688SAaron.Zang@Sun.COM }
2340*7688SAaron.Zang@Sun.COM
2341*7688SAaron.Zang@Sun.COM static void
tem_safe_virtual_cls(struct tem_vt_state * tem,int count,screen_pos_t row,screen_pos_t col)2342*7688SAaron.Zang@Sun.COM tem_safe_virtual_cls(struct tem_vt_state *tem,
2343*7688SAaron.Zang@Sun.COM int count, screen_pos_t row, screen_pos_t col)
2344*7688SAaron.Zang@Sun.COM {
2345*7688SAaron.Zang@Sun.COM text_color_t fg_color;
2346*7688SAaron.Zang@Sun.COM text_color_t bg_color;
2347*7688SAaron.Zang@Sun.COM
2348*7688SAaron.Zang@Sun.COM tem_safe_get_color(tem, &fg_color, &bg_color, TEM_ATTR_SCREEN_REVERSE);
2349*7688SAaron.Zang@Sun.COM tem_safe_virtual_display(tem, tems.ts_blank_line, count, row, col,
2350*7688SAaron.Zang@Sun.COM fg_color, bg_color);
2351*7688SAaron.Zang@Sun.COM }
2352*7688SAaron.Zang@Sun.COM
2353*7688SAaron.Zang@Sun.COM /*
2354*7688SAaron.Zang@Sun.COM * only blank screen, not clear our screen buffer
2355*7688SAaron.Zang@Sun.COM */
2356*7688SAaron.Zang@Sun.COM void
tem_safe_blank_screen(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2357*7688SAaron.Zang@Sun.COM tem_safe_blank_screen(struct tem_vt_state *tem, cred_t *credp,
2358*7688SAaron.Zang@Sun.COM enum called_from called_from)
2359*7688SAaron.Zang@Sun.COM {
2360*7688SAaron.Zang@Sun.COM int row;
2361*7688SAaron.Zang@Sun.COM
2362*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2363*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
2364*7688SAaron.Zang@Sun.COM
2365*7688SAaron.Zang@Sun.COM if (tems.ts_display_mode == VIS_PIXEL) {
2366*7688SAaron.Zang@Sun.COM tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2367*7688SAaron.Zang@Sun.COM return;
2368*7688SAaron.Zang@Sun.COM }
2369*7688SAaron.Zang@Sun.COM
2370*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_c_dimension.height; row++) {
2371*7688SAaron.Zang@Sun.COM tem_safe_callback_cls(tem,
2372*7688SAaron.Zang@Sun.COM tems.ts_c_dimension.width,
2373*7688SAaron.Zang@Sun.COM row, 0, credp, called_from);
2374*7688SAaron.Zang@Sun.COM }
2375*7688SAaron.Zang@Sun.COM }
2376*7688SAaron.Zang@Sun.COM
2377*7688SAaron.Zang@Sun.COM /*
2378*7688SAaron.Zang@Sun.COM * unblank screen with associated tem from its screen buffer
2379*7688SAaron.Zang@Sun.COM */
2380*7688SAaron.Zang@Sun.COM void
tem_safe_unblank_screen(struct tem_vt_state * tem,cred_t * credp,enum called_from called_from)2381*7688SAaron.Zang@Sun.COM tem_safe_unblank_screen(struct tem_vt_state *tem, cred_t *credp,
2382*7688SAaron.Zang@Sun.COM enum called_from called_from)
2383*7688SAaron.Zang@Sun.COM {
2384*7688SAaron.Zang@Sun.COM text_color_t fg_color, fg_last;
2385*7688SAaron.Zang@Sun.COM text_color_t bg_color, bg_last;
2386*7688SAaron.Zang@Sun.COM size_t tc_size = sizeof (text_color_t);
2387*7688SAaron.Zang@Sun.COM int row, col, count, col_start;
2388*7688SAaron.Zang@Sun.COM int width;
2389*7688SAaron.Zang@Sun.COM unsigned char *buf;
2390*7688SAaron.Zang@Sun.COM
2391*7688SAaron.Zang@Sun.COM ASSERT((MUTEX_HELD(&tems.ts_lock) && MUTEX_HELD(&tem->tvs_lock)) ||
2392*7688SAaron.Zang@Sun.COM called_from == CALLED_FROM_STANDALONE);
2393*7688SAaron.Zang@Sun.COM
2394*7688SAaron.Zang@Sun.COM if (tems.ts_display_mode == VIS_PIXEL)
2395*7688SAaron.Zang@Sun.COM tem_safe_pix_clear_entire_screen(tem, credp, called_from);
2396*7688SAaron.Zang@Sun.COM
2397*7688SAaron.Zang@Sun.COM tem_safe_callback_cursor(tem, VIS_HIDE_CURSOR, credp, called_from);
2398*7688SAaron.Zang@Sun.COM
2399*7688SAaron.Zang@Sun.COM width = tems.ts_c_dimension.width;
2400*7688SAaron.Zang@Sun.COM
2401*7688SAaron.Zang@Sun.COM /*
2402*7688SAaron.Zang@Sun.COM * Display data in tvs_screen_buf to the actual framebuffer in a
2403*7688SAaron.Zang@Sun.COM * row by row way.
2404*7688SAaron.Zang@Sun.COM * When dealing with one row, output data with the same foreground
2405*7688SAaron.Zang@Sun.COM * and background color all together.
2406*7688SAaron.Zang@Sun.COM */
2407*7688SAaron.Zang@Sun.COM for (row = 0; row < tems.ts_c_dimension.height; row++) {
2408*7688SAaron.Zang@Sun.COM buf = tem->tvs_screen_buf + (row * width);
2409*7688SAaron.Zang@Sun.COM count = col_start = 0;
2410*7688SAaron.Zang@Sun.COM for (col = 0; col < width; col++) {
2411*7688SAaron.Zang@Sun.COM fg_color =
2412*7688SAaron.Zang@Sun.COM tem->tvs_fg_buf[(row * width + col) * tc_size];
2413*7688SAaron.Zang@Sun.COM bg_color =
2414*7688SAaron.Zang@Sun.COM tem->tvs_bg_buf[(row * width + col) * tc_size];
2415*7688SAaron.Zang@Sun.COM if (col == 0) {
2416*7688SAaron.Zang@Sun.COM fg_last = fg_color;
2417*7688SAaron.Zang@Sun.COM bg_last = bg_color;
2418*7688SAaron.Zang@Sun.COM }
2419*7688SAaron.Zang@Sun.COM
2420*7688SAaron.Zang@Sun.COM if ((fg_color != fg_last) || (bg_color != bg_last)) {
2421*7688SAaron.Zang@Sun.COM /*
2422*7688SAaron.Zang@Sun.COM * Call the primitive to render this data.
2423*7688SAaron.Zang@Sun.COM */
2424*7688SAaron.Zang@Sun.COM tem_safe_callback_display(tem,
2425*7688SAaron.Zang@Sun.COM buf, count, row, col_start,
2426*7688SAaron.Zang@Sun.COM fg_last, bg_last, credp, called_from);
2427*7688SAaron.Zang@Sun.COM buf += count;
2428*7688SAaron.Zang@Sun.COM count = 1;
2429*7688SAaron.Zang@Sun.COM col_start = col;
2430*7688SAaron.Zang@Sun.COM fg_last = fg_color;
2431*7688SAaron.Zang@Sun.COM bg_last = bg_color;
2432*7688SAaron.Zang@Sun.COM } else {
2433*7688SAaron.Zang@Sun.COM count++;
2434*7688SAaron.Zang@Sun.COM }
2435*7688SAaron.Zang@Sun.COM }
2436*7688SAaron.Zang@Sun.COM
2437*7688SAaron.Zang@Sun.COM if (col_start == (width - 1))
2438*7688SAaron.Zang@Sun.COM continue;
2439*7688SAaron.Zang@Sun.COM
2440*7688SAaron.Zang@Sun.COM /*
2441*7688SAaron.Zang@Sun.COM * Call the primitive to render this data.
2442*7688SAaron.Zang@Sun.COM */
2443*7688SAaron.Zang@Sun.COM tem_safe_callback_display(tem,
2444*7688SAaron.Zang@Sun.COM buf, count, row, col_start,
2445*7688SAaron.Zang@Sun.COM fg_last, bg_last, credp, called_from);
2446*7688SAaron.Zang@Sun.COM }
2447*7688SAaron.Zang@Sun.COM
2448*7688SAaron.Zang@Sun.COM tem_safe_callback_cursor(tem, VIS_DISPLAY_CURSOR, credp, called_from);
2449*7688SAaron.Zang@Sun.COM }
2450