UI patches
Subsystems (5)
From: Marc-André Lureau <[email protected]>
The following changes since commit ee7eb612be8f8886d48c1d0c1f1c65e495138f83:
Merge tag 'single-binary-20260506' of https://github.com/philmd/qemu into staging (2026-05-06 10:45:02 -0400)
are available in the Git repository at:
https://gitlab.com/marcandre.lureau/qemu.git tags/ui-pull-request
for you to fetch changes up to e4c7ebde643811e8dc1f640b50f37ad0a0dd1dac:
qemu-options: document -chardev dbus (2026-05-09 18:54:16 +0400)
----------------------------------------------------------------
- gtk clipboard fixes
- dbus-vmstate test fixes
- vt100 emulator support for utf8
- qemu-vnc tool
----------------------------------------------------------------
Fabiano Rosas (5):
tests/qtest/dbus-vmstate: Bring the test up-to-date tests/qtest/dbus-vmstate: Mute Glib complaints about g_unsetenv
thread-safety
tests/qtest/dbus-vmstate: Honor QTEST_LOG env variable tests/qtest/dbus-vmstate: Stop the daemons explicitly tests/qtest/dbus-vmstate: Re-enable the test
Jindřich Makovička (1):
ui/gtk: Fix GTK assertion failure introduced with clipboard fixes
Marc-André Lureau (26):
ui/input: do not assert() when tracing invalid input qemu-options.hx: document -chardev vc backend-specific behavior
char: error out if given unhandled size options ui/console: add vc encoding=utf8/cp437 option
ui/console: default vc encoding to cp437 for machine < 11.1 ui/dbus: expose vc encoding via D-Bus Chardev.VCEncoding interface ui/console-vc: add UTF-8 input decoding with CP437 rendering ui/console-vc: move VT100 state machine and output FIFO into QemuVT100 ui/console-vc: extract vt100_input() from vc_chr_write() ui/console-vc: extract vt100_keysym() from
qemu_text_console_handle_keysym()
ui/console-vc: extract vt100_init() and vt100_fini() ui/console: remove console_ch_t typedef and console_write_ch() ui/console-vc: move VT100 emulation into separate unit ui/vnc: make the worker thread per-VncDisplay
ui/vnc: vnc_display_init() and vnc_display_open() return bool ui/vnc: merge vnc_display_init() and vnc_display_open() ui/vnc: clean up VNC displays on exit
ui/vnc: defer listener registration until the console is known ui/vnc: add vnc-system unit, to allow different implementations ui/console: simplify registering display/console change listener ui/console: add doc comment for qemu_console_{un}register_listener() ui/console: rename public API to use consistent qemu_console_ prefix ui/vnc: replace VNC_DEBUG with trace-events
ui: extract common sources into a static library tests/qtest: drop DBUS_VMSTATE_TEST_TMPDIR
tools/qemu-vnc: add standalone VNC server over D-Bus
uchouT (1):
qemu-options: document -chardev dbus
MAINTAINERS | 5 + docs/conf.py | 3 + docs/interop/dbus-display.rst | 2 + docs/interop/dbus-vnc.rst | 26 + docs/interop/index.rst | 1 + docs/meson.build | 1 + docs/tools/index.rst | 1 + docs/tools/qemu-vnc.rst | 226 +++++ meson.build | 17 + qapi/char.json | 30 +- include/chardev/char.h | 21 + include/qemu/option.h | 1 + include/ui/console.h | 124 ++- tools/qemu-vnc/qemu-vnc.h | 49 ++ tools/qemu-vnc/trace.h | 4 + ui/console-priv.h | 1 - ui/cp437.h | 13 + ui/dbus.h | 1 + ui/vnc-jobs.h | 3 +- ui/vnc.h | 17 +- ui/vt100.h | 95 +++ chardev/char.c | 22 + hw/arm/musicpal.c | 4 +- hw/core/machine.c | 4 +- hw/display/artist.c | 4 +- hw/display/ati.c | 16 +- hw/display/bcm2835_fb.c | 5 +- hw/display/bochs-display.c | 14 +- hw/display/cg3.c | 6 +- hw/display/cirrus_vga.c | 8 +- hw/display/cirrus_vga_isa.c | 2 +- hw/display/dm163.c | 6 +- hw/display/exynos4210_fimd.c | 4 +- hw/display/g364fb.c | 10 +- hw/display/imx6ul_lcdif.c | 14 +- hw/display/jazz_led.c | 18 +- hw/display/macfb.c | 6 +- hw/display/next-fb.c | 4 +- hw/display/omap_lcdc.c | 4 +- hw/display/pl110.c | 4 +- hw/display/qxl-render.c | 12 +- hw/display/qxl.c | 18 +- hw/display/ramfb-standalone.c | 2 +- hw/display/ramfb.c | 4 +- hw/display/sm501.c | 6 +- hw/display/ssd0303.c | 4 +- hw/display/ssd0323.c | 5 +- hw/display/tcx.c | 16 +- hw/display/vga-isa.c | 2 +- hw/display/vga-mmio.c | 2 +- hw/display/vga-pci.c | 6 +- hw/display/vga.c | 56 +- hw/display/vhost-user-gpu.c | 22 +- hw/display/virtio-gpu-base.c | 4 +- hw/display/virtio-gpu-rutabaga.c | 10 +- hw/display/virtio-gpu-udmabuf.c | 4 +- hw/display/virtio-gpu-virgl.c | 20 +- hw/display/virtio-gpu.c | 26 +- hw/display/virtio-vga.c | 4 +- hw/display/vmware_vga.c | 14 +- hw/display/xenfb.c | 6 +- hw/display/xlnx_dp.c | 10 +- hw/vfio/display.c | 32 +- system/runstate.c | 5 + tests/qtest/dbus-vmstate-test.c | 123 ++- tests/qtest/dbus-vnc-test.c | 1346 ++++++++++++++++++++++++++++++ tools/qemu-vnc/audio.c | 308 +++++++ tools/qemu-vnc/chardev.c | 148 ++++ tools/qemu-vnc/clipboard.c | 376 +++++++++ tools/qemu-vnc/console.c | 170 ++++ tools/qemu-vnc/dbus.c | 474 +++++++++++ tools/qemu-vnc/display.c | 456 ++++++++++ tools/qemu-vnc/input.c | 239 ++++++ tools/qemu-vnc/qemu-vnc.c | 581 +++++++++++++ tools/qemu-vnc/stubs.c | 62 ++ tools/qemu-vnc/utils.c | 59 ++ ui/console-vc-stubs.c | 1 + ui/console-vc.c | 1074 ++---------------------- ui/console.c | 173 ++-- ui/cp437.c | 205 +++++ ui/curses.c | 23 +- ui/dbus-chardev.c | 10 + ui/dbus-console.c | 10 +- ui/dbus-listener.c | 37 +- ui/dbus.c | 59 ++ ui/egl-headless.c | 8 +- ui/gtk-clipboard.c | 2 +- ui/gtk-egl.c | 6 +- ui/gtk-gl-area.c | 6 +- ui/gtk.c | 28 +- ui/input.c | 8 +- ui/sdl2-2d.c | 2 +- ui/sdl2-gl.c | 2 +- ui/sdl2.c | 14 +- ui/spice-display.c | 24 +- ui/vnc-auth-sasl.c | 13 +- ui/vnc-enc-tight.c | 4 +- ui/vnc-enc-zlib.c | 4 +- ui/vnc-jobs.c | 62 +- ui/vnc-system.c | 19 + ui/vnc-ws.c | 10 +- ui/vnc.c | 232 +++-- ui/vt100.c | 984 ++++++++++++++++++++++ util/qemu-option.c | 13 + hw/display/apple-gfx.m | 16 +- meson_options.txt | 2 + qemu-options.hx | 36 +- scripts/meson-buildoptions.sh | 3 + tests/dbus-daemon.sh | 16 +- tests/qtest/meson.build | 23 +- tools/qemu-vnc/meson.build | 26 + tools/qemu-vnc/qemu-vnc1.xml | 201 +++++ tools/qemu-vnc/trace-events | 21 + ui/cocoa.m | 23 +- ui/dbus-display1.xml | 18 + ui/meson.build | 103 +-- ui/trace-events | 29 +- 117 files changed, 7221 insertions(+), 1757 deletions(-) create mode 100644 docs/interop/dbus-vnc.rst create mode 100644 docs/tools/qemu-vnc.rst create mode 100644 tools/qemu-vnc/qemu-vnc.h create mode 100644 tools/qemu-vnc/trace.h create mode 100644 ui/cp437.h create mode 100644 ui/vt100.h create mode 100644 tests/qtest/dbus-vnc-test.c create mode 100644 tools/qemu-vnc/audio.c create mode 100644 tools/qemu-vnc/chardev.c create mode 100644 tools/qemu-vnc/clipboard.c create mode 100644 tools/qemu-vnc/console.c create mode 100644 tools/qemu-vnc/dbus.c create mode 100644 tools/qemu-vnc/display.c create mode 100644 tools/qemu-vnc/input.c create mode 100644 tools/qemu-vnc/qemu-vnc.c create mode 100644 tools/qemu-vnc/stubs.c create mode 100644 tools/qemu-vnc/utils.c create mode 100644 ui/cp437.c create mode 100644 ui/vnc-system.c create mode 100644 ui/vt100.c create mode 100644 tools/qemu-vnc/meson.build create mode 100644 tools/qemu-vnc/qemu-vnc1.xml create mode 100644 tools/qemu-vnc/trace-events
Signature · 1 line
2.54.0
[PULL v2 02/33] tests/qtest/dbus-vmstate: Mute Glib complaints about g_unsetenv thread-safety
From: Fabiano Rosas <[email protected]>
TLDR: GLib is bugged, the dbus-vmstate-test spams debug messages unconditionally. Mute them.
GLib is trying to protect against the lack of thread-safety of setenv/unsetsenv functions by warning when those functions were invoked after a thread has been started.
https://gitlab.gnome.org/GNOME/glib/issues/715
Unfortunately:
1) GLib itself starts a thread pool via _g_dbus_initialize when working around a bug in its type dependency chain. This happens in many places, but the test triggers it via g_dbus_address_get_for_bus_sync.
https://bugzilla.gnome.org/show_bug.cgi?id=627724
2) GLib itself calls g_unsetenv after the test calls g_test_dbus_up.
3) The debug message at g_unsetenv is issued to the G_LOG_DOMAIN defined while compiling the library, i.e "GLib", but this domain is never initialized, so the log functions go into a fallback chain that results in ignoring the G_MESSAGES_DEBUG environment variable, causing the debug messages to not be suppressed when they should.
Mute the messages by implementing a handler for G_LOG_LEVEL_DEBUG in the "GLib" log domain and honoring G_MESSAGES_DEBUG.
Message-ID: <[email protected]>
--- tests/qtest/dbus-vmstate-test.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
tests/qtest/dbus-vmstate-test.c +21 -0
@@ -357,12 +357,33 @@ test_dbus_vmstate_missing_dst(char *name, MigrateCommon *args)g_test_trap_assert_passed (); } +static void log_func (const gchar *log_domain,GLogLevelFlags log_level, +const gchar *message,gpointer user_data) +{ +const gchar *domains; + +assert (log_level &G_LOG_LEVEL_DEBUG ); + + domains =getenv ("G_MESSAGES_DEBUG" ); +if (!domains || (!strstr (domains,"GLib" ) && !strstr (domains,"all" ))) { +return ; + } +g_log_default_handler ("GLib" ,G_LOG_LEVEL_DEBUG , message,NULL ); +} +int main (int argc,char **argv) {GError *err =NULL ;int ret; +/* +* GLib currently emits debug messages that ignore +* G_MESSAGES_DEBUG. Set a custom log handler to work around the +* issue. +*/ +g_log_set_handler ("GLib" ,G_LOG_LEVEL_DEBUG , log_func,NULL ); +g_test_init (&argc, &argv,NULL ); workdir =g_dir_make_tmp ("dbus-vmstate-test-XXXXXX" , &err);
Signature · 1 line
2.54.0
[PULL v2 05/33] tests/qtest/dbus-vmstate: Re-enable the test
In reply to [email protected]From: Fabiano Rosas <[email protected]>
Back in 2020, the dbus-vmstate test was disabled by commit d46f81cb74 ("tests: Disable dbus-vmstate-test") due to Patchew failures. We don't use Patchew anymore for CI, so re-enable the test.
G_TEST_DBUS_DAEMON=../tests/dbus-vmstate-daemon.sh \
QTEST_QEMU_BINARY=./qemu-system-x86_64 \
./tests/qtest/dbus-vmstate-test
Message-ID: <[email protected]>
--- tests/qtest/meson.build | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
tests/qtest/meson.build +1 -2
@@ -125,8 +125,7 @@ endif dbus_daemon = find_program('dbus-daemon', required: false) if dbus_daemon.found() and gdbus_codegen.found() - # Temporarily disabled due to Patchew failures: - #qtests_i386 += ['dbus-vmstate-test'] + qtests_i386 += ['dbus-vmstate-test'] dbus_vmstate1 = custom_target('dbus-vmstate description', build_by_default: true, output: [ 'dbus-vmstate1.h', 'dbus-vmstate1.c'],
Signature · 1 line
2.54.0
[PULL v2 01/33] tests/qtest/dbus-vmstate: Bring the test up-to-date
In reply to [email protected]From: Fabiano Rosas <[email protected]>
The dbus-vmstate-test has been disabled for years. Here's the things that have changed in the meantime and how to update the test:
- Migration tests got new headers.
Update the includes.
- migrate_qmp got new parameters.
Update the caller.
- migrate_incoming_qmp is now used instead of -incoming URL. Use -incoming defer.
- Tests expecting failure should not check non-zero return code. Check for failed migration state instead.
- The test result enum was introduced.
Replace the migration_fail flag with the enum.
- The DEVICE state was added.
Replace wait_for_migration_complete with migration_event_wait, which won't trip on intermediary states.
- Migration completion was reworked.
Explicitly wait for the RESUME event before asserting runstate is RUNNING to avoid checking too quickly and seeing FINISH_MIGRATE instead.
- The FAILING state was added.
Wait for it before waiting for the RESUME event.
- Sanity checks were added to migration_get_env(). Start calling that function in main.
- qtest_add_func now has a wrapper.
Replace qtest_add_func with migration_test_add. Update tests' signatures to take MigrationCommon, although it's unused.
- meson now sets up G_TEST_DBUS_DAEMON.
Remove the logic around it.
Message-ID: <[email protected]>
--- tests/qtest/dbus-vmstate-test.c | 71 +++++++++++++++++++-------------- tests/qtest/meson.build | 7 +++- 2 files changed, 46 insertions(+), 32 deletions(-)
tests/qtest/dbus-vmstate-test.c +41 -30
@@ -2,8 +2,8 @@#include <glib/gstdio.h> #include <gio/gio.h> #include "libqtest.h" +#include "migration/migration-qmp.h" #include "dbus-vmstate1.h" -#include "migration-helpers.h" static char *workdir;
@@ -29,7 +29,7 @@ typedef struct TestServer { typedef struct Test { const char *id_list; - bool migrate_fail; + int result; bool without_dst_b; TestServer srcA; TestServer dstA;
@@ -190,6 +190,7 @@ test_dbus_vmstate(Test *test) g_autofree char *uri = NULL;QTestState *src_qemu =NULL , *dst_qemu =NULL ;guint ownsrcA, ownsrcB, owndstA, owndstB; +QTestMigrationState src_state = { }; uri =g_strdup_printf ("unix:%s/migsocket" , workdir);
@@ -224,17 +225,33 @@ test_dbus_vmstate(Test *test) src_qemu =qtest_init (src_qemu_args); dst_qemu =qtest_init (dst_qemu_args); + +migrate_set_capability (src_qemu,"events" , true); +qtest_qmp_set_event_callback (src_qemu, migrate_watch_for_events, + &src_state); +set_id_list (test, src_qemu);set_id_list (test, dst_qemu); thread =g_thread_new ("dbus-vmstate-thread" , dbus_vmstate_thread, loop);migrate_incoming_qmp (dst_qemu, uri,NULL ,"{}" ); -migrate_qmp (src_qemu, uri,"{}" ); +migrate_ensure_converge (src_qemu); +migrate_qmp (src_qemu,NULL , uri,NULL ,"{}" ); test->src_qemu = src_qemu; -if (test->migrate_fail) { -wait_for_migration_fail (src_qemu, true); -qtest_set_expected_status (dst_qemu,EXIT_FAILURE ); + +if (test->result !=MIG_TEST_SUCCEED ) { +QDict *rsp; + +migration_event_wait (src_qemu,"failing" ); +wait_for_resume (src_qemu, &src_state); +migration_event_wait (src_qemu,"failed" ); + + rsp =qtest_qmp_assert_success_ref (src_qemu, +"{ 'execute': 'query-status' }" ); +g_assert (qdict_haskey (rsp,"running" )); +g_assert (qdict_get_bool (rsp,"running" )); +qobject_unref (rsp); }else {wait_for_migration_complete (src_qemu); }
@@ -270,7 +287,7 @@ check_migrated(TestServer *s, TestServer *d) }static void -test_dbus_vmstate_without_list (void ) +test_dbus_vmstate_without_list (char *name,MigrateCommon *args) {Test test = {0 , };
@@ -281,7 +298,7 @@ test_dbus_vmstate_without_list(void) }static void -test_dbus_vmstate_with_list (void ) +test_dbus_vmstate_with_list (char *name,MigrateCommon *args) {Test test = { .id_list ="idA,idB" };
@@ -292,7 +309,7 @@ test_dbus_vmstate_with_list(void) }static void -test_dbus_vmstate_only_a (void ) +test_dbus_vmstate_only_a (char *name,MigrateCommon *args) {Test test = { .id_list ="idA" };
@@ -303,9 +320,10 @@ test_dbus_vmstate_only_a(void) }static void -test_dbus_vmstate_missing_src (void ) +test_dbus_vmstate_missing_src (char *name,MigrateCommon *args) { -Test test = { .id_list ="idA,idC" , .migrate_fail = true }; +Test test = { .id_list ="idA,idC" , + .result =MIG_TEST_FAIL };/* run in subprocess to silence QEMU error reporting */ if (g_test_subprocess ()) {
@@ -320,11 +338,11 @@ test_dbus_vmstate_missing_src(void) }static void -test_dbus_vmstate_missing_dst (void ) +test_dbus_vmstate_missing_dst (char *name,MigrateCommon *args) {Test test = { .id_list ="idA,idB" , .without_dst_b = true, - .migrate_fail = true }; + .result =MIG_TEST_FAIL };/* run in subprocess to silence QEMU error reporting */ if (g_test_subprocess ()) {
@@ -343,15 +361,8 @@ int main(int argc, char **argv) { GError *err = NULL; - g_autofree char *dbus_daemon = NULL;int ret; - dbus_daemon =g_build_filename (G_STRINGIFY (SRCDIR ), -"tests" , -"dbus-vmstate-daemon.sh" , -NULL ); -g_setenv ("G_TEST_DBUS_DAEMON" , dbus_daemon, true); -g_test_init (&argc, &argv,NULL ); workdir =g_dir_make_tmp ("dbus-vmstate-test-XXXXXX" , &err);
@@ -362,16 +373,16 @@ main(int argc, char **argv)g_setenv ("DBUS_VMSTATE_TEST_TMPDIR" , workdir, true); -qtest_add_func ("/dbus-vmstate/without-list" , - test_dbus_vmstate_without_list); -qtest_add_func ("/dbus-vmstate/with-list" , - test_dbus_vmstate_with_list); -qtest_add_func ("/dbus-vmstate/only-a" , - test_dbus_vmstate_only_a); -qtest_add_func ("/dbus-vmstate/missing-src" , - test_dbus_vmstate_missing_src); -qtest_add_func ("/dbus-vmstate/missing-dst" , - test_dbus_vmstate_missing_dst); +migration_test_add ("/dbus-vmstate/without-list" , + test_dbus_vmstate_without_list); +migration_test_add ("/dbus-vmstate/with-list" , + test_dbus_vmstate_with_list); +migration_test_add ("/dbus-vmstate/only-a" , + test_dbus_vmstate_only_a); +migration_test_add ("/dbus-vmstate/missing-src" , + test_dbus_vmstate_missing_src); +migration_test_add ("/dbus-vmstate/missing-dst" , + test_dbus_vmstate_missing_dst); ret =g_test_run ();
tests/qtest/meson.build +5 -2
@@ -128,10 +128,12 @@ if dbus_daemon.found() and gdbus_codegen.found() # Temporarily disabled due to Patchew failures: #qtests_i386 += ['dbus-vmstate-test'] dbus_vmstate1 = custom_target('dbus-vmstate description', - output: ['dbus-vmstate1.h', 'dbus-vmstate1.c'], + build_by_default: true, + output: [ 'dbus-vmstate1.h', 'dbus-vmstate1.c'], input: meson.project_source_root() / 'backends/dbus-vmstate1.xml', command: [gdbus_codegen, '@INPUT@', '--interface-prefix', 'org.qemu', + '--output-directory', meson.current_build_dir(), '--generate-c-code', '@BASENAME@']).to_list() else dbus_vmstate1 = []
@@ -387,7 +389,8 @@ qtests = { 'bios-tables-test': [io, 'boot-sector.c', 'acpi-utils.c', 'tpm-emu.c'], 'cdrom-test': files('boot-sector.c'), 'dbus-vmstate-test': files('migration/migration-qmp.c', - 'migration/migration-util.c') + dbus_vmstate1, + 'migration/migration-util.c') + dbus_vmstate1 + + [gio], 'erst-test': files('erst-test.c'), 'ivshmem-test': [rt, '../../contrib/ivshmem-server/ivshmem-server.c'], 'migration-test': test_migration_files + migration_tls_files + migration_colo_files,
Signature · 1 line
2.54.0
[PULL v2 07/33] ui/gtk: Fix GTK assertion failure introduced with clipboard fixes
In reply to [email protected]From: Jindřich Makovička <[email protected]>
gtk_clipboard_request_targets actually returns n_targets == -1 when targets == NULL instead of zero. This result in failed assertion within GTK:
qemu: Gtk: gtk_targets_include_text:
assertion 'targets != NULL || n_targets == 0' failed
Extend the check to require non-null targets and positive n_targets.
Message-ID: <[email protected]>
--- ui/gtk-clipboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ui/gtk-clipboard.c +1 -1
@@ -175,7 +175,7 @@ static void gd_clipboard_owner_change_targets_received_callback( {QemuClipboardInfo *info = (QemuClipboardInfo *)data; -if (n_targets) { +if (targets && n_targets >0 ) {if (gtk_targets_include_text (targets, n_targets)) { info->types[QEMU_CLIPBOARD_TYPE_TEXT ].available = true; }
Signature · 1 line
2.54.0
[PULL v2 08/33] qemu-options.hx: document -chardev vc backend-specific behavior
In reply to [email protected]From: Marc-André Lureau <[email protected]>
The -chardev vc documentation only mentioned the built-in console with optional size parameters, but the actual behavior depends on the display backend. Document the GTK (libvte), D-Bus and spice-app cases.
--- qemu-options.hx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
qemu-options.hx +11 -2
@@ -4286,8 +4286,17 @@ The available backends are: and hub devices is not supported as well. ``-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]`` - Connect to a QEMU text console. ``vc`` may optionally be given a - specific size. + Connect to a QEMU text console. The implementation and supported feature + set depend on the selected display backend. + + - The GTK backend uses libvte for the emulation and display (when available). + + - The D-Bus backend exports the character device as a Chardev object. + + - spice-app backend exports it as a Spice port. + + In other cases, QEMU uses its own emulated VT100, and ``vc`` may optionally be + given a specific size. ``width`` and ``height`` specify the width and height respectively of the console, in pixels.
Signature · 1 line
2.54.0
[PULL v2 09/33] char: error out if given unhandled size options
In reply to [email protected]From: Marc-André Lureau <[email protected]>
This is a small help, because in fact all combined chardev options are accepted by qemu_chardev_opts[]. But given that a user may legitimately want to use the size options with a VC backend, we can report an error when we know the backend doesn't support it.
--- include/chardev/char.h | 1 + include/qemu/option.h | 1 + chardev/char.c | 12 ++++++++++++ ui/console-vc.c | 1 + util/qemu-option.c | 13 +++++++++++++ 5 files changed, 28 insertions(+)
include/chardev/char.h +1 -0
@@ -254,6 +254,7 @@ struct ChardevClass {bool internal;/* TODO: eventually use TYPE_USER_CREATABLE */ bool supports_yank; +bool supports_size_opts;/* parse command line options and populate QAPI @backend */ void (*chr_parse)(QemuOpts *opts,ChardevBackend *backend,Error **errp);
include/qemu/option.h +1 -0
@@ -73,6 +73,7 @@ struct QemuOptsList {const char *qemu_opt_get (QemuOpts *opts,const char *name);char *qemu_opt_get_del (QemuOpts *opts,const char *name); +bool qemu_opt_has_any (QemuOpts *opts,const char *const *names);/** * qemu_opt_has_help_opt: * @opts: options to search for a help request
chardev/char.c +12 -0
@@ -639,6 +639,18 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp)return NULL ; } +if (!cc->supports_size_opts) { +const char *const invalid_opts[] = { +"width" ,"height" ,"cols" ,"rows" ,NULL + }; + +if (qemu_opt_has_any (opts, invalid_opts)) { +error_setg (errp,"chardev '%s' does not support size options" , +qemu_opts_id (opts)); +return NULL ; + } + } + backend =g_new0 (ChardevBackend,1 ); backend->type =CHARDEV_BACKEND_KIND_NULL ;
ui/console-vc.c +1 -0
@@ -1251,6 +1251,7 @@ static void char_vc_class_init(ObjectClass *oc, const void *data) cc->chr_write = vc_chr_write; cc->chr_accept_input = vc_chr_accept_input; cc->chr_set_echo = vc_chr_set_echo; + cc->supports_size_opts = true; }static const TypeInfo char_vc_type_info = {
util/qemu-option.c +13 -0
@@ -271,6 +271,19 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)return opt->str; } +bool qemu_opt_has_any (QemuOpts *opts,const char *const *names) +{ +int it; + +for (it =0 ; names[it]; it++) { +if (qemu_opt_get (opts, names[it])) { +return true; + } + } +return false; +} + +void qemu_opt_iter_init (QemuOptsIter *iter,QemuOpts *opts,const char *name) { iter->opts = opts;
Signature · 1 line
2.54.0
[PULL v2 04/33] tests/qtest/dbus-vmstate: Stop the daemons explicitly
In reply to [email protected]From: Fabiano Rosas <[email protected]>
The dbus-vmstate test is currently non-deterministically emitting a "cleaning up pid" message, followed by the PID of one of the dbus-daemon processes used during the test. This is due to a race between the GTestDBus g_autoptr destructor and a child process that does cleanup when the program ends.
Add calls to g_test_dbus_down() to make the issuance of the SIGTERM to the dbus-daemon deterministic.
Message-ID: <[email protected]>
--- tests/qtest/dbus-vmstate-test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tests/qtest/dbus-vmstate-test.c +2 -1
@@ -260,11 +260,12 @@ test_dbus_vmstate(Test *test)qtest_quit (src_qemu);g_bus_unown_name (ownsrcA);g_bus_unown_name (ownsrcB); +g_test_dbus_down (srcbus);g_bus_unown_name (owndstA);if (!test->without_dst_b) {g_bus_unown_name (owndstB); } - +g_test_dbus_down (dstbus);g_main_loop_quit (test->loop); }
Signature · 1 line
2.54.0
[PULL v2 11/33] ui/console: default vc encoding to cp437 for machine < 11.1
In reply to [email protected]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.
--- 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(-)
include/chardev/char.h +19 -0
@@ -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
hw/core/machine.c +3 -1
@@ -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[] = {
ui/console-vc.c +18 -0
@@ -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, };
ui/dbus.c +40 -0
@@ -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, };
Signature · 1 line
2.54.0
[PULL v2 15/33] ui/console-vc: extract vt100_input() from vc_chr_write()
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Move the VT100 input processing logic out of vc_chr_write() into a new vt100_input() function that operates on QemuVT100 directly, rather than going through the Chardev/VCChardev layers. This continues the effort to decouple the VT100 emulation from the chardev backend, making the VT100 layer self-contained and reusable.
vc_chr_write() becomes a thin wrapper that extracts the QemuVT100 from the chardev and delegates to vt100_input().
--- ui/console-vc.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
ui/console-vc.c +20 -14
@@ -1059,29 +1059,35 @@ static void vt100_putchar(QemuVT100 *vt, int ch)DECLARE_INSTANCE_CHECKER (VCChardev,VC_CHARDEV , TYPE_CHARDEV_VC) -static int vc_chr_write (Chardev *chr,const uint8_t *buf,int len) +static size_t vt100_input (QemuVT100 *vt,const uint8_t *buf,size_t len) { -VCChardev *drv =VC_CHARDEV (chr); -QemuTextConsole *s = drv->console;int i; - s->vt.update_x0 = s->vt.width *FONT_WIDTH ; - s->vt.update_y0 = s->vt.height *FONT_HEIGHT ; - s->vt.update_x1 =0 ; - s->vt.update_y1 =0 ; -vt100_show_cursor (&s->vt,0 ); + vt->update_x0 = vt->width *FONT_WIDTH ; + vt->update_y0 = vt->height *FONT_HEIGHT ; + vt->update_x1 =0 ; + vt->update_y1 =0 ; +vt100_show_cursor (vt,0 );for (i =0 ; i < len; i++) { -vt100_putchar (&s->vt, buf[i]); +vt100_putchar (vt, buf[i]); } -vt100_show_cursor (&s->vt,1 ); -if (s->vt.update_x0 < s->vt.update_x1) { -vt100_image_update (&s->vt, s->vt.update_x0, s->vt.update_y0, - s->vt.update_x1 - s->vt.update_x0, - s->vt.update_y1 - s->vt.update_y0); +vt100_show_cursor (vt,1 ); +if (vt->update_x0 < vt->update_x1) { +vt100_image_update (vt, vt->update_x0, vt->update_y0, + vt->update_x1 - vt->update_x0, + vt->update_y1 - vt->update_y0); }return len; } +static int vc_chr_write (Chardev *chr,const uint8_t *buf,int len) +{ +VCChardev *drv =VC_CHARDEV (chr); +QemuTextConsole *s = drv->console; + +return vt100_input (&s->vt, buf, len); +} +void vt100_update_cursor (void ) {QemuVT100 *vt;
Signature · 1 line
2.54.0
[PULL v2 03/33] tests/qtest/dbus-vmstate: Honor QTEST_LOG env variable
In reply to [email protected]From: Fabiano Rosas <[email protected]>
Don't hide QEMU error messages unconditionally, make the tests that expect to fail honor QTEST_LOG and show every output if the variable is set.
Message-ID: <[email protected]>
--- tests/qtest/dbus-vmstate-test.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
tests/qtest/dbus-vmstate-test.c +15 -13
@@ -324,17 +324,18 @@ test_dbus_vmstate_missing_src(char *name, MigrateCommon *args) {Test test = { .id_list ="idA,idC" , .result =MIG_TEST_FAIL }; +bool silent = !getenv ("QTEST_LOG" );/* run in subprocess to silence QEMU error reporting */ -if (g_test_subprocess ()) { -test_dbus_vmstate (&test); -check_not_migrated (&test.srcA, &test.dstA); -check_not_migrated (&test.srcB, &test.dstB); +if (silent && !g_test_subprocess ()) { +g_test_trap_subprocess (NULL ,0 ,0 ); +g_test_trap_assert_passed ();return ; } -g_test_trap_subprocess (NULL ,0 ,0 ); -g_test_trap_assert_passed (); +test_dbus_vmstate (&test); +check_not_migrated (&test.srcA, &test.dstA); +check_not_migrated (&test.srcB, &test.dstB); } static void
@@ -343,18 +344,19 @@ test_dbus_vmstate_missing_dst(char *name, MigrateCommon *args)Test test = { .id_list ="idA,idB" , .without_dst_b = true, .result =MIG_TEST_FAIL }; +bool silent = !getenv ("QTEST_LOG" );/* run in subprocess to silence QEMU error reporting */ -if (g_test_subprocess ()) { -test_dbus_vmstate (&test); -assert (test.srcA.save_called); -assert (test.srcB.save_called); -assert (!test.dstB.save_called); +if (silent && !g_test_subprocess ()) { +g_test_trap_subprocess (NULL ,0 ,0 ); +g_test_trap_assert_passed ();return ; } -g_test_trap_subprocess (NULL ,0 ,0 ); -g_test_trap_assert_passed (); +test_dbus_vmstate (&test); +assert (test.srcA.save_called); +assert (test.srcB.save_called); +assert (!test.dstB.save_called); } static void log_func(const gchar *log_domain, GLogLevelFlags log_level,
Signature · 1 line
2.54.0
[PULL v2 12/33] ui/dbus: expose vc encoding via D-Bus Chardev.VCEncoding interface
In reply to [email protected]From: Marc-André Lureau <[email protected]>
When a D-Bus VC chardev is instantiated, export an extra org.qemu.Display1.Chardev.VCEncoding interface on the chardev object. This lets D-Bus display clients discover the encoding (cp437 or utf8) in use by the virtual console.
--- ui/dbus.h | 1 + ui/dbus-chardev.c | 10 ++++++++++ ui/dbus.c | 6 ++++++ ui/dbus-display1.xml | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+)
ui/dbus.h +1 -0
@@ -126,6 +126,7 @@ typedef struct DBusChardev {bool exported;QemuDBusDisplay1Chardev *iface; +QemuDBusDisplay1ChardevVCEncoding *iface_vc_encoding; } DBusChardev;DECLARE_INSTANCE_CHECKER (DBusChardev,DBUS_CHARDEV ,TYPE_CHARDEV_DBUS )
ui/dbus-chardev.c +10 -0
@@ -53,6 +53,15 @@ dbus_display_chardev_export(DBusDisplay *dpy, DBusChardev *chr) sk =g_dbus_object_skeleton_new (path);g_dbus_object_skeleton_add_interface ( sk,G_DBUS_INTERFACE_SKELETON (chr->iface)); +if (chr->iface_vc_encoding) { +const char *interfaces[] = { +"org.qemu.Display1.Chardev.VCEncoding" , +NULL + }; +g_dbus_object_skeleton_add_interface ( + sk,G_DBUS_INTERFACE_SKELETON (chr->iface_vc_encoding)); +g_object_set (chr->iface,"interfaces" , interfaces,NULL ); + }g_dbus_object_manager_server_export (dpy->server, sk); chr->exported = true; }
@@ -290,6 +299,7 @@ char_dbus_finalize(Object *obj) };dbus_display_notify (&event); +g_clear_object (&dc->iface_vc_encoding);g_clear_object (&dc->iface); }
ui/dbus.c +6 -0
@@ -514,6 +514,7 @@ CHARDEV_VC_ENCODING_PROPERTY_DEFINE(DBUS_VC_CHARDEV)static bool dbus_vc_open (Chardev *chr,ChardevBackend *backend,Error **errp) { +DBusChardev *dc =DBUS_CHARDEV (chr);DBusVCChardev *vc =DBUS_VC_CHARDEV (chr);ChardevClass *parent =CHARDEV_CLASS (object_class_by_name (TYPE_CHARDEV_DBUS ));
@@ -522,6 +523,11 @@ dbus_vc_open(Chardev *chr, ChardevBackend *backend, Error **errp)if (be->has_encoding) { vc->encoding = be->encoding; } + dc->iface_vc_encoding = +qemu_dbus_display1_chardev_vcencoding_skeleton_new (); +qemu_dbus_display1_chardev_vcencoding_set_encoding ( + dc->iface_vc_encoding, +qapi_enum_lookup (&ChardevVCEncoding_lookup, vc->encoding));return parent->chr_open (chr, backend, errp); }
ui/dbus-display1.xml +18 -0
@@ -1141,4 +1141,22 @@ --> <property name="Interfaces" type="as" access="read"/> </interface> + + <!-- + org.qemu.Display1.Chardev.VCEncoding: + + Provides encoding information for virtual console chardevs. + + This interface is present on chardev objects that are virtual + consoles, and exposes the character encoding used by the guest. + --> + <interface name="org.qemu.Display1.Chardev.VCEncoding"> + <!-- + Encoding: + + The character encoding used by the virtual console + (matching ``ChardevVCEncoding``): ``cp437`` or ``utf8``. + --> + <property name="Encoding" type="s" access="read"/> + </interface> </node>
Signature · 1 line
2.54.0
[PULL v2 17/33] ui/console-vc: extract vt100_init() and vt100_fini()
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Consolidate VT100 initialization and finalization into dedicated functions, continuing the extraction of the VT100 layer from the console/chardev code.
vt100_init() gathers the scattered setup (cursor timer, list insertion, FIFO creation, default attributes, and image) that was previously spread across vc_chr_open() and qemu_text_console_class_init().
vt100_fini() pairs with it by handling list removal, FIFO destruction, and cells cleanup, replacing the open-coded QTAILQ_REMOVE in qemu_text_console_finalize().
--- ui/console-vc.c | 55 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-)
ui/console-vc.c +37 -18
@@ -331,7 +331,7 @@ static void vt100_write(QemuVT100 *vt, const void *buf, size_t len) vt->out_flush (vt); } -static int vt100_input (QemuVT100 *vt,const uint8_t *buf,int len); +static size_t vt100_input (QemuVT100 *vt,const uint8_t *buf,size_t len);static void vt100_keysym (QemuVT100 *vt,int keysym) {
@@ -1129,12 +1129,19 @@ static void text_console_invalidate(void *opaque)vt100_refresh (&s->vt); } +static void vt100_fini (QemuVT100 *vt) +{ +QTAILQ_REMOVE (&vt100s, vt, list); +fifo8_destroy (&vt->out_fifo); +g_free (vt->cells); +} +static void qemu_text_console_finalize (Object *obj) {QemuTextConsole *s =QEMU_TEXT_CONSOLE (obj); -QTAILQ_REMOVE (&vt100s, &s->vt, list); +vt100_fini (&s->vt); } static void
@@ -1142,10 +1149,6 @@ qemu_text_console_class_init(ObjectClass *oc, const void *data) {QemuConsoleClass *cc =QEMU_CONSOLE_CLASS (oc); -if (!cursor_timer) { - cursor_timer =timer_new_ms (QEMU_CLOCK_REALTIME , cursor_timer_cb,NULL ); - } - cc->get_label = qemu_text_console_get_label; }
@@ -1211,6 +1214,27 @@ static void text_console_out_flush(QemuVT100 *vt)qemu_text_console_out_flush (console); } +static void vt100_init (QemuVT100 *vt, +pixman_image_t *image, +ChardevVCEncoding encoding, +void (*image_update)(QemuVT100 *vt,int x,int y,int w,int h), +void (*out_flush)(QemuVT100 *vt)) +{ +if (!cursor_timer) { + cursor_timer =timer_new_ms (QEMU_CLOCK_REALTIME , cursor_timer_cb,NULL ); + } + + vt->encoding = encoding; +QTAILQ_INSERT_HEAD (&vt100s, vt, list); +fifo8_create (&vt->out_fifo,16 ); + vt->total_height =DEFAULT_BACKSCROLL ; + vt->image_update = image_update; + vt->out_flush = out_flush; +/* set current text attributes to default */ + vt->t_attrib =TEXT_ATTRIBUTES_DEFAULT ; +vt100_set_image (vt, image); +} +static bool vc_chr_open (Chardev *chr,ChardevBackend *backend,Error **errp) {ChardevVC *vc = backend->u.vc.data;
@@ -1240,22 +1264,17 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp) s =QEMU_TEXT_CONSOLE (object_new (TYPE_QEMU_FIXED_TEXT_CONSOLE )); } -QTAILQ_INSERT_HEAD (&vt100s, &s->vt, list); -fifo8_create (&s->vt.out_fifo,16 ); - s->vt.total_height =DEFAULT_BACKSCROLL ;dpy_gfx_replace_surface (QEMU_CONSOLE (s),qemu_create_displaysurface (width, height)); - s->vt.image_update = text_console_image_update; - s->vt.out_flush = text_console_out_flush; - - s->chr = chr; - drv->console = s;if (vc->has_encoding) { - drv->encoding = s->vt.encoding = vc->encoding; + drv->encoding = vc->encoding; } +vt100_init (&s->vt,QEMU_CONSOLE (s)->surface->image, + drv->encoding, + text_console_image_update, + text_console_out_flush); -/* set current text attributes to default */ - s->vt.t_attrib =TEXT_ATTRIBUTES_DEFAULT ; -vt100_set_image (&s->vt,QEMU_CONSOLE (s)->surface->image); + s->chr = chr; + drv->console = s;if (chr->label) {char *msg;
Signature · 1 line
2.54.0
[PULL v2 18/33] ui/console: remove console_ch_t typedef and console_write_ch()
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Since commit e2f82e924d05 ("console: purge curses bits from console.h"), console_ch_t is a plain uint32_t typedef and console_write_ch() is a trivial assignment (*dest = ch). These abstractions were originally needed because console_ch_t was the curses chtype when CONFIG_CURSES was enabled, and console_write_ch() handled VGA-to-curses character translation. That commit moved the curses logic into curses_update(), making the typedef and helper dead abstractions.
Replace console_ch_t with uint32_t and console_write_ch() calls with direct assignments.
--- include/ui/console.h | 9 +-------- hw/display/jazz_led.c | 10 +++++----- hw/display/vga.c | 16 ++++++++-------- hw/display/virtio-gpu-base.c | 2 +- hw/display/virtio-vga.c | 2 +- hw/display/vmware_vga.c | 2 +- ui/console-vc.c | 11 +++++------ ui/console.c | 2 +- ui/curses.c | 6 +++--- 9 files changed, 26 insertions(+), 34 deletions(-)
include/ui/console.h +1 -8
@@ -336,13 +336,6 @@ int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx);bool console_has_gl (QemuConsole *con); -typedef uint32_t console_ch_t ; - -static inline void console_write_ch (console_ch_t *dest,uint32_t ch) -{ - *dest = ch; -} -enum {GRAPHIC_FLAGS_NONE =0 ,/* require a console/display with GL callbacks */
@@ -377,7 +370,7 @@ void graphic_console_close(QemuConsole *con);void graphic_hw_update (QemuConsole *con);void graphic_hw_update_done (QemuConsole *con);void graphic_hw_invalidate (QemuConsole *con); -void graphic_hw_text_update (QemuConsole *con,console_ch_t *chardata); +void graphic_hw_text_update (QemuConsole *con,uint32_t *chardata);void graphic_hw_gl_block (QemuConsole *con,bool block);void qemu_console_early_init (void );
hw/display/jazz_led.c +5 -5
@@ -228,7 +228,7 @@ static void jazz_led_invalidate_display(void *opaque) s->state |=REDRAW_SEGMENTS |REDRAW_BACKGROUND ; } -static void jazz_led_text_update (void *opaque,console_ch_t *chardata) +static void jazz_led_text_update (void *opaque,uint32_t *chardata) {LedState *s = opaque;char buf[3 ];
@@ -238,10 +238,10 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)/* TODO: draw the segments */ snprintf (buf,3 ,"%02hhx" , s->segments); -console_write_ch (chardata++,ATTR2CHTYPE (buf[0 ],QEMU_COLOR_BLUE , -QEMU_COLOR_BLACK ,1 )); -console_write_ch (chardata++,ATTR2CHTYPE (buf[1 ],QEMU_COLOR_BLUE , -QEMU_COLOR_BLACK ,1 )); + *chardata++ =ATTR2CHTYPE (buf[0 ],QEMU_COLOR_BLUE , +QEMU_COLOR_BLACK ,1 ); + *chardata++ =ATTR2CHTYPE (buf[1 ],QEMU_COLOR_BLUE , +QEMU_COLOR_BLACK ,1 );dpy_text_update (s->con,0 ,0 ,2 ,1 ); }
hw/display/vga.c +8 -8
@@ -1901,13 +1901,13 @@ static void vga_reset(void *opaque) ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))/* relay text rendering to the display driver * instead of doing a full vga_update_display() */ -static void vga_update_text (void *opaque,console_ch_t *chardata) +static void vga_update_text (void *opaque,uint32_t *chardata) {VGACommonState *s = opaque;int graphic_mode, i, cursor_offset, cursor_visible;int cw, cheight, width, height, size, c_min, c_max;uint32_t *src; -console_ch_t *dst, val; +uint32_t *dst, val;char msg_buffer[80 ];int full_update =0 ;
@@ -2007,14 +2007,14 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)if (full_update) {for (i =0 ; i < size; src ++, dst ++, i ++) -console_write_ch (dst,VMEM2CHTYPE (le32_to_cpu (*src))); + *dst =VMEM2CHTYPE (le32_to_cpu (*src));dpy_text_update (s->con,0 ,0 , width, height); }else { c_max =0 ;for (i =0 ; i < size; src ++, dst ++, i ++) { -console_write_ch (&val,VMEM2CHTYPE (le32_to_cpu (*src))); + val =VMEM2CHTYPE (le32_to_cpu (*src));if (*dst != val) { *dst = val; c_max = i;
@@ -2023,7 +2023,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata) } c_min = i;for (; i < size; src ++, dst ++, i ++) { -console_write_ch (&val,VMEM2CHTYPE (le32_to_cpu (*src))); + val =VMEM2CHTYPE (le32_to_cpu (*src));if (*dst != val) { *dst = val; c_max = i;
@@ -2061,14 +2061,14 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)dpy_text_resize (s->con, s->last_width, height);for (dst = chardata, i =0 ; i < s->last_width * height; i ++) -console_write_ch (dst ++,' ' ); + *dst++ =' ' ; size =strlen (msg_buffer); width = (s->last_width - size) /2 ; dst = chardata + s->last_width + width;for (i =0 ; i < size; i ++) -console_write_ch (dst ++,ATTR2CHTYPE (msg_buffer[i],QEMU_COLOR_BLUE , -QEMU_COLOR_BLACK ,1 )); + *dst++ =ATTR2CHTYPE (msg_buffer[i],QEMU_COLOR_BLUE , +QEMU_COLOR_BLACK ,1 );dpy_text_update (s->con,0 ,0 , s->last_width, height); }
hw/display/virtio-gpu-base.c +1 -1
@@ -88,7 +88,7 @@ static bool virtio_gpu_update_display(void *opaque)return true; } -static void virtio_gpu_text_update (void *opaque,console_ch_t *chardata) +static void virtio_gpu_text_update (void *opaque,uint32_t *chardata) { }
hw/display/virtio-vga.c +1 -1
@@ -31,7 +31,7 @@ static bool virtio_vga_base_update_display(void *opaque) } } -static void virtio_vga_base_text_update (void *opaque,console_ch_t *chardata) +static void virtio_vga_base_text_update (void *opaque,uint32_t *chardata) {VirtIOVGABase *vvga = opaque;VirtIOGPUBase *g = vvga->vgpu;
hw/display/vmware_vga.c +1 -1
@@ -1184,7 +1184,7 @@ static void vmsvga_invalidate_display(void *opaque) s->invalidated =1 ; } -static void vmsvga_text_update (void *opaque,console_ch_t *chardata) +static void vmsvga_text_update (void *opaque,uint32_t *chardata) {struct vmsvga_state_s *s = opaque;
ui/console-vc.c +5 -6
@@ -386,7 +386,7 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)vt100_keysym (&s->vt, keysym); } -static void text_console_update (void *opaque,console_ch_t *chardata) +static void text_console_update (void *opaque,uint32_t *chardata) {QemuTextConsole *s =QEMU_TEXT_CONSOLE (opaque);int i, j, src;
@@ -396,11 +396,10 @@ static void text_console_update(void *opaque, console_ch_t *chardata) chardata += s->vt.text_y[0 ] * s->vt.width;for (i = s->vt.text_y[0 ]; i <= s->vt.text_y[1 ]; i ++)for (j =0 ; j < s->vt.width; j++, src++) { -console_write_ch (chardata ++, -ATTR2CHTYPE (s->vt.cells[src].ch, - s->vt.cells[src].t_attrib.fgcol, - s->vt.cells[src].t_attrib.bgcol, - s->vt.cells[src].t_attrib.bold)); + *chardata++ =ATTR2CHTYPE (s->vt.cells[src].ch, + s->vt.cells[src].t_attrib.fgcol, + s->vt.cells[src].t_attrib.bgcol, + s->vt.cells[src].t_attrib.bold); }dpy_text_update (QEMU_CONSOLE (s), s->vt.text_x[0 ], s->vt.text_y[0 ], s->vt.text_x[1 ] - s->vt.text_x[0 ], i - s->vt.text_y[0 ]);
ui/console.c +1 -1
@@ -210,7 +210,7 @@ void graphic_hw_invalidate(QemuConsole *con) } } -void graphic_hw_text_update (QemuConsole *con,console_ch_t *chardata) +void graphic_hw_text_update (QemuConsole *con,uint32_t *chardata) {if (con && con->hw_ops->text_update) { con->hw_ops->text_update (con->hw, chardata);
ui/curses.c +3 -3
@@ -57,7 +57,7 @@ enum maybe_keycode { };static DisplayChangeListener *dcl; -static console_ch_t *screen; +static uint32_t *screen;static WINDOW *screenpad =NULL ;static int width, height, gwidth, gheight, invalidate;static int px, py, sminx, sminy, smaxx, smaxy;
@@ -68,7 +68,7 @@ static cchar_t *vga_to_curses;static void curses_update (DisplayChangeListener *dcl,int x,int y,int w,int h) { -console_ch_t *line; +uint32_t *line; g_autofree cchar_t *curses_line = g_new(cchar_t, width);wchar_t wch[CCHARW_MAX ];attr_t attrs;
@@ -796,7 +796,7 @@ static void curses_display_init(DisplayState *ds, DisplayOptions *opts)if (opts->u.curses.charset) { font_charset = opts->u.curses.charset; } - screen =g_new0 (console_ch_t,160 *100 ); + screen =g_new0 (uint32_t,160 *100 ); vga_to_curses =g_new0 (cchar_t,256 );curses_setup ();curses_keyboard_setup ();
Signature · 1 line
2.54.0
[PULL v2 16/33] ui/console-vc: extract vt100_keysym() from qemu_text_console_handle_keysym()
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Move the keysym handling logic out of qemu_text_console_handle_keysym() into a new vt100_keysym() helper that operates on QemuVT100 directly, continuing the effort to decouple the VT100 layer from the console layer.
The echo path is updated to call vt100_input() instead of qemu_chr_write(), since the function no longer has direct access to the chardev.
--- ui/console-vc.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
ui/console-vc.c +18 -11
@@ -331,24 +331,25 @@ static void vt100_write(QemuVT100 *vt, const void *buf, size_t len) vt->out_flush (vt); } -/* called when an ascii key is pressed */ -void qemu_text_console_handle_keysym (QemuTextConsole *s,int keysym) +static int vt100_input (QemuVT100 *vt,const uint8_t *buf,int len); + +static void vt100_keysym (QemuVT100 *vt,int keysym) {uint8_t buf[16 ], *q;int c;switch (keysym) {case QEMU_KEY_CTRL_UP : -vt100_scroll (&s->vt,-1 ); +vt100_scroll (vt,-1 );break ;case QEMU_KEY_CTRL_DOWN : -vt100_scroll (&s->vt,1 ); +vt100_scroll (vt,1 );break ;case QEMU_KEY_CTRL_PAGEUP : -vt100_scroll (&s->vt,-10 ); +vt100_scroll (vt,-10 );break ;case QEMU_KEY_CTRL_PAGEDOWN : -vt100_scroll (&s->vt,10 ); +vt100_scroll (vt,10 );break ;default :/* convert the QEMU keysym to VT100 key string */
@@ -365,18 +366,24 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) *q++ ='\033' ; *q++ ='[' ; *q++ = keysym &0xff ; - }else if (s->vt.echo && (keysym =='\r' || keysym =='\n' )) { -qemu_chr_write (s->chr, (uint8_t *)"\r" ,1 , true); + }else if (vt->echo && (keysym =='\r' || keysym =='\n' )) { +vt100_input (vt, (uint8_t *)"\r" ,1 ); *q++ ='\n' ; }else { *q++ = keysym; } -if (s->vt.echo) { -qemu_chr_write (s->chr, buf, q - buf, true); +if (vt->echo) { +vt100_input (vt, buf, q - buf); } -vt100_write (&s->vt, buf, q - buf); +vt100_write (vt, buf, q - buf);break ; } + +} +/* called when an ascii key is pressed */ +void qemu_text_console_handle_keysym (QemuTextConsole *s,int keysym) +{ +vt100_keysym (&s->vt, keysym); }static void text_console_update (void *opaque,console_ch_t *chardata)
Signature · 1 line
2.54.0
[PULL v2 13/33] ui/console-vc: add UTF-8 input decoding with CP437 rendering
In reply to [email protected]From: Marc-André Lureau <[email protected]>
The text console receives bytes that may be UTF-8 encoded (e.g. from a guest running a modern distro), but currently treats each byte as a raw character index into the VGA/CP437 font, producing garbled output for any multi-byte sequence.
Add a UTF-8 decoder using Bjoern Hoehrmann's DFA. The DFA inherently rejects overlong encodings, surrogates, and codepoints above U+10FFFF. Completed codepoints are then mapped to CP437, unmappable characters are displayed as '?'.
Note that QEMU has a "buffered" utf8 decoder in util/unicode.c, but it is not a good fit for byte-per-byte decoding.
--- ui/cp437.h | 13 +++ ui/console-vc.c | 59 ++++++++++++++ ui/cp437.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++++ ui/meson.build | 2 +- 4 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 ui/cp437.h create mode 100644 ui/cp437.c
ui/cp437.h new file +13 -0
@@ -0,0 +1,13 @@ +/* +* SPDX-License-Identifier: GPL-2.0-or-later +* +* Copyright (c) QEMU contributors +*/ +#ifndef QEMU_CP437_H +#define QEMU_CP437_H + +#include <stdint.h> + +int unicode_to_cp437 (uint32_t codepoint); + +#endif /* QEMU_CP437_H */
ui/console-vc.c +59 -0
83 lines not on this page · raw message
ui/cp437.c new file +205 -0
205 lines not on this page · raw message
ui/meson.build +1 -1
@@ -18,7 +18,7 @@ system_ss.add(files( 'util.c', 'vgafont.c', )) -system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: files('console-vc-stubs.c')) +system_ss.add(when: pixman, if_true: files('console-vc.c', 'cp437.c'), if_false: files('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c')) endif
Signature · 1 line
2.54.0
[PULL v2 14/33] ui/console-vc: move VT100 state machine and output FIFO into QemuVT100
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Move the terminal escape sequence parser state (TTYState, esc_params, text attributes, saved cursor position) and the output FIFO from VCChardev/QemuTextConsole into QemuVT100. Rename the corresponding functions from vc_* to vt100_* to reflect they now operate on the VT100 layer directly, removing the indirection through vc->console->vt.
Add an out_flush callback to QemuVT100 so vt100_write() can flush output without knowing about QemuTextConsole, and move FIFO/VT100 initialization from qemu_text_console_init() to vc_chr_open() where the callback can be wired up.
This continues the decoupling of VT100 terminal emulation from the chardev layer, making QemuVT100 a self-contained terminal emulator.
--- ui/console-vc.c | 382 +++++++++++++++++++++++------------------------- 1 file changed, 184 insertions(+), 198 deletions(-)
ui/console-vc.c +184 -198
@@ -58,6 +58,7 @@ struct QemuVT100 {pixman_image_t *image;void (*image_update)(QemuVT100 *vt,int x,int y,int width,int height); +ChardevVCEncoding encoding;int width;int height;int total_height;
@@ -74,6 +75,18 @@ struct QemuVT100 {int update_x1;int update_y1; +enum TTYState state; +int esc_params[MAX_ESC_PARAMS ]; +int nb_esc_params; +uint32_t utf8_state;/* UTF-8 DFA decoder state */ +uint32_t utf8_codepoint;/* accumulated UTF-8 code point */ +TextAttributes t_attrib;/* currently active text attributes */ +TextAttributes t_attrib_saved; +int x_saved, y_saved; +/* fifo for key pressed */ +Fifo8 out_fifo; +void (*out_flush)(QemuVT100 *vt); +QTAILQ_ENTRY (QemuVT100) list; };
@@ -85,8 +98,6 @@ typedef struct QemuTextConsole {QemuVT100 vt;Chardev *chr; -/* fifo for key pressed */ -Fifo8 out_fifo; } QemuTextConsole;typedef QemuConsoleClass QemuTextConsoleClass ;
@@ -103,17 +114,9 @@ OBJECT_DEFINE_TYPE(QemuFixedTextConsole, qemu_fixed_text_console, QEMU_FIXED_TEXstruct VCChardev {Chardev parent; -QemuTextConsole *console; -enum TTYState state; -int esc_params[MAX_ESC_PARAMS ]; -int nb_esc_params; -uint32_t utf8_state;/* UTF-8 DFA decoder state */ -uint32_t utf8_codepoint;/* accumulated UTF-8 code point */ -TextAttributes t_attrib;/* currently active text attributes */ -TextAttributes t_attrib_saved; -int x_saved, y_saved;ChardevVCEncoding encoding; +QemuTextConsole *console; };typedef struct VCChardev VCChardev ;
@@ -302,36 +305,35 @@ static void vt100_scroll(QemuVT100 *vt, int ydelta)vt100_refresh (vt); } -static void qemu_text_console_flush (QemuTextConsole *s) +static void qemu_text_console_out_flush (QemuTextConsole *s) {uint32_t len, avail; len =qemu_chr_be_can_write (s->chr); - avail =fifo8_num_used (&s->out_fifo); + avail =fifo8_num_used (&s->vt.out_fifo);while (len >0 && avail >0 ) {const uint8_t *buf;uint32_t size; - buf =fifo8_pop_bufptr (&s->out_fifo,MIN (len, avail), &size); + buf =fifo8_pop_bufptr (&s->vt.out_fifo,MIN (len, avail), &size);qemu_chr_be_write (s->chr, buf, size); len =qemu_chr_be_can_write (s->chr); avail -= size; } } -static void qemu_text_console_write (QemuTextConsole *s,const void *buf,size_t len) +static void vt100_write (QemuVT100 *vt,const void *buf,size_t len) {uint32_t num_free; - num_free =fifo8_num_free (&s->out_fifo); -fifo8_push_all (&s->out_fifo, buf,MIN (num_free, len)); -qemu_text_console_flush (s); + num_free =fifo8_num_free (&vt->out_fifo); +fifo8_push_all (&vt->out_fifo, buf,MIN (num_free, len)); + vt->out_flush (vt); }/* called when an ascii key is pressed */ void qemu_text_console_handle_keysym (QemuTextConsole *s,int keysym) { -QemuVT100 *vt = &s->vt;uint8_t buf[16 ], *q;int c;
@@ -363,16 +365,16 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) *q++ ='\033' ; *q++ ='[' ; *q++ = keysym &0xff ; - }else if (vt->echo && (keysym =='\r' || keysym =='\n' )) { + }else if (s->vt.echo && (keysym =='\r' || keysym =='\n' )) {qemu_chr_write (s->chr, (uint8_t *)"\r" ,1 , true); *q++ ='\n' ; }else { *q++ = keysym; } -if (vt->echo) { +if (s->vt.echo) {qemu_chr_write (s->chr, buf, q - buf, true); } -qemu_text_console_write (s, buf, q - buf); +vt100_write (&s->vt, buf, q - buf);break ; } }
@@ -380,30 +382,29 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)static void text_console_update (void *opaque,console_ch_t *chardata) {QemuTextConsole *s =QEMU_TEXT_CONSOLE (opaque); -QemuVT100 *vt = &s->vt;int i, j, src; -if (vt->text_x[0 ] <= vt->text_x[1 ]) { - src = (vt->y_base + vt->text_y[0 ]) * vt->width; - chardata += vt->text_y[0 ] * vt->width; -for (i = vt->text_y[0 ]; i <= vt->text_y[1 ]; i ++) -for (j =0 ; j < vt->width; j++, src++) { +if (s->vt.text_x[0 ] <= s->vt.text_x[1 ]) { + src = (s->vt.y_base + s->vt.text_y[0 ]) * s->vt.width; + chardata += s->vt.text_y[0 ] * s->vt.width; +for (i = s->vt.text_y[0 ]; i <= s->vt.text_y[1 ]; i ++) +for (j =0 ; j < s->vt.width; j++, src++) {console_write_ch (chardata ++, -ATTR2CHTYPE (vt->cells[src].ch, - vt->cells[src].t_attrib.fgcol, - vt->cells[src].t_attrib.bgcol, - vt->cells[src].t_attrib.bold)); +ATTR2CHTYPE (s->vt.cells[src].ch, + s->vt.cells[src].t_attrib.fgcol, + s->vt.cells[src].t_attrib.bgcol, + s->vt.cells[src].t_attrib.bold)); } -dpy_text_update (QEMU_CONSOLE (s), vt->text_x[0 ], vt->text_y[0 ], - vt->text_x[1 ] - vt->text_x[0 ], i - vt->text_y[0 ]); - vt->text_x[0 ] = vt->width; - vt->text_y[0 ] = vt->height; - vt->text_x[1 ] =0 ; - vt->text_y[1 ] =0 ; +dpy_text_update (QEMU_CONSOLE (s), s->vt.text_x[0 ], s->vt.text_y[0 ], + s->vt.text_x[1 ] - s->vt.text_x[0 ], i - s->vt.text_y[0 ]); + s->vt.text_x[0 ] = s->vt.width; + s->vt.text_y[0 ] = s->vt.height; + s->vt.text_x[1 ] =0 ; + s->vt.text_y[1 ] =0 ; } -if (vt->cursor_invalidate) { -dpy_text_cursor (QEMU_CONSOLE (s), vt->x, vt->y); - vt->cursor_invalidate =0 ; +if (s->vt.cursor_invalidate) { +dpy_text_cursor (QEMU_CONSOLE (s), s->vt.x, s->vt.y); + s->vt.cursor_invalidate =0 ; } }
@@ -492,103 +493,101 @@ static void vt100_put_lf(QemuVT100 *vt)* NOTE: I know this code is not very efficient (checking every color for it * self) but it is more readable and better maintainable. */ -static void vc_handle_escape (VCChardev *vc) +static void vt100_handle_escape (QemuVT100 *vt) {int i; -for (i =0 ; i < vc->nb_esc_params; i++) { -switch (vc->esc_params[i]) { +for (i =0 ; i < vt->nb_esc_params; i++) { +switch (vt->esc_params[i]) {case 0 :/* reset all console attributes to default */ - vc->t_attrib =TEXT_ATTRIBUTES_DEFAULT ; + vt->t_attrib =TEXT_ATTRIBUTES_DEFAULT ;break ;case 1 : - vc->t_attrib.bold =1 ; + vt->t_attrib.bold =1 ;break ;case 4 : - vc->t_attrib.uline =1 ; + vt->t_attrib.uline =1 ;break ;case 5 : - vc->t_attrib.blink =1 ; + vt->t_attrib.blink =1 ;break ;case 7 : - vc->t_attrib.invers =1 ; + vt->t_attrib.invers =1 ;break ;case 8 : - vc->t_attrib.unvisible =1 ; + vt->t_attrib.unvisible =1 ;break ;case 22 : - vc->t_attrib.bold =0 ; + vt->t_attrib.bold =0 ;break ;case 24 : - vc->t_attrib.uline =0 ; + vt->t_attrib.uline =0 ;break ;case 25 : - vc->t_attrib.blink =0 ; + vt->t_attrib.blink =0 ;break ;case 27 : - vc->t_attrib.invers =0 ; + vt->t_attrib.invers =0 ;break ;case 28 : - vc->t_attrib.unvisible =0 ; + vt->t_attrib.unvisible =0 ;break ;/* set foreground color */ case 30 : - vc->t_attrib.fgcol =QEMU_COLOR_BLACK ; + vt->t_attrib.fgcol =QEMU_COLOR_BLACK ;break ;case 31 : - vc->t_attrib.fgcol =QEMU_COLOR_RED ; + vt->t_attrib.fgcol =QEMU_COLOR_RED ;break ;case 32 : - vc->t_attrib.fgcol =QEMU_COLOR_GREEN ; + vt->t_attrib.fgcol =QEMU_COLOR_GREEN ;break ;case 33 : - vc->t_attrib.fgcol =QEMU_COLOR_YELLOW ; + vt->t_attrib.fgcol =QEMU_COLOR_YELLOW ;break ;case 34 : - vc->t_attrib.fgcol =QEMU_COLOR_BLUE ; + vt->t_attrib.fgcol =QEMU_COLOR_BLUE ;break ;case 35 : - vc->t_attrib.fgcol =QEMU_COLOR_MAGENTA ; + vt->t_attrib.fgcol =QEMU_COLOR_MAGENTA ;break ;case 36 : - vc->t_attrib.fgcol =QEMU_COLOR_CYAN ; + vt->t_attrib.fgcol =QEMU_COLOR_CYAN ;break ;case 37 : - vc->t_attrib.fgcol =QEMU_COLOR_WHITE ; + vt->t_attrib.fgcol =QEMU_COLOR_WHITE ;break ;/* set background color */ case 40 : - vc->t_attrib.bgcol =QEMU_COLOR_BLACK ; + vt->t_attrib.bgcol =QEMU_COLOR_BLACK ;break ;case 41 : - vc->t_attrib.bgcol =QEMU_COLOR_RED ; + vt->t_attrib.bgcol =QEMU_COLOR_RED ;break ;case 42 : - vc->t_attrib.bgcol =QEMU_COLOR_GREEN ; + vt->t_attrib.bgcol =QEMU_COLOR_GREEN ;break ;case 43 : - vc->t_attrib.bgcol =QEMU_COLOR_YELLOW ; + vt->t_attrib.bgcol =QEMU_COLOR_YELLOW ;break ;case 44 : - vc->t_attrib.bgcol =QEMU_COLOR_BLUE ; + vt->t_attrib.bgcol =QEMU_COLOR_BLUE ;break ;case 45 : - vc->t_attrib.bgcol =QEMU_COLOR_MAGENTA ; + vt->t_attrib.bgcol =QEMU_COLOR_MAGENTA ;break ;case 46 : - vc->t_attrib.bgcol =QEMU_COLOR_CYAN ; + vt->t_attrib.bgcol =QEMU_COLOR_CYAN ;break ;case 47 : - vc->t_attrib.bgcol =QEMU_COLOR_WHITE ; + vt->t_attrib.bgcol =QEMU_COLOR_WHITE ;break ; } } } -static void vc_update_xy (VCChardev *vc,int x,int y) +static void vt100_update_xy (QemuVT100 *vt,int x,int y) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt;TextCell *c;int y1, y2;
@@ -609,14 +608,12 @@ static void vc_update_xy(VCChardev *vc, int x, int y) c = &vt->cells[y1 * vt->width + x];vt100_putcharxy (vt, x, y2, c->ch, &(c->t_attrib)); -vt100_invalidate_xy (&s->vt, x, y2); +vt100_invalidate_xy (vt, x, y2); } } -static void vc_clear_xy (VCChardev *vc,int x,int y) +static void vt100_clear_xy (QemuVT100 *vt,int x,int y) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt;int y1 = (vt->y_base + y) % vt->total_height;if (x >= vt->width) { x = vt->width -1 ;
@@ -624,7 +621,7 @@ static void vc_clear_xy(VCChardev *vc, int x, int y)TextCell *c = &vt->cells[y1 * vt->width + x]; c->ch =' ' ; c->t_attrib =TEXT_ATTRIBUTES_DEFAULT ; -vc_update_xy (vc, x, y); +vt100_update_xy (vt, x, y); }/*
@@ -667,10 +664,8 @@ static uint32_t bh_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t byte)return *state; } -static void vc_put_one (VCChardev *vc,int ch) +static void vt100_put_one (QemuVT100 *vt,int ch) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt;TextCell *c;int y1;if (vt->x >= vt->width) {
@@ -681,17 +676,14 @@ static void vc_put_one(VCChardev *vc, int ch) y1 = (vt->y_base + vt->y) % vt->total_height; c = &vt->cells[y1 * vt->width + vt->x]; c->ch = ch; - c->t_attrib = vc->t_attrib; -vc_update_xy (vc, vt->x, vt->y); + c->t_attrib = vt->t_attrib; +vt100_update_xy (vt, vt->x, vt->y); vt->x++; }/* set cursor, checking bounds */ -static void vc_set_cursor (VCChardev *vc,int x,int y) +static void vt100_set_cursor (QemuVT100 *vt,int x,int y) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt; -if (x <0 ) { x =0 ; }
@@ -715,10 +707,8 @@ static void vc_set_cursor(VCChardev *vc, int x, int y)* characters between the cursor and right margin move to the * left. Character attributes move with the characters. */ -static void vc_csi_P (struct VCChardev *vc,unsigned int nr) +static void vt100_csi_P (QemuVT100 *vt,unsigned int nr) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt;TextCell *c1, *c2;unsigned int x1, x2, y;unsigned int end, len;
@@ -742,12 +732,12 @@ static void vc_csi_P(struct VCChardev *vc, unsigned int nr) c2 = &vt->cells[y * vt->width + x2];memmove (c1, c2, len *sizeof (*c1));for (end = x1 + len; x1 < end; x1++) { -vc_update_xy (vc, x1, vt->y); +vt100_update_xy (vt, x1, vt->y); } }/* Clear the rest */ for (; x1 < vt->width; x1++) { -vc_clear_xy (vc, x1, vt->y); +vt100_clear_xy (vt, x1, vt->y); } }
@@ -757,10 +747,8 @@ static void vc_csi_P(struct VCChardev *vc, unsigned int nr)* blank characters. Text between the cursor and right margin moves to * the right. Characters scrolled past the right margin are lost. */ -static void vc_csi_at (struct VCChardev *vc,unsigned int nr) +static void vt100_csi_at (QemuVT100 *vt,unsigned int nr) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt;TextCell *c1, *c2;unsigned int x1, x2, y;unsigned int end, len;
@@ -784,59 +772,51 @@ static void vc_csi_at(struct VCChardev *vc, unsigned int nr) c2 = &vt->cells[y * vt->width + x2];memmove (c1, c2, len *sizeof (*c1));for (end = x1 + len; x1 < end; x1++) { -vc_update_xy (vc, x1, vt->y); +vt100_update_xy (vt, x1, vt->y); } }/* Insert blanks */ for (x1 = vt->x; x1 < vt->x + nr; x1++) { -vc_clear_xy (vc, x1, vt->y); +vt100_clear_xy (vt, x1, vt->y); } }/** -* vc_save_cursor() - saves cursor position and character attributes. +* vt100_save_cursor() - saves cursor position and character attributes. */ -static void vc_save_cursor (VCChardev *vc) +static void vt100_save_cursor (QemuVT100 *vt) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt; - - vc->x_saved = vt->x; - vc->y_saved = vt->y; - vc->t_attrib_saved = vc->t_attrib; + vt->x_saved = vt->x; + vt->y_saved = vt->y; + vt->t_attrib_saved = vt->t_attrib; }/** -* vc_restore_cursor() - restores cursor position and character +* vt100_restore_cursor() - restores cursor position and character * attributes from saved state. */ -static void vc_restore_cursor (VCChardev *vc) +static void vt100_restore_cursor (QemuVT100 *vt) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt; - - vt->x = vc->x_saved; - vt->y = vc->y_saved; - vc->t_attrib = vc->t_attrib_saved; + vt->x = vt->x_saved; + vt->y = vt->y_saved; + vt->t_attrib = vt->t_attrib_saved; } -static void vc_putchar (VCChardev *vc,int ch) +static void vt100_putchar (QemuVT100 *vt,int ch) { -QemuTextConsole *s = vc->console; -QemuVT100 *vt = &s->vt;int i;int x, y; g_autofree char *response = NULL; -switch (vc->state) { +switch (vt->state) {case TTY_STATE_NORM : -if (ch >=0x80 && vc->encoding ==CHARDEV_VC_ENCODING_UTF8 ) { -switch (bh_utf8_decode (&vc->utf8_state, &vc->utf8_codepoint, ch)) { +if (ch >=0x80 && vt->encoding ==CHARDEV_VC_ENCODING_UTF8 ) { +switch (bh_utf8_decode (&vt->utf8_state, &vt->utf8_codepoint, ch)) {case BH_UTF8_ACCEPT : -vc_put_one (vc,unicode_to_cp437 (vc->utf8_codepoint)); +vt100_put_one (vt,unicode_to_cp437 (vt->utf8_codepoint));break ;case BH_UTF8_REJECT : - vc->utf8_state =BH_UTF8_ACCEPT ; + vt->utf8_state =BH_UTF8_ACCEPT ;break ;default :/* Need more bytes */
@@ -844,14 +824,13 @@ static void vc_putchar(VCChardev *vc, int ch) }break ; } -/* ASCII byte: abort any pending UTF-8 sequence */ - vc->utf8_state =BH_UTF8_ACCEPT ; + vt->utf8_state =BH_UTF8_ACCEPT ;switch (ch) {case '\r' :/* carriage return */ vt->x =0 ;break ;case '\n' :/* newline */ -vt100_put_lf (&s->vt); +vt100_put_lf (vt);break ;case '\b' :/* backspace */ if (vt->x >0 )
@@ -875,95 +854,95 @@ static void vc_putchar(VCChardev *vc, int ch)/* SI (shift in), character set 0 (ignored) */ break ;case 27 :/* esc (introducing an escape sequence) */ - vc->state =TTY_STATE_ESC ; + vt->state =TTY_STATE_ESC ;break ;default : -vc_put_one (vc, ch); +vt100_put_one (vt, ch);break ; }break ;case TTY_STATE_ESC :/* check if it is a terminal escape sequence */ if (ch =='[' ) {for (i=0 ;i<MAX_ESC_PARAMS ;i++) - vc->esc_params[i] =0 ; - vc->nb_esc_params =0 ; - vc->state =TTY_STATE_CSI ; + vt->esc_params[i] =0 ; + vt->nb_esc_params =0 ; + vt->state =TTY_STATE_CSI ; }else if (ch =='(' ) { - vc->state =TTY_STATE_G0 ; + vt->state =TTY_STATE_G0 ; }else if (ch ==')' ) { - vc->state =TTY_STATE_G1 ; + vt->state =TTY_STATE_G1 ; }else if (ch ==']' || ch =='P' || ch =='X' || ch =='^' || ch =='_' ) {/* String sequences: OSC, DCS, SOS, PM, APC */ - vc->state =TTY_STATE_OSC ; + vt->state =TTY_STATE_OSC ; }else if (ch =='7' ) { -vc_save_cursor (vc); - vc->state =TTY_STATE_NORM ; +vt100_save_cursor (vt); + vt->state =TTY_STATE_NORM ; }else if (ch =='8' ) { -vc_restore_cursor (vc); - vc->state =TTY_STATE_NORM ; +vt100_restore_cursor (vt); + vt->state =TTY_STATE_NORM ; }else { - vc->state =TTY_STATE_NORM ; + vt->state =TTY_STATE_NORM ; }break ;case TTY_STATE_CSI :/* handle escape sequence parameters */ if (ch >='0' && ch <='9' ) { -if (vc->nb_esc_params <MAX_ESC_PARAMS ) { -int *param = &vc->esc_params[vc->nb_esc_params]; +if (vt->nb_esc_params <MAX_ESC_PARAMS ) { +int *param = &vt->esc_params[vt->nb_esc_params];int digit = (ch -'0' ); *param = (*param <= (INT_MAX - digit) /10 ) ? *param *10 + digit :INT_MAX ; } }else { -if (vc->nb_esc_params <MAX_ESC_PARAMS ) - vc->nb_esc_params++; +if (vt->nb_esc_params <MAX_ESC_PARAMS ) + vt->nb_esc_params++;if (ch ==';' || ch =='?' ) {break ; } -trace_console_putchar_csi (vc->esc_params[0 ], vc->esc_params[1 ], - ch, vc->nb_esc_params); - vc->state =TTY_STATE_NORM ; +trace_console_putchar_csi (vt->esc_params[0 ], vt->esc_params[1 ], + ch, vt->nb_esc_params); + vt->state =TTY_STATE_NORM ;switch (ch) {case 'A' :/* move cursor up */ -if (vc->esc_params[0 ] ==0 ) { - vc->esc_params[0 ] =1 ; +if (vt->esc_params[0 ] ==0 ) { + vt->esc_params[0 ] =1 ; } -vc_set_cursor (vc, vt->x, vt->y - vc->esc_params[0 ]); +vt100_set_cursor (vt, vt->x, vt->y - vt->esc_params[0 ]);break ;case 'B' :/* move cursor down */ -if (vc->esc_params[0 ] ==0 ) { - vc->esc_params[0 ] =1 ; +if (vt->esc_params[0 ] ==0 ) { + vt->esc_params[0 ] =1 ; } -vc_set_cursor (vc, vt->x, vt->y + vc->esc_params[0 ]); +vt100_set_cursor (vt, vt->x, vt->y + vt->esc_params[0 ]);break ;case 'C' :/* move cursor right */ -if (vc->esc_params[0 ] ==0 ) { - vc->esc_params[0 ] =1 ; +if (vt->esc_params[0 ] ==0 ) { + vt->esc_params[0 ] =1 ; } -vc_set_cursor (vc, vt->x + vc->esc_params[0 ], vt->y); +vt100_set_cursor (vt, vt->x + vt->esc_params[0 ], vt->y);break ;case 'D' :/* move cursor left */ -if (vc->esc_params[0 ] ==0 ) { - vc->esc_params[0 ] =1 ; +if (vt->esc_params[0 ] ==0 ) { + vt->esc_params[0 ] =1 ; } -vc_set_cursor (vc, vt->x - vc->esc_params[0 ], vt->y); +vt100_set_cursor (vt, vt->x - vt->esc_params[0 ], vt->y);break ;case 'G' :/* move cursor to column */ -vc_set_cursor (vc, vc->esc_params[0 ] -1 , vt->y); +vt100_set_cursor (vt, vt->esc_params[0 ] -1 , vt->y);break ;case 'f' :case 'H' :/* move cursor to row, column */ -vc_set_cursor (vc, vc->esc_params[1 ] -1 , vc->esc_params[0 ] -1 ); +vt100_set_cursor (vt, vt->esc_params[1 ] -1 , vt->esc_params[0 ] -1 );break ;case 'J' : -switch (vc->esc_params[0 ]) { +switch (vt->esc_params[0 ]) {case 0 :/* clear to end of screen */ for (y = vt->y; y < vt->height; y++) {
@@ -971,7 +950,7 @@ static void vc_putchar(VCChardev *vc, int ch)if (y == vt->y && x < vt->x) {continue ; } -vc_clear_xy (vc, x, y); +vt100_clear_xy (vt, x, y); } }break ;
@@ -982,7 +961,7 @@ static void vc_putchar(VCChardev *vc, int ch)if (y == vt->y && x > vt->x) {break ; } -vc_clear_xy (vc, x, y); +vt100_clear_xy (vt, x, y); } }break ;
@@ -990,62 +969,62 @@ static void vc_putchar(VCChardev *vc, int ch)/* clear entire screen */ for (y =0 ; y < vt->height; y++) {for (x =0 ; x < vt->width; x++) { -vc_clear_xy (vc, x, y); +vt100_clear_xy (vt, x, y); } }break ; }break ;case 'K' : -switch (vc->esc_params[0 ]) { +switch (vt->esc_params[0 ]) {case 0 :/* clear to eol */ for (x = vt->x; x < vt->width; x++) { -vc_clear_xy (vc, x, vt->y); +vt100_clear_xy (vt, x, vt->y); }break ;case 1 :/* clear from beginning of line */ for (x =0 ; x <= vt->x && x < vt->width; x++) { -vc_clear_xy (vc, x, vt->y); +vt100_clear_xy (vt, x, vt->y); }break ;case 2 :/* clear entire line */ for (x =0 ; x < vt->width; x++) { -vc_clear_xy (vc, x, vt->y); +vt100_clear_xy (vt, x, vt->y); }break ; }break ;case 'P' : -vc_csi_P (vc, vc->esc_params[0 ]); +vt100_csi_P (vt, vt->esc_params[0 ]);break ;case 'm' : -vc_handle_escape (vc); +vt100_handle_escape (vt);break ;case 'n' : -switch (vc->esc_params[0 ]) { +switch (vt->esc_params[0 ]) {case 5 :/* report console status (always succeed)*/ -qemu_text_console_write (s,"\033[0n" ,4 ); +vt100_write (vt,"\033[0n" ,4 );break ;case 6 :/* report cursor position */ response =g_strdup_printf ("\033[%d;%dR" , vt->y +1 , vt->x +1 ); -qemu_text_console_write (s, response,strlen (response)); +vt100_write (vt, response,strlen (response));break ; }break ;case 's' : -vc_save_cursor (vc); +vt100_save_cursor (vt);break ;case 'u' : -vc_restore_cursor (vc); +vt100_restore_cursor (vt);break ;case '@' : -vc_csi_at (vc, vc->esc_params[0 ]); +vt100_csi_at (vt, vt->esc_params[0 ]);break ;default :trace_console_putchar_unhandled (ch);
@@ -1057,10 +1036,10 @@ static void vc_putchar(VCChardev *vc, int ch)case TTY_STATE_OSC :/* Operating System Command: ESC ] ... BEL/ST */ if (ch =='\a' ) {/* BEL terminates OSC */ - vc->state =TTY_STATE_NORM ; + vt->state =TTY_STATE_NORM ; }else if (ch ==27 ) {/* ESC might start ST (ESC \) */ - vc->state =TTY_STATE_ESC ; + vt->state =TTY_STATE_ESC ; }/* All other bytes are silently consumed */ break ;
@@ -1071,7 +1050,7 @@ static void vc_putchar(VCChardev *vc, int ch)/* Latin-1 map */ break ; } - vc->state =TTY_STATE_NORM ; + vt->state =TTY_STATE_NORM ;break ; } }
@@ -1084,22 +1063,21 @@ static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len) {VCChardev *drv =VC_CHARDEV (chr);QemuTextConsole *s = drv->console; -QemuVT100 *vt = &s->vt;int i; - vt->update_x0 = vt->width *FONT_WIDTH ; - vt->update_y0 = vt->height *FONT_HEIGHT ; - vt->update_x1 =0 ; - vt->update_y1 =0 ; -vt100_show_cursor (vt,0 ); + s->vt.update_x0 = s->vt.width *FONT_WIDTH ; + s->vt.update_y0 = s->vt.height *FONT_HEIGHT ; + s->vt.update_x1 =0 ; + s->vt.update_y1 =0 ; +vt100_show_cursor (&s->vt,0 );for (i =0 ; i < len; i++) { -vc_putchar (drv, buf[i]); +vt100_putchar (&s->vt, buf[i]); } -vt100_show_cursor (vt,1 ); -if (vt->update_x0 < vt->update_x1) { -vt100_image_update (vt, vt->update_x0, vt->update_y0, - vt->update_x1 - vt->update_x0, - vt->update_y1 - vt->update_y0); +vt100_show_cursor (&s->vt,1 ); +if (s->vt.update_x0 < s->vt.update_x1) { +vt100_image_update (&s->vt, s->vt.update_x0, s->vt.update_y0, + s->vt.update_x1 - s->vt.update_x0, + s->vt.update_y1 - s->vt.update_y0); }return len; }
@@ -1168,9 +1146,6 @@ qemu_text_console_init(Object *obj) {QemuTextConsole *c =QEMU_TEXT_CONSOLE (obj); -QTAILQ_INSERT_HEAD (&vt100s, &c->vt, list); -fifo8_create (&c->out_fifo,16 ); - c->vt.total_height =DEFAULT_BACKSCROLL ;QEMU_CONSOLE (c)->hw_ops = &text_console_ops;QEMU_CONSOLE (c)->hw = c; }
@@ -1194,7 +1169,7 @@ static void vc_chr_accept_input(Chardev *chr) {VCChardev *drv =VC_CHARDEV (chr); -qemu_text_console_flush (drv->console); +qemu_text_console_out_flush (drv->console); }static void vc_chr_set_echo (Chardev *chr,bool echo)
@@ -1216,6 +1191,13 @@ static void text_console_image_update(QemuVT100 *vt, int x, int y, int width, indpy_gfx_update (QEMU_CONSOLE (console), x, y, width, height); } +static void text_console_out_flush (QemuVT100 *vt) +{ +QemuTextConsole *console =container_of (vt, QemuTextConsole, vt); + +qemu_text_console_out_flush (console); +} +static bool vc_chr_open (Chardev *chr,ChardevBackend *backend,Error **errp) {ChardevVC *vc = backend->u.vc.data;
@@ -1245,27 +1227,31 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp) s =QEMU_TEXT_CONSOLE (object_new (TYPE_QEMU_FIXED_TEXT_CONSOLE )); } +QTAILQ_INSERT_HEAD (&vt100s, &s->vt, list); +fifo8_create (&s->vt.out_fifo,16 ); + s->vt.total_height =DEFAULT_BACKSCROLL ;dpy_gfx_replace_surface (QEMU_CONSOLE (s),qemu_create_displaysurface (width, height)); s->vt.image_update = text_console_image_update; + s->vt.out_flush = text_console_out_flush; s->chr = chr; drv->console = s;if (vc->has_encoding) { - drv->encoding = vc->encoding; + drv->encoding = s->vt.encoding = vc->encoding; }/* set current text attributes to default */ - drv->t_attrib =TEXT_ATTRIBUTES_DEFAULT ; + s->vt.t_attrib =TEXT_ATTRIBUTES_DEFAULT ;vt100_set_image (&s->vt,QEMU_CONSOLE (s)->surface->image);if (chr->label) {char *msg; - drv->t_attrib.bgcol =QEMU_COLOR_BLUE ; + s->vt.t_attrib.bgcol =QEMU_COLOR_BLUE ; msg =g_strdup_printf ("%s console\r\n" , chr->label);qemu_chr_write (chr, (uint8_t *)msg,strlen (msg), true);g_free (msg); - drv->t_attrib =TEXT_ATTRIBUTES_DEFAULT ; + s->vt.t_attrib =TEXT_ATTRIBUTES_DEFAULT ; }qemu_chr_be_event (chr,CHR_EVENT_OPENED );
Signature · 1 line
2.54.0
[PULL v2 25/33] ui/vnc: add vnc-system unit, to allow different implementations
In reply to [email protected]From: Marc-André Lureau <[email protected]>
The qemu-vnc server will want to signal the XVP requests, let it have its own implementation.
--- ui/vnc.h | 4 ++++ ui/vnc-system.c | 19 +++++++++++++++++++ ui/vnc.c | 4 ++-- ui/meson.build | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 ui/vnc-system.c
ui/vnc.h +4 -0
@@ -648,4 +648,8 @@ void vnc_server_cut_text_caps(VncState *vs);void vnc_client_cut_text (VncState *vs,size_t len,uint8_t *text);void vnc_client_cut_text_ext (VncState *vs,int32_t len,uint32_t flags,uint8_t *data); +/* XVP events */ +void vnc_action_shutdown (VncState *vs); +void vnc_action_reset (VncState *vs); +#endif /* QEMU_VNC_H */
ui/vnc-system.c new file +19 -0
@@ -0,0 +1,19 @@ +/* +* QEMU VNC display driver +* +* SPDX-License-Identifier: GPL-2.0-or-later +*/ +#include "qemu/osdep.h" + +#include "ui/vnc.h" +#include "system/runstate.h" + +void vnc_action_shutdown (VncState *vs) +{ +qemu_system_powerdown_request (); +} + +void vnc_action_reset (VncState *vs) +{ +qemu_system_reset_request (SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET ); +}
ui/vnc.c +2 -2
@@ -2522,13 +2522,13 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)switch (action) {case VNC_XVP_ACTION_SHUTDOWN : -qemu_system_powerdown_request (); +vnc_action_shutdown (vs);break ;case VNC_XVP_ACTION_REBOOT :send_xvp_message (vs,VNC_XVP_CODE_FAIL );break ;case VNC_XVP_ACTION_RESET : -qemu_system_reset_request (SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET ); +vnc_action_reset (vs);break ;default :send_xvp_message (vs,VNC_XVP_CODE_FAIL );
ui/meson.build +1 -1
@@ -48,7 +48,7 @@ vnc_ss.add(files( vnc_ss.add(zlib, jpeg, png) vnc_ss.add(when: sasl, if_true: files('vnc-auth-sasl.c')) system_ss.add_all(when: [vnc, pixman], if_true: vnc_ss) -system_ss.add(when: vnc, if_false: files('vnc-stubs.c')) +system_ss.add(when: vnc, if_true: files('vnc-system.c'), if_false: files('vnc-stubs.c')) ui_modules = {}
Signature · 1 line
2.54.0
[PULL v2 24/33] ui/vnc: defer listener registration until the console is known
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Previously, the display change listener was registered early in vnc_display_new() without a console, requiring vnc_display_open() to conditionally unregister and re-register it when the actual console was resolved. Since vnc_display_new() and vnc_display_open() were merged in the previous commit, simply delay the registration and keyboard state initialization to vnc_display_open(), after the console has been looked up. This removes the conditional re-registration and simplifies the code.
--- ui/vnc.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
ui/vnc.c +3 -9
@@ -3457,8 +3457,6 @@ VncDisplay *vnc_display_new(const char *id, Error **errp)vnc_start_worker_thread (vd); -register_displaychangelistener (&vd->dcl); - vd->kbd =qkbd_state_init (vd->dcl.con); vd->vmstate_handler_entry =qemu_add_vm_change_state_handler ( &vmstate_change_handler, vd);
@@ -4269,13 +4267,9 @@ static bool vnc_display_open(VncDisplay *vd, Error **errp) con =qemu_console_lookup_default (); } -if (con != vd->dcl.con) { -qkbd_state_free (vd->kbd); -unregister_displaychangelistener (&vd->dcl); - vd->dcl.con = con; -register_displaychangelistener (&vd->dcl); - vd->kbd =qkbd_state_init (vd->dcl.con); - } + vd->dcl.con = con; +register_displaychangelistener (&vd->dcl); + vd->kbd =qkbd_state_init (vd->dcl.con);qkbd_state_set_delay (vd->kbd, key_delay_ms);if (saddr_list ==NULL ) {
Signature · 1 line
2.54.0
[PULL v2 20/33] ui/vnc: make the worker thread per-VncDisplay
In reply to [email protected]From: Marc-André Lureau <[email protected]>
The VNC encoding worker thread was using a single global queue shared across all VNC displays, with no way to stop it. This made it impossible to properly clean up resources when a VncDisplay is freed.
Move the VncJobQueue from a file-scoped global to a per-VncDisplay member, so each display owns its worker thread and queue. Add vnc_stop_worker_thread() to perform an orderly shutdown: signal the thread to exit, join it, and destroy the queue. The thread is now created as QEMU_THREAD_JOINABLE instead of QEMU_THREAD_DETACHED.
--- ui/vnc-jobs.h | 3 ++- ui/vnc.h | 2 ++ ui/vnc-jobs.c | 62 +++++++++++++++++++++++++++++++++------------------ ui/vnc.c | 3 ++- 4 files changed, 46 insertions(+), 24 deletions(-)
ui/vnc-jobs.h +2 -1
@@ -37,7 +37,8 @@ void vnc_job_push(VncJob *job);void vnc_jobs_join (VncState *vs);void vnc_jobs_consume_buffer (VncState *vs); -void vnc_start_worker_thread (void ); +void vnc_start_worker_thread (VncDisplay *vd); +void vnc_stop_worker_thread (VncDisplay *vd);/* Locks */ static inline int vnc_trylock_display (VncDisplay *vd)
ui/vnc.h +2 -0
@@ -62,6 +62,7 @@typedef struct VncState VncState ;typedef struct VncJob VncJob ; +typedef struct VncJobQueue VncJobQueue ;typedef struct VncRect VncRect ;typedef struct VncRectEntry VncRectEntry ;
@@ -158,6 +159,7 @@ struct VncDisplayint ledstate;QKbdState *kbd;QemuMutex mutex; +VncJobQueue *queue;int cursor_msize;uint8_t *cursor_mask;
ui/vnc-jobs.c +40 -22
134 lines not on this page · raw message
ui/vnc.c +2 -1
@@ -3457,7 +3457,7 @@ void vnc_display_init(const char *id, Error **errp) vd->share_policy =VNC_SHARE_POLICY_ALLOW_EXCLUSIVE ; vd->connections_limit =32 ; -vnc_start_worker_thread (); +vnc_start_worker_thread (vd);register_displaychangelistener (&vd->dcl); vd->kbd =qkbd_state_init (vd->dcl.con);
@@ -3513,6 +3513,7 @@ static void vnc_display_free(VncDisplay *vd)assert (QTAILQ_EMPTY (&vd->clients)); +vnc_stop_worker_thread (vd);vnc_display_close (vd);unregister_displaychangelistener (&vd->dcl);qkbd_state_free (vd->kbd);
Signature · 1 line
2.54.0
[PULL v2 26/33] ui/console: simplify registering display/console change listener
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Introduce qemu_console_register_listener() which combines setting dcl->con, dcl->ops and calling register_displaychangelistener() into a single call. This removes repetitive boilerplate across all display backends and makes it harder to forget setting one of the fields.
Also move the early-return check in unregister_displaychangelistener() before the trace call, so that unregistering a never-registered listener (e.g. on error paths) does not dereference a NULL ops pointer.
--- include/ui/console.h | 6 ++++-- hw/display/qxl.c | 4 +--- ui/console.c | 11 ++++++++--- ui/curses.c | 9 +++------ ui/dbus-console.c | 6 ++---- ui/dbus-listener.c | 27 ++++++++------------------- ui/egl-headless.c | 4 +--- ui/gtk.c | 10 ++++------ ui/sdl2.c | 8 +++----- ui/spice-display.c | 8 +++----- ui/vnc.c | 11 ++++------- ui/cocoa.m | 13 ++++--------- 12 files changed, 45 insertions(+), 72 deletions(-)
include/ui/console.h +4 -2
@@ -291,10 +291,12 @@ struct DisplayGLCtx {DisplayState *init_displaystate (void ); -void register_displaychangelistener (DisplayChangeListener *dcl); +void qemu_console_register_listener (QemuConsole *con, +DisplayChangeListener *dcl, +const DisplayChangeListenerOps *ops);void update_displaychangelistener (DisplayChangeListener *dcl,uint64_t interval); -void unregister_displaychangelistener (DisplayChangeListener *dcl); +void qemu_console_unregister_listener (DisplayChangeListener *dcl);bool dpy_ui_info_supported (const QemuConsole *con);const QemuUIInfo *dpy_get_ui_info (const QemuConsole *con);
hw/display/qxl.c +1 -3
@@ -2251,9 +2251,7 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp)return ; } - qxl->ssd.dcl.ops = &display_listener_ops; - qxl->ssd.dcl.con = vga->con; -register_displaychangelistener (&qxl->ssd.dcl); +qemu_console_register_listener (vga->con, &qxl->ssd.dcl, &display_listener_ops); }static void qxl_realize_secondary (PCIDevice *dev,Error **errp)
ui/console.c +8 -3
@@ -572,10 +572,15 @@ dcl_set_graphic_cursor(DisplayChangeListener *dcl, QemuGraphicConsole *con) } } -void register_displaychangelistener (DisplayChangeListener *dcl) +void qemu_console_register_listener (QemuConsole *con, +DisplayChangeListener *dcl, +const DisplayChangeListenerOps *ops) {assert (!dcl->ds); + dcl->con = con; + dcl->ops = ops; +trace_displaychangelistener_register (dcl, dcl->ops->dpy_name); dcl->ds =get_alloc_displaystate ();QLIST_INSERT_HEAD (&dcl->ds->listeners, dcl, next);
@@ -600,10 +605,10 @@ void update_displaychangelistener(DisplayChangeListener *dcl, } } -void unregister_displaychangelistener (DisplayChangeListener *dcl) +void qemu_console_unregister_listener (DisplayChangeListener *dcl) {DisplayState *ds = dcl->ds; -trace_displaychangelistener_unregister (dcl, dcl->ops->dpy_name); +trace_displaychangelistener_unregister (dcl, dcl->ops ? dcl->ops->dpy_name :NULL );if (!ds) {return ; }
ui/curses.c +3 -6
@@ -324,9 +324,8 @@ static void curses_refresh(DisplayChangeListener *dcl)if (con) {erase ();wnoutrefresh (stdscr); -unregister_displaychangelistener (dcl); - dcl->con = con; -register_displaychangelistener (dcl); +qemu_console_unregister_listener (dcl); +qemu_console_register_listener (con, dcl, dcl->ops); invalidate =1 ; }
@@ -805,9 +804,7 @@ static void curses_display_init(DisplayState *ds, DisplayOptions *opts)curses_winch_init (); dcl =g_new0 (DisplayChangeListener,1 ); - dcl->con =qemu_console_lookup_default (); - dcl->ops = &dcl_ops; -register_displaychangelistener (dcl); +qemu_console_register_listener (qemu_console_lookup_default (), dcl, &dcl_ops); invalidate =1 ; }
ui/dbus-console.c +2 -4
@@ -143,7 +143,6 @@ dbus_display_console_init(DBusDisplayConsole *object)DBusDisplayConsole *ddc =DBUS_DISPLAY_CONSOLE (object); ddc->listeners =g_ptr_array_new_with_free_func (g_object_unref); - ddc->dcl.ops = &dbus_console_dcl_ops; } static void
@@ -151,7 +150,7 @@ dbus_display_console_dispose(GObject *object) {DBusDisplayConsole *ddc =DBUS_DISPLAY_CONSOLE (object); -unregister_displaychangelistener (&ddc->dcl); +qemu_console_unregister_listener (&ddc->dcl);g_clear_object (&ddc->iface_touch);g_clear_object (&ddc->iface_mouse);g_clear_object (&ddc->iface_kbd);
@@ -553,7 +552,6 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con)"g-object-path" , path, NULL); ddc->display = display; - ddc->dcl.con = con;/* handle errors, and skip non graphics? */ qemu_console_fill_device_address ( con, device_addr,sizeof (device_addr),NULL );
@@ -611,7 +609,7 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con) slot->tracking_id =-1 ; } -register_displaychangelistener (&ddc->dcl); +qemu_console_register_listener (con, &ddc->dcl, &dbus_console_dcl_ops); ddc->mouse_mode_notifier.notify = dbus_mouse_mode_change;qemu_add_mouse_mode_change_notifier (&ddc->mouse_mode_notifier);dbus_mouse_update_is_absolute (ddc);
ui/dbus-listener.c +8 -19
@@ -957,7 +957,7 @@ dbus_display_listener_dispose(GObject *object) {DBusDisplayListener *ddl =DBUS_DISPLAY_LISTENER (object); -unregister_displaychangelistener (&ddl->dcl); +qemu_console_unregister_listener (&ddl->dcl);g_clear_object (&ddl->conn);g_clear_pointer (&ddl->bus_name, g_free);g_clear_object (&ddl->proxy);
@@ -978,28 +978,12 @@ dbus_display_listener_dispose(GObject *object)G_OBJECT_CLASS (dbus_display_listener_parent_class)->dispose (object); } -static void -dbus_display_listener_constructed (GObject *object) -{ -DBusDisplayListener *ddl =DBUS_DISPLAY_LISTENER (object); - - ddl->dcl.ops = &dbus_dcl_ops; -#ifdef CONFIG_OPENGL -if (display_opengl) { - ddl->dcl.ops = &dbus_gl_dcl_ops; - } -#endif - -G_OBJECT_CLASS (dbus_display_listener_parent_class)->constructed (object); -} -static void dbus_display_listener_class_init (DBusDisplayListenerClass *klass) {GObjectClass *object_class =G_OBJECT_CLASS (klass); object_class->dispose = dbus_display_listener_dispose; - object_class->constructed = dbus_display_listener_constructed; } static void
@@ -1258,6 +1242,7 @@ dbus_display_listener_new(const char *bus_name, GDBusConnection *conn, DBusDisplayConsole *console) { +const DisplayChangeListenerOps *ops = &dbus_dcl_ops;DBusDisplayListener *ddl;QemuConsole *con;g_autoptr (GError) err =NULL ;
@@ -1290,8 +1275,12 @@ dbus_display_listener_new(const char *bus_name, con =qemu_console_lookup_by_index (dbus_display_console_get_index (console));assert (con); - ddl->dcl.con = con; -register_displaychangelistener (&ddl->dcl); +#ifdef CONFIG_OPENGL +if (display_opengl) { + ops = &dbus_gl_dcl_ops; + } +#endif +qemu_console_register_listener (con, &ddl->dcl, ops);return ddl; }
ui/egl-headless.c +1 -3
@@ -229,13 +229,11 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts) } edpy =g_new0 (egl_dpy,1 ); - edpy->dcl.con = con; - edpy->dcl.ops = &egl_ops; edpy->gls =qemu_gl_init_shader (); ctx =g_new0 (DisplayGLCtx,1 ); ctx->ops = &eglctx_ops;qemu_console_set_display_gl_ctx (con, ctx); -register_displaychangelistener (&edpy->dcl); +qemu_console_register_listener (con, &edpy->dcl, &egl_ops); } }
ui/gtk.c +4 -6
@@ -2251,6 +2251,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, QemuConsole *con, int idx, GSList *group, GtkWidget *view_menu) { + const DisplayChangeListenerOps *ops = &dcl_ops;bool zoom_to_fit = false;int i;
@@ -2275,7 +2276,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, vc->gfx.drawing_area =gtk_gl_area_new ();g_signal_connect (vc->gfx.drawing_area,"realize" ,G_CALLBACK (gl_area_realize), vc); - vc->gfx.dcl.ops = &dcl_gl_area_ops; + ops = &dcl_gl_area_ops; vc->gfx.dgc.ops = &gl_area_ctx_ops; }else {#ifdef CONFIG_X11
@@ -2290,7 +2291,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,#pragma GCC diagnostic ignored "-Wdeprecated-declarations"gtk_widget_set_double_buffered (vc->gfx.drawing_area, FALSE);#pragma GCC diagnostic pop - vc->gfx.dcl.ops = &dcl_egl_ops; + ops = &dcl_egl_ops; vc->gfx.dgc.ops = &egl_ctx_ops; vc->gfx.has_dmabuf =qemu_egl_has_dmabuf ();#else
@@ -2301,7 +2302,6 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,#endif { vc->gfx.drawing_area =gtk_drawing_area_new (); - vc->gfx.dcl.ops = &dcl_ops; }
@@ -2325,12 +2325,10 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, vc->tab_item, gtk_label_new(vc->label)); vc->gfx.kbd =qkbd_state_init (con); - vc->gfx.dcl.con = con; -if (display_opengl) {qemu_console_set_display_gl_ctx (con, &vc->gfx.dgc); } -register_displaychangelistener (&vc->gfx.dcl); +qemu_console_register_listener (con, &vc->gfx.dcl, ops);gd_connect_vc_gfx_signals (vc); group =gd_vc_menu_init (s, vc, idx, group, view_menu);
ui/sdl2.c +3 -5
@@ -934,6 +934,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);for (i =0 ; i < sdl2_num_outputs; i++) {QemuConsole *con =qemu_console_lookup_by_index (i); +const DisplayChangeListenerOps *ops = &dcl_2d_ops;assert (con !=NULL );if (!qemu_console_is_graphic (con) &&qemu_console_get_index (con) !=0 ) {
@@ -943,13 +944,11 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) sdl2_console[i].opts = o;#ifdef CONFIG_OPENGL sdl2_console[i].opengl = display_opengl; - sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops; sdl2_console[i].dgc.ops = display_opengl ? &gl_ctx_ops :NULL ; + ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;#else sdl2_console[i].opengl =0 ; - sdl2_console[i].dcl.ops = &dcl_2d_ops;#endif - sdl2_console[i].dcl.con = con; sdl2_console[i].kbd =qkbd_state_init (con);#ifdef CONFIG_OPENGL if (display_opengl) {
@@ -957,8 +956,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)sdl2_gl_console_init (&sdl2_console[i]); }#endif -register_displaychangelistener (&sdl2_console[i].dcl); - +qemu_console_register_listener (con, &sdl2_console[i].dcl, ops);#if defined(SDL_VIDEO_DRIVER_WINDOWS ) || defined(SDL_VIDEO_DRIVER_X11 )if (SDL_GetWindowWMInfo (sdl2_console[i].real_window, &info)) {#if defined(SDL_VIDEO_DRIVER_WINDOWS )
ui/spice-display.c +3 -5
@@ -1387,13 +1387,13 @@ static void qemu_spice_display_init_one(QemuConsole *con)SimpleSpiceDisplay *ssd =g_new0 (SimpleSpiceDisplay,1 );Error *err =NULL ;char device_address[256 ] ="" ; +const DisplayChangeListenerOps *ops = &display_listener_ops;qemu_spice_display_init_common (ssd); - ssd->dcl.ops = &display_listener_ops;#ifdef HAVE_SPICE_GL if (spice_opengl) { - ssd->dcl.ops = &display_listener_gl_ops; + ops = &display_listener_gl_ops; ssd->dgc.ops = &gl_ctx_ops; ssd->gl_unblock_bh =qemu_bh_new (qemu_spice_gl_unblock_bh, ssd); ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
@@ -1403,8 +1403,6 @@ static void qemu_spice_display_init_one(QemuConsole *con) ssd->have_scanout = false; }#endif - ssd->dcl.con = con; - ssd->qxl.base.sif = &dpy_interface.base;qemu_spice_add_display_interface (&ssd->qxl, con);
@@ -1422,7 +1420,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)if (spice_opengl) {qemu_console_set_display_gl_ctx (con, &ssd->dgc); } -register_displaychangelistener (&ssd->dcl); +qemu_console_register_listener (con, &ssd->dcl, ops); }void qemu_spice_display_init (void )
ui/vnc.c +4 -7
@@ -1860,10 +1860,9 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {QemuConsole *con =qemu_console_lookup_by_index (qcode -Q_KEY_CODE_1 );if (con) { -unregister_displaychangelistener (&vs->vd->dcl); +qemu_console_unregister_listener (&vs->vd->dcl);qkbd_state_switch_console (vs->vd->kbd, con); - vs->vd->dcl.con = con; -register_displaychangelistener (&vs->vd->dcl); +qemu_console_register_listener (con, &vs->vd->dcl, vs->vd->dcl.ops); }return ; }
@@ -3434,7 +3433,6 @@ VncDisplay *vnc_display_new(const char *id, Error **errp) vd =g_new0 (VncDisplay,1 );qemu_mutex_init (&vd->mutex); vd->id =g_strdup (id); - vd->dcl.ops = &dcl_ops;QTAILQ_INIT (&vd->clients); vd->expires =TIME_MAX ;
@@ -3524,7 +3522,7 @@ void vnc_display_free(VncDisplay *vd) }vnc_stop_worker_thread (vd); -unregister_displaychangelistener (&vd->dcl); +qemu_console_unregister_listener (&vd->dcl);qkbd_state_free (vd->kbd);qemu_del_vm_change_state_handler (vd->vmstate_handler_entry);kbd_layout_free (vd->kbd_layout);
@@ -4267,8 +4265,7 @@ static bool vnc_display_open(VncDisplay *vd, Error **errp) con =qemu_console_lookup_default (); } - vd->dcl.con = con; -register_displaychangelistener (&vd->dcl); +qemu_console_register_listener (con, &vd->dcl, &dcl_ops); vd->kbd =qkbd_state_init (vd->dcl.con);qkbd_state_set_delay (vd->kbd, key_delay_ms);
ui/cocoa.m +4 -9
@@ -93,9 +93,7 @@ static void cocoa_switch(DisplayChangeListener *dcl, .dpy_mouse_set = cocoa_mouse_set, .dpy_cursor_define = cocoa_cursor_define, }; -static DisplayChangeListener dcl = { - .ops = &dcl_ops, -}; +static DisplayChangeListener dcl; static QKbdState *kbd; static int cursor_hide = 1; static int left_command_key_enabled = 1;
@@ -425,8 +423,7 @@ - (void) selectConsoleLocked:(unsigned int)index unregister_displaychangelistener(&dcl); qkbd_state_switch_console(kbd, con); - dcl.con = con; - register_displaychangelistener(&dcl); + qemu_console_register_listener(con, &dcl, &dcl_ops); [self notifyMouseModeChange]; [self updateUIInfo]; }
@@ -2145,11 +2142,9 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts) add_console_menu_entries(); addRemovableDevicesMenuItems(); - dcl.con = qemu_console_lookup_default(); + qemu_console_register_listener(qemu_console_lookup_default(), + &dcl, &dcl_ops); kbd = qkbd_state_init(dcl.con); - - // register vga output callbacks - register_displaychangelistener(&dcl); qemu_add_mouse_mode_change_notifier(&mouse_mode_change_notifier); [cocoaView notifyMouseModeChange]; [cocoaView updateUIInfo];
Signature · 1 line
2.54.0
[PULL v2 22/33] ui/vnc: merge vnc_display_init() and vnc_display_open()
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Combine the two-step vnc_display_init()/vnc_display_open() sequence into a single vnc_display_new() function that returns VncDisplay*. This simplifies the API by making vnc_display_open() an internal detail and will allow further code simplification.
vnc_display_new() is moved to vnc.h, since it returns VncDisplay* now. Add vnc_display_free() for consistency, and it will be later used.
--- include/ui/console.h | 2 -- ui/vnc.h | 3 ++ ui/vnc.c | 79 ++++++++++++++++++-------------------------- 3 files changed, 36 insertions(+), 48 deletions(-)
include/ui/console.h +0 -2
@@ -438,8 +438,6 @@ const char *qemu_display_get_vc(DisplayOptions *opts);void qemu_display_help (void );/* vnc.c */ -bool vnc_display_init (const char *id,Error **errp); -bool vnc_display_open (const char *id,Error **errp);void vnc_display_add_client (const char *id,int csock,bool skipauth);int vnc_display_password (const char *id,const char *password,Error **errp);int vnc_display_pw_expire (const char *id,time_t expires);
ui/vnc.h +3 -0
@@ -549,6 +549,9 @@ enum VncFeatures {#define VNC_CLIPBOARD_NOTIFY (1 << 27)#define VNC_CLIPBOARD_PROVIDE (1 << 28) +VncDisplay *vnc_display_new (const char *id,Error **errp); +void vnc_display_free (VncDisplay *vd); +/***************************************************************************** * * Internal APIs
ui/vnc.c +33 -46
239 lines not on this page · raw message
Signature · 1 line
2.54.0
[PULL v2 28/33] ui/console: rename public API to use consistent qemu_console_ prefix
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Rename the display and graphic console public functions to follow a consistent qemu_console_ (or qemu_graphic_console_) naming convention.
The previous API used a mix of prefixes: dpy_, graphic_hw_, graphic_console_, console_has_, and update_displaychangelistener(). Unify them under a common qemu_console_ namespace for better discoverability and consistency.
The main renames are:
- dpy_gfx_*() / dpy_text_*() / dpy_gl_*() → qemu_console_*()
- dpy_{get,set}_ui_info() → qemu_console_{get,set}_ui_info()
- graphic_hw_*() → qemu_console_hw_*()
- graphic_console_*() → qemu_graphic_console_*()
- console_has_gl() → qemu_console_has_gl()
- update_displaychangelistener() → qemu_console_listener_set_refresh()
No functional changes.
--- include/ui/console.h | 108 ++++++++++++------------ hw/arm/musicpal.c | 4 +- hw/display/artist.c | 4 +- hw/display/ati.c | 16 ++-- hw/display/bcm2835_fb.c | 5 +- hw/display/bochs-display.c | 14 ++-- hw/display/cg3.c | 6 +- hw/display/cirrus_vga.c | 8 +- hw/display/cirrus_vga_isa.c | 2 +- hw/display/dm163.c | 6 +- hw/display/exynos4210_fimd.c | 4 +- hw/display/g364fb.c | 10 +-- hw/display/imx6ul_lcdif.c | 14 ++-- hw/display/jazz_led.c | 8 +- hw/display/macfb.c | 6 +- hw/display/next-fb.c | 4 +- hw/display/omap_lcdc.c | 4 +- hw/display/pl110.c | 4 +- hw/display/qxl-render.c | 12 +-- hw/display/qxl.c | 14 ++-- hw/display/ramfb-standalone.c | 2 +- hw/display/ramfb.c | 4 +- hw/display/sm501.c | 6 +- hw/display/ssd0303.c | 4 +- hw/display/ssd0323.c | 5 +- hw/display/tcx.c | 16 ++-- hw/display/vga-isa.c | 2 +- hw/display/vga-mmio.c | 2 +- hw/display/vga-pci.c | 6 +- hw/display/vga.c | 40 +++++---- hw/display/vhost-user-gpu.c | 22 ++--- hw/display/virtio-gpu-base.c | 2 +- hw/display/virtio-gpu-rutabaga.c | 10 +-- hw/display/virtio-gpu-udmabuf.c | 4 +- hw/display/virtio-gpu-virgl.c | 20 ++--- hw/display/virtio-gpu.c | 26 +++--- hw/display/virtio-vga.c | 2 +- hw/display/vmware_vga.c | 12 +-- hw/display/xenfb.c | 6 +- hw/display/xlnx_dp.c | 10 +-- hw/vfio/display.c | 32 +++---- ui/console-vc.c | 12 +-- ui/console.c | 140 +++++++++++++++---------------- ui/curses.c | 8 +- ui/dbus-console.c | 4 +- ui/dbus-listener.c | 10 +-- ui/egl-headless.c | 4 +- ui/gtk-egl.c | 6 +- ui/gtk-gl-area.c | 6 +- ui/gtk.c | 18 ++-- ui/sdl2-2d.c | 2 +- ui/sdl2-gl.c | 2 +- ui/sdl2.c | 6 +- ui/spice-display.c | 16 ++-- ui/vnc.c | 22 ++--- hw/display/apple-gfx.m | 16 ++-- ui/cocoa.m | 10 +-- 57 files changed, 379 insertions(+), 389 deletions(-)
include/ui/console.h +54 -54
@@ -294,49 +294,49 @@ DisplayState *init_displaystate(void);void qemu_console_register_listener (QemuConsole *con,DisplayChangeListener *dcl,const DisplayChangeListenerOps *ops); -void update_displaychangelistener (DisplayChangeListener *dcl, -uint64_t interval); +void qemu_console_listener_set_refresh (DisplayChangeListener *dcl, +uint64_t interval);void qemu_console_unregister_listener (DisplayChangeListener *dcl); -bool dpy_ui_info_supported (const QemuConsole *con); -const QemuUIInfo *dpy_get_ui_info (const QemuConsole *con); -int dpy_set_ui_info (QemuConsole *con,QemuUIInfo *info,bool delay); - -void dpy_gfx_update (QemuConsole *con,int x,int y,int w,int h); -void dpy_gfx_update_full (QemuConsole *con); -void dpy_gfx_replace_surface (QemuConsole *con, -DisplaySurface *surface); -void dpy_text_cursor (QemuConsole *con,int x,int y); -void dpy_text_update (QemuConsole *con,int x,int y,int w,int h); -void dpy_text_resize (QemuConsole *con,int w,int h); -void dpy_mouse_set (QemuConsole *con,int x,int y,bool on); -void dpy_cursor_define (QemuConsole *con,QEMUCursor *cursor); -bool dpy_gfx_check_format (QemuConsole *con, -pixman_format_code_t format); - -void dpy_gl_scanout_disable (QemuConsole *con); -void dpy_gl_scanout_texture (QemuConsole *con, -uint32_t backing_id,bool backing_y_0_top, -uint32_t backing_width,uint32_t backing_height, -uint32_t x,uint32_t y,uint32_t w,uint32_t h, -void *d3d_tex2d); -void dpy_gl_scanout_dmabuf (QemuConsole *con, -QemuDmaBuf *dmabuf); -void dpy_gl_cursor_dmabuf (QemuConsole *con,QemuDmaBuf *dmabuf, -bool have_hot,uint32_t hot_x,uint32_t hot_y); -void dpy_gl_cursor_position (QemuConsole *con, -uint32_t pos_x,uint32_t pos_y); -void dpy_gl_release_dmabuf (QemuConsole *con, -QemuDmaBuf *dmabuf); -void dpy_gl_update (QemuConsole *con, -uint32_t x,uint32_t y,uint32_t w,uint32_t h); - -QEMUGLContext dpy_gl_ctx_create (QemuConsole *con, -QEMUGLParams *params); -void dpy_gl_ctx_destroy (QemuConsole *con,QEMUGLContext ctx); -int dpy_gl_ctx_make_current (QemuConsole *con,QEMUGLContext ctx); - -bool console_has_gl (QemuConsole *con); +bool qemu_console_ui_info_supported (const QemuConsole *con); +const QemuUIInfo *qemu_console_get_ui_info (const QemuConsole *con); +int qemu_console_set_ui_info (QemuConsole *con,QemuUIInfo *info,bool delay); + +void qemu_console_update (QemuConsole *con,int x,int y,int w,int h); +void qemu_console_update_full (QemuConsole *con); +void qemu_console_set_surface (QemuConsole *con, +DisplaySurface *surface); +void qemu_console_text_set_cursor (QemuConsole *con,int x,int y); +void qemu_console_text_update (QemuConsole *con,int x,int y,int w,int h); +void qemu_console_text_resize (QemuConsole *con,int w,int h); +void qemu_console_set_mouse (QemuConsole *con,int x,int y,bool on); +void qemu_console_set_cursor (QemuConsole *con,QEMUCursor *cursor); +bool qemu_console_check_format (QemuConsole *con, +pixman_format_code_t format); + +void qemu_console_gl_scanout_disable (QemuConsole *con); +void qemu_console_gl_scanout_texture (QemuConsole *con, +uint32_t backing_id,bool backing_y_0_top, +uint32_t backing_width,uint32_t backing_height, +uint32_t x,uint32_t y,uint32_t w,uint32_t h, +void *d3d_tex2d); +void qemu_console_gl_scanout_dmabuf (QemuConsole *con, +QemuDmaBuf *dmabuf); +void qemu_console_gl_cursor_dmabuf (QemuConsole *con,QemuDmaBuf *dmabuf, +bool have_hot,uint32_t hot_x,uint32_t hot_y); +void qemu_console_gl_cursor_position (QemuConsole *con, +uint32_t pos_x,uint32_t pos_y); +void qemu_console_gl_release_dmabuf (QemuConsole *con, +QemuDmaBuf *dmabuf); +void qemu_console_gl_update (QemuConsole *con, +uint32_t x,uint32_t y,uint32_t w,uint32_t h); + +QEMUGLContext qemu_console_gl_ctx_create (QemuConsole *con, +QEMUGLParams *params); +void qemu_console_gl_ctx_destroy (QemuConsole *con,QEMUGLContext ctx); +int qemu_console_gl_ctx_make_current (QemuConsole *con,QEMUGLContext ctx); + +bool qemu_console_has_gl (QemuConsole *con);enum {GRAPHIC_FLAGS_NONE =0 ,
@@ -361,19 +361,19 @@ typedef struct GraphicHwOps {void (*gl_block)(void *opaque,bool block); } GraphicHwOps; -QemuConsole *graphic_console_init (DeviceState *dev,uint32_t head, -const GraphicHwOps *ops, -void *opaque); -void graphic_console_set_hwops (QemuConsole *con, -const GraphicHwOps *hw_ops, -void *opaque); -void graphic_console_close (QemuConsole *con); - -void graphic_hw_update (QemuConsole *con); -void graphic_hw_update_done (QemuConsole *con); -void graphic_hw_invalidate (QemuConsole *con); -void graphic_hw_text_update (QemuConsole *con,uint32_t *chardata); -void graphic_hw_gl_block (QemuConsole *con,bool block); +QemuConsole *qemu_graphic_console_create (DeviceState *dev,uint32_t head, +const GraphicHwOps *ops, +void *opaque); +void qemu_graphic_console_set_hwops (QemuConsole *con, +const GraphicHwOps *hw_ops, +void *opaque); +void qemu_graphic_console_close (QemuConsole *con); + +void qemu_console_hw_update (QemuConsole *con); +void qemu_console_hw_update_done (QemuConsole *con); +void qemu_console_hw_invalidate (QemuConsole *con); +void qemu_console_hw_text_update (QemuConsole *con,uint32_t *chardata); +void qemu_console_hw_gl_block (QemuConsole *con,bool block);void qemu_console_early_init (void );
hw/arm/musicpal.c +2 -2
@@ -170,7 +170,7 @@ static bool lcd_refresh(void *opaque) } } -dpy_gfx_update (s->con,0 ,0 ,128 *3 ,64 *3 ); +qemu_console_update (s->con,0 ,0 ,128 *3 ,64 *3 );return true; }
@@ -253,7 +253,7 @@ static const GraphicHwOps musicpal_gfx_ops = {static void musicpal_lcd_realize (DeviceState *dev,Error **errp) {musicpal_lcd_state *s =MUSICPAL_LCD (dev); - s->con =graphic_console_init (dev,0 , &musicpal_gfx_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &musicpal_gfx_ops, s);qemu_console_resize (s->con,128 *3 ,64 *3 ); }
hw/display/artist.c +2 -2
@@ -1324,7 +1324,7 @@ static bool artist_update_display(void *opaque)artist_draw_cursor (s);if (first >=0 ) { -dpy_gfx_update (s->con,0 , first, s->width, last - first +1 ); +qemu_console_update (s->con,0 , first, s->width, last - first +1 ); }return true;
@@ -1424,7 +1424,7 @@ static void artist_realizefn(DeviceState *dev, Error **errp) s->misc_video |=0x0A000000 ; s->misc_ctrl |=0x00800000 ; - s->con =graphic_console_init (dev,0 , &artist_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &artist_ops, s);qemu_console_resize (s->con, s->width, s->height); }
hw/display/ati.c +8 -8
@@ -161,7 +161,7 @@ static void ati_cursor_define(ATIVGAState *s) }cursor_set_mono (s->cursor, s->regs.cur_color1, s->regs.cur_color0, (uint8_t *)&data[64 ],1 , (uint8_t *)&data[0 ]); -dpy_cursor_define (s->vga.con, s->cursor); +qemu_console_set_cursor (s->vga.con, s->cursor); }/* Alternatively support guest rendered hardware cursor */
@@ -626,9 +626,9 @@ static void ati_mm_write(void *opaque, hwaddr addr,if (s->regs.crtc_gen_cntl &CRTC2_CUR_EN ) {ati_cursor_define (s); } -dpy_mouse_set (s->vga.con, s->regs.cur_hv_pos >>16 , - s->regs.cur_hv_pos &0xffff , - (s->regs.crtc_gen_cntl &CRTC2_CUR_EN ) !=0 ); +qemu_console_set_mouse (s->vga.con, s->regs.cur_hv_pos >>16 , + s->regs.cur_hv_pos &0xffff , + (s->regs.crtc_gen_cntl &CRTC2_CUR_EN ) !=0 ); } } if ((val & (CRTC2_EXT_DISP_EN | CRTC2_EN)) !=
@@ -780,8 +780,8 @@ static void ati_mm_write(void *opaque, hwaddr addr, }if (!s->cursor_guest_mode && (s->regs.crtc_gen_cntl &CRTC2_CUR_EN ) && !(t &BIT (31 ))) { -dpy_mouse_set (s->vga.con, s->regs.cur_hv_pos >>16 , - s->regs.cur_hv_pos &0xffff , true); +qemu_console_set_mouse (s->vga.con, s->regs.cur_hv_pos >>16 , + s->regs.cur_hv_pos &0xffff , true); }break ; }
@@ -1094,7 +1094,7 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp) }vga_init (vga,OBJECT (s),pci_address_space (dev),pci_address_space_io (dev), true); - vga->con =graphic_console_init (DEVICE (s),0 , s->vga.hw_ops, vga); + vga->con =qemu_graphic_console_create (DEVICE (s),0 , s->vga.hw_ops, vga);if (s->cursor_guest_mode) { vga->cursor_invalidate = ati_cursor_invalidate; vga->cursor_draw_line = ati_cursor_draw_line;
@@ -1167,7 +1167,7 @@ static void ati_vga_exit(PCIDevice *dev)ATIVGAState *s =ATI_VGA (dev);timer_del (&s->vblank_timer); -graphic_console_close (s->vga.con); +qemu_graphic_console_close (s->vga.con); }static const Property ati_vga_properties[] = {
hw/display/bcm2835_fb.c +2 -3
@@ -207,8 +207,7 @@ static bool fb_update_display(void *opaque) draw_line_src16, s, &first, &last);if (first >=0 ) { -dpy_gfx_update (s->con,0 , first, s->config.xres, - last - first +1 ); +qemu_console_update (s->con,0 , first, s->config.xres, last - first +1 ); } s->invalidate = false;
@@ -427,7 +426,7 @@ static void bcm2835_fb_realize(DeviceState *dev, Error **errp)bcm2835_fb_reset (dev); - s->con =graphic_console_init (dev,0 , &vgafb_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &vgafb_ops, s);qemu_console_resize (s->con, s->config.xres, s->config.yres); }
hw/display/bochs-display.c +6 -8
@@ -224,12 +224,12 @@ static bool bochs_display_update(void *opaque) mode.format, mode.stride, ptr + mode.offset); -dpy_gfx_replace_surface (s->con, ds); +qemu_console_set_surface (s->con, ds); full_update = true; }if (full_update) { -dpy_gfx_update_full (s->con); +qemu_console_update_full (s->con); }else { snap = memory_region_snapshot_and_clear_dirty(&s->vram, mode.offset, mode.size,
@@ -243,14 +243,12 @@ static bool bochs_display_update(void *opaque) ys = y; }if (!dirty && ys >=0 ) { -dpy_gfx_update (s->con,0 , ys, - mode.width, y - ys); +qemu_console_update (s->con,0 , ys, mode.width, y - ys); ys =-1 ; } }if (ys >=0 ) { -dpy_gfx_update (s->con,0 , ys, - mode.width, y - ys); +qemu_console_update (s->con,0 , ys, mode.width, y - ys); }g_free (snap);
@@ -279,7 +277,7 @@ static void bochs_display_realize(PCIDevice *dev, Error **errp) } s->vgamem =pow2ceil (s->vgamem); - s->con =graphic_console_init (DEVICE (dev),0 , &bochs_display_gfx_ops, s); + s->con =qemu_graphic_console_create (DEVICE (dev),0 , &bochs_display_gfx_ops, s);memory_region_init_ram (&s->vram, obj,"bochs-display-vram" , s->vgamem, &error_fatal);
@@ -344,7 +342,7 @@ static void bochs_display_exit(PCIDevice *dev) {BochsDisplayState *s =BOCHS_DISPLAY (dev); -graphic_console_close (s->con); +qemu_graphic_console_close (s->con); }static const Property bochs_display_properties[] = {
hw/display/cg3.c +3 -3
@@ -137,7 +137,7 @@ static bool cg3_update_display(void *opaque) } }else {if (y_start >=0 ) { -dpy_gfx_update (s->con,0 , y_start, width, y - y_start); +qemu_console_update (s->con,0 , y_start, width, y - y_start); y_start =-1 ; } pix += width;
@@ -146,7 +146,7 @@ static bool cg3_update_display(void *opaque) } s->full_update =0 ;if (y_start >=0 ) { -dpy_gfx_update (s->con,0 , y_start, width, y - y_start); +qemu_console_update (s->con,0 , y_start, width, y - y_start); }/* vsync interrupt? */ if (s->regs[0 ] &CG3_CR_ENABLE_INTS ) {
@@ -311,7 +311,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)sysbus_init_irq (sbd, &s->irq); - s->con =graphic_console_init (dev,0 , &cg3_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &cg3_ops, s);qemu_console_resize (s->con, s->width, s->height); }
hw/display/cirrus_vga.c +4 -4
@@ -779,9 +779,9 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) s->cirrus_blt_width, s->cirrus_blt_height);if (notify) { -dpy_gfx_update (s->vga.con, dx, dy, - s->cirrus_blt_width / depth, - s->cirrus_blt_height); +qemu_console_update (s->vga.con, dx, dy, + s->cirrus_blt_width / depth, + s->cirrus_blt_height); }/* we don't have to notify the display that this portion has
@@ -2964,7 +2964,7 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp) }cirrus_init_common (s,OBJECT (dev), device_id,1 ,pci_address_space (dev),pci_address_space_io (dev)); - s->vga.con =graphic_console_init (DEVICE (dev),0 , s->vga.hw_ops, &s->vga); + s->vga.con =qemu_graphic_console_create (DEVICE (dev),0 , s->vga.hw_ops, &s->vga);/* setup PCI */ memory_region_init (&s->pci_bar,OBJECT (dev),"cirrus-pci-bar0" ,0x2000000 );
hw/display/cirrus_vga_isa.c +1 -1
@@ -62,7 +62,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)cirrus_init_common (&d->cirrus_vga,OBJECT (dev),CIRRUS_ID_CLGD5430 ,0 ,isa_address_space (isadev),isa_address_space_io (isadev)); - s->con =graphic_console_init (dev,0 , s->hw_ops, s); + s->con =qemu_graphic_console_create (dev,0 , s->hw_ops, s);rom_add_vga (VGABIOS_CIRRUS_FILENAME );/* XXX ISA-LFB support */ /* FIXME not qdev yet */
hw/display/dm163.c +3 -3
@@ -277,8 +277,8 @@ static uint32_t *update_display_of_row(DM163State *s, uint32_t *dest, } } -dpy_gfx_update (s->console,0 ,LED_SQUARE_SIZE * row, -RGB_MATRIX_NUM_COLS *LED_SQUARE_SIZE ,LED_SQUARE_SIZE ); +qemu_console_update (s->console,0 ,LED_SQUARE_SIZE * row, +RGB_MATRIX_NUM_COLS *LED_SQUARE_SIZE ,LED_SQUARE_SIZE ); s->redraw &= ~(1 << row);trace_dm163_redraw (s->redraw);
@@ -322,7 +322,7 @@ static void dm163_realize(DeviceState *dev, Error **errp)qdev_init_gpio_in (dev, dm163_en_b_gpio_handler,1 );qdev_init_gpio_out_named (dev, &s->sout,"sout" ,1 ); - s->console =graphic_console_init (dev,0 , &dm163_ops, s); + s->console =qemu_graphic_console_create (dev,0 , &dm163_ops, s);qemu_console_resize (s->console,RGB_MATRIX_NUM_COLS *LED_SQUARE_SIZE ,RGB_MATRIX_NUM_ROWS *LED_SQUARE_SIZE ); }
hw/display/exynos4210_fimd.c +2 -2
@@ -1340,7 +1340,7 @@ static bool exynos4210_fimd_update(void *opaque)fimd_copy_line_toqemu (global_width, s->ifb + global_width * line *RGBA_SIZE , d + global_width * line * bpp); } -dpy_gfx_update_full (s->console); +qemu_console_update_full (s->console); } s->invalidate = false; s->vidintcon[1 ] |=FIMD_VIDINT_INTFRMPEND ;
@@ -1964,7 +1964,7 @@ static void exynos4210_fimd_realize(DeviceState *dev, Error **errp)return ; } - s->console =graphic_console_init (dev,0 , &exynos4210_fimd_ops, s); + s->console =qemu_graphic_console_create (dev,0 , &exynos4210_fimd_ops, s); }static void exynos4210_fimd_class_init (ObjectClass *klass,const void *data)
hw/display/g364fb.c +5 -5
@@ -191,8 +191,8 @@ static void g364fb_draw_graphic8(G364State *s) }else {int dy;if (xmax || ymax) { -dpy_gfx_update (s->con, xmin, ymin, - xmax - xmin +1 , ymax - ymin +1 ); +qemu_console_update (s->con, xmin, ymin, + xmax - xmin +1 , ymax - ymin +1 ); xmin = s->width; xmax =0 ; ymin = s->height;
@@ -211,7 +211,7 @@ static void g364fb_draw_graphic8(G364State *s) done:if (xmax || ymax) { -dpy_gfx_update (s->con, xmin, ymin, xmax - xmin +1 , ymax - ymin +1 ); +qemu_console_update (s->con, xmin, ymin, xmax - xmin +1 , ymax - ymin +1 ); }g_free (snap); }
@@ -234,7 +234,7 @@ static void g364fb_draw_blank(G364State *s) d +=surface_stride (surface); } -dpy_gfx_update_full (s->con); +qemu_console_update_full (s->con); s->blanked =1 ; }
@@ -478,7 +478,7 @@ static const GraphicHwOps g364fb_ops = {static void g364fb_init (DeviceState *dev,G364State *s) { - s->con =graphic_console_init (dev,0 , &g364fb_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &g364fb_ops, s);memory_region_init_io (&s->mem_ctrl,OBJECT (dev), &g364fb_ctrl_ops, s,"ctrl" ,0x180000 );
hw/display/imx6ul_lcdif.c +7 -7
@@ -203,7 +203,7 @@ static bool imx6ul_lcdif_update_display(void *opaque) src_width,surface_stride (surface),0 , s->invalidate, fn, s, &first, &last);if (first >=0 ) { -dpy_gfx_update (s->con,0 , first, width, last - first +1 ); +qemu_console_update (s->con,0 , first, width, last - first +1 ); } s->invalidate = false;
@@ -301,7 +301,7 @@ static void imx6ul_lcdif_write(void *opaque, hwaddr offset,if (!FIELD_EX32 (oldv,CTRL ,RUN ) &&FIELD_EX32 (s->regs[idx],CTRL ,RUN )) { s->invalidate = true; -graphic_hw_invalidate (s->con); +qemu_console_hw_invalidate (s->con);imx6ul_lcdif_maybe_schedule_frame (s);break ; }
@@ -318,17 +318,17 @@ static void imx6ul_lcdif_write(void *opaque, hwaddr offset,break ;case A_V4_TRANSFER_COUNT : s->invalidate = true; -graphic_hw_invalidate (s->con); +qemu_console_hw_invalidate (s->con);break ;case A_V4_CUR_BUF : s->invalidate = true; -graphic_hw_invalidate (s->con); +qemu_console_hw_invalidate (s->con);break ;case A_V4_NEXT_BUF : s->regs[IMX6UL_LCDIF_REG_V4_CUR_BUF ] = s->regs[idx];imx6ul_lcdif_frame_done (s); s->invalidate = true; -graphic_hw_invalidate (s->con); +qemu_console_hw_invalidate (s->con);imx6ul_lcdif_maybe_schedule_frame (s);return ;case A_AS_NEXT_BUF :
@@ -411,7 +411,7 @@ static void imx6ul_lcdif_realize(DeviceState *dev, Error **errp) TYPE_IMX6UL_LCDIF, LCDIF_MMIO_SIZE);sysbus_init_mmio (SYS_BUS_DEVICE (dev), &s->iomem);sysbus_init_irq (SYS_BUS_DEVICE (dev), &s->irq); - s->con =graphic_console_init (dev,0 , &imx6ul_lcdif_graphic_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &imx6ul_lcdif_graphic_ops, s); }static void imx6ul_lcdif_unrealize (DeviceState *dev)
@@ -423,7 +423,7 @@ static void imx6ul_lcdif_unrealize(DeviceState *dev) s->frame_timer =NULL ;if (s->con) { -graphic_console_close (s->con); +qemu_graphic_console_close (s->con); s->con =NULL ; } }
hw/display/jazz_led.c +4 -4
@@ -217,7 +217,7 @@ static bool jazz_led_update_display(void *opaque) } s->state =REDRAW_NONE ; -dpy_gfx_update_full (s->con); +qemu_console_update_full (s->con);return true; }
@@ -233,7 +233,7 @@ static void jazz_led_text_update(void *opaque, uint32_t *chardata)LedState *s = opaque;char buf[3 ]; -dpy_text_cursor (s->con,-1 ,-1 ); +qemu_console_text_set_cursor (s->con,-1 ,-1 );qemu_console_resize (s->con,2 ,1 );/* TODO: draw the segments */
@@ -243,7 +243,7 @@ static void jazz_led_text_update(void *opaque, uint32_t *chardata) *chardata++ =ATTR2CHTYPE (buf[1 ],QEMU_COLOR_BLUE ,QEMU_COLOR_BLACK ,1 ); -dpy_text_update (s->con,0 ,0 ,2 ,1 ); +qemu_console_text_update (s->con,0 ,0 ,2 ,1 ); }static int jazz_led_post_load (void *opaque,int version_id)
@@ -284,7 +284,7 @@ static void jazz_led_realize(DeviceState *dev, Error **errp) {LedState *s =JAZZ_LED (dev); - s->con =graphic_console_init (dev,0 , &jazz_led_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &jazz_led_ops, s); }static void jazz_led_reset (DeviceState *d)
hw/display/macfb.c +3 -3
@@ -320,14 +320,14 @@ static void macfb_draw_graphic(MacfbState *s) } }else {if (ymin >=0 ) { -dpy_gfx_update (s->con,0 , ymin, s->width, y - ymin); +qemu_console_update (s->con,0 , ymin, s->width, y - ymin); ymin =-1 ; } } }if (ymin >=0 ) { -dpy_gfx_update (s->con,0 , ymin, s->width, y - ymin); +qemu_console_update (s->con,0 , ymin, s->width, y - ymin); }g_free (snap);
@@ -671,7 +671,7 @@ static bool macfb_common_realize(DeviceState *dev, MacfbState *s, Error **errp) s->regs[DAFB_MODE_CTRL1 >>2 ] = s->mode->mode_ctrl1; s->regs[DAFB_MODE_CTRL2 >>2 ] = s->mode->mode_ctrl2; - s->con =graphic_console_init (dev,0 , &macfb_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &macfb_ops, s); surface =qemu_console_surface (s->con);if (surface_bits_per_pixel (surface) !=32 ) {
hw/display/next-fb.c +2 -2
@@ -89,7 +89,7 @@ static bool nextfb_update(void *opaque) src_width, dest_width,0 ,1 , nextfb_draw_line, s, &first, &last); -dpy_gfx_update (s->con,0 ,0 , s->cols, s->rows); +qemu_console_update (s->con,0 ,0 , s->cols, s->rows);return true; }
@@ -117,7 +117,7 @@ static void nextfb_realize(DeviceState *dev, Error **errp) s->cols =1120 ; s->rows =832 ; - s->con =graphic_console_init (dev,0 , &nextfb_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &nextfb_ops, s);qemu_console_resize (s->con, s->cols, s->rows); }
hw/display/omap_lcdc.c +2 -2
@@ -320,7 +320,7 @@ static bool omap_update_display(void *opaque) &first, &last);if (first >=0 ) { -dpy_gfx_update (omap_lcd->con,0 , first, width, last - first +1 ); +qemu_console_update (omap_lcd->con,0 , first, width, last - first +1 ); } omap_lcd->invalidate =0 ;
@@ -504,7 +504,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,memory_region_init_io (&s->iomem,NULL , &omap_lcdc_ops, s,"omap.lcdc" ,0x100 );memory_region_add_subregion (sysmem, base, &s->iomem); - s->con =graphic_console_init (NULL ,0 , &omap_ops, s); + s->con =qemu_graphic_console_create (NULL ,0 , &omap_ops, s);return s; }
hw/display/pl110.c +2 -2
@@ -303,7 +303,7 @@ static bool pl110_update_display(void *opaque) &first, &last);if (first >=0 ) { -dpy_gfx_update (s->con,0 , first, s->cols, last - first +1 ); +qemu_console_update (s->con,0 , first, s->cols, last - first +1 ); } s->invalidate =0 ;return true;
@@ -557,7 +557,7 @@ static void pl110_realize(DeviceState *dev, Error **errp) s->vblank_timer =timer_new_ns (QEMU_CLOCK_VIRTUAL , pl110_vblank_interrupt, s);qdev_init_gpio_in (dev, pl110_mux_ctrl_set,1 ); - s->con =graphic_console_init (dev,0 , &pl110_gfx_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &pl110_gfx_ops, s); }static void pl110_init (Object *obj)
hw/display/qxl-render.c +6 -6
@@ -135,7 +135,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) (width, height); } -dpy_gfx_replace_surface (vga->con, surface); +qemu_console_set_surface (vga->con, surface); }if (!qxl->guest_primary.data) {
@@ -154,16 +154,16 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)continue ; }qxl_blit (qxl, qxl->dirty+i); -dpy_gfx_update (vga->con, - qxl->dirty[i].left, qxl->dirty[i].top, - qxl->dirty[i].right - qxl->dirty[i].left, - qxl->dirty[i].bottom - qxl->dirty[i].top); +qemu_console_update (vga->con, + qxl->dirty[i].left, qxl->dirty[i].top, + qxl->dirty[i].right - qxl->dirty[i].left, + qxl->dirty[i].bottom - qxl->dirty[i].top); } qxl->num_dirty_rects =0 ; end:if (qxl->render_update_cookie_num ==0 ) { -graphic_hw_update_done (qxl->ssd.dcl.con); +qemu_console_hw_update_done (qxl->ssd.dcl.con); } }
hw/display/qxl.c +7 -7
@@ -1153,13 +1153,13 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d) }trace_qxl_enter_vga_mode (d->id);spice_qxl_driver_unload (&d->ssd.qxl); -graphic_console_set_hwops (d->ssd.dcl.con, d->vga.hw_ops, &d->vga); -update_displaychangelistener (&d->ssd.dcl,GUI_REFRESH_INTERVAL_DEFAULT ); +qemu_graphic_console_set_hwops (d->ssd.dcl.con, d->vga.hw_ops, &d->vga); +qemu_console_listener_set_refresh (&d->ssd.dcl,GUI_REFRESH_INTERVAL_DEFAULT );qemu_spice_create_host_primary (&d->ssd); d->mode =QXL_MODE_VGA ;qemu_spice_display_switch (&d->ssd, d->ssd.ds);vga_dirty_log_start (&d->vga); -graphic_hw_update (d->vga.con); +qemu_console_hw_update (d->vga.con); }static void qxl_exit_vga_mode (PCIQXLDevice *d)
@@ -1168,8 +1168,8 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d)return ; }trace_qxl_exit_vga_mode (d->id); -graphic_console_set_hwops (d->ssd.dcl.con, &qxl_ops, d); -update_displaychangelistener (&d->ssd.dcl,GUI_REFRESH_INTERVAL_IDLE ); +qemu_graphic_console_set_hwops (d->ssd.dcl.con, &qxl_ops, d); +qemu_console_listener_set_refresh (&d->ssd.dcl,GUI_REFRESH_INTERVAL_IDLE );vga_dirty_log_stop (&d->vga);qxl_destroy_primary (d,QXL_SYNC ); }
@@ -2237,7 +2237,7 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp)portio_list_add (&qxl->vga_port_list,pci_address_space_io (dev),0x3b0 ); qxl->have_vga = true; - vga->con =graphic_console_init (DEVICE (dev),0 , &qxl_ops, qxl); + vga->con =qemu_graphic_console_create (DEVICE (dev),0 , &qxl_ops, qxl); qxl->id =qemu_console_get_index (vga->con);/* == channel_id */ if (qxl->id !=0 ) { error_setg(errp, "primary qxl-vga device must be console 0 "
@@ -2262,7 +2262,7 @@ static void qxl_realize_secondary(PCIDevice *dev, Error **errp)memory_region_init_ram (&qxl->vga.vram,OBJECT (dev),"qxl.vgavram" , qxl->vga.vram_size, &error_fatal); qxl->vga.vram_ptr =memory_region_get_ram_ptr (&qxl->vga.vram); - qxl->vga.con =graphic_console_init (DEVICE (dev),0 , &qxl_ops, qxl); + qxl->vga.con =qemu_graphic_console_create (DEVICE (dev),0 , &qxl_ops, qxl); qxl->ssd.dcl.con = qxl->vga.con; qxl->id =qemu_console_get_index (qxl->vga.con);/* == channel_id */
hw/display/ramfb-standalone.c +1 -1
@@ -41,7 +41,7 @@ static void ramfb_realizefn(DeviceState *dev, Error **errp) {RAMFBStandaloneState *ramfb =RAMFB (dev); - ramfb->con =graphic_console_init (dev,0 , &wrapper_ops, dev); + ramfb->con =qemu_graphic_console_create (dev,0 , &wrapper_ops, dev); ramfb->state =ramfb_setup (ramfb->use_legacy_x86_rom, errp); }
hw/display/ramfb.c +2 -2
@@ -111,12 +111,12 @@ void ramfb_display_update(QemuConsole *con, RAMFBState *s) }if (s->ds) { -dpy_gfx_replace_surface (con, s->ds); +qemu_console_set_surface (con, s->ds); s->ds =NULL ; }/* simple full screen update */ -dpy_gfx_update_full (con); +qemu_console_update_full (con); }static int ramfb_post_load (void *opaque,int version_id)
hw/display/sm501.c +3 -3
@@ -1822,7 +1822,7 @@ static bool sm501_update_display(void *opaque) }else {if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (s->con,0 , y_start, width, y - y_start); +qemu_console_update (s->con,0 , y_start, width, y - y_start); y_start =-1 ; } }
@@ -1831,7 +1831,7 @@ static bool sm501_update_display(void *opaque)/* complete flush to display */ if (y_start >=0 ) { -dpy_gfx_update (s->con,0 , y_start, width, y - y_start); +qemu_console_update (s->con,0 , y_start, width, y - y_start); }return true;
@@ -1936,7 +1936,7 @@ static void sm501_init(SM501State *s, DeviceState *dev, &s->twoD_engine_region);/* create qemu graphic console */ - s->con =graphic_console_init (dev,0 , &sm501_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &sm501_ops, s); }static const VMStateDescription vmstate_sm501_state = {
hw/display/ssd0303.c +2 -2
@@ -268,7 +268,7 @@ static bool ssd0303_update_display(void *opaque) } } s->redraw =0 ; -dpy_gfx_update (s->con,0 ,0 ,96 *MAGNIFY ,16 *MAGNIFY ); +qemu_console_update (s->con,0 ,0 ,96 *MAGNIFY ,16 *MAGNIFY );return true; }
@@ -309,7 +309,7 @@ static void ssd0303_realize(DeviceState *dev, Error **errp) {ssd0303_state *s =SSD0303 (dev); - s->con =graphic_console_init (dev,0 , &ssd0303_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &ssd0303_ops, s);qemu_console_resize (s->con,96 *MAGNIFY ,16 *MAGNIFY ); }
hw/display/ssd0323.c +3 -2
@@ -270,7 +270,8 @@ static bool ssd0323_update_display(void *opaque) } } s->redraw =0 ; -dpy_gfx_update (s->con,0 ,0 ,128 *MAGNIFY ,64 *MAGNIFY ); +qemu_console_update (s->con,0 ,0 ,128 *MAGNIFY ,64 *MAGNIFY ); +return true; }
@@ -356,7 +357,7 @@ static void ssd0323_realize(SSIPeripheral *d, Error **errp) s->col_end =63 ; s->row_end =79 ; - s->con =graphic_console_init (dev,0 , &ssd0323_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &ssd0323_ops, s);qemu_console_resize (s->con,128 *MAGNIFY ,64 *MAGNIFY );qdev_init_gpio_in (dev, ssd0323_cd,1 );
hw/display/tcx.c +6 -10
@@ -243,8 +243,7 @@ static bool tcx_update_display(void *opaque) }else {if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (ts->con,0 , y_start, - ts->width, y - y_start); +qemu_console_update (ts->con,0 , y_start, ts->width, y - y_start); y_start =-1 ; } }
@@ -253,8 +252,7 @@ static bool tcx_update_display(void *opaque) }if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (ts->con,0 , y_start, - ts->width, y - y_start); +qemu_console_update (ts->con,0 , y_start, ts->width, y - y_start); }g_free (snap);return true;
@@ -297,8 +295,7 @@ static bool tcx24_update_display(void *opaque) }else {if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (ts->con,0 , y_start, - ts->width, y - y_start); +qemu_console_update (ts->con,0 , y_start, ts->width, y - y_start); y_start =-1 ; } }
@@ -309,8 +306,7 @@ static bool tcx24_update_display(void *opaque) }if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (ts->con,0 , y_start, - ts->width, y - y_start); +qemu_console_update (ts->con,0 , y_start, ts->width, y - y_start); }g_free (snap);return true;
@@ -864,9 +860,9 @@ static void tcx_realize(DeviceState *dev, Error **errp)sysbus_init_irq (sbd, &s->irq);if (s->depth ==8 ) { - s->con =graphic_console_init (dev,0 , &tcx_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &tcx_ops, s); }else { - s->con =graphic_console_init (dev,0 , &tcx24_ops, s); + s->con =qemu_graphic_console_create (dev,0 , &tcx24_ops, s); } s->thcmisc =0 ;
hw/display/vga-isa.c +1 -1
@@ -79,7 +79,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)0x000a0000 , vga_io_memory, 1);memory_region_set_coalescing (vga_io_memory); - s->con =graphic_console_init (dev,0 , s->hw_ops, s); + s->con =qemu_graphic_console_create (dev,0 , s->hw_ops, s); memory_region_add_subregion(isa_address_space(isadev), VBE_DISPI_LFB_PHYSICAL_ADDRESS,
hw/display/vga-mmio.c +1 -1
@@ -108,7 +108,7 @@ static void vga_mmio_realizefn(DeviceState *dev, Error **errp) }sysbus_init_mmio (sbd, &s->vga.vram); - s->vga.con =graphic_console_init (dev,0 , s->vga.hw_ops, &s->vga); + s->vga.con =qemu_graphic_console_create (dev,0 , s->vga.hw_ops, &s->vga); }static const Property vga_mmio_properties[] = {
hw/display/vga-pci.c +3 -3
@@ -247,7 +247,7 @@ static void pci_std_vga_realize(PCIDevice *dev, Error **errp)vga_init (s,OBJECT (dev),pci_address_space (dev),pci_address_space_io (dev), true); - s->con =graphic_console_init (DEVICE (dev),0 , s->hw_ops, s); + s->con =qemu_graphic_console_create (DEVICE (dev),0 , s->hw_ops, s);/* XXX: VGA_RAM_SIZE must be a power of two */ pci_register_bar (&d->dev,0 ,PCI_BASE_ADDRESS_MEM_PREFETCH , &s->vram);
@@ -282,7 +282,7 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)if (!vga_common_init (s,OBJECT (dev), errp)) {return ; } - s->con =graphic_console_init (DEVICE (dev),0 , s->hw_ops, s); + s->con =qemu_graphic_console_create (DEVICE (dev),0 , s->hw_ops, s);/* mmio bar */ memory_region_init_io(&d->mmio, OBJECT(dev), &unassigned_io_ops, NULL,
@@ -306,7 +306,7 @@ static void pci_secondary_vga_exit(PCIDevice *dev)PCIVGAState *d =PCI_VGA (dev);VGACommonState *s = &d->vga; -graphic_console_close (s->con); +qemu_graphic_console_close (s->con);memory_region_del_subregion (&d->mmio, &d->mrs[0 ]);memory_region_del_subregion (&d->mmio, &d->mrs[1 ]);if (d->flags & (1 <<PCI_VGA_FLAG_ENABLE_QEXT )) {
hw/display/vga.c +19 -21
@@ -1246,7 +1246,7 @@ static void vga_draw_text(VGACommonState *s, int full_update) s->last_scr_height = height * cheight;qemu_console_resize (s->con, s->last_scr_width, s->last_scr_height); surface =qemu_console_surface (s->con); -dpy_text_resize (s->con, width, height); +qemu_console_text_resize (s->con, width, height); s->last_depth =0 ; s->last_width = width; s->last_height = height;
@@ -1365,8 +1365,8 @@ static void vga_draw_text(VGACommonState *s, int full_update) ch_attr_ptr++; }if (cx_max !=-1 ) { -dpy_gfx_update (s->con, cx_min * cw, cy * cheight, - (cx_max - cx_min +1 ) * cw, cheight); +qemu_console_update (s->con, cx_min * cw, cy * cheight, + (cx_max - cx_min +1 ) * cw, cheight); } dest += linesize * cheight; line1 = line + cheight;
@@ -1610,7 +1610,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)*/ format =qemu_default_pixman_format (depth, !byteswap);if (format) { - allocate_surface = !dpy_gfx_check_format (s->con, format) + allocate_surface = !qemu_console_check_format (s->con, format) || s->force_shadow || force_shadow; }else { allocate_surface = true;
@@ -1647,7 +1647,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) surface =qemu_create_displaysurface_from (disp_width, height, format, s->params.line_offset, s->vram_ptr + (s->params.start_addr *4 )); -dpy_gfx_replace_surface (s->con, surface); +qemu_console_set_surface (s->con, surface); }else {qemu_console_resize (s->con, disp_width, height); surface =qemu_console_surface (s->con);
@@ -1720,8 +1720,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) }else {if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (s->con,0 , y_start, - disp_width, y - y_start); +qemu_console_update (s->con,0 , y_start, disp_width, y - y_start); y_start =-1 ; } }
@@ -1745,8 +1744,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) }if (y_start >=0 ) {/* flush to display */ -dpy_gfx_update (s->con,0 , y_start, - disp_width, y - y_start); +qemu_console_update (s->con,0 , y_start, disp_width, y - y_start); }g_free (snap);memset (s->invalidated_y_table,0 ,sizeof (s->invalidated_y_table));
@@ -1767,7 +1765,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update)/* unshare buffer, otherwise the blanking corrupts vga vram */ surface =qemu_create_displaysurface (s->last_scr_width, s->last_scr_height); -dpy_gfx_replace_surface (s->con, surface); +qemu_console_set_surface (s->con, surface); } w = s->last_scr_width *surface_bytes_per_pixel (surface);
@@ -1776,7 +1774,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update)memset (d,0 , w); d +=surface_stride (surface); } -dpy_gfx_update_full (s->con); +qemu_console_update_full (s->con); }#define GMODE_TEXT 0
@@ -1967,7 +1965,7 @@ static void vga_update_text(void *opaque, uint32_t *chardata) s->last_scr_width = width * cw; s->last_scr_height = height * cheight;qemu_console_resize (s->con, s->last_scr_width, s->last_scr_height); -dpy_text_resize (s->con, width, height); +qemu_console_text_resize (s->con, width, height); s->last_depth =0 ; s->last_width = width; s->last_height = height;
@@ -1992,11 +1990,11 @@ static void vga_update_text(void *opaque, uint32_t *chardata) s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) { cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START ] &0x20 );if (cursor_visible && cursor_offset < size && cursor_offset >=0 ) -dpy_text_cursor (s->con, -TEXTMODE_X (cursor_offset), -TEXTMODE_Y (cursor_offset)); +qemu_console_text_set_cursor (s->con, +TEXTMODE_X (cursor_offset), +TEXTMODE_Y (cursor_offset));else -dpy_text_cursor (s->con,-1 ,-1 ); +qemu_console_text_set_cursor (s->con,-1 ,-1 ); s->cursor_offset = cursor_offset; s->cursor_start = s->cr[VGA_CRTC_CURSOR_START ]; s->cursor_end = s->cr[VGA_CRTC_CURSOR_END ];
@@ -2009,7 +2007,7 @@ static void vga_update_text(void *opaque, uint32_t *chardata)for (i =0 ; i < size; src ++, dst ++, i ++) *dst =VMEM2CHTYPE (le32_to_cpu (*src)); -dpy_text_update (s->con,0 ,0 , width, height); +qemu_console_text_update (s->con,0 ,0 , width, height); }else { c_max =0 ;
@@ -2032,7 +2030,7 @@ static void vga_update_text(void *opaque, uint32_t *chardata)if (c_min <= c_max) { i =TEXTMODE_Y (c_min); -dpy_text_update (s->con,0 , i, width,TEXTMODE_Y (c_max) - i +1 ); +qemu_console_text_update (s->con,0 , i, width,TEXTMODE_Y (c_max) - i +1 ); } }
@@ -2057,8 +2055,8 @@ static void vga_update_text(void *opaque, uint32_t *chardata)/* Display a message */ s->last_width =60 ; s->last_height = height =3 ; -dpy_text_cursor (s->con,-1 ,-1 ); -dpy_text_resize (s->con, s->last_width, height); +qemu_console_text_set_cursor (s->con,-1 ,-1 ); +qemu_console_text_resize (s->con, s->last_width, height);for (dst = chardata, i =0 ; i < s->last_width * height; i ++) *dst++ =' ' ;
@@ -2070,7 +2068,7 @@ static void vga_update_text(void *opaque, uint32_t *chardata) *dst++ =ATTR2CHTYPE (msg_buffer[i],QEMU_COLOR_BLUE ,QEMU_COLOR_BLACK ,1 ); -dpy_text_update (s->con,0 ,0 , s->last_width, height); +qemu_console_text_update (s->con,0 ,0 , s->last_width, height); } static uint64_t vga_mem_read(void *opaque, hwaddr addr,
hw/display/vhost-user-gpu.c +11 -11
@@ -142,11 +142,11 @@ vhost_user_gpu_handle_cursor(VhostUserGPU *g, VhostUserGpuMsg *msg)memcpy (s->current_cursor->data, up->data,64 *64 *sizeof (uint32_t )); -dpy_cursor_define (s->con, s->current_cursor); +qemu_console_set_cursor (s->con, s->current_cursor); } -dpy_mouse_set (s->con, pos->x, pos->y, - msg->request !=VHOST_USER_GPU_CURSOR_POS_HIDE ); +qemu_console_set_mouse (s->con, pos->x, pos->y, + msg->request !=VHOST_USER_GPU_CURSOR_POS_HIDE ); } static void
@@ -238,7 +238,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) con = s->con;if (m->width ==0 ) { -dpy_gfx_replace_surface (con,NULL ); +qemu_console_set_surface (con,NULL ); }else { s->ds =qemu_create_displaysurface (m->width, m->height);/* replace surface on next update */
@@ -269,12 +269,12 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)if (dmabuf) {qemu_dmabuf_close (dmabuf); -dpy_gl_release_dmabuf (con, dmabuf); +qemu_console_gl_release_dmabuf (con, dmabuf);g_clear_pointer (&dmabuf, qemu_dmabuf_free); }if (fd ==-1 ) { -dpy_gl_scanout_disable (con); +qemu_console_gl_scanout_disable (con); g->dmabuf[m->scanout_id] =NULL ;break ; }
@@ -291,7 +291,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) &fd,1 , false, m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP); -dpy_gl_scanout_dmabuf (con, dmabuf); +qemu_console_gl_scanout_dmabuf (con, dmabuf); g->dmabuf[m->scanout_id] = dmabuf;break ; }
@@ -306,13 +306,13 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) } con = g->parent_obj.scanout[m->scanout_id].con; -if (!console_has_gl (con)) { +if (!qemu_console_has_gl (con)) {error_report ("console doesn't support GL!" );vhost_user_gpu_unblock (g);break ; } g->backend_blocked = true; -dpy_gl_update (con, m->x, m->y, m->width, m->height); +qemu_console_gl_update (con, m->x, m->y, m->width, m->height);break ; }#ifdef CONFIG_PIXMAN
@@ -337,9 +337,9 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)pixman_image_unref (image);if (qemu_console_surface (con) != s->ds) { -dpy_gfx_replace_surface (con, s->ds); +qemu_console_set_surface (con, s->ds); }else { -dpy_gfx_update (con, m->x, m->y, m->width, m->height); +qemu_console_update (con, m->x, m->y, m->width, m->height); }break ; }
hw/display/virtio-gpu-base.c +1 -1
@@ -253,7 +253,7 @@ virtio_gpu_base_device_realize(DeviceState *qdev, g->hw_ops = &virtio_gpu_ops;for (i =0 ; i < g->conf.max_outputs; i++) { g->scanout[i].con = -graphic_console_init (DEVICE (g), i, &virtio_gpu_ops, g); +qemu_graphic_console_create (DEVICE (g), i, &virtio_gpu_ops, g); }return true;
hw/display/virtio-gpu-rutabaga.c +5 -5
@@ -282,7 +282,7 @@ rutabaga_cmd_resource_flush(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd) rf.resource_id, &transfer, &transfer_iovec);CHECK (!result, cmd); -dpy_gfx_update_full (scanout->con); +qemu_console_update_full (scanout->con); } static void
@@ -306,8 +306,8 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd) scanout = &vb->scanout[ss.scanout_id];if (ss.resource_id ==0 ) { -dpy_gfx_replace_surface (scanout->con,NULL ); -dpy_gl_scanout_disable (scanout->con); +qemu_console_set_surface (scanout->con,NULL ); +qemu_console_gl_scanout_disable (scanout->con);return ; }
@@ -331,8 +331,8 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd)/* realloc the surface ptr */ scanout->ds =qemu_create_displaysurface_pixman (res->image); -dpy_gfx_replace_surface (scanout->con,NULL ); -dpy_gfx_replace_surface (scanout->con, scanout->ds); +qemu_console_set_surface (scanout->con,NULL ); +qemu_console_set_surface (scanout->con, scanout->ds); res->scanout_bitmask = ss.scanout_id; }
hw/display/virtio-gpu-udmabuf.c +2 -2
@@ -156,7 +156,7 @@ static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)struct virtio_gpu_scanout *scanout; scanout = &g->parent_obj.scanout[dmabuf->scanout_id]; -dpy_gl_release_dmabuf (scanout->con, dmabuf->buf); +qemu_console_gl_release_dmabuf (scanout->con, dmabuf->buf);g_clear_pointer (&dmabuf->buf, qemu_dmabuf_free);QTAILQ_REMOVE (&g->dmabuf.bufs, dmabuf, next);g_free (dmabuf);
@@ -232,7 +232,7 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g, height =qemu_dmabuf_get_height (new_primary->buf); g->dmabuf.primary[scanout_id] = new_primary;qemu_console_resize (scanout->con, width, height); -dpy_gl_scanout_dmabuf (scanout->con, new_primary->buf); +qemu_console_gl_scanout_dmabuf (scanout->con, new_primary->buf);if (old_primary) {virtio_gpu_free_dmabuf (g, old_primary);
hw/display/virtio-gpu-virgl.c +9 -11
@@ -521,7 +521,7 @@ static void virtio_gpu_rect_update(VirtIOGPU *g, int idx, int x, int y,return ; } -dpy_gl_update (g->parent_obj.scanout[idx].con, x, y, width, height); +qemu_console_gl_update (g->parent_obj.scanout[idx].con, x, y, width, height); } static void virgl_cmd_resource_flush(VirtIOGPU *g,
@@ -584,16 +584,15 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,qemu_console_resize (g->parent_obj.scanout[ss.scanout_id].con, ss.r.width, ss.r.height);virgl_renderer_force_ctx_0 (); -dpy_gl_scanout_texture ( +qemu_console_gl_scanout_texture ( g->parent_obj.scanout[ss.scanout_id].con, info.tex_id, info.flags &VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP , info.width, info.height, ss.r.x, ss.r.y, ss.r.width, ss.r.height, d3d_tex2d); }else { -dpy_gfx_replace_surface ( - g->parent_obj.scanout[ss.scanout_id].con,NULL ); -dpy_gl_scanout_disable (g->parent_obj.scanout[ss.scanout_id].con); +qemu_console_set_surface (g->parent_obj.scanout[ss.scanout_id].con,NULL ); +qemu_console_gl_scanout_disable (g->parent_obj.scanout[ss.scanout_id].con); } g->parent_obj.scanout[ss.scanout_id].resource_id = ss.resource_id; }
@@ -1315,7 +1314,7 @@ virgl_create_context(void *opaque, int scanout_idx, qparams.major_ver = params->major_ver; qparams.minor_ver = params->minor_ver; - ctx =dpy_gl_ctx_create (g->parent_obj.scanout[scanout_idx].con, &qparams); + ctx =qemu_console_gl_ctx_create (g->parent_obj.scanout[scanout_idx].con, &qparams);return (virgl_renderer_gl_context )ctx; }
@@ -1324,7 +1323,7 @@ static void virgl_destroy_context(void *opaque, virgl_renderer_gl_context ctx)VirtIOGPU *g = opaque;QEMUGLContext qctx = (QEMUGLContext )ctx; -dpy_gl_ctx_destroy (g->parent_obj.scanout[0 ].con, qctx); +qemu_console_gl_ctx_destroy (g->parent_obj.scanout[0 ].con, qctx); } static int virgl_make_context_current(void *opaque, int scanout_idx,
@@ -1333,8 +1332,7 @@ static int virgl_make_context_current(void *opaque, int scanout_idx,VirtIOGPU *g = opaque;QEMUGLContext qctx = (QEMUGLContext )ctx; -return dpy_gl_ctx_make_current (g->parent_obj.scanout[scanout_idx].con, - qctx); +return qemu_console_gl_ctx_make_current (g->parent_obj.scanout[scanout_idx].con, qctx); }static struct virgl_renderer_callbacks virtio_gpu_3d_cbs = {
@@ -1399,8 +1397,8 @@ void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g)int i;for (i =0 ; i < g->parent_obj.conf.max_outputs; i++) { -dpy_gfx_replace_surface (g->parent_obj.scanout[i].con,NULL ); -dpy_gl_scanout_disable (g->parent_obj.scanout[i].con); +qemu_console_set_surface (g->parent_obj.scanout[i].con,NULL ); +qemu_console_gl_scanout_disable (g->parent_obj.scanout[i].con); } }
hw/display/virtio-gpu.c +13 -13
@@ -103,14 +103,14 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)if (cursor->resource_id >0 ) { vgc->update_cursor_data (g, s, cursor->resource_id); } -dpy_cursor_define (s->con, s->current_cursor); +qemu_console_set_cursor (s->con, s->current_cursor); s->cursor = *cursor; }else { s->cursor.pos.x = cursor->pos.x; s->cursor.pos.y = cursor->pos.y; } -dpy_mouse_set (s->con, cursor->pos.x, cursor->pos.y, cursor->resource_id); +qemu_console_set_mouse (s->con, cursor->pos.x, cursor->pos.y, cursor->resource_id); } struct virtio_gpu_simple_resource *
@@ -390,7 +390,7 @@ void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id) res->scanout_bitmask &= ~(1 << scanout_id); } -dpy_gfx_replace_surface (scanout->con,NULL ); +qemu_console_set_surface (scanout->con,NULL ); scanout->resource_id =0 ; scanout->ds =NULL ; scanout->width =0 ;
@@ -531,8 +531,8 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g, rf.r.y + rf.r.height >= scanout->y) { within_bounds = true; -if (console_has_gl (scanout->con)) { -dpy_gl_update (scanout->con,0 ,0 , scanout->width, +if (qemu_console_has_gl (scanout->con)) { +qemu_console_gl_update (scanout->con,0 ,0 , scanout->width, scanout->height); update_submitted = true; }
@@ -582,8 +582,8 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,/* work out the area we need to update for each console */ if (qemu_rect_intersect (&flush_rect, &rect, &rect)) {qemu_rect_translate (&rect, -scanout->x, -scanout->y); -dpy_gfx_update (g->parent_obj.scanout[i].con, - rect.x, rect.y, rect.width, rect.height); +qemu_console_update (g->parent_obj.scanout[i].con, + rect.x, rect.y, rect.width, rect.height); } } }
@@ -649,7 +649,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, g->parent_obj.enable =1 ;if (res->blob) { -if (console_has_gl (scanout->con)) { +if (qemu_console_has_gl (scanout->con)) {if (!virtio_gpu_update_dmabuf (g, scanout_id, res, fb, r)) {virtio_gpu_update_scanout (g, scanout_id, res, fb, r); }else {
@@ -665,7 +665,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, }/* create a surface for this scanout */ - if ((res->blob && !console_has_gl(scanout->con)) || + if ((res->blob && !qemu_console_has_gl(scanout->con)) || !scanout->ds || surface_data(scanout->ds) != data + fb->offset || scanout->width != r->width ||
@@ -686,7 +686,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,qemu_displaysurface_set_share_handle (scanout->ds, res->share_handle, fb->offset);pixman_image_unref (rect); -dpy_gfx_replace_surface (g->parent_obj.scanout[scanout_id].con, +qemu_console_set_surface (g->parent_obj.scanout[scanout_id].con, scanout->ds); }
@@ -1483,10 +1483,10 @@ static int virtio_gpu_post_load(void *opaque, int version_id) } scanout->ds =qemu_create_displaysurface_pixman (res->image);qemu_displaysurface_set_share_handle (scanout->ds, res->share_handle,0 ); -dpy_gfx_replace_surface (scanout->con, scanout->ds); +qemu_console_set_surface (scanout->con, scanout->ds); } -dpy_gfx_update_full (scanout->con); +qemu_console_update_full (scanout->con);if (scanout->cursor.resource_id) {update_cursor (g, &scanout->cursor); }
@@ -1602,7 +1602,7 @@ static void virtio_gpu_reset_bh(void *opaque) }for (i =0 ; i < g->parent_obj.conf.max_outputs; i++) { -dpy_gfx_replace_surface (g->parent_obj.scanout[i].con,NULL ); +qemu_console_set_surface (g->parent_obj.scanout[i].con,NULL ); } g->reset_finished = true;
hw/display/virtio-vga.c +1 -1
@@ -172,7 +172,7 @@ static void virtio_vga_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp) vvga->vga_mrs, true, false); vga->con = g->scanout[0 ].con; -graphic_console_set_hwops (vga->con, &virtio_vga_base_ops, vvga); +qemu_graphic_console_set_hwops (vga->con, &virtio_vga_base_ops, vvga);for (i =0 ; i < g->conf.max_outputs; i++) { object_property_set_link(OBJECT(g->scanout[i].con), "device",
hw/display/vmware_vga.c +6 -6
@@ -378,7 +378,7 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,for (line = h; line >0 ; line--, src += bypl, dst += bypl) {memcpy (dst, src, width); } -dpy_gfx_update (s->vga.con, x, y, w, h); +qemu_console_update (s->vga.con, x, y, w, h); }static inline void vmsvga_update_rect_flush (struct vmsvga_state_s *s)
@@ -554,7 +554,7 @@ static inline void vmsvga_cursor_define(struct vmsvga_state_s *s, qc = cursor_builtin_left_ptr(); } -dpy_cursor_define (s->vga.con, qc); +qemu_console_set_cursor (s->vga.con, qc);cursor_unref (qc); }#endif
@@ -1082,7 +1082,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) s->cursor.on &= (value !=SVGA_CURSOR_ON_HIDE );#ifdef HW_MOUSE_ACCEL if (value <=SVGA_CURSOR_ON_SHOW ) { -dpy_mouse_set (s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on); +qemu_console_set_mouse (s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on); }#endif break ;
@@ -1130,7 +1130,7 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s) surface =qemu_create_displaysurface_from (s->new_width, s->new_height, format, stride, s->vga.vram_ptr); -dpy_gfx_replace_surface (s->vga.con, surface); +qemu_console_set_surface (s->vga.con, surface); s->invalidated =1 ; } }
@@ -1151,7 +1151,7 @@ static bool vmsvga_update_display(void *opaque)if (s->invalidated) { s->invalidated =0 ; -dpy_gfx_update_full (s->vga.con); +qemu_console_update_full (s->vga.con); }return true;
@@ -1254,7 +1254,7 @@ static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s, s->scratch_size =SVGA_SCRATCH_SIZE ; s->scratch =g_malloc (s->scratch_size *4 ); - s->vga.con =graphic_console_init (dev,0 , &vmsvga_ops, s); + s->vga.con =qemu_graphic_console_create (dev,0 , &vmsvga_ops, s); s->fifo_size =SVGA_FIFO_SIZE ; memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size,
hw/display/xenfb.c +3 -3
@@ -657,7 +657,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)xen_pv_printf (&xenfb->c.xendev,0 ,"%s: oops: convert %d -> %d bpp?\n" , __func__, xenfb->depth, bpp); -dpy_gfx_update (xenfb->con, x, y, w, h); +qemu_console_update (xenfb->con, x, y, w, h); }#ifdef XENFB_TYPE_REFRESH_PERIOD
@@ -743,7 +743,7 @@ static bool xenfb_update(void *opaque) surface =qemu_create_displaysurface (xenfb->width, xenfb->height);break ; } -dpy_gfx_replace_surface (xenfb->con, surface); +qemu_console_set_surface (xenfb->con, surface); xen_pv_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n", xenfb->width, xenfb->height, xenfb->depth,
@@ -903,7 +903,7 @@ static int fb_initialise(struct XenLegacyDevice *xendev)if (rc !=0 )return rc; - fb->con =graphic_console_init (NULL ,0 , &xenfb_ops, fb); + fb->con =qemu_graphic_console_create (NULL ,0 , &xenfb_ops, fb);if (xenstore_read_fe_int (xendev,"feature-update" , &fb->feature_update) ==-1 ) fb->feature_update =0 ;
hw/display/xlnx_dp.c +5 -5
@@ -605,7 +605,7 @@ static void xlnx_dp_recreate_surface(XlnxDPState *s)if ((width !=0 ) && (height !=0 )) {/* -* As dpy_gfx_replace_surface calls qemu_free_displaysurface on the +* As qemu_console_replace_surface calls qemu_free_displaysurface on the * surface we need to be careful and don't free the surface associated * to the console or double free will happen. */
@@ -631,10 +631,10 @@ static void xlnx_dp_recreate_surface(XlnxDPState *s) height, s->g_plane.format, 0, NULL); -dpy_gfx_replace_surface (s->console, s->bout_plane.surface); +qemu_console_set_surface (s->console, s->bout_plane.surface); }else { s->bout_plane.surface =NULL ; -dpy_gfx_replace_surface (s->console, s->g_plane.surface); +qemu_console_set_surface (s->console, s->g_plane.surface); } xlnx_dpdma_set_host_data_location(s->dpdma, DP_GRAPHIC_DMA_CHANNEL,
@@ -1287,7 +1287,7 @@ static bool xlnx_dp_update_display(void *opaque)/* * XXX: We might want to update only what changed. */ -dpy_gfx_update_full (s->console); +qemu_console_update_full (s->console);return true; }
@@ -1387,7 +1387,7 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp)qdev_realize (DEVICE (s->edid),BUS (aux_get_i2c_bus (s->aux_bus)), &error_fatal); - s->console =graphic_console_init (dev,0 , &xlnx_dp_gfx_ops, s); + s->console =qemu_graphic_console_create (dev,0 , &xlnx_dp_gfx_ops, s); surface =qemu_console_surface (s->console);xlnx_dpdma_set_host_data_location (s->dpdma,DP_GRAPHIC_DMA_CHANNEL ,surface_data (surface));
hw/vfio/display.c +16 -16
@@ -264,7 +264,7 @@ static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf)QTAILQ_REMOVE (&dpy->dmabuf.bufs, dmabuf, next);qemu_dmabuf_close (dmabuf->buf); -dpy_gl_release_dmabuf (dpy->con, dmabuf->buf); +qemu_console_gl_release_dmabuf (dpy->con, dmabuf->buf);g_clear_pointer (&dmabuf->buf, qemu_dmabuf_free);g_free (dmabuf); }
@@ -307,7 +307,7 @@ static bool vfio_display_dmabuf_update(void *opaque)if (dpy->dmabuf.primary != primary) { dpy->dmabuf.primary = primary;qemu_console_resize (dpy->con, width, height); -dpy_gl_scanout_dmabuf (dpy->con, primary->buf); +qemu_console_gl_scanout_dmabuf (dpy->con, primary->buf); free_bufs = true; }
@@ -321,21 +321,21 @@ static bool vfio_display_dmabuf_update(void *opaque)if (cursor && (new_cursor || cursor->hot_updates)) {bool have_hot = (cursor->hot_x !=0xffffffff && cursor->hot_y !=0xffffffff ); -dpy_gl_cursor_dmabuf (dpy->con, cursor->buf, have_hot, - cursor->hot_x, cursor->hot_y); +qemu_console_gl_cursor_dmabuf (dpy->con, cursor->buf, have_hot, + cursor->hot_x, cursor->hot_y); cursor->hot_updates =0 ; }else if (!cursor && new_cursor) { -dpy_gl_cursor_dmabuf (dpy->con,NULL , false,0 ,0 ); +qemu_console_gl_cursor_dmabuf (dpy->con,NULL , false,0 ,0 ); }if (cursor && cursor->pos_updates) { -dpy_gl_cursor_position (dpy->con, +qemu_console_gl_cursor_position (dpy->con, cursor->pos_x, cursor->pos_y); cursor->pos_updates =0 ; } -dpy_gl_update (dpy->con,0 ,0 , width, height); +qemu_console_gl_update (dpy->con,0 ,0 , width, height);if (free_bufs) {vfio_display_free_dmabufs (vdev);
@@ -363,7 +363,7 @@ static bool vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp) } vdev->dpy =g_new0 (VFIODisplay,1 ); - vdev->dpy->con =graphic_console_init (DEVICE (vdev),0 , + vdev->dpy->con =qemu_graphic_console_create (DEVICE (vdev),0 , &vfio_display_dmabuf_ops, vdev);if (vdev->enable_ramfb) {
@@ -396,9 +396,9 @@ void vfio_display_reset(VFIOPCIDevice *vdev)return ; } -dpy_gl_scanout_disable (vdev->dpy->con); +qemu_console_gl_scanout_disable (vdev->dpy->con);vfio_display_dmabuf_exit (vdev->dpy); -dpy_gfx_update_full (vdev->dpy->con); +qemu_console_update_full (vdev->dpy->con); }static bool vfio_display_region_update (void *opaque)
@@ -471,13 +471,13 @@ static bool vfio_display_region_update(void *opaque) dpy->region.surface =qemu_create_displaysurface_from (plane.width, plane.height, format, plane.stride, dpy->region.buffer.mmaps[0 ].mmap); -dpy_gfx_replace_surface (dpy->con, dpy->region.surface); +qemu_console_set_surface (dpy->con, dpy->region.surface); }/* full screen update */ -dpy_gfx_update (dpy->con,0 ,0 , -surface_width (dpy->region.surface), -surface_height (dpy->region.surface)); +qemu_console_update (dpy->con,0 ,0 , +surface_width (dpy->region.surface), +surface_height (dpy->region.surface));return true; err:
@@ -493,7 +493,7 @@ static const GraphicHwOps vfio_display_region_ops = {static bool vfio_display_region_init (VFIOPCIDevice *vdev,Error **errp) { vdev->dpy =g_new0 (VFIODisplay,1 ); - vdev->dpy->con =graphic_console_init (DEVICE (vdev),0 , + vdev->dpy->con =qemu_graphic_console_create (DEVICE (vdev),0 , &vfio_display_region_ops, vdev);if (vdev->enable_ramfb) {
@@ -553,7 +553,7 @@ void vfio_display_finalize(VFIOPCIDevice *vdev)return ; } -graphic_console_close (vdev->dpy->con); +qemu_graphic_console_close (vdev->dpy->con);vfio_display_dmabuf_exit (vdev->dpy);vfio_display_region_exit (vdev->dpy);vfio_display_edid_exit (vdev->dpy);
ui/console-vc.c +6 -6
@@ -90,15 +90,15 @@ static void text_console_update(void *opaque, uint32_t *chardata) s->vt.cells[src].t_attrib.bgcol, s->vt.cells[src].t_attrib.bold); } -dpy_text_update (QEMU_CONSOLE (s), s->vt.text_x[0 ], s->vt.text_y[0 ], - s->vt.text_x[1 ] - s->vt.text_x[0 ], i - s->vt.text_y[0 ]); +qemu_console_text_update (QEMU_CONSOLE (s), s->vt.text_x[0 ], s->vt.text_y[0 ], + s->vt.text_x[1 ] - s->vt.text_x[0 ], i - s->vt.text_y[0 ]); s->vt.text_x[0 ] = s->vt.width; s->vt.text_y[0 ] = s->vt.height; s->vt.text_x[1 ] =0 ; s->vt.text_y[1 ] =0 ; }if (s->vt.cursor_invalidate) { -dpy_text_cursor (QEMU_CONSOLE (s), s->vt.x, s->vt.y); +qemu_console_text_set_cursor (QEMU_CONSOLE (s), s->vt.x, s->vt.y); s->vt.cursor_invalidate =0 ; } }
@@ -186,14 +186,14 @@ static void vc_chr_set_echo(Chardev *chr, bool echo)void qemu_text_console_update_size (QemuTextConsole *c) { -dpy_text_resize (QEMU_CONSOLE (c), c->vt.width, c->vt.height); +qemu_console_text_resize (QEMU_CONSOLE (c), c->vt.width, c->vt.height); }static void text_console_image_update (QemuVT100 *vt,int x,int y,int width,int height) {QemuTextConsole *console =container_of (vt, QemuTextConsole, vt); -dpy_gfx_update (QEMU_CONSOLE (console), x, y, width, height); +qemu_console_update (QEMU_CONSOLE (console), x, y, width, height); }static void text_console_out_flush (QemuVT100 *vt)
@@ -232,7 +232,7 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **errp) s =QEMU_TEXT_CONSOLE (object_new (TYPE_QEMU_FIXED_TEXT_CONSOLE )); } -dpy_gfx_replace_surface (QEMU_CONSOLE (s),qemu_create_displaysurface (width, height)); +qemu_console_set_surface (QEMU_CONSOLE (s),qemu_create_displaysurface (width, height));if (vc->has_encoding) { drv->encoding = vc->encoding; }
ui/console.c +70 -70
399 lines not on this page · raw message
ui/curses.c +4 -4
@@ -1,8 +1,8 @@/* * QEMU curses/ncurses display driver -* +* * Copyright (c) 2005 Andrzej Zaborowski <[email protected]> -* +* * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights
@@ -275,11 +275,11 @@ static void curses_refresh(DisplayChangeListener *dcl)clear ();refresh ();curses_calc_pad (); -graphic_hw_invalidate (dcl->con); +qemu_console_hw_invalidate (dcl->con); invalidate =0 ; } -graphic_hw_text_update (dcl->con, screen); +qemu_console_hw_text_update (dcl->con, screen);while (1 ) {/* while there are any pending key strokes to process */
ui/dbus-console.c +2 -2
@@ -200,7 +200,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc, .height = arg_height, }; -if (!dpy_ui_info_supported (ddc->dcl.con)) { +if (!qemu_console_ui_info_supported (ddc->dcl.con)) { g_dbus_method_invocation_return_error(invocation, DBUS_DISPLAY_ERROR, DBUS_DISPLAY_ERROR_UNSUPPORTED,
@@ -208,7 +208,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc,return DBUS_METHOD_INVOCATION_HANDLED ; } -dpy_set_ui_info (ddc->dcl.con, &info, false); +qemu_console_set_ui_info (ddc->dcl.con, &info, false);qemu_dbus_display1_console_complete_set_uiinfo (ddc->iface, invocation);return DBUS_METHOD_INVOCATION_HANDLED ; }
ui/dbus-listener.c +5 -5
@@ -241,7 +241,7 @@ static void dbus_update_gl_cb(GObject *source_object, }#endif -graphic_hw_gl_block (ddl->dcl.con, false); +qemu_console_hw_gl_block (ddl->dcl.con, false);g_object_unref (ddl); }#endif
@@ -257,7 +257,7 @@ static void dbus_call_update_gl(DisplayChangeListener *dcl,glFlush ();#ifdef CONFIG_GBM -graphic_hw_gl_block (ddl->dcl.con, true); +qemu_console_hw_gl_block (ddl->dcl.con, true); qemu_dbus_display1_listener_call_update_dmabuf(ddl->proxy, x, y, w, h, G_DBUS_CALL_FLAGS_NONE,
@@ -276,7 +276,7 @@ static void dbus_call_update_gl(DisplayChangeListener *dcl,Error *err =NULL ;assert (ddl->d3d_texture); -graphic_hw_gl_block (ddl->dcl.con, true); +qemu_console_hw_gl_block (ddl->dcl.con, true);if (!d3d_texture2d_release0 (ddl->d3d_texture, &err)) {error_report_err (err);return ;
@@ -711,7 +711,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl) {DBusDisplayListener *ddl =container_of (dcl, DBusDisplayListener, dcl); -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con);if (!ddl->ds ||qemu_console_is_gl_blocked (ddl->dcl.con)) {return ;
@@ -740,7 +740,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl)static void dbus_refresh (DisplayChangeListener *dcl) { -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con); }#ifdef CONFIG_OPENGL
ui/egl-headless.c +2 -2
@@ -23,7 +23,7 @@ typedef struct egl_dpy {static void egl_refresh (DisplayChangeListener *dcl) { -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con); } static void egl_gfx_update(DisplayChangeListener *dcl,
@@ -161,7 +161,7 @@ static void egl_scanout_flush(DisplayChangeListener *dcl, }egl_fb_read (edpy->ds, &edpy->blit_fb); -dpy_gfx_update (edpy->dcl.con, x, y, w, h); +qemu_console_update (edpy->dcl.con, x, y, w, h); }static const DisplayChangeListenerOps egl_ops = {
ui/gtk-egl.c +3 -3
@@ -108,7 +108,7 @@ void gd_egl_draw(VirtualConsole *vc)qemu_set_fd_handler (fence_fd, gd_hw_gl_flushed,NULL , vc); return; } -graphic_hw_gl_block (vc->gfx.dcl.con, false); +qemu_console_hw_gl_block (vc->gfx.dcl.con, false); }#endif }else {
@@ -176,7 +176,7 @@ void gd_egl_refresh(DisplayChangeListener *dcl)return ; } -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con);if (vc->gfx.glupdates) { vc->gfx.glupdates =0 ;
@@ -405,7 +405,7 @@ void gd_egl_flush(DisplayChangeListener *dcl,if (vc->gfx.guest_fb.dmabuf && !qemu_dmabuf_get_draw_submitted (vc->gfx.guest_fb.dmabuf)) { -graphic_hw_gl_block (vc->gfx.dcl.con, true); +qemu_console_hw_gl_block (vc->gfx.dcl.con, true);qemu_dmabuf_set_draw_submitted (vc->gfx.guest_fb.dmabuf, true);gtk_egl_set_scanout_mode (vc, true);gtk_widget_queue_draw_area (area, x, y, w, h);
ui/gtk-gl-area.c +3 -3
@@ -131,7 +131,7 @@ void gd_gl_area_draw(VirtualConsole *vc)qemu_set_fd_handler (fence_fd, gd_hw_gl_flushed,NULL , vc); return; } -graphic_hw_gl_block (vc->gfx.dcl.con, false); +qemu_console_hw_gl_block (vc->gfx.dcl.con, false); }#endif }else {
@@ -195,7 +195,7 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl) } } -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con);if (vc->gfx.glupdates) { vc->gfx.glupdates =0 ;
@@ -347,7 +347,7 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,if (vc->gfx.guest_fb.dmabuf && !qemu_dmabuf_get_draw_submitted (vc->gfx.guest_fb.dmabuf)) { -graphic_hw_gl_block (vc->gfx.dcl.con, true); +qemu_console_hw_gl_block (vc->gfx.dcl.con, true);qemu_dmabuf_set_draw_submitted (vc->gfx.guest_fb.dmabuf, true);gtk_gl_area_set_scanout_mode (vc, true); }
ui/gtk.c +9 -9
@@ -436,7 +436,7 @@ static void gd_update(DisplayChangeListener *dcl,static void gd_refresh (DisplayChangeListener *dcl) { -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con); }static GdkDevice *gd_get_pointer (GdkDisplay *dpy)
@@ -602,7 +602,7 @@ void gd_hw_gl_flushed(void *vcon)qemu_set_fd_handler (fence_fd,NULL ,NULL ,NULL );close (fence_fd);qemu_dmabuf_set_fence_fd (dmabuf,-1 ); -graphic_hw_gl_block (vc->gfx.dcl.con, false); +qemu_console_hw_gl_block (vc->gfx.dcl.con, false); } }
@@ -729,27 +729,27 @@ static void gd_set_ui_refresh_rate(VirtualConsole *vc, int refresh_rate) {QemuUIInfo info; -if (!dpy_ui_info_supported (vc->gfx.dcl.con)) { +if (!qemu_console_ui_info_supported (vc->gfx.dcl.con)) {return ; } - info = *dpy_get_ui_info (vc->gfx.dcl.con); + info = *qemu_console_get_ui_info (vc->gfx.dcl.con); info.refresh_rate = refresh_rate; -dpy_set_ui_info (vc->gfx.dcl.con, &info, true); +qemu_console_set_ui_info (vc->gfx.dcl.con, &info, true); }static void gd_set_ui_size (VirtualConsole *vc,gint width,gint height) {QemuUIInfo info; -if (!dpy_ui_info_supported (vc->gfx.dcl.con)) { +if (!qemu_console_ui_info_supported (vc->gfx.dcl.con)) {return ; } - info = *dpy_get_ui_info (vc->gfx.dcl.con); + info = *qemu_console_get_ui_info (vc->gfx.dcl.con); info.width = width; info.height = height; -dpy_set_ui_info (vc->gfx.dcl.con, &info, true); +qemu_console_set_ui_info (vc->gfx.dcl.con, &info, true); }#if defined(CONFIG_OPENGL )
@@ -2333,7 +2333,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,gd_connect_vc_gfx_signals (vc); group =gd_vc_menu_init (s, vc, idx, group, view_menu); -if (dpy_ui_info_supported (vc->gfx.dcl.con)) { +if (qemu_console_ui_info_supported (vc->gfx.dcl.con)) { zoom_to_fit = true; }if (s->opts->u.gtk.has_zoom_to_fit) {
ui/sdl2-2d.c +1 -1
@@ -129,7 +129,7 @@ void sdl2_2d_refresh(DisplayChangeListener *dcl) struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);assert (!scon->opengl); -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con);sdl2_poll_events (scon); }
ui/sdl2-gl.c +1 -1
@@ -115,7 +115,7 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)assert (scon->opengl); -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con);if (scon->updates && scon->real_window) { scon->updates =0 ;sdl2_gl_render_surface (scon);
ui/sdl2.c +3 -3
@@ -604,7 +604,7 @@ static void handle_windowevent(SDL_Event *ev) .width = ev->window.data1, .height = ev->window.data2, }; -dpy_set_ui_info (scon->dcl.con, &info, true); +qemu_console_set_ui_info (scon->dcl.con, &info, true); }sdl2_redraw (scon);break ;
@@ -632,10 +632,10 @@ static void handle_windowevent(SDL_Event *ev) }break ;case SDL_WINDOWEVENT_RESTORED : -update_displaychangelistener (&scon->dcl,GUI_REFRESH_INTERVAL_DEFAULT ); +qemu_console_listener_set_refresh (&scon->dcl,GUI_REFRESH_INTERVAL_DEFAULT );break ;case SDL_WINDOWEVENT_MINIMIZED : -update_displaychangelistener (&scon->dcl,500 ); +qemu_console_listener_set_refresh (&scon->dcl,500 );break ;case SDL_WINDOWEVENT_CLOSE :if (qemu_console_is_graphic (scon->dcl.con)) {
ui/spice-display.c +8 -8
@@ -468,7 +468,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque)assert (ssd->dcl.con);cursor_ref (c);qemu_mutex_unlock (&ssd->lock); -dpy_cursor_define (ssd->dcl.con, c); +qemu_console_set_cursor (ssd->dcl.con, c);qemu_mutex_lock (&ssd->lock);cursor_unref (c); }
@@ -481,7 +481,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque) ssd->mouse_x =-1 ; ssd->mouse_y =-1 ;qemu_mutex_unlock (&ssd->lock); -dpy_mouse_set (ssd->dcl.con, x, y, true); +qemu_console_set_mouse (ssd->dcl.con, x, y, true); }else {qemu_mutex_unlock (&ssd->lock); }
@@ -489,7 +489,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque)void qemu_spice_display_refresh (SimpleSpiceDisplay *ssd) { -graphic_hw_update (ssd->dcl.con); +qemu_console_hw_update (ssd->dcl.con); WITH_QEMU_LOCK_GUARD(&ssd->lock) {if (QTAILQ_EMPTY (&ssd->updates) && ssd->ds) {
@@ -668,7 +668,7 @@ static int interface_client_monitors_config(QXLInstance *sin,QemuUIInfo info;int head; -if (!dpy_ui_info_supported (ssd->dcl.con)) { +if (!qemu_console_ui_info_supported (ssd->dcl.con)) {return 0 ;/* == not supported by guest */ }
@@ -676,7 +676,7 @@ static int interface_client_monitors_config(QXLInstance *sin,return 1 ; } - info = *dpy_get_ui_info (ssd->dcl.con); + info = *qemu_console_get_ui_info (ssd->dcl.con); head =qemu_console_get_index (ssd->dcl.con);if (mc->num_of_monitors > head) {
@@ -690,7 +690,7 @@ static int interface_client_monitors_config(QXLInstance *sin, }trace_qemu_spice_ui_info (ssd->qxl.id, info.width, info.height); -dpy_set_ui_info (ssd->dcl.con, &info, false); +qemu_console_set_ui_info (ssd->dcl.con, &info, false);return 1 ; }
@@ -817,7 +817,7 @@ static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block) }else {timer_del (ssd->gl_unblock_timer); } -graphic_hw_gl_block (ssd->dcl.con, block); +qemu_console_hw_gl_block (ssd->dcl.con, block); }static void qemu_spice_gl_unblock_bh (void *opaque)
@@ -861,7 +861,7 @@ static void spice_gl_refresh(DisplayChangeListener *dcl)return ; } -graphic_hw_update (dcl->con); +qemu_console_hw_update (dcl->con);if (ssd->gl_updates && ssd->have_surface) {qemu_spice_gl_block (ssd, true);glFlush ();
ui/vnc.c +11 -11
@@ -2325,8 +2325,8 @@ static void set_pixel_format(VncState *vs, int bits_per_pixel,set_pixel_conversion (vs); -graphic_hw_invalidate (vs->vd->dcl.con); -graphic_hw_update (vs->vd->dcl.con); +qemu_console_hw_invalidate (vs->vd->dcl.con); +qemu_console_hw_update (vs->vd->dcl.con); }static void pixel_format_message (VncState *vs) {
@@ -2384,7 +2384,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)VncDisplay *vd = vs->vd;if (data[0 ] >3 ) { -update_displaychangelistener (&vd->dcl,VNC_REFRESH_INTERVAL_BASE ); +qemu_console_listener_set_refresh (&vd->dcl,VNC_REFRESH_INTERVAL_BASE ); }switch (data[0 ]) {
@@ -2638,9 +2638,9 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) h =read_u16 (data,4 );trace_vnc_msg_client_set_desktop_size (vs, vs->ioc, w, h, screens); -if (dpy_ui_info_supported (vs->vd->dcl.con)) { +if (qemu_console_ui_info_supported (vs->vd->dcl.con)) {QemuUIInfo info = { .width = w, .height = h }; -dpy_set_ui_info (vs->vd->dcl.con, &info, false); +qemu_console_set_ui_info (vs->vd->dcl.con, &info, false);vnc_desktop_resize_ext (vs,4 /* Request forwarded */ ); }else {vnc_desktop_resize_ext (vs,3 /* Invalid screen layout */ );
@@ -3242,14 +3242,14 @@ static void vnc_refresh(DisplayChangeListener *dcl)int has_dirty, rects =0 ;if (QTAILQ_EMPTY (&vd->clients)) { -update_displaychangelistener (&vd->dcl,VNC_REFRESH_INTERVAL_MAX ); +qemu_console_listener_set_refresh (&vd->dcl,VNC_REFRESH_INTERVAL_MAX );return ; } -graphic_hw_update (vd->dcl.con); +qemu_console_hw_update (vd->dcl.con);if (vnc_trylock_display (vd)) { -update_displaychangelistener (&vd->dcl,VNC_REFRESH_INTERVAL_BASE ); +qemu_console_listener_set_refresh (&vd->dcl,VNC_REFRESH_INTERVAL_BASE );return ; }
@@ -3323,7 +3323,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc, sioc, websocket, vs->auth, vs->subauth);VNC_DEBUG ("New client on socket %p\n" , vs->sioc); -update_displaychangelistener (&vd->dcl,VNC_REFRESH_INTERVAL_BASE ); +qemu_console_listener_set_refresh (&vd->dcl,VNC_REFRESH_INTERVAL_BASE );qio_channel_set_blocking (vs->ioc, false, &error_abort);g_clear_handle_id (&vs->ioc_tag, g_source_remove);if (websocket) {
@@ -3363,7 +3363,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,vnc_update_server_surface (vd); } -graphic_hw_update (vd->dcl.con); +qemu_console_hw_update (vd->dcl.con);if (!vs->websocket) {vnc_start_protocol (vs);
@@ -3419,7 +3419,7 @@ static void vmstate_change_handler(void *opaque, bool running, RunState state)if (state !=RUN_STATE_RUNNING ) {return ; } -update_displaychangelistener (&vd->dcl,VNC_REFRESH_INTERVAL_BASE ); +qemu_console_listener_set_refresh (&vd->dcl,VNC_REFRESH_INTERVAL_BASE ); }static bool vnc_display_open (VncDisplay *vd,Error **errp);
hw/display/apple-gfx.m +8 -8
@@ -317,8 +317,8 @@ static void apple_gfx_render_frame_completed_bh(void *opaque) copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->surface)); if (s->gfx_update_requested) { s->gfx_update_requested = false; - dpy_gfx_update_full(s->con); - graphic_hw_update_done(s->con); + qemu_console_update_full(s->con); + qemu_console_hw_update_done(s->con); s->new_frame_ready = false; } else { s->new_frame_ready = true;
@@ -337,7 +337,7 @@ static bool apple_gfx_fb_update_display(void *opaque) assert(bql_locked()); if (s->new_frame_ready) { - dpy_gfx_update_full(s->con); + qemu_console_update_full(s->con); s->new_frame_ready = false; } else if (s->pending_frames > 0) { s->gfx_update_requested = true;
@@ -380,14 +380,14 @@ static void set_mode(AppleGFXState *s, uint32_t width, uint32_t height) (s->texture.storageMode == MTLStorageModeManaged); } - dpy_gfx_replace_surface(s->con, s->surface); + qemu_console_set_surface(s->con, s->surface); } static void update_cursor(AppleGFXState *s) { assert(bql_locked()); - dpy_mouse_set(s->con, s->pgdisp.cursorPosition.x, - s->pgdisp.cursorPosition.y, qatomic_read(&s->cursor_show)); + qemu_console_set_mouse(s->con, s->pgdisp.cursorPosition.x, + s->pgdisp.cursorPosition.y, qatomic_read(&s->cursor_show)); } static void update_cursor_bh(void *opaque)
@@ -443,7 +443,7 @@ static void set_cursor_glyph(void *opaque) } px_data += padding_bytes_per_row; } - dpy_cursor_define(s->con, s->cursor); + qemu_console_set_cursor(s->con, s->cursor); update_cursor(s); } [glyph release];
@@ -792,7 +792,7 @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev, apple_gfx_create_display_mode_array(display_modes, num_display_modes); [mode_array release]; - s->con = graphic_console_init(dev, 0, &apple_gfx_fb_ops, s); + s->con = qemu_graphic_console_create(dev, 0, &apple_gfx_fb_ops, s); return true; }
ui/cocoa.m +5 -5
@@ -421,7 +421,7 @@ - (void) selectConsoleLocked:(unsigned int)index return; } - unregister_displaychangelistener(&dcl); + qemu_console_unregister_listener(&dcl); qkbd_state_switch_console(kbd, con); qemu_console_register_listener(con, &dcl, &dcl_ops); [self notifyMouseModeChange];
@@ -669,8 +669,8 @@ - (void) updateUIInfoLocked CVTime period = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink); CVDisplayLinkRelease(displayLink); if (!(period.flags & kCVTimeIsIndefinite)) { - update_displaychangelistener(&dcl, - 1000 * period.timeValue / period.timeScale); + qemu_console_listener_set_refresh(&dcl, + 1000 * period.timeValue / period.timeScale); info.refresh_rate = (int64_t)1000 * period.timeScale / period.timeValue; } }
@@ -688,7 +688,7 @@ - (void) updateUIInfoLocked info.width = frameSize.width * [[self window] backingScaleFactor]; info.height = frameSize.height * [[self window] backingScaleFactor]; - dpy_set_ui_info(dcl.con, &info, TRUE); + qemu_console_set_ui_info(dcl.con, &info, TRUE); } #pragma clang diagnostic pop
@@ -2056,7 +2056,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl) NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n"); - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); if (cbchangecount != [[NSPasteboard generalPasteboard] changeCount]) { qemu_clipboard_info_unref(cbinfo);
Signature · 1 line
2.54.0
[PULL v2 19/33] ui/console-vc: move VT100 emulation into separate unit
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Move the VT100 terminal emulation code into dedicated ui/vt100.c and ui/vt100.h files, completing the extraction from console-vc.c started in the previous patches. This makes the VT100 layer a self-contained module that can be reused independently of the chardev/console infrastructure.
The code is moved as-is, with minor coding style fixes (adding missing braces, fixing whitespace) applied during the move.
--- ui/console-priv.h | 1 - ui/vt100.h | 95 ++++ ui/console-vc-stubs.c | 1 + ui/console-vc.c | 1033 +---------------------------------------- ui/console.c | 2 + ui/vt100.c | 984 +++++++++++++++++++++++++++++++++++++++ ui/meson.build | 4 +- 7 files changed, 1086 insertions(+), 1034 deletions(-) create mode 100644 ui/vt100.h create mode 100644 ui/vt100.c
ui/console-priv.h +0 -1
@@ -30,7 +30,6 @@ struct QemuConsole { };void qemu_text_console_update_size (QemuTextConsole *c); -void vt100_update_cursor (void );void qemu_text_console_handle_keysym (QemuTextConsole *s,int keysym);#endif
ui/vt100.h new file +95 -0
95 lines not on this page · raw message
ui/console-vc-stubs.c +1 -0
@@ -9,6 +9,7 @@#include "qemu/option.h" #include "chardev/char.h" #include "ui/console-priv.h" +#include "vt100.h" void qemu_text_console_update_size (QemuTextConsole *c) {
ui/console-vc.c +1 -1032
1,095 lines not on this page · raw message
ui/console.c +2 -0
@@ -39,6 +39,8 @@#include "system/memory.h" #include "qom/object.h" #include "qemu/memfd.h" +#include "ui/vt100.h" +#include "vgafont.h" #include "console-priv.h"
ui/vt100.c new file +984 -0
984 lines not on this page · raw message
ui/meson.build +3 -1
@@ -3,6 +3,7 @@ system_ss.add(png) system_ss.add(files( 'clipboard.c', 'console.c', + 'cp437.c', 'cursor.c', 'display-surface.c', 'dmabuf.c',
@@ -17,8 +18,9 @@ system_ss.add(files( 'ui-qmp-cmds.c', 'util.c', 'vgafont.c', + 'vt100.c', )) -system_ss.add(when: pixman, if_true: files('console-vc.c', 'cp437.c'), if_false: files('console-vc-stubs.c')) +system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: files('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c')) endif
Signature · 1 line
2.54.0
[PULL v2 06/33] ui/input: do not assert() when tracing invalid input
In reply to [email protected]From: Marc-André Lureau <[email protected]>
It's possible to reach an assert() in the input tracing code by sending some out of range input values via D-Bus for ex:
#0 0x00007fec8652186c in __pthread_kill_implementation () at /lib64/libc.so.6 #1 0x00007fec864c648e in raise () at /lib64/libc.so.6 #2 0x00007fec864ad7b3 in abort () at /lib64/libc.so.6 #3 0x00007fec864ae804 in __libc_message_impl.cold () at /lib64/libc.so.6 #4 0x00007fec864be345 in __assert_fail () at /lib64/libc.so.6 #5 0x00005597964c551e in qapi_enum_lookup[cold] () #6 0x000055979650514a in qemu_input_event_send_impl () #7 0x0000559796505a4d in qemu_input_queue_btn () #8 0x00007fec85780c19 in dbus_mouse_press () at /usr/bin/../lib64/qemu/ui-dbus.so #9 0x00007fec857912fc in _g_dbus_codegen_marshal_BOOLEAN__OBJECT_UINT.part.0 () at /usr/bin/../lib64/qemu/ui-dbus.so
#10 0x00007fec874cce7c in g_closure_invoke () at /lib64/libgobject-2.0.so.0
#11 0x00007fec874eb849 in signal_emit_unlocked_R.isra.0 () at /lib64/libgobject-2.0.so.0
#12 0x00007fec874ec66f in g_signal_emitv () at /lib64/libgobject-2.0.so.0
#13 0x00007fec85797e0a in _qemu_dbus_display1_mouse_skeleton_handle_method_call () at /usr/bin/../lib64/qemu/ui-dbus.so
Other paths in input code accept out-of-range values (qemu_input_key_value_to_number etc). Let it pass tracing.
--- ui/input.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
ui/input.c +4 -4
@@ -207,22 +207,22 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)break ;case INPUT_EVENT_KIND_BTN : btn = evt->u.btn.data; - name =InputButton_str (btn->button); + name = btn->button <INPUT_BUTTON__MAX ?InputButton_str (btn->button) :"invalid" ;trace_input_event_btn (idx, name, btn->down);break ;case INPUT_EVENT_KIND_REL : move = evt->u.rel.data; - name =InputAxis_str (move->axis); + name = move->axis <INPUT_AXIS__MAX ?InputAxis_str (move->axis) :"invalid" ;trace_input_event_rel (idx, name, move->value);break ;case INPUT_EVENT_KIND_ABS : move = evt->u.abs.data; - name =InputAxis_str (move->axis); + name = move->axis <INPUT_AXIS__MAX ?InputAxis_str (move->axis) :"invalid" ;trace_input_event_abs (idx, name, move->value);break ;case INPUT_EVENT_KIND_MTT : mtt = evt->u.mtt.data; - name =InputAxis_str (mtt->axis); + name = mtt->axis <INPUT_AXIS__MAX ?InputAxis_str (mtt->axis) :"invalid" ;trace_input_event_mtt (idx, name, mtt->value);break ;case INPUT_EVENT_KIND__MAX :
Signature · 1 line
2.54.0
[PULL v2 27/33] ui/console: add doc comment for qemu_console_{un}register_listener()
In reply to [email protected]From: Marc-André Lureau <[email protected]>
--- ui/console.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
ui/console.c +20 -0
@@ -572,6 +572,17 @@ dcl_set_graphic_cursor(DisplayChangeListener *dcl, QemuGraphicConsole *con) } } +/* +* qemu_console_register_listener: +* @con: the console to attach the listener to +* @dcl: the display change listener to register +* @ops: the listener operations (callbacks for display updates) +* +* Register a display change listener on a console. The listener +* must not already be registered (i.e. @dcl->ds must be NULL). +* This sets up the listener, adds it to the display state, triggers +* an initial display update, and setup the cursor. +*/ void qemu_console_register_listener (QemuConsole *con,DisplayChangeListener *dcl,const DisplayChangeListenerOps *ops)
@@ -605,6 +616,15 @@ void update_displaychangelistener(DisplayChangeListener *dcl, } } +/* +* qemu_console_unregister_listener: +* @dcl: the display change listener to unregister +* +* Unregister a display change listener, removing it from the +* display state's listener list. If the listener is not currently +* registered (@dcl->ds is NULL), this is a no-op. After unregistering, +* the display refresh timer is recalculated. +*/ void qemu_console_unregister_listener (DisplayChangeListener *dcl) {DisplayState *ds = dcl->ds;
Signature · 1 line
2.54.0
[PULL v2 10/33] ui/console: add vc encoding=utf8/cp437 option
In reply to [email protected]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.
--- 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(-)
qapi/char.json +28 -2
@@ -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' } ##
include/chardev/char.h +1 -0
@@ -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);
chardev/char.c +10 -0
@@ -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,
ui/console-vc.c +12 -0
@@ -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 = {
ui/dbus.c +13 -0
@@ -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 = {
qemu-options.hx +5 -2
@@ -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``.
Signature · 1 line
2.54.0
[PULL v2 32/33] tools/qemu-vnc: add standalone VNC server over D-Bus
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Add a standalone VNC server binary that connects to a running QEMU instance via the D-Bus display interface (org.qemu.Display1, via the bus or directly p2p). This allows serving a VNC display without compiling VNC support directly into the QEMU system emulator, and enables running the VNC server as a separate process with independent lifecycle and privilege domain.
Built only when both VNC and D-Bus display support are enabled. If we wanted to have qemu -vnc disabled, and qemu-vnc built, we would need to split CONFIG_VNC. This is left as a future exercise.
Current omissions include some QEMU VNC runtime features (better handled via restart), legacy options, and Windows support.
--- MAINTAINERS | 5 + docs/conf.py | 3 + docs/interop/dbus-display.rst | 2 + docs/interop/dbus-vnc.rst | 26 + docs/interop/index.rst | 1 + docs/meson.build | 1 + docs/tools/index.rst | 1 + docs/tools/qemu-vnc.rst | 226 ++++++ meson.build | 17 + tools/qemu-vnc/qemu-vnc.h | 49 ++ tools/qemu-vnc/trace.h | 4 + tests/qtest/dbus-vnc-test.c | 1346 +++++++++++++++++++++++++++++++++ tools/qemu-vnc/audio.c | 308 ++++++++ tools/qemu-vnc/chardev.c | 148 ++++ tools/qemu-vnc/clipboard.c | 376 +++++++++ tools/qemu-vnc/console.c | 170 +++++ tools/qemu-vnc/dbus.c | 474 ++++++++++++ tools/qemu-vnc/display.c | 456 +++++++++++ tools/qemu-vnc/input.c | 239 ++++++ tools/qemu-vnc/qemu-vnc.c | 581 ++++++++++++++ tools/qemu-vnc/stubs.c | 62 ++ tools/qemu-vnc/utils.c | 59 ++ meson_options.txt | 2 + scripts/meson-buildoptions.sh | 3 + tests/dbus-daemon.sh | 14 +- tests/qtest/meson.build | 13 + tools/qemu-vnc/meson.build | 26 + tools/qemu-vnc/qemu-vnc1.xml | 201 +++++ tools/qemu-vnc/trace-events | 21 + 29 files changed, 4831 insertions(+), 3 deletions(-) create mode 100644 docs/interop/dbus-vnc.rst create mode 100644 docs/tools/qemu-vnc.rst create mode 100644 tools/qemu-vnc/qemu-vnc.h create mode 100644 tools/qemu-vnc/trace.h create mode 100644 tests/qtest/dbus-vnc-test.c create mode 100644 tools/qemu-vnc/audio.c create mode 100644 tools/qemu-vnc/chardev.c create mode 100644 tools/qemu-vnc/clipboard.c create mode 100644 tools/qemu-vnc/console.c create mode 100644 tools/qemu-vnc/dbus.c create mode 100644 tools/qemu-vnc/display.c create mode 100644 tools/qemu-vnc/input.c create mode 100644 tools/qemu-vnc/qemu-vnc.c create mode 100644 tools/qemu-vnc/stubs.c create mode 100644 tools/qemu-vnc/utils.c create mode 100644 tools/qemu-vnc/meson.build create mode 100644 tools/qemu-vnc/qemu-vnc1.xml create mode 100644 tools/qemu-vnc/trace-events
MAINTAINERS +5 -0
@@ -2830,6 +2830,11 @@ F: docs/interop/vhost-user-gpu.rst F: contrib/vhost-user-gpu F: hw/display/vhost-user-* +qemu-vnc: +M: Marc-André Lureau <[email protected]> +S: Maintained +F: tools/qemu-vnc + Cirrus VGA M: Gerd Hoffmann <[email protected]> S: Odd Fixes
docs/conf.py +3 -0
@@ -333,6 +333,9 @@ ('tools/qemu-trace-stap', 'qemu-trace-stap', 'QEMU SystemTap trace tool', [], 1), + ('tools/qemu-vnc', 'qemu-vnc', + 'QEMU standalone VNC server', + [], 1), ] man_make_section_directory = False
docs/interop/dbus-display.rst +2 -0
@@ -1,3 +1,5 @@ +.. _dbus-display: + D-Bus display =============
docs/interop/dbus-vnc.rst new file +26 -0
@@ -0,0 +1,26 @@ +D-Bus VNC +========= + +The ``qemu-vnc`` standalone VNC server exposes a D-Bus interface for management +and monitoring of VNC connections. + +The service is available on the bus under the well-known name ``org.qemu.vnc``. +Objects are exported under ``/org/qemu/Vnc1/``. + +.. contents:: + :local: + :depth: 1 + +.. only:: sphinx4 + + .. dbus-doc:: tools/qemu-vnc/qemu-vnc1.xml + +.. only:: not sphinx4 + + .. warning:: + Sphinx 4 is required to build D-Bus documentation. + + This is the content of ``tools/qemu-vnc/qemu-vnc1.xml``: + + .. literalinclude:: ../../tools/qemu-vnc/qemu-vnc1.xml + :language: xml
docs/interop/index.rst +1 -0
@@ -13,6 +13,7 @@ are useful for making QEMU interoperate with other software. dbus dbus-vmstate dbus-display + dbus-vnc live-block-operations nbd parallels
docs/meson.build +1 -0
@@ -54,6 +54,7 @@ if build_docs 'qemu-pr-helper.8': (have_tools ? 'man8' : ''), 'qemu-storage-daemon.1': (have_tools ? 'man1' : ''), 'qemu-trace-stap.1': (stap.found() ? 'man1' : ''), + 'qemu-vnc.1': (have_qemu_vnc ? 'man1' : ''), 'qemu.1': 'man1', 'qemu-block-drivers.7': 'man7', 'qemu-cpu-models.7': 'man7'
docs/tools/index.rst +1 -0
@@ -16,3 +16,4 @@ command line utilities and other standalone programs. qemu-pr-helper qemu-trace-stap qemu-vmsr-helper + qemu-vnc
docs/tools/qemu-vnc.rst new file +226 -0
226 lines not on this page · raw message
meson.build +17 -0
@@ -2338,6 +2338,17 @@ dbus_display = get_option('dbus_display') \ error_message: gdbus_codegen_error.format('-display dbus')) \ .allowed() +have_qemu_vnc = get_option('qemu_vnc') \ + .require(have_tools, + error_message: 'qemu-vnc requires tools support') \ + .require(dbus_display, + error_message: 'qemu-vnc requires dbus-display support') \ + .require(vnc.found(), + error_message: 'qemu-vnc requires vnc support') \ + .require(host_os != 'windows', + error_message: 'qemu-vnc is not currently supported on Windows') \ + .allowed() + have_virtfs = get_option('virtfs') \ .require(host_os == 'linux' or host_os == 'darwin' or host_os == 'freebsd', error_message: 'virtio-9p (virtfs) requires Linux or macOS or FreeBSD') \
@@ -3591,6 +3602,7 @@ trace_events_subdirs = [ 'monitor', 'util', 'gdbstub', + 'tools/qemu-vnc', ] if have_linux_user trace_events_subdirs += [ 'linux-user' ]
@@ -4580,6 +4592,10 @@ if have_tools subdir('contrib/ivshmem-client') subdir('contrib/ivshmem-server') endif + + if have_qemu_vnc + subdir('tools/qemu-vnc') + endif endif if stap.found()
@@ -4915,6 +4931,7 @@ if vnc.found() summary_info += {'VNC SASL support': sasl} summary_info += {'VNC JPEG support': jpeg} endif +summary_info += {'VNC D-Bus server (qemu-vnc)': have_qemu_vnc} summary_info += {'spice protocol support': spice_protocol} if spice_protocol.found() summary_info += {' spice server support': spice}
tools/qemu-vnc/qemu-vnc.h new file +49 -0
49 lines not on this page · raw message
tools/qemu-vnc/trace.h new file +4 -0
@@ -0,0 +1,4 @@ +/* +* SPDX-License-Identifier: GPL-2.0-or-later +*/ +#include "trace/trace-tools_qemu_vnc.h"
tests/qtest/dbus-vnc-test.c new file +1346 -0
1,346 lines not on this page · raw message
tools/qemu-vnc/audio.c new file +308 -0
308 lines not on this page · raw message
tools/qemu-vnc/chardev.c new file +148 -0
148 lines not on this page · raw message
tools/qemu-vnc/clipboard.c new file +376 -0
376 lines not on this page · raw message
tools/qemu-vnc/console.c new file +170 -0
170 lines not on this page · raw message
tools/qemu-vnc/dbus.c new file +474 -0
263 lines not on this page · raw message
tools/qemu-vnc/display.c new file +456 -0
456 lines not on this page · raw message
tools/qemu-vnc/input.c new file +239 -0
239 lines not on this page · raw message
tools/qemu-vnc/qemu-vnc.c new file +581 -0
581 lines not on this page · raw message
tools/qemu-vnc/stubs.c new file +62 -0
62 lines not on this page · raw message
tools/qemu-vnc/utils.c new file +59 -0
59 lines not on this page · raw message
tools/qemu-vnc/qemu-vnc1.xml new file +201 -0
201 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.54.0
Part of the diff is not shown here. View the raw message.
[PULL v2 30/33] ui: extract common sources into a static library
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Move clipboard, cursor, display-surface, input-keymap, kbd-state, keymaps, vt100, and qemu-pixman into a separate static library 'qemuui'. This allows these common UI sources to be linked by targets outside of the system emulator build, such as standalone VNC or D-Bus display binaries.
keymaps generation has to be moved earlier, so that header dependency are resolved first.
The library objects are re-exported via a dependency so existing system_ss consumers are unaffected.
--- ui/meson.build | 103 ++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 48 deletions(-)
ui/meson.build +55 -48
@@ -1,25 +1,67 @@ -system_ss.add(pixman) +keymaps = [ + ['atset1', 'qcode'], + ['linux', 'qcode'], + ['qcode', 'atset1'], + ['qcode', 'atset2'], + ['qcode', 'atset3'], + ['qcode', 'linux'], + ['qcode', 'qnum'], + ['qcode', 'sun'], + ['qnum', 'qcode'], + ['usb', 'qcode'], + ['win32', 'qcode'], + ['x11', 'qcode'], + ['xorgevdev', 'qcode'], + ['xorgkbd', 'qcode'], + ['xorgxquartz', 'qcode'], + ['xorgxwin', 'qcode'], + ['osx', 'qcode'], +] + +if have_system or xkbcommon.found() + keycodemapdb_proj = subproject('keycodemapdb', required: true) + foreach e : keymaps + output = 'input-keymap-@0@-to-@[email protected]'.format(e[0], e[1]) + genh += custom_target(output, + output: output, + capture: true, + input: keycodemapdb_proj.get_variable('keymaps_csv'), + command: [python, keycodemapdb_proj.get_variable('keymap_gen').full_path(), + 'code-map', '--lang', 'glib2', + '--varname', 'qemu_input_map_@0@_to_@1@'.format(e[0], e[1]), + '@INPUT0@', e[0], e[1]]) + endforeach +endif + +libui_sources = files( + 'clipboard.c', + 'console.c', + 'cursor.c', + 'dmabuf.c', + 'display-surface.c', + 'input-keymap.c', + 'kbd-state.c', + 'keymaps.c', + 'qemu-pixman.c', + 'vgafont.c', + ) +if pixman.found() + libui_sources += files('cp437.c', 'vt100.c') +endif +libui = static_library('qemuui', libui_sources + genh, + dependencies: [pixman], + build_by_default: false) +ui = declare_dependency(objects: libui.extract_all_objects(recursive: false), dependencies: [pixman]) system_ss.add(png) system_ss.add(files( - 'clipboard.c', - 'console.c', - 'cp437.c', - 'cursor.c', - 'display-surface.c', - 'dmabuf.c', - 'input-keymap.c', 'input-legacy.c', 'input-barrier.c', 'input.c', - 'kbd-state.c', - 'keymaps.c', - 'qemu-pixman.c', 'ui-hmp-cmds.c', 'ui-qmp-cmds.c', 'util.c', - 'vgafont.c', - 'vt100.c', )) +system_ss.add(ui) system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: files('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c'))
@@ -149,41 +191,6 @@ if spice.found() endif endif -keymaps = [ - ['atset1', 'qcode'], - ['linux', 'qcode'], - ['qcode', 'atset1'], - ['qcode', 'atset2'], - ['qcode', 'atset3'], - ['qcode', 'linux'], - ['qcode', 'qnum'], - ['qcode', 'sun'], - ['qnum', 'qcode'], - ['usb', 'qcode'], - ['win32', 'qcode'], - ['x11', 'qcode'], - ['xorgevdev', 'qcode'], - ['xorgkbd', 'qcode'], - ['xorgxquartz', 'qcode'], - ['xorgxwin', 'qcode'], - ['osx', 'qcode'], -] - -if have_system or xkbcommon.found() - keycodemapdb_proj = subproject('keycodemapdb', required: true) - foreach e : keymaps - output = 'input-keymap-@0@-to-@[email protected]'.format(e[0], e[1]) - genh += custom_target(output, - output: output, - capture: true, - input: keycodemapdb_proj.get_variable('keymaps_csv'), - command: [python, keycodemapdb_proj.get_variable('keymap_gen').full_path(), - 'code-map', '--lang', 'glib2', - '--varname', 'qemu_input_map_@0@_to_@1@'.format(e[0], e[1]), - '@INPUT0@', e[0], e[1]]) - endforeach -endif - subdir('shader') if have_system
Signature · 1 line
2.54.0
[PULL v2 31/33] tests/qtest: drop DBUS_VMSTATE_TEST_TMPDIR
In reply to [email protected]From: Marc-André Lureau <[email protected]>
It can rely on the location of the temporary configuration instead, so we don't have to set that environment variable on every test.
--- tests/qtest/dbus-vmstate-test.c | 2 -- tests/dbus-daemon.sh | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-)
tests/qtest/dbus-vmstate-test.c +0 -2
@@ -395,8 +395,6 @@ main(int argc, char **argv)exit (1 ); } -g_setenv ("DBUS_VMSTATE_TEST_TMPDIR" , workdir, true); -migration_test_add ("/dbus-vmstate/without-list" , test_dbus_vmstate_without_list); migration_test_add("/dbus-vmstate/with-list",
tests/dbus-daemon.sh +1 -1
@@ -26,7 +26,7 @@ write_config() cat > "$CONF" <<EOF <busconfig> <type>session</type> - <listen>unix:tmpdir=$DBUS_VMSTATE_TEST_TMPDIR</listen> + <listen>unix:tmpdir=$(dirname "$CONF")</listen> <policy context="default"> <!-- Holes must be punched in service configuration files for
Signature · 1 line
2.54.0
[PULL v2 33/33] qemu-options: document -chardev dbus
In reply to [email protected]From: uchouT <[email protected]>
Document the dbus backend introduced in commit 3e301c8d7ef0 ("ui/dbus:
add chardev backend & interface")
Message-ID: <[email protected]>
--- qemu-options.hx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
qemu-options.hx +14 -2
@@ -4077,6 +4077,9 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev, #if defined(CONFIG_SPICE) "-chardev spicevmc,id=id,name=name[,debug=debug][,logfile=PATH][,logappend=on|off]\n" "-chardev spiceport,id=id,name=name[,debug=debug][,logfile=PATH][,logappend=on|off]\n" +#endif +#if defined(CONFIG_DBUS_DISPLAY) + "-chardev dbus,id=id,name=name[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" #endif , QEMU_ARCH_ALL )
@@ -4088,8 +4091,8 @@ The general form of a character device option is: Backend is one of: ``null``, ``socket``, ``udp``, ``msmouse``, ``hub``, ``vc``, ``ringbuf``, ``file``, ``pipe``, ``console``, ``serial``, ``pty``, ``stdio``, ``braille``, ``parallel``, - ``spicevmc``, ``spiceport``. The specific backend will determine the - applicable options. + ``spicevmc``, ``spiceport``, ``dbus``. The specific backend will + determine the applicable options. Use ``-chardev help`` to print all available chardev backend types.
@@ -4408,6 +4411,15 @@ The available backends are: Connect to a spice port, allowing a Spice client to handle the traffic identified by a name (preferably a fqdn). + +``-chardev dbus,id=id,name=name`` + ``dbus`` is only available when D-Bus display support is built in. + + ``name`` name of the chardev as exported on the D-Bus display + interface + + Export the character device on the D-Bus display interface, so that + a D-Bus client can connect to it. ERST DEFHEADING()
Signature · 1 line
2.54.0
[PULL v2 29/33] ui/vnc: replace VNC_DEBUG with trace-events
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Replace #ifdef printf() with run-time trace events.
--- ui/vnc.h | 8 ----- ui/vnc-auth-sasl.c | 13 +++----- ui/vnc-enc-tight.c | 4 +-- ui/vnc-enc-zlib.c | 4 +-- ui/vnc-ws.c | 10 +++--- ui/vnc.c | 83 +++++++++++++++++----------------------------- ui/trace-events | 29 +++++++++++++++- 7 files changed, 73 insertions(+), 78 deletions(-)
ui/vnc.h +0 -8
@@ -46,14 +46,6 @@#include "vnc-enc-zrle.h" #include "ui/kbd-state.h" -// #define _VNC_DEBUG 1 - -#ifdef _VNC_DEBUG -#define VNC_DEBUG (fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) -#else -#define VNC_DEBUG (fmt, ...) do { } while (0) -#endif -/***************************************************************************** * * Core data structures
ui/vnc-auth-sasl.c +5 -8
@@ -73,10 +73,10 @@ size_t vnc_client_write_sasl(VncState *vs) {size_t ret; -VNC_DEBUG ("Write SASL: Pending output %p size %zd offset %zd " -"Encoded: %p size %d offset %d\n" , - vs->output.buffer, vs->output.capacity, vs->output.offset, - vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOffset); +trace_vnc_sasl_write_pending (vs, vs->output.buffer, vs->output.capacity, + vs->output.offset, vs->sasl.encoded, + vs->sasl.encodedLength, + vs->sasl.encodedOffset);if (!vs->sasl.encoded) {int err;
@@ -157,8 +157,7 @@ size_t vnc_client_read_sasl(VncState *vs)if (err !=SASL_OK )return vnc_client_io_error (vs,-1 ,NULL ); -VNC_DEBUG ("Read SASL Encoded %p size %ld Decoded %p size %d\n" , - encoded, ret, decoded, decodedLen); +trace_vnc_sasl_read_decoded (vs, encoded, ret, decoded, decodedLen);buffer_reserve (&vs->input, decodedLen);buffer_append (&vs->input, decoded, decodedLen);return decodedLen;
@@ -717,5 +716,3 @@ void start_auth_sasl(VncState *vs)error_free (local_err);vnc_client_error (vs); } - -
ui/vnc-enc-tight.c +2 -2
@@ -46,6 +46,7 @@#include "vnc.h" #include "vnc-enc-tight.h" #include "vnc-palette.h" +#include "trace.h" /* Compression level stuff. The following array contains various encoder parameters for each of 10 compression levels (0..9).
@@ -795,8 +796,7 @@ static int tight_init_stream(VncState *vs, VncTight *tight, int stream_id,if (zstream->opaque ==NULL ) {int err; -VNC_DEBUG ("VNC: TIGHT: initializing zlib stream %d\n" , stream_id); -VNC_DEBUG ("VNC: TIGHT: opaque = %p | vs = %p\n" , zstream->opaque, vs); +trace_vnc_tight_zlib_init (vs, stream_id, zstream->opaque); zstream->zalloc = vnc_zlib_zalloc; zstream->zfree = vnc_zlib_zfree;
ui/vnc-enc-zlib.c +2 -2
@@ -26,6 +26,7 @@#include "qemu/osdep.h" #include "vnc.h" +#include "trace.h" #define ZALLOC_ALIGNMENT 16
@@ -71,8 +72,7 @@ static int vnc_zlib_stop(VncState *vs, VncWorker *worker)if (zstream->opaque != vs) {int err; -VNC_DEBUG ("VNC: initializing zlib stream\n" ); -VNC_DEBUG ("VNC: opaque = %p | vs = %p\n" , zstream->opaque, vs); +trace_vnc_zlib_init (vs, zstream->opaque); zstream->zalloc = vnc_zlib_zalloc; zstream->zfree = vnc_zlib_zfree;
ui/vnc-ws.c +5 -5
@@ -32,11 +32,11 @@ static void vncws_tls_handshake_done(QIOTask *task,Error *err =NULL ;if (qio_task_propagate_error (task, &err)) { -VNC_DEBUG ("Handshake failed %s\n" ,error_get_pretty (err)); +trace_vnc_ws_tls_handshake_fail (vs,error_get_pretty (err));vnc_client_error (vs);error_free (err); }else { -VNC_DEBUG ("TLS handshake complete, starting websocket handshake\n" ); +trace_vnc_ws_tls_handshake_complete (vs);if (vs->ioc_tag) {g_source_remove (vs->ioc_tag); }
@@ -67,7 +67,7 @@ gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED, vs->vd->tlsauthzid, &err);if (!tls) { -VNC_DEBUG ("Failed to setup TLS %s\n" ,error_get_pretty (err)); +trace_vnc_ws_tls_setup_fail (vs,error_get_pretty (err));error_free (err);vnc_client_error (vs);return TRUE;
@@ -97,11 +97,11 @@ static void vncws_handshake_done(QIOTask *task,Error *err =NULL ;if (qio_task_propagate_error (task, &err)) { -VNC_DEBUG ("Websock handshake failed %s\n" ,error_get_pretty (err)); +trace_vnc_ws_handshake_fail (vs,error_get_pretty (err));vnc_client_error (vs);error_free (err); }else { -VNC_DEBUG ("Websock handshake complete, starting VNC protocol\n" ); +trace_vnc_ws_handshake_complete (vs);vnc_start_protocol (vs);if (vs->ioc_tag) {g_source_remove (vs->ioc_tag);
ui/vnc.c +31 -52
253 lines not on this page · raw message
ui/trace-events +28 -1
@@ -83,7 +83,7 @@ vnc_job_discard_rect(void *state, void *job, int x, int y, int w, int h) "VNC jo vnc_job_clamp_rect(void *state, void *job, int x, int y, int w, int h) "VNC job clamp rect state=%p job=%p offset=%d,%d size=%dx%d" vnc_job_clamped_rect(void *state, void *job, int x, int y, int w, int h) "VNC job clamp rect state=%p job=%p offset=%d,%d size=%dx%d" vnc_job_nrects(void *state, void *job, int nrects) "VNC job state=%p job=%p nrects=%d" -vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth init state=%p websock=%d auth=%d subauth=%d" +vnc_auth_init(void *display, int websock, int auth, int subauth, const char *name) "VNC auth init state=%p websock=%d auth=%d subauth=%d name=%s" vnc_auth_start(void *state, int method) "VNC client auth start state=%p method=%d" vnc_auth_pass(void *state, int method) "VNC client auth passed state=%p method=%d" vnc_auth_fail(void *state, int method, const char *message, const char *reason) "VNC client auth failed state=%p method=%d message=%s reason=%s"
@@ -97,6 +97,33 @@ vnc_auth_sasl_step(void *state, const void *clientdata, size_t clientlen, const vnc_auth_sasl_ssf(void *state, int ssf) "VNC client auth SASL SSF state=%p size=%d" vnc_auth_sasl_username(void *state, const char *name) "VNC client auth SASL user state=%p name=%s" vnc_auth_sasl_acl(void *state, int allow) "VNC client auth SASL ACL state=%p allow=%d" +vnc_set_share_mode(void *state, void *ioc, int old_mode, int new_mode) "VNC set share mode state=%p ioc=%p old=%d new=%d" +vnc_client_protocol_error(void *state) "VNC client protocol error state=%p" +vnc_client_write_wire(void *state, const void *data, size_t datalen, ssize_t ret) "VNC client write wire state=%p data=%p len=%zu ret=%zd" +vnc_client_write_plain(void *state, const void *buffer, size_t capacity, size_t offset, int wait_ssf) "VNC client write plain state=%p buffer=%p capacity=%zu offset=%zu wait_ssf=%d" +vnc_client_read_wire(void *state, const void *data, size_t datalen, ssize_t ret) "VNC client read wire state=%p data=%p len=%zu ret=%zd" +vnc_client_read_plain(void *state, const void *buffer, size_t capacity, size_t offset) "VNC client read plain state=%p buffer=%p capacity=%zu offset=%zu" +vnc_client_unknown_encoding(void *state, int index, int encoding) "VNC client unknown encoding state=%p index=%d encoding=0x%x" +vnc_client_invalid_audio_format(void *state, int fmt) "VNC client invalid audio format state=%p fmt=%d" +vnc_client_invalid_audio_channels(void *state, int channels) "VNC client invalid audio channel count state=%p channels=%d" +vnc_client_invalid_audio_freq(void *state, unsigned int freq) "VNC client invalid audio frequency state=%p freq=%u" +vnc_client_invalid_audio_msg(void *state, int msg) "VNC client invalid audio message state=%p msg=%d" +vnc_client_unknown_qemu_msg(void *state, int msg) "VNC client unknown QEMU msg state=%p msg=%d" +vnc_client_unknown_msg(void *state, int msg) "VNC client unknown msg state=%p msg=%d" +vnc_client_protocol_version(void *state, int major, int minor) "VNC client protocol version state=%p version=%d.%d" +vnc_client_protocol_version_malformed(void *state, const char *version) "VNC client malformed protocol version state=%p version=%s" +vnc_client_protocol_version_unsupported(void *state) "VNC client unsupported protocol version state=%p" +vnc_client_auth_method(void *state, int auth) "VNC client auth method state=%p auth=%d" +vnc_client_setup(void *state, void *ioc, int websocket, int auth, int subauth) "VNC client setup state=%p ioc=%p websocket=%d auth=%d subauth=%d" +vnc_ws_tls_handshake_fail(void *state, const char *msg) "VNC WS TLS handshake failed state=%p msg=%s" +vnc_ws_tls_handshake_complete(void *state) "VNC WS TLS handshake complete state=%p" +vnc_ws_tls_setup_fail(void *state, const char *msg) "VNC WS TLS setup failed state=%p msg=%s" +vnc_ws_handshake_fail(void *state, const char *msg) "VNC WS handshake failed state=%p msg=%s" +vnc_ws_handshake_complete(void *state) "VNC WS handshake complete state=%p" +vnc_sasl_write_pending(void *state, const void *buffer, size_t capacity, size_t offset, const void *encoded, int encoded_len, int encoded_offset) "VNC SASL write pending state=%p buffer=%p capacity=%zu offset=%zu encoded=%p encoded_len=%d encoded_offset=%d" +vnc_sasl_read_decoded(void *state, const void *encoded, size_t encoded_len, const void *decoded, unsigned int decoded_len) "VNC SASL read decoded state=%p encoded=%p encoded_len=%zu decoded=%p decoded_len=%u" +vnc_zlib_init(void *state, const void *opaque) "VNC zlib init state=%p opaque=%p" +vnc_tight_zlib_init(void *state, int stream_id, const void *opaque) "VNC tight zlib init state=%p stream=%d opaque=%p" # input.c
Signature · 1 line
2.54.0
[PULL v2 23/33] ui/vnc: clean up VNC displays on exit
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Previously, VNC displays were never torn down on QEMU exit, leaking resources and leaving connected clients with unclean disconnects.
Add vnc_cleanup() to free all VNC displays during qemu_cleanup(). Make vnc_display_close() initiate disconnection of active clients, and have vnc_display_free() drain the main loop until all clients have completed their teardown, instead of asserting the client list is empty.
--- include/ui/console.h | 1 + system/runstate.c | 5 +++++ ui/vnc.c | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-)
include/ui/console.h +1 -0
@@ -445,6 +445,7 @@ void vnc_parse(const char *str);int vnc_init_func (void *opaque,QemuOpts *opts,Error **errp);bool vnc_display_reload_certs (const char *id,Error **errp);bool vnc_display_update (DisplayUpdateOptionsVNC *arg,Error **errp); +void vnc_cleanup (void );/* input.c */ int index_from_key (const char *key,size_t key_length);
system/runstate.c +5 -0
@@ -61,6 +61,8 @@#include "system/confidential-guest-support.h" #include "system/system.h" #include "system/tpm.h" +#include "ui/console.h" +#include "trace.h" static NotifierList exit_notifiers =
@@ -1044,5 +1046,8 @@ void qemu_cleanup(int status)monitor_cleanup ();qemu_chr_cleanup ();user_creatable_cleanup (); +#ifdef CONFIG_VNC +vnc_cleanup (); +#endif /* TODO: unref root container, check all devices are ok */ }
ui/vnc.c +18 -2
@@ -3473,8 +3473,13 @@ VncDisplay *vnc_display_new(const char *id, Error **errp)static void vnc_display_close (VncDisplay *vd) { +VncState *vs; +assert (vd); + QTAILQ_FOREACH(vs, &vd->clients, next) { +vnc_disconnect_start (vs); + }if (vd->listener) {qio_net_listener_disconnect (vd->listener);object_unref (OBJECT (vd->listener));
@@ -3515,10 +3520,12 @@ void vnc_display_free(VncDisplay *vd)return ; } -assert (QTAILQ_EMPTY (&vd->clients)); +vnc_display_close (vd); +while (!QTAILQ_EMPTY (&vd->clients)) { +main_loop_wait (false); + }vnc_stop_worker_thread (vd); -vnc_display_close (vd);unregister_displaychangelistener (&vd->dcl);qkbd_state_free (vd->kbd);qemu_del_vm_change_state_handler (vd->vmstate_handler_entry);
@@ -4348,6 +4355,15 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)return vnc_display_new (id, errp) !=NULL ?0 :-1 ; } +void vnc_cleanup (void ) +{ +VncDisplay *vd, *vd_next; + + QTAILQ_FOREACH_SAFE(vd, &vnc_displays, next, vd_next) { +vnc_display_free (vd); + } +} +static void vnc_register_config (void ) {qemu_add_opts (&qemu_vnc_opts);
Signature · 1 line
2.54.0
[PULL v2 21/33] ui/vnc: vnc_display_init() and vnc_display_open() return bool
In reply to [email protected]From: Marc-André Lureau <[email protected]>
Use the QEMU-style error pattern returning "true" on success.
--- include/ui/console.h | 4 ++-- ui/vnc.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-)
include/ui/console.h +2 -2
@@ -438,8 +438,8 @@ const char *qemu_display_get_vc(DisplayOptions *opts);void qemu_display_help (void );/* vnc.c */ -void vnc_display_init (const char *id,Error **errp); -void vnc_display_open (const char *id,Error **errp); +bool vnc_display_init (const char *id,Error **errp); +bool vnc_display_open (const char *id,Error **errp);void vnc_display_add_client (const char *id,int csock,bool skipauth);int vnc_display_password (const char *id,const char *password,Error **errp);int vnc_display_pw_expire (const char *id,time_t expires);
ui/vnc.c +10 -10
@@ -3425,12 +3425,12 @@ static void vmstate_change_handler(void *opaque, bool running, RunState state)static void vnc_display_free (VncDisplay *vd); -void vnc_display_init (const char *id,Error **errp) +bool vnc_display_init (const char *id,Error **errp) {VncDisplay *vd;if (vnc_display_find (id) !=NULL ) { -return ; +return true; } vd =g_malloc0 (sizeof (*vd));
@@ -3451,7 +3451,7 @@ void vnc_display_init(const char *id, Error **errp)if (!vd->kbd_layout) {vnc_display_free (vd); -return ; +return false; } vd->share_policy =VNC_SHARE_POLICY_ALLOW_EXCLUSIVE ;
@@ -3465,6 +3465,7 @@ void vnc_display_init(const char *id, Error **errp) &vmstate_change_handler, vd);QTAILQ_INSERT_TAIL (&vnc_displays, vd, next); +return true; }static void vnc_display_close (VncDisplay *vd)
@@ -4070,7 +4071,7 @@ bool vnc_display_update(DisplayUpdateOptionsVNC *arg, Error **errp)return true; } -void vnc_display_open (const char *id,Error **errp) +bool vnc_display_open (const char *id,Error **errp) {VncDisplay *vd =vnc_display_find (id);QemuOpts *opts =qemu_opts_find (&qemu_vnc_opts, id);
@@ -4273,7 +4274,7 @@ void vnc_display_open(const char *id, Error **errp)qkbd_state_set_delay (vd->kbd, key_delay_ms);if (saddr_list ==NULL ) { -return ; +return true; }if (reverse) {
@@ -4291,10 +4292,11 @@ void vnc_display_open(const char *id, Error **errp) }/* Success */ -return ; +return true; fail:vnc_display_close (vd); +return false; }void vnc_display_add_client (const char *id,int csock,bool skipauth)
@@ -4350,12 +4352,10 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp) id =vnc_auto_assign_id (opts); } -vnc_display_init (id, errp); -if (*errp) { +if (!vnc_display_init (id, errp)) {return -1 ; } -vnc_display_open (id, errp); -if (*errp) { +if (!vnc_display_open (id, errp)) {return -1 ; }return 0 ;
Signature · 1 line
2.54.0
Stefan Hajnoczi
AppliedApplied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.