diff options
Diffstat (limited to 'ui/console.c')
| -rw-r--r-- | ui/console.c | 111 |
1 files changed, 66 insertions, 45 deletions
diff --git a/ui/console.c b/ui/console.c index b9575f2ee5..fe03a666f7 100644 --- a/ui/console.c +++ b/ui/console.c @@ -158,7 +158,7 @@ struct QemuConsole { int esc_params[MAX_ESC_PARAMS]; int nb_esc_params; - CharDriverState *chr; + Chardev *chr; /* fifo for key pressed */ QEMUFIFO out_fifo; uint8_t out_fifo_buf[16]; @@ -183,7 +183,7 @@ static int nb_consoles = 0; static bool cursor_visible_phase; static QEMUTimer *cursor_timer; -static void text_console_do_init(CharDriverState *chr, DisplayState *ds); +static void text_console_do_init(Chardev *chr, DisplayState *ds); static void dpy_refresh(DisplayState *s); static DisplayState *get_alloc_displaystate(void); static void text_console_update_cursor_timer(void); @@ -1046,11 +1046,24 @@ void console_select(unsigned int index) } } -static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) +typedef struct VCChardev { + Chardev parent; + QemuConsole *console; +} VCChardev; + +#define TYPE_CHARDEV_VC "chardev-vc" +#define VC_CHARDEV(obj) OBJECT_CHECK(VCChardev, (obj), TYPE_CHARDEV_VC) + +static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len) { - QemuConsole *s = chr->opaque; + VCChardev *drv = VC_CHARDEV(chr); + QemuConsole *s = drv->console; int i; + if (!s->ds) { + return 0; + } + s->update_x0 = s->width * FONT_WIDTH; s->update_y0 = s->height * FONT_HEIGHT; s->update_x1 = 0; @@ -1129,13 +1142,13 @@ void kbd_put_keysym_console(QemuConsole *s, int keysym) *q++ = '['; *q++ = keysym & 0xff; } else if (s->echo && (keysym == '\r' || keysym == '\n')) { - console_puts(s->chr, (const uint8_t *) "\r", 1); + vc_chr_write(s->chr, (const uint8_t *) "\r", 1); *q++ = '\n'; } else { *q++ = keysym; } if (s->echo) { - console_puts(s->chr, buf, q - buf); + vc_chr_write(s->chr, buf, q - buf); } be = s->chr->be; if (be && be->chr_read) { @@ -1952,9 +1965,10 @@ int qemu_console_get_height(QemuConsole *con, int fallback) return con ? surface_height(con->surface) : fallback; } -static void text_console_set_echo(CharDriverState *chr, bool echo) +static void vc_chr_set_echo(Chardev *chr, bool echo) { - QemuConsole *s = chr->opaque; + VCChardev *drv = VC_CHARDEV(chr); + QemuConsole *s = drv->console; s->echo = echo; } @@ -1992,16 +2006,13 @@ static const GraphicHwOps text_console_ops = { .text_update = text_console_update, }; -static void text_console_do_init(CharDriverState *chr, DisplayState *ds) +static void text_console_do_init(Chardev *chr, DisplayState *ds) { - QemuConsole *s; + VCChardev *drv = VC_CHARDEV(chr); + QemuConsole *s = drv->console; int g_width = 80 * FONT_WIDTH; int g_height = 24 * FONT_HEIGHT; - s = chr->opaque; - - chr->chr_write = console_puts; - s->out_fifo.buf = s->out_fifo_buf; s->out_fifo.buf_size = sizeof(s->out_fifo_buf); s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s); @@ -2041,26 +2052,26 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds) s->t_attrib.bgcol = QEMU_COLOR_BLUE; len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); - console_puts(chr, (uint8_t*)msg, len); + vc_chr_write(chr, (uint8_t *)msg, len); s->t_attrib = s->t_attrib_default; } qemu_chr_be_generic_open(chr); } -static CharDriverState *text_console_init(ChardevVC *vc, Error **errp) +static const CharDriver vc_driver; + +static void vc_chr_open(Chardev *chr, + ChardevBackend *backend, + bool *be_opened, + Error **errp) { - ChardevCommon *common = qapi_ChardevVC_base(vc); - CharDriverState *chr; + ChardevVC *vc = backend->u.vc.data; + VCChardev *drv = VC_CHARDEV(chr); QemuConsole *s; unsigned width = 0; unsigned height = 0; - chr = qemu_chr_alloc(common, errp); - if (!chr) { - return NULL; - } - if (vc->has_width) { width = vc->width; } else if (vc->has_cols) { @@ -2082,37 +2093,21 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp) } if (!s) { - g_free(chr); error_setg(errp, "cannot create text console"); - return NULL; + return; } s->chr = chr; - chr->opaque = s; - chr->chr_set_echo = text_console_set_echo; + drv->console = s; if (display_state) { text_console_do_init(chr, display_state); } - return chr; -} - -static VcHandler *vc_handler = text_console_init; -static CharDriverState *vc_init(const char *id, ChardevBackend *backend, - ChardevReturn *ret, bool *be_opened, - Error **errp) -{ /* console/chardev init sometimes completes elsewhere in a 2nd * stage, so defer OPENED events until they are fully initialized */ *be_opened = false; - return vc_handler(backend->u.vc.data, errp); -} - -void register_vc_handler(VcHandler *handler) -{ - vc_handler = handler; } void qemu_console_resize(QemuConsole *s, int width, int height) @@ -2150,8 +2145,7 @@ PixelFormat qemu_default_pixelformat(int bpp) return pf; } -static void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, - Error **errp) +void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp) { int val; ChardevVC *vc; @@ -2191,12 +2185,39 @@ static const TypeInfo qemu_console_info = { .class_size = sizeof(QemuConsoleClass), }; +static void char_vc_class_init(ObjectClass *oc, void *data) +{ + ChardevClass *cc = CHARDEV_CLASS(oc); + + cc->open = vc_chr_open; + cc->chr_write = vc_chr_write; + cc->chr_set_echo = vc_chr_set_echo; +} + +static const TypeInfo char_vc_type_info = { + .name = TYPE_CHARDEV_VC, + .parent = TYPE_CHARDEV, + .instance_size = sizeof(VCChardev), + .class_init = char_vc_class_init, +}; + +void qemu_console_early_init(void) +{ + /* set the default vc driver */ + if (!object_class_by_name(TYPE_CHARDEV_VC)) { + type_register(&char_vc_type_info); + register_char_driver(&vc_driver); + } +} + +static const CharDriver vc_driver = { + .kind = CHARDEV_BACKEND_KIND_VC, + .parse = qemu_chr_parse_vc, +}; static void register_types(void) { type_register_static(&qemu_console_info); - register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc, - vc_init); } type_init(register_types); |