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