From: Marc-André Lureau <[email protected]>

Expose a new "encoding" QemuOpt option.

Add the corresponding QAPI type and properties.

This is going to be wired in the following commits.

Reviewed-by: Daniel P. Berrangé <[email protected]>
Signed-off-by: Marc-André Lureau <[email protected]>
---
 qapi/char.json         | 30 ++++++++++++++++++++++++++++--
 include/chardev/char.h |  1 +
 chardev/char.c         | 10 ++++++++++
 ui/console-vc.c        | 12 ++++++++++++
 ui/dbus.c              | 13 +++++++++++++
 qemu-options.hx        |  7 +++++--
 6 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/qapi/char.json b/qapi/char.json
index a4abafa6803..aa5ee9ffcd0 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -377,6 +377,24 @@
   'base': 'ChardevCommon',
   'if': 'CONFIG_SPICE' }
 
+##
+# @ChardevVCEncoding:
+#
+# Character encoding expected from the guest on a virtual console.
+#
+# @cp437: CP437 (8-bit Extended ASCII / VGA).  Every byte maps
+#     directly to a glyph; suitable for DOS or other guests that
+#     output raw CP437.
+#
+# @utf8: UTF-8.  Multi-byte sequences are decoded and then mapped
+#     back to CP437 glyphs for display; unmappable codepoints are
+#     shown as '?'.  Suitable for modern Linux guests.
+#
+# Since: 11.1
+##
+{ 'enum': 'ChardevVCEncoding',
+  'data': [ 'cp437', 'utf8' ] }
+
 ##
 # @ChardevDBus:
 #
@@ -384,10 +402,14 @@
 #
 # @name: name of the channel (following docs/spice-port-fqdn.txt)
 #
+# @encoding: character encoding the guest is expected to use
+#     (since 11.1)
+#
 # Since: 7.0
 ##
 { 'struct': 'ChardevDBus',
-  'data': { 'name': 'str' },
+  'data': { 'name': 'str',
+            '*encoding': 'ChardevVCEncoding' },
   'base': 'ChardevCommon',
   'if': 'CONFIG_DBUS_DISPLAY' }
 
@@ -404,6 +426,9 @@
 #
 # @rows: console height, in chars
 #
+# @encoding: character encoding the guest is expected to use
+#     (since 11.1)
+#
 # .. note:: The options are only effective when the VNC or SDL
 #    graphical display backend is active.  They are ignored with the
 #    GTK, Spice, VNC and D-Bus display backends.
@@ -414,7 +439,8 @@
   'data': { '*width': 'int',
             '*height': 'int',
             '*cols': 'int',
-            '*rows': 'int' },
+            '*rows': 'int',
+            '*encoding': 'ChardevVCEncoding' },
   'base': 'ChardevCommon' }
 
 ##
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 51995f06a82..f05e8dba0a9 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -255,6 +255,7 @@ struct ChardevClass {
     bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */
     bool supports_yank;
     bool supports_size_opts;
+    bool supports_encoding_opts;
 
     /* parse command line options and populate QAPI @backend */
     void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp);
diff --git a/chardev/char.c b/chardev/char.c
index 55dce9725e8..ca8b37ed8d7 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -650,6 +650,13 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error 
**errp)
             return NULL;
         }
     }
+    if (!cc->supports_encoding_opts) {
+        if (qemu_opt_get(opts, "encoding")) {
+            error_setg(errp, "chardev '%s' does not support encoding option",
+                       qemu_opts_id(opts));
+            return NULL;
+        }
+    }
 
     backend = g_new0(ChardevBackend, 1);
     backend->type = CHARDEV_BACKEND_KIND_NULL;
@@ -972,6 +979,9 @@ QemuOptsList qemu_chardev_opts = {
         },{
             .name = "rows",
             .type = QEMU_OPT_NUMBER,
+        },{
+            .name = "encoding",
+            .type = QEMU_OPT_STRING,
         },{
             .name = "mux",
             .type = QEMU_OPT_BOOL,
diff --git a/ui/console-vc.c b/ui/console-vc.c
index 62a5e3caf57..7bb6a483753 100644
--- a/ui/console-vc.c
+++ b/ui/console-vc.c
@@ -1211,6 +1211,7 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend 
*backend, Error **errp)
 static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
 {
     int val;
+    const char *str;
     ChardevVC *vc;
 
     backend->type = CHARDEV_BACKEND_KIND_VC;
@@ -1240,6 +1241,16 @@ static void vc_chr_parse(QemuOpts *opts, ChardevBackend 
*backend, Error **errp)
         vc->has_rows = true;
         vc->rows = val;
     }
+
+    str = qemu_opt_get(opts, "encoding");
+    if (str) {
+        int cs = qapi_enum_parse(&ChardevVCEncoding_lookup, str, -1, errp);
+        if (cs < 0) {
+            return;
+        }
+        vc->has_encoding = true;
+        vc->encoding = cs;
+    }
 }
 
 static void char_vc_class_init(ObjectClass *oc, const void *data)
@@ -1252,6 +1263,7 @@ static void char_vc_class_init(ObjectClass *oc, const 
void *data)
     cc->chr_accept_input = vc_chr_accept_input;
     cc->chr_set_echo = vc_chr_set_echo;
     cc->supports_size_opts = true;
+    cc->supports_encoding_opts = true;
 }
 
 static const TypeInfo char_vc_type_info = {
diff --git a/ui/dbus.c b/ui/dbus.c
index 794b65c4ada..721cc71d39b 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -471,6 +471,8 @@ dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend,
     DBusVCClass *klass = DBUS_VC_CLASS(object_class_by_name(TYPE_CHARDEV_VC));
     const char *name = qemu_opt_get(opts, "name");
     const char *id = qemu_opts_id(opts);
+    const char *str;
+    ChardevDBus *dbus;
 
     if (name == NULL) {
         if (g_str_has_prefix(id, "compat_monitor")) {
@@ -486,6 +488,16 @@ dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend,
     }
 
     klass->parent_parse(opts, backend, errp);
+    dbus = backend->u.dbus.data;
+    str = qemu_opt_get(opts, "encoding");
+    if (str) {
+        int cs = qapi_enum_parse(&ChardevVCEncoding_lookup, str, -1, errp);
+        if (cs < 0) {
+            return;
+        }
+        dbus->has_encoding = true;
+        dbus->encoding = cs;
+    }
 }
 
 static void
@@ -496,6 +508,7 @@ dbus_vc_class_init(ObjectClass *oc, const void *data)
 
     klass->parent_parse = cc->chr_parse;
     cc->chr_parse = dbus_vc_parse;
+    cc->supports_encoding_opts = true;
 }
 
 static const TypeInfo dbus_vc_type_info = {
diff --git a/qemu-options.hx b/qemu-options.hx
index e7842b10c8c..5387bcd751b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4053,7 +4053,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
     "         [,logfile=PATH][,logappend=on|off]\n"
     "-chardev msmouse,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
     "-chardev 
vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
-    "         [,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
+    "         
[,mux=on|off][,logfile=PATH][,logappend=on|off][,encoding=ENCODING]\n"
     "-chardev ringbuf,id=id[,size=size][,logfile=PATH][,logappend=on|off]\n"
     "-chardev 
file,id=id,path=path[,input-path=input-file][,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
     "-chardev 
pipe,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
@@ -4285,7 +4285,7 @@ The available backends are:
     Several frontend devices is not supported. Stacking of multiplexers
     and hub devices is not supported as well.
 
-``-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]``
+``-chardev 
vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]][,encoding=ENCODING]``
     Connect to a QEMU text console. The implementation and supported feature
     set depend on the selected display backend.
 
@@ -4304,6 +4304,9 @@ The available backends are:
     ``cols`` and ``rows`` specify that the console be sized to fit a
     text console with the given dimensions.
 
+    ``encoding`` specifies the character set expected from the guest:
+    ``utf8`` or ``cp437`` (8-bit Extended ASCII / VGA).
+
 ``-chardev ringbuf,id=id[,size=size]``
     Create a ring buffer with fixed size ``size``. size must be a power
     of two and defaults to ``64K``.
-- 
2.54.0


Reply via email to