📄 console.c.svn-base
字号:
s->esc_params[s->nb_esc_params] = s->esc_params[s->nb_esc_params] * 10 + ch - '0'; } } else { 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 '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': /* 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; } break; } }}void console_select(unsigned int index){ TextConsole *s; if (index >= MAX_CONSOLES) return; s = consoles[index]; if (s) { active_console = s; if (s->console_type != GRAPHIC_CONSOLE) { if (s->g_width != s->ds->width || s->g_height != s->ds->height) { if (s->console_type == TEXT_CONSOLE_FIXED_SIZE) { dpy_resize(s->ds, s->g_width, s->g_height); } else { s->g_width = s->ds->width; s->g_height = s->ds->height; text_console_resize(s); } } console_refresh(s); } else { vga_hw_invalidate(); } }}static int console_puts(CharDriverState *chr, const uint8_t *buf, int len){ TextConsole *s = chr->opaque; int i; console_show_cursor(s, 0); for(i = 0; i < len; i++) { console_putchar(s, buf[i]); } console_show_cursor(s, 1); return len;}static void console_send_event(CharDriverState *chr, int event){ TextConsole *s = chr->opaque; int i; if (event == CHR_EVENT_FOCUS) { for(i = 0; i < nb_consoles; i++) { if (consoles[i] == s) { console_select(i); break; } } }}static void kbd_send_chars(void *opaque){ TextConsole *s = opaque; int len; uint8_t buf[16]; len = qemu_chr_can_read(s->chr); if (len > s->out_fifo.count) len = s->out_fifo.count; if (len > 0) { if (len > sizeof(buf)) len = sizeof(buf); qemu_fifo_read(&s->out_fifo, buf, len); qemu_chr_read(s->chr, buf, len); } /* characters are pending: we send them a bit later (XXX: horrible, should change char device API) */ if (s->out_fifo.count > 0) { qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1); }}/* called when an ascii key is pressed */void kbd_put_keysym(int keysym){ TextConsole *s; uint8_t buf[16], *q; int c; s = active_console; if (!s || (s->console_type == GRAPHIC_CONSOLE)) return; switch(keysym) { case QEMU_KEY_CTRL_UP: console_scroll(-1); break; case QEMU_KEY_CTRL_DOWN: console_scroll(1); break; case QEMU_KEY_CTRL_PAGEUP: console_scroll(-10); break; case QEMU_KEY_CTRL_PAGEDOWN: console_scroll(10); break; default: /* convert the QEMU keysym to VT100 key string */ q = buf; if (keysym >= 0xe100 && keysym <= 0xe11f) { *q++ = '\033'; *q++ = '['; c = keysym - 0xe100; if (c >= 10) *q++ = '0' + (c / 10); *q++ = '0' + (c % 10); *q++ = '~'; } else if (keysym >= 0xe120 && keysym <= 0xe17f) { *q++ = '\033'; *q++ = '['; *q++ = keysym & 0xff; } else { *q++ = keysym; } if (s->chr->chr_read) { qemu_fifo_write(&s->out_fifo, buf, q - buf); kbd_send_chars(s); } break; }}static TextConsole *new_console(DisplayState *ds, console_type_t console_type){ TextConsole *s; int i; if (nb_consoles >= MAX_CONSOLES) return NULL; s = qemu_mallocz(sizeof(TextConsole)); if (!s) { return NULL; } if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) && (console_type == GRAPHIC_CONSOLE))) { active_console = s; } s->ds = ds; s->console_type = console_type; if (console_type != GRAPHIC_CONSOLE) { consoles[nb_consoles++] = s; } else { /* HACK: Put graphical consoles before text consoles. */ for (i = nb_consoles; i > 0; i--) { if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE) break; consoles[i] = consoles[i - 1]; } consoles[i] = s; } return s;}TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update, vga_hw_invalidate_ptr invalidate, vga_hw_screen_dump_ptr screen_dump, void *opaque){ TextConsole *s; s = new_console(ds, GRAPHIC_CONSOLE); if (!s) return NULL; s->hw_update = update; s->hw_invalidate = invalidate; s->hw_screen_dump = screen_dump; s->hw = opaque; return s;}int is_graphic_console(void){ return active_console->console_type == GRAPHIC_CONSOLE;}void console_color_init(DisplayState *ds){ int i, j; for (j = 0; j < 2; j++) { for (i = 0; i < 8; i++) { color_table[j][i] = col_expand(ds, vga_get_color(ds, color_table_rgb[j][i])); } }}CharDriverState *text_console_init(DisplayState *ds, const char *p){ CharDriverState *chr; TextConsole *s; unsigned width; unsigned height; static int color_inited; chr = qemu_mallocz(sizeof(CharDriverState)); if (!chr) return NULL; s = new_console(ds, (p == 0) ? TEXT_CONSOLE : TEXT_CONSOLE_FIXED_SIZE); if (!s) { free(chr); return NULL; } chr->opaque = s; chr->chr_write = console_puts; chr->chr_send_event = console_send_event; s->chr = chr; s->out_fifo.buf = s->out_fifo_buf; s->out_fifo.buf_size = sizeof(s->out_fifo_buf); s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s); if (!color_inited) { color_inited = 1; console_color_init(s->ds); } s->y_displayed = 0; s->y_base = 0; s->total_height = DEFAULT_BACKSCROLL; s->x = 0; s->y = 0; width = s->ds->width; height = s->ds->height; if (p != 0) { width = strtoul(p, (char **)&p, 10); if (*p == 'C') { p++; width *= FONT_WIDTH; } if (*p == 'x') { p++; height = strtoul(p, (char **)&p, 10); if (*p == 'C') { p++; height *= FONT_HEIGHT; } } } s->g_width = width; s->g_height = height; /* Set text attribute defaults */ s->t_attrib_default.bold = 0; s->t_attrib_default.uline = 0; s->t_attrib_default.blink = 0; s->t_attrib_default.invers = 0; s->t_attrib_default.unvisible = 0; s->t_attrib_default.fgcol = COLOR_WHITE; s->t_attrib_default.bgcol = COLOR_BLACK; /* set current text attributes to default */ s->t_attrib = s->t_attrib_default; text_console_resize(s); qemu_chr_reset(chr); return chr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -