1 /* ----------------------------------------------------------------------- *
3 * Copyright 2004-2008 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
= {
43 .cindex
= 0, /* First color table entry */
51 .autocr
= true, /* Mimic \n -> \r\n conversion by default */
52 .autowrap
= true, /* Wrap lines by default */
57 /* DEC VT graphics to codepage 437 table (characters 0x60-0x7F only) */
58 static const char decvt_to_cp437
[] = {
59 0004, 0261, 0007, 0007, 0007, 0007, 0370, 0361,
60 0007, 0007, 0331, 0277, 0332, 0300, 0305, 0304,
61 0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302,
62 0263, 0363, 0362, 0343, 0330, 0234, 0007, 00
65 void __ansi_init(const struct term_info
*ti
)
67 memcpy(ti
->ts
, &default_state
, sizeof default_state
);
70 void __ansi_putchar(const struct term_info
*ti
, uint8_t ch
)
72 const struct ansi_ops
*op
= ti
->op
;
73 struct term_state
*st
= ti
->ts
;
74 const int rows
= ti
->rows
;
75 const int cols
= ti
->cols
;
76 struct curxy xy
= st
->xy
;
94 int nsp
= 8 - (xy
.x
& 7);
96 __ansi_putchar(ti
, ' ');
98 return; /* Cursor already updated */
122 /* Print character */
124 if (st
->vtgraphics
&& (ch
& 0xe0) == 0x60)
125 ch
= decvt_to_cp437
[ch
- 0x60];
127 op
->write_char(xy
.x
, xy
.y
, ch
, st
);
140 /* Ignore this plus the subsequent character, allows
141 compatibility with Linux sequence to set charset */
147 memset(st
->parms
, 0, sizeof st
->parms
);
151 memcpy(&st
, &default_state
, sizeof st
);
152 op
->erase(st
, 0, 0, cols
- 1, rows
- 1);
157 /* Ignore sequence */
165 int p0
= st
->parms
[0] ? st
->parms
[0] : 1;
167 if (ch
>= '0' && ch
<= '9') {
168 st
->parms
[st
->nparms
] = st
->parms
[st
->nparms
] * 10 + (ch
- '0');
169 } else if (ch
== ';') {
171 if (st
->nparms
>= ANSI_MAX_PARMS
)
172 st
->nparms
= ANSI_MAX_PARMS
- 1;
174 } else if (ch
== '?') {
181 xy
.y
= (y
< 0) ? 0 : y
;
187 xy
.y
= (y
>= rows
) ? rows
- 1 : y
;
193 xy
.x
= (x
>= cols
) ? cols
- 1 : x
;
199 xy
.x
= (x
< 0) ? 0 : x
;
205 xy
.y
= (y
>= rows
) ? rows
- 1 : y
;
212 xy
.y
= (y
< 0) ? 0 : y
;
219 int x
= st
->parms
[0] - 1;
220 xy
.x
= (x
>= cols
) ? cols
- 1 : (x
< 0) ? 0 : x
;
226 int y
= st
->parms
[0] - 1;
227 int x
= st
->parms
[1] - 1;
229 xy
.x
= (x
>= cols
) ? cols
- 1 : (x
< 0) ? 0 : x
;
230 xy
.y
= (y
>= rows
) ? rows
- 1 : (y
< 0) ? 0 : y
;
235 switch (st
->parms
[0]) {
237 op
->erase(st
, xy
.x
, xy
.y
, cols
- 1, xy
.y
);
239 op
->erase(st
, 0, xy
.y
+ 1, cols
- 1, rows
- 1);
244 op
->erase(st
, 0, 0, cols
- 1, xy
.y
- 1);
246 op
->erase(st
, 0, xy
.y
, xy
.x
- 1, xy
.y
);
250 op
->erase(st
, 0, 0, cols
- 1, rows
- 1);
261 switch (st
->parms
[0]) {
263 op
->erase(st
, xy
.x
, xy
.y
, cols
- 1, xy
.y
);
268 op
->erase(st
, 0, xy
.y
, xy
.x
- 1, xy
.y
);
272 op
->erase(st
, 0, xy
.y
, cols
- 1, xy
.y
);
284 bool set
= (ch
== 'h');
285 switch (st
->parms
[0]) {
292 case 25: /* DECTECM */
304 static const int ansi2pc
[8] =
305 { 0, 4, 2, 6, 1, 5, 3, 7 };
308 for (i
= 0; i
<= st
->nparms
; i
++) {
309 int a
= st
->parms
[i
];
348 st
->fg
= ansi2pc
[a
- 30];
359 st
->bg
= ansi2pc
[a
- 40];
377 default: /* Includes CAN and SUB */
378 break; /* Drop unknown sequence */
395 unsigned int n
= (unsigned char)ch
- '0';
399 st
->parms
[1] = st
->parms
[1] * 10 + n
;
401 if (!--st
->parms
[0]) {
402 if (st
->parms
[1] < console_color_table_size
) {
403 /* Set the color table index */
404 st
->cindex
= st
->parms
[1];
406 /* See if there are any other attributes we care about */
407 p
= console_color_table
[st
->parms
[1]].ansi
;
410 __ansi_putchar(ti
, '[');
411 __ansi_putchar(ti
, '0');
412 __ansi_putchar(ti
, ';');
414 __ansi_putchar(ti
, *p
++);
415 __ansi_putchar(ti
, 'm');
427 /* If we fell off the end of the screen, adjust */
436 while (xy
.y
>= rows
) {
441 /* Update cursor position */
442 op
->set_cursor(xy
.x
, xy
.y
, st
->cursor
);