Improved console handling, thanks Stefan Weil.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2322 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
dabd98ddf5
commit
adb4796796
181
console.c
181
console.c
@ -121,6 +121,7 @@ struct TextConsole {
|
||||
int total_height;
|
||||
int backscroll_height;
|
||||
int x, y;
|
||||
int x_saved, y_saved;
|
||||
int y_displayed;
|
||||
int y_base;
|
||||
TextAttributes t_attrib_default; /* default text attributes */
|
||||
@ -147,7 +148,7 @@ static int nb_consoles = 0;
|
||||
|
||||
void vga_hw_update(void)
|
||||
{
|
||||
if (active_console->hw_update)
|
||||
if (active_console && active_console->hw_update)
|
||||
active_console->hw_update(active_console->hw);
|
||||
}
|
||||
|
||||
@ -659,10 +660,6 @@ static void console_handle_escape(TextConsole *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s->nb_esc_params == 0) { /* ESC[m sets all attributes to default */
|
||||
s->t_attrib = s->t_attrib_default;
|
||||
return;
|
||||
}
|
||||
for (i=0; i<s->nb_esc_params; i++) {
|
||||
switch (s->esc_params[i]) {
|
||||
case 0: /* reset all console attributes to default */
|
||||
@ -752,10 +749,21 @@ static void console_handle_escape(TextConsole *s)
|
||||
}
|
||||
}
|
||||
|
||||
static void console_clear_xy(TextConsole *s, int x, int y)
|
||||
{
|
||||
int y1 = (s->y_base + y) % s->total_height;
|
||||
TextCell *c = &s->cells[y1 * s->width + x];
|
||||
c->ch = ' ';
|
||||
c->t_attrib = s->t_attrib_default;
|
||||
c++;
|
||||
update_xy(s, x, y);
|
||||
}
|
||||
|
||||
static void console_putchar(TextConsole *s, int ch)
|
||||
{
|
||||
TextCell *c;
|
||||
int y1, i, x;
|
||||
int y1, i;
|
||||
int x, y;
|
||||
|
||||
switch(s->state) {
|
||||
case TTY_STATE_NORM:
|
||||
@ -781,20 +789,31 @@ static void console_putchar(TextConsole *s, int ch)
|
||||
case '\a': /* alert aka. bell */
|
||||
/* TODO: has to be implemented */
|
||||
break;
|
||||
case 14:
|
||||
/* SI (shift in), character set 0 (ignored) */
|
||||
break;
|
||||
case 15:
|
||||
/* SO (shift out), character set 1 (ignored) */
|
||||
break;
|
||||
case 27: /* esc (introducing an escape sequence) */
|
||||
s->state = TTY_STATE_ESC;
|
||||
break;
|
||||
default:
|
||||
if (s->x >= s->width - 1) {
|
||||
break;
|
||||
}
|
||||
y1 = (s->y_base + s->y) % s->total_height;
|
||||
c = &s->cells[y1 * s->width + s->x];
|
||||
c->ch = ch;
|
||||
c->t_attrib = s->t_attrib;
|
||||
update_xy(s, s->x, s->y);
|
||||
s->x++;
|
||||
#if 0 /* line wrap disabled */
|
||||
if (s->x >= s->width) {
|
||||
s->x = 0;
|
||||
console_put_lf(s);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -818,31 +837,149 @@ static void console_putchar(TextConsole *s, int ch)
|
||||
s->nb_esc_params++;
|
||||
if (ch == ';')
|
||||
break;
|
||||
#ifdef DEBUG_CONSOLE
|
||||
fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
|
||||
s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
|
||||
#endif
|
||||
s->state = TTY_STATE_NORM;
|
||||
switch(ch) {
|
||||
case 'D':
|
||||
if (s->x > 0)
|
||||
s->x--;
|
||||
case 'A':
|
||||
/* move cursor up */
|
||||
if (s->esc_params[0] == 0) {
|
||||
s->esc_params[0] = 1;
|
||||
}
|
||||
s->y -= s->esc_params[0];
|
||||
if (s->y < 0) {
|
||||
s->y = 0;
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
/* move cursor down */
|
||||
if (s->esc_params[0] == 0) {
|
||||
s->esc_params[0] = 1;
|
||||
}
|
||||
s->y += s->esc_params[0];
|
||||
if (s->y >= s->height) {
|
||||
s->y = s->height - 1;
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
if (s->x < (s->width - 1))
|
||||
s->x++;
|
||||
break;
|
||||
case 'K':
|
||||
/* clear to eol */
|
||||
y1 = (s->y_base + s->y) % s->total_height;
|
||||
for(x = s->x; x < s->width; x++) {
|
||||
c = &s->cells[y1 * s->width + x];
|
||||
c->ch = ' ';
|
||||
c->t_attrib = s->t_attrib_default;
|
||||
c++;
|
||||
update_xy(s, x, s->y);
|
||||
/* move cursor right */
|
||||
if (s->esc_params[0] == 0) {
|
||||
s->esc_params[0] = 1;
|
||||
}
|
||||
s->x += s->esc_params[0];
|
||||
if (s->x >= s->width) {
|
||||
s->x = s->width - 1;
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
/* move cursor left */
|
||||
if (s->esc_params[0] == 0) {
|
||||
s->esc_params[0] = 1;
|
||||
}
|
||||
s->x -= s->esc_params[0];
|
||||
if (s->x < 0) {
|
||||
s->x = 0;
|
||||
}
|
||||
break;
|
||||
case 'G':
|
||||
/* move cursor to column */
|
||||
s->x = s->esc_params[0] - 1;
|
||||
if (s->x < 0) {
|
||||
s->x = 0;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
case 'H':
|
||||
/* move cursor to row, column */
|
||||
s->x = s->esc_params[1] - 1;
|
||||
if (s->x < 0) {
|
||||
s->x = 0;
|
||||
}
|
||||
s->y = s->esc_params[0] - 1;
|
||||
if (s->y < 0) {
|
||||
s->y = 0;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
switch (s->esc_params[0]) {
|
||||
case 0:
|
||||
/* clear to end of screen */
|
||||
for (y = s->y; y < s->height; y++) {
|
||||
for (x = 0; x < s->width; x++) {
|
||||
if (y == s->y && x < s->x) {
|
||||
continue;
|
||||
}
|
||||
console_clear_xy(s, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* clear from beginning of screen */
|
||||
for (y = 0; y <= s->y; y++) {
|
||||
for (x = 0; x < s->width; x++) {
|
||||
if (y == s->y && x > s->x) {
|
||||
break;
|
||||
}
|
||||
console_clear_xy(s, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* clear entire screen */
|
||||
for (y = 0; y <= s->height; y++) {
|
||||
for (x = 0; x < s->width; x++) {
|
||||
console_clear_xy(s, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'K':
|
||||
switch (s->esc_params[0]) {
|
||||
case 0:
|
||||
/* clear to eol */
|
||||
for(x = s->x; x < s->width; x++) {
|
||||
console_clear_xy(s, x, s->y);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* clear from beginning of line */
|
||||
for (x = 0; x <= s->x; x++) {
|
||||
console_clear_xy(s, x, s->y);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* clear entire line */
|
||||
for(x = 0; x < s->width; x++) {
|
||||
console_clear_xy(s, x, s->y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
console_handle_escape(s);
|
||||
break;
|
||||
case 'n':
|
||||
/* report cursor position */
|
||||
/* TODO: send ESC[row;colR */
|
||||
break;
|
||||
case 's':
|
||||
/* save cursor position */
|
||||
s->x_saved = s->x;
|
||||
s->y_saved = s->y;
|
||||
break;
|
||||
case 'u':
|
||||
/* restore cursor position */
|
||||
s->x = s->x_saved;
|
||||
s->y = s->y_saved;
|
||||
break;
|
||||
default:
|
||||
#ifdef DEBUG_CONSOLE
|
||||
fprintf(stderr, "unhandled escape character '%c'\n", ch);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
console_handle_escape(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user