Commit 6d6f7c288dbd892fb85028cb7a7fe8812ac11135

Authored by pbrook
1 parent d2ec1774

Improved terminal emulation (Piotr Esden-Tempski).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1773 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 268 additions and 48 deletions
console.c
@@ -23,16 +23,26 @@ @@ -23,16 +23,26 @@
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 25
  26 +//#define DEBUG_CONSOLE
26 #define DEFAULT_BACKSCROLL 512 27 #define DEFAULT_BACKSCROLL 512
27 #define MAX_CONSOLES 12 28 #define MAX_CONSOLES 12
28 29
29 #define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) 30 #define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
30 #define RGB(r, g, b) RGBA(r, g, b, 0xff) 31 #define RGB(r, g, b) RGBA(r, g, b, 0xff)
31 32
  33 +typedef struct TextAttributes {
  34 + uint8_t fgcol:4;
  35 + uint8_t bgcol:4;
  36 + uint8_t bold:1;
  37 + uint8_t uline:1;
  38 + uint8_t blink:1;
  39 + uint8_t invers:1;
  40 + uint8_t unvisible:1;
  41 +} TextAttributes;
  42 +
32 typedef struct TextCell { 43 typedef struct TextCell {
33 uint8_t ch; 44 uint8_t ch;
34 - uint8_t bgcol:4;  
35 - uint8_t fgcol:4; 45 + TextAttributes t_attrib;
36 } TextCell; 46 } TextCell;
37 47
38 #define MAX_ESC_PARAMS 3 48 #define MAX_ESC_PARAMS 3
@@ -43,6 +53,7 @@ enum TTYState { @@ -43,6 +53,7 @@ enum TTYState {
43 TTY_STATE_CSI, 53 TTY_STATE_CSI,
44 }; 54 };
45 55
  56 +
