summary refs log tree commit diff stats
path: root/ui/console.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-01-30 10:23:20 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-01-30 10:23:20 +0000
commita0def594286d9110a6035e02eef558cf3cf5d847 (patch)
tree32275a1bfdd6c17682788f2b2e018a15c3b30214 /ui/console.c
parent3aca12f841fcd6f3a7477076dad0d564360500de (diff)
parent6da67de6803e93cbb7e93ac3497865832f8c00ea (diff)
downloadfocaccia-qemu-a0def594286d9110a6035e02eef558cf3cf5d847.tar.gz
focaccia-qemu-a0def594286d9110a6035e02eef558cf3cf5d847.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* SCSI max_transfer support for scsi-generic (Eric)
* x86 SMI broadcast (Laszlo)
* Character device QOMification (Marc-André)
* Record/replay improvements (Pavel)
* iscsi fixes (Peter L.)
* "info mtree -f" command (Peter Xu)
* TSC clock rate reporting (Phil)
* DEVICE_CATEGORY_CPU (Thomas)
* Memory sign-extension fix (Ladi)

# gpg: Signature made Fri 27 Jan 2017 17:08:51 GMT
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (41 commits)
  memory: don't sign-extend 32-bit writes
  chardev: qom-ify
  vc: use a common prefix for chr callbacks
  baum: use a common prefix for chr callbacks
  gtk: overwrite the console.c char driver
  char: use error_report()
  spice-char: improve error reporting
  char: rename TCPChardev and NetChardev
  char: rename CharDriverState Chardev
  bt: use qemu_chr_alloc()
  char: allocate CharDriverState as a single object
  char: use a feature bit for replay
  char: introduce generic qemu_chr_get_kind()
  char: fold single-user functions in caller
  char: move callbacks in CharDriver
  char: use a static array for backends
  char: use a const CharDriver
  doc: fix spelling
  char: add qemu_chr_fe_add_watch() Returns description
  qemu-options: stdio is available on win32
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'ui/console.c')
-rw-r--r--ui/console.c111
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);