1 /* ----------------------------------------------------------------------- *
3 * Copyright 2004-2006 H. Peter Anvin - All Rights Reserved
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
26 * ----------------------------------------------------------------------- */
31 * ANSI character code engine
38 static const struct term_state default_state
=
41 .cindex
= 0, /* First color table entry */
58 /* DEC VT graphics to codepage 437 table (characters 0x60-0x7F only) */
59 static const char decvt_to_cp437
[] =
61 0004, 0261, 0007, 0007, 0007, 0007, 0370, 0361,
62 0007, 0007, 0331, 0277, 0332, 0300, 0305, 0304,
63 0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302,
64 0263, 0363, 0362, 0343, 0330, 0234, 0007, 00
67 void __ansi_init(const struct term_info
*ti
)
69 memcpy(ti
->ts
, &default_state
, sizeof default_state
);
72 void __ansi_putchar(const struct term_info
*ti
, uint8_t ch
)
74 const struct ansi_ops
*op
= ti
->op
;
75 struct term_state
*st
= ti
->ts
;
76 const int rows
= ti
->rows
;
77 const int cols
= ti
->cols
;
78 struct curxy xy
= st
->xy
;
80 switch ( st
->state
) {
87 if ( xy
.x
> 0 ) xy
.x
--;
91 int nsp
= 8 - (xy
.x
& 7);
93 __ansi_putchar(ti
, ' ');
95 return; /* Cursor already updated */
119 /* Print character */
121 if ( st
->vtgraphics
&& (ch
& 0xe0) == 0x60 )
122 ch
= decvt_to_cp437
[ch
- 0x60];
124 op
->write_char(xy
.x
, xy
.y
, ch
, st
);
137 /* Ignore this plus the subsequent character, allows
138 compatibility with Linux sequence to set charset */
142 st
->nparms
= st
->pvt
= 0;
143 memset(st
->parms
, 0, sizeof st
->parms
);
147 memcpy(&st
, &default_state
, sizeof st
);
148 op
->erase(st
, 0, 0, cols
-1, rows
-1);
153 /* Ignore sequence */
161 int p0
= st
->parms
[0] ? st
->parms
[0] : 1;
163 if ( ch
>= '0' && ch
<= '9' ) {
164 st
->parms
[st
->nparms
] = st
->parms
[st
->nparms
]*10 + (ch
-'0');
165 } else if ( ch
== ';' ) {
167 if ( st
->nparms
>= ANSI_MAX_PARMS
)
168 st
->nparms
= ANSI_MAX_PARMS
-1;
170 } else if ( ch
== '?' ) {
177 xy
.y
= (y
< 0) ? 0 : y
;
183 xy
.y
= (y
>= rows
) ? rows
-1 : y
;
189 xy
.x
= (x
>= cols
) ? cols
-1 : x
;
195 xy
.x
= (x
< 0) ? 0 : x
;
201 xy
.y
= (y
>= rows
) ? rows
-1 : y
;
208 xy
.y
= (y
< 0) ? 0 : y
;
215 int x
= st
->parms
[0] - 1;
216 xy
.x
= (x
>= cols
) ? cols
-1 : (x
< 0) ? 0 : x
;
222 int y
= st
->parms
[0] - 1;
223 int x
= st
->parms
[1] - 1;
225 xy
.x
= (x
>= cols
) ? cols
-1 : (x
< 0) ? 0 : x
;
226 xy
.y
= (y
>= rows
) ? rows
-1 : (y
< 0) ? 0 : y
;
231 switch ( st
->parms
[0] ) {
233 op
->erase(st
, xy
.x
, xy
.y
, cols
-1, xy
.y
);
235 op
->erase(st
, 0, xy
.y
+1, cols
-1, rows
-1);
240 op
->erase(st
, 0, 0, cols
-1, xy
.y
-1);
242 op
->erase(st
, 0, xy
.y
, xy
.x
-1, xy
.y
);
246 op
->erase(st
, 0, 0, cols
-1, rows
-1);
257 switch ( st
->parms
[0] ) {
259 op
->erase(st
, xy
.x
, xy
.y
, cols
-1, xy
.y
);
264 op
->erase(st
, 0, xy
.y
, xy
.x
-1, xy
.y
);
268 op
->erase(st
, 0, xy
.y
, cols
-1, xy
.y
);
280 int set
= (ch
== 'h');
281 switch ( st
->parms
[0] ) {
297 static const int ansi2pc
[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
300 for ( i
= 0 ; i
<= st
->nparms
; i
++ ) {
301 int a
= st
->parms
[i
];
340 st
->fg
= ansi2pc
[a
-30];
351 st
->bg
= ansi2pc
[a
-40];
369 default: /* Includes CAN and SUB */
370 break; /* Drop unknown sequence */
386 int n
= (unsigned char)ch
- '0';
389 st
->state
= st_sohc1
;
398 int n
= (unsigned char)ch
- '0';
403 if (st
->parms
[0] < console_color_table_size
) {
404 /* Set the color table index */
405 st
->cindex
= st
->parms
[0];
407 /* See if there are any other attributes we care about */
408 p
= console_color_table
[st
->parms
[0]].ansi
;
410 __ansi_putchar(ti
, '[');
411 __ansi_putchar(ti
, '0');
412 __ansi_putchar(ti
, ';');
414 __ansi_putchar(ti
, *p
++);
415 __ansi_putchar(ti
, 'm');
424 /* If we fell off the end of the screen, adjust */
425 if ( xy
.x
>= cols
) {
429 while ( xy
.y
>= rows
) {
434 /* Update cursor position */
435 op
->set_cursor(xy
.x
, xy
.y
, st
->cursor
);