46 struct TextConsole { 57 struct TextConsole {
47 int text_console; /* true if text console */ 58 int text_console; /* true if text console */
48 DisplayState *ds; 59 DisplayState *ds;
@@ -51,11 +62,11 @@ struct TextConsole { @@ -51,11 +62,11 @@ struct TextConsole {
51 int height; 62 int height;
52 int total_height; 63 int total_height;
53 int backscroll_height; 64 int backscroll_height;
54 - int fgcol;  
55 - int bgcol;  
56 int x, y; 65 int x, y;
57 int y_displayed; 66 int y_displayed;
58 int y_base; 67 int y_base;
  68 + TextAttributes t_attrib_default; /* default text attributes */
  69 + TextAttributes t_attrib; /* currently active text attributes */
59 TextCell *cells; 70 TextCell *cells;
60 71
61 enum TTYState state; 72 enum TTYState state;
@@ -221,17 +232,40 @@ static const uint32_t dmask4[4] = { @@ -221,17 +232,40 @@ static const uint32_t dmask4[4] = {
221 PAT(0xffffffff), 232 PAT(0xffffffff),
222 }; 233 };
223 234
224 -static uint32_t color_table[8];  
225 -  
226 -static const uint32_t color_table_rgb[8] = {  
227 - RGB(0x00, 0x00, 0x00),  
228 - RGB(0xff, 0x00, 0x00),  
229 - RGB(0x00, 0xff, 0x00),  
230 - RGB(0xff, 0xff, 0x00),  
231 - RGB(0x00, 0x00, 0xff),  
232 - RGB(0xff, 0x00, 0xff),  
233 - RGB(0x00, 0xff, 0xff),  
234 - RGB(0xff, 0xff, 0xff), 235 +static uint32_t color_table[2][8];
  236 +
  237 +enum color_names {
  238 + COLOR_BLACK = 0,
  239 + COLOR_RED = 1,
  240 + COLOR_GREEN = 2,
  241 + COLOR_YELLOW = 3,
  242 + COLOR_BLUE = 4,
  243 + COLOR_MAGENTA = 5,
  244 + COLOR_CYAN = 6,
  245 + COLOR_WHITE = 7
  246 +};
  247 +
  248 +static const uint32_t color_table_rgb[2][8] = {
  249 + { /* dark */
  250 + RGB(0x00, 0x00, 0x00), /* black */
  251 + RGB(0xaa, 0x00, 0x00), /* red */
  252 + RGB(0x00, 0xaa, 0x00), /* green */
  253 + RGB(0xaa, 0xaa, 0x00), /* yellow */
  254 + RGB(0x00, 0x00, 0xaa), /* blue */
  255 + RGB(0xaa, 0x00, 0xaa), /* magenta */
  256 + RGB(0x00, 0xaa, 0xaa), /* cyan */
  257 + RGB(0xaa, 0xaa, 0xaa), /* white */
  258 + },
  259 + { /* bright */
  260 + RGB(0x00, 0x00, 0x00), /* black */
  261 + RGB(0xff, 0x00, 0x00), /* red */
  262 + RGB(0x00, 0xff, 0x00), /* green */
  263 + RGB(0xff, 0xff, 0x00), /* yellow */
  264 + RGB(0x00, 0x00, 0xff), /* blue */
  265 + RGB(0xff, 0x00, 0xff), /* magenta */
  266 + RGB(0x00, 0xff, 0xff), /* cyan */
  267 + RGB(0xff, 0xff, 0xff), /* white */
  268 + }
235 }; 269 };
236 270
237 static inline unsigned int col_expand(DisplayState *ds, unsigned int col) 271 static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
@@ -251,14 +285,60 @@ static inline unsigned int col_expand(DisplayState *ds, unsigned int col) @@ -251,14 +285,60 @@ static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
251 285
252 return col; 286 return col;
253 } 287 }
  288 +#ifdef DEBUG_CONSOLE
  289 +static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
  290 +{
  291 + if (t_attrib->bold) {
  292 + printf("b");
  293 + } else {
  294 + printf(" ");
  295 + }
  296 + if (t_attrib->uline) {
  297 + printf("u");
  298 + } else {
  299 + printf(" ");
  300 + }
  301 + if (t_attrib->blink) {
  302 + printf("l");
  303 + } else {
  304 + printf(" ");
  305 + }
  306 + if (t_attrib->invers) {
  307 + printf("i");
  308 + } else {
  309 + printf(" ");
  310 + }
  311 + if (t_attrib->unvisible) {
  312 + printf("n");
  313 + } else {
  314 + printf(" ");
  315 + }
  316 +
  317 + printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch);
  318 +}
  319 +#endif
254 320
255 static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, 321 static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
256 - unsigned int fgcol, unsigned int bgcol) 322 + TextAttributes *t_attrib)
257 { 323 {
258 uint8_t *d; 324 uint8_t *d;
259 const uint8_t *font_ptr; 325 const uint8_t *font_ptr;
260 unsigned int font_data, linesize, xorcol, bpp; 326 unsigned int font_data, linesize, xorcol, bpp;
261 int i; 327 int i;
  328 + unsigned int fgcol, bgcol;
  329 +
  330 +#ifdef DEBUG_CONSOLE
  331 + printf("x: %2i y: %2i", x, y);
  332 + console_print_text_attributes(t_attrib, ch);
  333 +#endif
  334 +
  335 + if (t_attrib->invers) {
  336 + bgcol = color_table[t_attrib->bold][t_attrib->fgcol];
  337 + fgcol = color_table[t_attrib->bold][t_attrib->bgcol];
  338 + } else {
  339 + fgcol = color_table[t_attrib->bold][t_attrib->fgcol];
  340 + bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
  341 + }
262 342
263 bpp = (ds->depth + 7) >> 3; 343 bpp = (ds->depth + 7) >> 3;
264 d = ds->data + 344 d = ds->data +
@@ -270,6 +350,10 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, @@ -270,6 +350,10 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
270 case 8: 350 case 8:
271 for(i = 0; i < FONT_HEIGHT; i++) { 351 for(i = 0; i < FONT_HEIGHT; i++) {
272 font_data = *font_ptr++; 352 font_data = *font_ptr++;
  353 + if (t_attrib->uline
  354 + && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
  355 + font_data = 0xFFFF;
  356 + }
273 ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol; 357 ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
274 ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; 358 ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
275 d += linesize; 359 d += linesize;
@@ -279,6 +363,10 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, @@ -279,6 +363,10 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
279 case 15: 363 case 15:
280 for(i = 0; i < FONT_HEIGHT; i++) { 364 for(i = 0; i < FONT_HEIGHT; i++) {
281 font_data = *font_ptr++; 365 font_data = *font_ptr++;
  366 + if (t_attrib->uline
  367 + && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
  368 + font_data = 0xFFFF;
  369 + }
282 ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; 370 ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
283 ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol; 371 ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
284 ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol; 372 ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
@@ -289,6 +377,9 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, @@ -289,6 +377,9 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
289 case 32: 377 case 32:
290 for(i = 0; i < FONT_HEIGHT; i++) { 378 for(i = 0; i < FONT_HEIGHT; i++) {
291 font_data = *font_ptr++; 379 font_data = *font_ptr++;
  380 + if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
  381 + font_data = 0xFFFF;
  382 + }
292 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; 383 ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
293 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; 384 ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
294 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; 385 ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
@@ -327,8 +418,7 @@ static void text_console_resize(TextConsole *s) @@ -327,8 +418,7 @@ static void text_console_resize(TextConsole *s)
327 } 418 }
328 for(x = w1; x < s->width; x++) { 419 for(x = w1; x < s->width; x++) {
329 c->ch = ' '; 420 c->ch = ' ';
330 - c->fgcol = 7;  
331 - c->bgcol = 0; 421 + c->t_attrib = s->t_attrib_default;
332 c++; 422 c++;
333 } 423 }
334 } 424 }
@@ -349,7 +439,7 @@ static void update_xy(TextConsole *s, int x, int y) @@ -349,7 +439,7 @@ static void update_xy(TextConsole *s, int x, int y)
349 if (y2 < s->height) { 439 if (y2 < s->height) {
350 c = &s->cells[y1 * s->width + x]; 440 c = &s->cells[y1 * s->width + x];
351 vga_putcharxy(s->ds, x, y2, c->ch, 441 vga_putcharxy(s->ds, x, y2, c->ch,
352 - color_table[c->fgcol], color_table[c->bgcol]); 442 + &(c->t_attrib));
353 dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT, 443 dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
354 FONT_WIDTH, FONT_HEIGHT); 444 FONT_WIDTH, FONT_HEIGHT);
355 } 445 }
@@ -369,11 +459,12 @@ static void console_show_cursor(TextConsole *s, int show) @@ -369,11 +459,12 @@ static void console_show_cursor(TextConsole *s, int show)
369 if (y < s->height) { 459 if (y < s->height) {
370 c = &s->cells[y1 * s->width + s->x]; 460 c = &s->cells[y1 * s->width + s->x];
371 if (show) { 461 if (show) {
372 - vga_putcharxy(s->ds, s->x, y, c->ch,  
373 - color_table[0], color_table[7]); 462 + TextAttributes t_attrib = s->t_attrib_default;
  463 + t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
  464 + vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);
374 } else { 465 } else {
375 vga_putcharxy(s->ds, s->x, y, c->ch, 466 vga_putcharxy(s->ds, s->x, y, c->ch,
376 - color_table[c->fgcol], color_table[c->bgcol]); 467 + &(c->t_attrib));
377 } 468 }
378 dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT, 469 dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
379 FONT_WIDTH, FONT_HEIGHT); 470 FONT_WIDTH, FONT_HEIGHT);
@@ -390,13 +481,13 @@ static void console_refresh(TextConsole *s) @@ -390,13 +481,13 @@ static void console_refresh(TextConsole *s)
390 return; 481 return;
391 482
392 vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height, 483 vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
393 - color_table[0]); 484 + color_table[0][COLOR_BLACK]);
394 y1 = s->y_displayed; 485 y1 = s->y_displayed;
395 for(y = 0; y < s->height; y++) { 486 for(y = 0; y < s->height; y++) {
396 c = s->cells + y1 * s->width; 487 c = s->cells + y1 * s->width;
397 for(x = 0; x < s->width; x++) { 488 for(x = 0; x < s->width; x++) {
398 vga_putcharxy(s->ds, x, y, c->ch, 489 vga_putcharxy(s->ds, x, y, c->ch,
399 - color_table[c->fgcol], color_table[c->bgcol]); 490 + &(c->t_attrib));
400 c++; 491 c++;
401 } 492 }
402 if (++y1 == s->total_height) 493 if (++y1 == s->total_height)
@@ -449,7 +540,7 @@ static void console_put_lf(TextConsole *s) @@ -449,7 +540,7 @@ static void console_put_lf(TextConsole *s)
449 s->y++; 540 s->y++;
450 if (s->y >= s->height) { 541 if (s->y >= s->height) {
451 s->y = s->height - 1; 542 s->y = s->height - 1;
452 - 543 +
453 if (s->y_displayed == s->y_base) { 544 if (s->y_displayed == s->y_base) {
454 if (++s->y_displayed == s->total_height) 545 if (++s->y_displayed == s->total_height)
455 s->y_displayed = 0; 546 s->y_displayed = 0;
@@ -462,8 +553,7 @@ static void console_put_lf(TextConsole *s) @@ -462,8 +553,7 @@ static void console_put_lf(TextConsole *s)
462 c = &s->cells[y1 * s->width]; 553 c = &s->cells[y1 * s->width];
463 for(x = 0; x < s->width; x++) { 554 for(x = 0; x < s->width; x++) {
464 c->ch = ' '; 555 c->ch = ' ';
465 - c->fgcol = s->fgcol;  
466 - c->bgcol = s->bgcol; 556 + c->t_attrib = s->t_attrib_default;
467 c++; 557 c++;
468 } 558 }
469 if (s == active_console && s->y_displayed == s->y_base) { 559 if (s == active_console && s->y_displayed == s->y_base) {
@@ -472,13 +562,114 @@ static void console_put_lf(TextConsole *s) @@ -472,13 +562,114 @@ static void console_put_lf(TextConsole *s)
472 (s->height - 1) * FONT_HEIGHT); 562 (s->height - 1) * FONT_HEIGHT);
473 vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT, 563 vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
474 s->width * FONT_WIDTH, FONT_HEIGHT, 564 s->width * FONT_WIDTH, FONT_HEIGHT,
475 - color_table[s->bgcol]); 565 + color_table[0][s->t_attrib_default.bgcol]);
476 dpy_update(s->ds, 0, 0, 566 dpy_update(s->ds, 0, 0,
477 s->width * FONT_WIDTH, s->height * FONT_HEIGHT); 567 s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
478 } 568 }
479 } 569 }
480 } 570 }
481 571
  572 +/* Set console attributes depending on the current escape codes.
  573 + * NOTE: I know this code is not very efficient (checking every color for it
  574 + * self) but it is more readable and better maintainable.
  575 + */
  576 +static void console_handle_escape(TextConsole *s)
  577 +{
  578 + int i;
  579 +
  580 + if (s->nb_esc_params == 0) { /* ESC[m sets all attributes to default */
  581 + s->t_attrib = s->t_attrib_default;
  582 + return;
  583 + }
  584 + for (i=0; i<s->nb_esc_params; i++) {
  585 + switch (s->esc_params[i]) {
  586 + case 0: /* reset all console attributes to default */
  587 + s->t_attrib = s->t_attrib_default;
  588 + break;
  589 + case 1:
  590 + s->t_attrib.bold = 1;
  591 + break;
  592 + case 4:
  593 + s->t_attrib.uline = 1;
  594 + break;
  595 + case 5:
  596 + s->t_attrib.blink = 1;
  597 + break;
  598 + case 7:
  599 + s->t_attrib.invers = 1;
  600 + break;
  601 + case 8:
  602 + s->t_attrib.unvisible = 1;
  603 + break;
  604 + case 22:
  605 + s->t_attrib.bold = 0;
  606 + break;
  607 + case 24:
  608 + s->t_attrib.uline = 0;
  609 + break;
  610 + case 25:
  611 + s->t_attrib.blink = 0;
  612 + break;
  613 + case 27:
  614 + s->t_attrib.invers = 0;
  615 + break;
  616 + case 28:
  617 + s->t_attrib.unvisible = 0;
  618 + break;
  619 + /* set foreground color */
  620 + case 30:
  621 + s->t_attrib.fgcol=COLOR_BLACK;
  622 + break;
  623 + case 31:
  624 + s->t_attrib.fgcol=COLOR_RED;
  625 + break;
  626 + case 32:
  627 + s->t_attrib.fgcol=COLOR_GREEN;
  628 + break;
  629 + case 33:
  630 + s->t_attrib.fgcol=COLOR_YELLOW;
  631 + break;
  632 + case 34:
  633 + s->t_attrib.fgcol=COLOR_BLUE;
  634 + break;
  635 + case 35:
  636 + s->t_attrib.fgcol=COLOR_MAGENTA;
  637 + break;
  638 + case 36:
  639 + s->t_attrib.fgcol=COLOR_CYAN;
  640 + break;
  641 + case 37:
  642 + s->t_attrib.fgcol=COLOR_WHITE;
  643 + break;
  644 + /* set background color */
  645 + case 40:
  646 + s->t_attrib.bgcol=COLOR_BLACK;
  647 + break;
  648 + case 41:
  649 + s->t_attrib.bgcol=COLOR_RED;
  650 + break;
  651 + case 42:
  652 + s->t_attrib.bgcol=COLOR_GREEN;
  653 + break;
  654 + case 43:
  655 + s->t_attrib.bgcol=COLOR_YELLOW;
  656 + break;
  657 + case 44:
  658 + s->t_attrib.bgcol=COLOR_BLUE;
  659 + break;
  660 + case 45:
  661 + s->t_attrib.bgcol=COLOR_MAGENTA;
  662 + break;
  663 + case 46:
  664 + s->t_attrib.bgcol=COLOR_CYAN;
  665 + break;
  666 + case 47:
  667 + s->t_attrib.bgcol=COLOR_WHITE;
  668 + break;
  669 + }
  670 + }
  671 +}
  672 +
