From: Marc-André Lureau <[email protected]> Add a QOM "encoding" enum property to some chardev-vc backends (console-vc & dbus - gtk and spice don't make use of it) so that the machine compat mechanism can override the default. For machine versions prior to 11.1, the charset defaults to cp437 (raw 8-bit VGA) instead of utf8, preserving the historical behaviour.
The following commits are going to wire this to VT100 emulation code and an extra exported D-Bus property. Note that GTK libvte uses utf8 unconditionally, and Spice doesn't have a way to set the encoding, and typically just use libvte in client too. Reviewed-by: Daniel P. Berrangé <[email protected]> Signed-off-by: Marc-André Lureau <[email protected]> --- include/chardev/char.h | 19 +++++++++++++++++++ hw/core/machine.c | 4 +++- ui/console-vc.c | 18 ++++++++++++++++++ ui/dbus.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/include/chardev/char.h b/include/chardev/char.h index f05e8dba0a9..7377d8e60a0 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -332,4 +332,23 @@ void resume_mux_open(void); char *qemu_chr_get_pty_name(Chardev *chr); char *qemu_chr_get_filename(Chardev *chr); +#define CHARDEV_VC_ENCODING_PROPERTY_DEFINE(cast_func) \ +static int get_encoding(Object *obj, Error **errp) \ +{ \ + return cast_func(obj)->encoding; \ +} \ + \ +static void set_encoding(Object *obj, int value, Error **errp) \ +{ \ + cast_func(obj)->encoding = value; \ +} + +static inline void chardev_vc_add_encoding_prop(ObjectClass *oc, + int (*get)(Object *, Error **), + void (*set)(Object *, int, Error **)) +{ + object_class_property_add_enum(oc, "encoding", "ChardevVCEncoding", + &ChardevVCEncoding_lookup, get, set); +} + #endif diff --git a/hw/core/machine.c b/hw/core/machine.c index 1b661fd36ae..63baff859f3 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -39,7 +39,9 @@ #include "hw/acpi/generic_event_device.h" #include "qemu/audio.h" -GlobalProperty hw_compat_11_0[] = {}; +GlobalProperty hw_compat_11_0[] = { + { "chardev-vc", "encoding", "cp437" }, +}; const size_t hw_compat_11_0_len = G_N_ELEMENTS(hw_compat_11_0); GlobalProperty hw_compat_10_2[] = { diff --git a/ui/console-vc.c b/ui/console-vc.c index 7bb6a483753..fd7e6fb7b06 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -9,6 +9,7 @@ #include "qemu/fifo8.h" #include "qemu/option.h" #include "qemu/queue.h" +#include "qom/compat-properties.h" #include "ui/console.h" #include "ui/vgafont.h" @@ -109,6 +110,7 @@ struct VCChardev { TextAttributes t_attrib; /* currently active text attributes */ TextAttributes t_attrib_saved; int x_saved, y_saved; + ChardevVCEncoding encoding; }; typedef struct VCChardev VCChardev; @@ -1189,6 +1191,9 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp) s->chr = chr; drv->console = s; + if (vc->has_encoding) { + drv->encoding = vc->encoding; + } /* set current text attributes to default */ drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT; @@ -1253,6 +1258,8 @@ static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp) } } +CHARDEV_VC_ENCODING_PROPERTY_DEFINE(VC_CHARDEV) + static void char_vc_class_init(ObjectClass *oc, const void *data) { ChardevClass *cc = CHARDEV_CLASS(oc); @@ -1264,12 +1271,23 @@ static void char_vc_class_init(ObjectClass *oc, const void *data) cc->chr_set_echo = vc_chr_set_echo; cc->supports_size_opts = true; cc->supports_encoding_opts = true; + + chardev_vc_add_encoding_prop(oc, get_encoding, set_encoding); +} + +static void char_vc_init(Object *obj) +{ + VCChardev *vc = VC_CHARDEV(obj); + + vc->encoding = CHARDEV_VC_ENCODING_UTF8; } static const TypeInfo char_vc_type_info = { .name = TYPE_CHARDEV_VC, .parent = TYPE_CHARDEV, .instance_size = sizeof(VCChardev), + .instance_init = char_vc_init, + .instance_post_init = object_apply_compat_props, .class_init = char_vc_class_init, }; diff --git a/ui/dbus.c b/ui/dbus.c index 721cc71d39b..59b73e0aa94 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -28,6 +28,7 @@ #include "qemu/main-loop.h" #include "qemu/option.h" #include "qom/object_interfaces.h" +#include "qapi-types-char.h" #include "system/system.h" #include "ui/dbus-module.h" #ifdef CONFIG_OPENGL @@ -455,12 +456,20 @@ dbus_display_class_init(ObjectClass *oc, const void *data) #define TYPE_CHARDEV_VC "chardev-vc" +typedef struct DBusVCChardev { + DBusChardev parent; + + ChardevVCEncoding encoding; +} DBusVCChardev; + typedef struct DBusVCClass { DBusChardevClass parent_class; void (*parent_parse)(QemuOpts *opts, ChardevBackend *b, Error **errp); } DBusVCClass; +DECLARE_INSTANCE_CHECKER(DBusVCChardev, DBUS_VC_CHARDEV, + TYPE_CHARDEV_VC) DECLARE_CLASS_CHECKERS(DBusVCClass, DBUS_VC, TYPE_CHARDEV_VC) @@ -500,6 +509,23 @@ dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend, } } +CHARDEV_VC_ENCODING_PROPERTY_DEFINE(DBUS_VC_CHARDEV) + +static bool +dbus_vc_open(Chardev *chr, ChardevBackend *backend, Error **errp) +{ + DBusVCChardev *vc = DBUS_VC_CHARDEV(chr); + ChardevClass *parent = + CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_DBUS)); + ChardevDBus *be = backend->u.dbus.data; + + if (be->has_encoding) { + vc->encoding = be->encoding; + } + + return parent->chr_open(chr, backend, errp); +} + static void dbus_vc_class_init(ObjectClass *oc, const void *data) { @@ -508,12 +534,26 @@ dbus_vc_class_init(ObjectClass *oc, const void *data) klass->parent_parse = cc->chr_parse; cc->chr_parse = dbus_vc_parse; + cc->chr_open = dbus_vc_open; cc->supports_encoding_opts = true; + + chardev_vc_add_encoding_prop(oc, get_encoding, set_encoding); +} + +static void +dbus_vc_init(Object *obj) +{ + DBusVCChardev *vc = DBUS_VC_CHARDEV(obj); + + vc->encoding = CHARDEV_VC_ENCODING_UTF8; } static const TypeInfo dbus_vc_type_info = { .name = TYPE_CHARDEV_VC, .parent = TYPE_CHARDEV_DBUS, + .instance_size = sizeof(DBusVCChardev), + .instance_init = dbus_vc_init, + .instance_post_init = object_apply_compat_props, .class_size = sizeof(DBusVCClass), .class_init = dbus_vc_class_init, }; -- 2.54.0