482 static void console_putchar(TextConsole *s, int ch) 673 static void console_putchar(TextConsole *s, int ch)
483 { 674 {
484 TextCell *c; 675 TextCell *c;
@@ -487,21 +678,38 @@ static void console_putchar(TextConsole *s, int ch) @@ -487,21 +678,38 @@ static void console_putchar(TextConsole *s, int ch)
487 switch(s->state) { 678 switch(s->state) {
488 case TTY_STATE_NORM: 679 case TTY_STATE_NORM:
489 switch(ch) { 680 switch(ch) {
490 - case '\r': 681 + case '\r': /* carriage return */
491 s->x = 0; 682 s->x = 0;
492 break; 683 break;
493 - case '\n': 684 + case '\n': /* newline */
494 console_put_lf(s); 685 console_put_lf(s);
495 break; 686 break;
496 - case 27: 687 + case '\b': /* backspace */
  688 + if(s->x > 0) s->x--;
  689 + y1 = (s->y_base + s->y) % s->total_height;
  690 + c = &s->cells[y1 * s->width + s->x];
  691 + c->ch = ' ';
  692 + c->t_attrib = s->t_attrib;
  693 + update_xy(s, s->x, s->y);
  694 + break;
  695 + case '\t': /* tabspace */
  696 + if (s->x + (8 - (s->x % 8)) > s->width) {
  697 + console_put_lf(s);
  698 + } else {
  699 + s->x = s->x + (8 - (s->x % 8));
  700 + }
  701 + break;
  702 + case '\a': /* alert aka. bell */
  703 + /* TODO: has to be implemented */
  704 + break;
  705 + case 27: /* esc (introducing an escape sequence) */
497 s->state = TTY_STATE_ESC; 706 s->state = TTY_STATE_ESC;
498 break; 707 break;
499 default: 708 default:
500 y1 = (s->y_base + s->y) % s->total_height; 709 y1 = (s->y_base + s->y) % s->total_height;
501 c = &s->cells[y1 * s->width + s->x]; 710 c = &s->cells[y1 * s->width + s->x];
502 c->ch = ch; 711 c->ch = ch;
503 - c->fgcol = s->fgcol;  
504 - c->bgcol = s->bgcol; 712 + c->t_attrib = s->t_attrib;
505 update_xy(s, s->x, s->y); 713 update_xy(s, s->x, s->y);
506 s->x++; 714 s->x++;
507 if (s->x >= s->width) 715 if (s->x >= s->width)
@@ -509,7 +717,7 @@ static void console_putchar(TextConsole *s, int ch) @@ -509,7 +717,7 @@ static void console_putchar(TextConsole *s, int ch)
509 break; 717 break;
510 } 718 }
511 break; 719 break;
512 - case TTY_STATE_ESC: 720 + case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
513 if (ch == '[') { 721 if (ch == '[') {
514 for(i=0;i<MAX_ESC_PARAMS;i++) 722 for(i=0;i<MAX_ESC_PARAMS;i++)
515 s->esc_params[i] = 0; 723 s->esc_params[i] = 0;
@@ -519,7 +727,7 @@ static void console_putchar(TextConsole *s, int ch) @@ -519,7 +727,7 @@ static void console_putchar(TextConsole *s, int ch)
519 s->state = TTY_STATE_NORM; 727 s->state = TTY_STATE_NORM;
520 } 728 }
521 break; 729 break;
522 - case TTY_STATE_CSI: 730 + case TTY_STATE_CSI: /* handle escape sequence parameters */
523 if (ch >= '0' && ch <= '9') { 731 if (ch >= '0' && ch <= '9') {
524 if (s->nb_esc_params < MAX_ESC_PARAMS) { 732 if (s->nb_esc_params < MAX_ESC_PARAMS) {
525 s->esc_params[s->nb_esc_params] = 733 s->esc_params[s->nb_esc_params] =
@@ -545,8 +753,7 @@ static void console_putchar(TextConsole *s, int ch) @@ -545,8 +753,7 @@ static void console_putchar(TextConsole *s, int ch)
545 for(x = s->x; x < s->width; x++) { 753 for(x = s->x; x < s->width; x++) {
546 c = &s->cells[y1 * s->width + x]; 754 c = &s->cells[y1 * s->width + x];
547 c->ch = ' '; 755 c->ch = ' ';
548 - c->fgcol = s->fgcol;  
549 - c->bgcol = s->bgcol; 756 + c->t_attrib = s->t_attrib_default;
550 c++; 757 c++;
551 update_xy(s, x, s->y); 758 update_xy(s, x, s->y);
552 } 759 }
@@ -554,6 +761,7 @@ static void console_putchar(TextConsole *s, int ch) @@ -554,6 +761,7 @@ static void console_putchar(TextConsole *s, int ch)
554 default: 761 default:
555 break; 762 break;
556 } 763 }
  764 + console_handle_escape(s);
557 break; 765 break;
558 } 766 }
559 } 767 }
@@ -562,7 +770,7 @@ static void console_putchar(TextConsole *s, int ch) @@ -562,7 +770,7 @@ static void console_putchar(TextConsole *s, int ch)
562 void console_select(unsigned int index) 770 void console_select(unsigned int index)
563 { 771 {
564 TextConsole *s; 772 TextConsole *s;
565 - 773 +
566 if (index >= MAX_CONSOLES) 774 if (index >= MAX_CONSOLES)
567 return; 775 return;
568 s = consoles[index]; 776 s = consoles[index];
@@ -571,10 +779,10 @@ void console_select(unsigned int index) @@ -571,10 +779,10 @@ void console_select(unsigned int index)
571 if (s->text_console) { 779 if (s->text_console) {
572 if (s->g_width != s->ds->width || 780 if (s->g_width != s->ds->width ||
573 s->g_height != s->ds->height) { 781 s->g_height != s->ds->height) {
574 - s->g_width = s->ds->width;  
575 - s->g_height = s->ds->height; 782 + s->g_width = s->ds->width;
  783 + s->g_height = s->ds->height;
576 text_console_resize(s); 784 text_console_resize(s);
577 - } 785 + }
578 console_refresh(s); 786 console_refresh(s);
579 } 787 }
580 } 788 }
@@ -692,9 +900,9 @@ CharDriverState *text_console_init(DisplayState *ds) @@ -692,9 +900,9 @@ CharDriverState *text_console_init(DisplayState *ds)
692 { 900 {
693 CharDriverState *chr; 901 CharDriverState *chr;
694 TextConsole *s; 902 TextConsole *s;
695 - int i; 903 + int i,j;
696 static int color_inited; 904 static int color_inited;
697 - 905 +
698 chr = qemu_mallocz(sizeof(CharDriverState)); 906 chr = qemu_mallocz(sizeof(CharDriverState));
699 if (!chr) 907 if (!chr)
700 return NULL; 908 return NULL;
@@ -711,9 +919,11 @@ CharDriverState *text_console_init(DisplayState *ds) @@ -711,9 +919,11 @@ CharDriverState *text_console_init(DisplayState *ds)
711 919
712 if (!color_inited) { 920 if (!color_inited) {
713 color_inited = 1; 921 color_inited = 1;
714 - for(i = 0; i < 8; i++) {  
715 - color_table[i] = col_expand(s->ds,  
716 - vga_get_color(s->ds, color_table_rgb[i])); 922 + for(j = 0; j < 2; j++) {
  923 + for(i = 0; i < 8; i++) {
  924 + color_table[j][i] = col_expand(s->ds,
  925 + vga_get_color(s->ds, color_table_rgb[j][i]));
  926 + }
717 } 927 }
718 } 928 }
719 s->y_displayed = 0; 929 s->y_displayed = 0;
@@ -721,10 +931,20 @@ CharDriverState *text_console_init(DisplayState *ds) @@ -721,10 +931,20 @@ CharDriverState *text_console_init(DisplayState *ds)
721 s->total_height = DEFAULT_BACKSCROLL; 931 s->total_height = DEFAULT_BACKSCROLL;
722 s->x = 0; 932 s->x = 0;
723 s->y = 0; 933 s->y = 0;
724 - s->fgcol = 7;  
725 - s->bgcol = 0;  
726 s->g_width = s->ds->width; 934 s->g_width = s->ds->width;
727 s->g_height = s->ds->height; 935 s->g_height = s->ds->height;
  936 +
  937 + /* Set text attribute defaults */
  938 + s->t_attrib_default.bold = 0;
  939 + s->t_attrib_default.uline = 0;
  940 + s->t_attrib_default.blink = 0;
  941 + s->t_attrib_default.invers = 0;
  942 + s->t_attrib_default.unvisible = 0;
  943 + s->t_attrib_default.fgcol = COLOR_WHITE;
  944 + s->t_attrib_default.bgcol = COLOR_BLACK;
  945 +
  946 + /* set current text attributes to default */
  947 + s->t_attrib = s->t_attrib_default;
728 text_console_resize(s); 948 text_console_resize(s);
729 949
730 return chr; 950 return chr;