Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2230552/?format=api
{ "id": 2230552, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2230552/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260430-qemu-vnc-v3-20-be96757428d0@redhat.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/1.1/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260430-qemu-vnc-v3-20-be96757428d0@redhat.com>", "date": "2026-04-29T21:02:53", "name": "[v3,20/26] ui/console: simplify registering display/console change listener", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "73569a21a5e60a4260c93fce9736a9ade75cc3bd", "submitter": { "id": 66774, "url": "http://patchwork.ozlabs.org/api/1.1/people/66774/?format=api", "name": "Marc-André Lureau", "email": "marcandre.lureau@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260430-qemu-vnc-v3-20-be96757428d0@redhat.com/mbox/", "series": [ { "id": 502150, "url": "http://patchwork.ozlabs.org/api/1.1/series/502150/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=502150", "date": "2026-04-29T21:02:34", "name": "ui: add standalone VNC server over D-Bus", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/502150/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2230552/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2230552/checks/", "tags": {}, "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=KVoXT9St;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5VGd6p8Fz1yJr\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 07:06:33 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wIC6Y-0007A7-4x; Wed, 29 Apr 2026 17:05:58 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1wIC5x-0006hn-Th\n for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:39 -0400", "from us-smtp-delivery-124.mimecast.com ([170.10.129.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <marcandre.lureau@redhat.com>)\n id 1wIC5s-0003Wt-2F\n for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:21 -0400", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-629-0YUU2C5aNn-Tv3G7y5z3Zg-1; Wed,\n 29 Apr 2026 17:05:11 -0400", "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id DE08A18003FC; Wed, 29 Apr 2026 21:05:10 +0000 (UTC)", "from localhost (unknown [10.44.22.2])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id E42E830001A1; Wed, 29 Apr 2026 21:05:08 +0000 (UTC)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1777496713;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=Dw3WlezUpgW1Ac2LZpVgWB6GhjwurpwxGK8jST2SZXg=;\n b=KVoXT9StYk6M03FM7ci+nx//zbE+Sh3tJzMZbGnxatHbz0UDET2heATolbOK8A5IbEeos3\n 3p4fEV5jYpf4Kp/8fiPAWDmDH+gRaQjcirja+dUBaH0axGRIkyQWXc7RNLtA28MvFf9eux\n KgGBqeC3hkFbRHdK5cTQ2uukI4Ztm8I=", "X-MC-Unique": "0YUU2C5aNn-Tv3G7y5z3Zg-1", "X-Mimecast-MFC-AGG-ID": "0YUU2C5aNn-Tv3G7y5z3Zg_1777496711", "From": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>", "Date": "Thu, 30 Apr 2026 01:02:53 +0400", "Subject": "[PATCH v3 20/26] ui/console: simplify registering display/console\n change listener", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "8bit", "Message-Id": "<20260430-qemu-vnc-v3-20-be96757428d0@redhat.com>", "References": "<20260430-qemu-vnc-v3-0-be96757428d0@redhat.com>", "In-Reply-To": "<20260430-qemu-vnc-v3-0-be96757428d0@redhat.com>", "To": "qemu-devel@nongnu.org", "Cc": "=?utf-8?q?Marc-Andr=C3=A9_Lureau?= <marcandre.lureau@redhat.com>,\n\t=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>", "X-Developer-Signature": "v=1; a=openpgp-sha256; l=17792;\n i=marcandre.lureau@redhat.com; h=from:subject:message-id;\n bh=bNajfHycqchmwU1i8YMXXyZVCFfcYK1+9bm/MFXideQ=;\n b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMjZNAvRxOxC6yxAwPOivKMhYd5TnOJKj+8\n HDorjrmroKJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac\n 5fsVD/sFilojNecetEKlEqH/RWaHNj+19lNOnU63AGknjh7qeS20kWEbSuxwzyLKggYH8XmqZ1A\n FOT4sA0abGEjwfu7pIIFtxLbD0hF8shhkn33OSA86PdO9JnoJ567s0s+D9LYbTJF4hmHkitwkmz\n K9AUMCRuixuScbtMXBffkiFY7L+4LyS1iGClzloPQPBOIWvx+s8LY/QyL79+dM5QtJXqqxAlULe\n 7TroRM6/D1nATIzcNGMZkyWYPkcjgiS7u8IXYyYHEOFehq56kU12q7OVjnRbHSbpHvLHyN9ATds\n qi0snSentnWzI38eu+4NkzMafDo5IMxlAe+lHzunMM9b4v5y6RIArDBdMf2r0igIeTpZ31tNiuV\n arsYGYYwQGO2S8ND4jX1EG717/4MyaGXH4+TL5uqPVB3lhiVMjrTrsz76QixDGUNd78UHNRJ1Hc\n PcCqQMS9mMebQHjJxW6i1G9I94QkygULs4L9wd8fiPY4h75bKJ4mFZH9XvTKumVRgwTjuHjaGUT\n mnLVAEglovtthAyNQWXioA6+Kc0BNPLE8UPdeTNaj4rTN6g+jhJRrhLofsgdezcLKRqpimIOeKi\n otjCnYvtwPSOtAxdTGU3O4aYiUoBkfSN51/8w7h7w3ExPT80xmyJ0yDxL8Lfc3UxsFDP6TgxQ0a\n PGsqVocSuPFMsYw==", "X-Developer-Key": "i=marcandre.lureau@redhat.com; a=openpgp;\n fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4", "Received-SPF": "pass client-ip=170.10.129.124;\n envelope-from=marcandre.lureau@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,\n SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "Introduce qemu_console_register_listener() which combines setting\ndcl->con, dcl->ops and calling register_displaychangelistener() into a\nsingle call. This removes repetitive boilerplate across all display\nbackends and makes it harder to forget setting one of the fields.\n\nAlso move the early-return check in unregister_displaychangelistener()\nbefore the trace call, so that unregistering a never-registered listener\n(e.g. on error paths) does not dereference a NULL ops pointer.\n\nReviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>\nSigned-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>\n---\n include/ui/console.h | 6 ++++--\n hw/display/qxl.c | 4 +---\n ui/console.c | 11 ++++++++---\n ui/curses.c | 9 +++------\n ui/dbus-console.c | 6 ++----\n ui/dbus-listener.c | 27 ++++++++-------------------\n ui/egl-headless.c | 4 +---\n ui/gtk.c | 10 ++++------\n ui/sdl2.c | 8 +++-----\n ui/spice-display.c | 8 +++-----\n ui/vnc.c | 11 ++++-------\n ui/cocoa.m | 13 ++++---------\n 12 files changed, 45 insertions(+), 72 deletions(-)", "diff": "diff --git a/include/ui/console.h b/include/ui/console.h\nindex 89fb4c1942a..69ac7b01b33 100644\n--- a/include/ui/console.h\n+++ b/include/ui/console.h\n@@ -291,10 +291,12 @@ struct DisplayGLCtx {\n \n DisplayState *init_displaystate(void);\n \n-void register_displaychangelistener(DisplayChangeListener *dcl);\n+void qemu_console_register_listener(QemuConsole *con,\n+ DisplayChangeListener *dcl,\n+ const DisplayChangeListenerOps *ops);\n void update_displaychangelistener(DisplayChangeListener *dcl,\n uint64_t interval);\n-void unregister_displaychangelistener(DisplayChangeListener *dcl);\n+void qemu_console_unregister_listener(DisplayChangeListener *dcl);\n \n bool dpy_ui_info_supported(const QemuConsole *con);\n const QemuUIInfo *dpy_get_ui_info(const QemuConsole *con);\ndiff --git a/hw/display/qxl.c b/hw/display/qxl.c\nindex 0a3c42c8ec2..4244ebe51d2 100644\n--- a/hw/display/qxl.c\n+++ b/hw/display/qxl.c\n@@ -2251,9 +2251,7 @@ static void qxl_realize_primary(PCIDevice *dev, Error **errp)\n return;\n }\n \n- qxl->ssd.dcl.ops = &display_listener_ops;\n- qxl->ssd.dcl.con = vga->con;\n- register_displaychangelistener(&qxl->ssd.dcl);\n+ qemu_console_register_listener(vga->con, &qxl->ssd.dcl, &display_listener_ops);\n }\n \n static void qxl_realize_secondary(PCIDevice *dev, Error **errp)\ndiff --git a/ui/console.c b/ui/console.c\nindex b837ce1c9fc..4f3b4394268 100644\n--- a/ui/console.c\n+++ b/ui/console.c\n@@ -572,10 +572,15 @@ dcl_set_graphic_cursor(DisplayChangeListener *dcl, QemuGraphicConsole *con)\n }\n }\n \n-void register_displaychangelistener(DisplayChangeListener *dcl)\n+void qemu_console_register_listener(QemuConsole *con,\n+ DisplayChangeListener *dcl,\n+ const DisplayChangeListenerOps *ops)\n {\n assert(!dcl->ds);\n \n+ dcl->con = con;\n+ dcl->ops = ops;\n+\n trace_displaychangelistener_register(dcl, dcl->ops->dpy_name);\n dcl->ds = get_alloc_displaystate();\n QLIST_INSERT_HEAD(&dcl->ds->listeners, dcl, next);\n@@ -600,10 +605,10 @@ void update_displaychangelistener(DisplayChangeListener *dcl,\n }\n }\n \n-void unregister_displaychangelistener(DisplayChangeListener *dcl)\n+void qemu_console_unregister_listener(DisplayChangeListener *dcl)\n {\n DisplayState *ds = dcl->ds;\n- trace_displaychangelistener_unregister(dcl, dcl->ops->dpy_name);\n+ trace_displaychangelistener_unregister(dcl, dcl->ops ? dcl->ops->dpy_name : NULL);\n if (!ds) {\n return;\n }\ndiff --git a/ui/curses.c b/ui/curses.c\nindex 96427aa6bb9..dbb5992981c 100644\n--- a/ui/curses.c\n+++ b/ui/curses.c\n@@ -324,9 +324,8 @@ static void curses_refresh(DisplayChangeListener *dcl)\n if (con) {\n erase();\n wnoutrefresh(stdscr);\n- unregister_displaychangelistener(dcl);\n- dcl->con = con;\n- register_displaychangelistener(dcl);\n+ qemu_console_unregister_listener(dcl);\n+ qemu_console_register_listener(con, dcl, dcl->ops);\n \n invalidate = 1;\n }\n@@ -805,9 +804,7 @@ static void curses_display_init(DisplayState *ds, DisplayOptions *opts)\n curses_winch_init();\n \n dcl = g_new0(DisplayChangeListener, 1);\n- dcl->con = qemu_console_lookup_default();\n- dcl->ops = &dcl_ops;\n- register_displaychangelistener(dcl);\n+ qemu_console_register_listener(qemu_console_lookup_default(), dcl, &dcl_ops);\n \n invalidate = 1;\n }\ndiff --git a/ui/dbus-console.c b/ui/dbus-console.c\nindex 564f004bd86..23f547a673d 100644\n--- a/ui/dbus-console.c\n+++ b/ui/dbus-console.c\n@@ -143,7 +143,6 @@ dbus_display_console_init(DBusDisplayConsole *object)\n DBusDisplayConsole *ddc = DBUS_DISPLAY_CONSOLE(object);\n \n ddc->listeners = g_ptr_array_new_with_free_func(g_object_unref);\n- ddc->dcl.ops = &dbus_console_dcl_ops;\n }\n \n static void\n@@ -151,7 +150,7 @@ dbus_display_console_dispose(GObject *object)\n {\n DBusDisplayConsole *ddc = DBUS_DISPLAY_CONSOLE(object);\n \n- unregister_displaychangelistener(&ddc->dcl);\n+ qemu_console_unregister_listener(&ddc->dcl);\n g_clear_object(&ddc->iface_touch);\n g_clear_object(&ddc->iface_mouse);\n g_clear_object(&ddc->iface_kbd);\n@@ -553,7 +552,6 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con)\n \"g-object-path\", path,\n NULL);\n ddc->display = display;\n- ddc->dcl.con = con;\n /* handle errors, and skip non graphics? */\n qemu_console_fill_device_address(\n con, device_addr, sizeof(device_addr), NULL);\n@@ -611,7 +609,7 @@ dbus_display_console_new(DBusDisplay *display, QemuConsole *con)\n slot->tracking_id = -1;\n }\n \n- register_displaychangelistener(&ddc->dcl);\n+ qemu_console_register_listener(con, &ddc->dcl, &dbus_console_dcl_ops);\n ddc->mouse_mode_notifier.notify = dbus_mouse_mode_change;\n qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier);\n dbus_mouse_update_is_absolute(ddc);\ndiff --git a/ui/dbus-listener.c b/ui/dbus-listener.c\nindex e5ce92d1257..cc2c969686e 100644\n--- a/ui/dbus-listener.c\n+++ b/ui/dbus-listener.c\n@@ -957,7 +957,7 @@ dbus_display_listener_dispose(GObject *object)\n {\n DBusDisplayListener *ddl = DBUS_DISPLAY_LISTENER(object);\n \n- unregister_displaychangelistener(&ddl->dcl);\n+ qemu_console_unregister_listener(&ddl->dcl);\n g_clear_object(&ddl->conn);\n g_clear_pointer(&ddl->bus_name, g_free);\n g_clear_object(&ddl->proxy);\n@@ -978,28 +978,12 @@ dbus_display_listener_dispose(GObject *object)\n G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object);\n }\n \n-static void\n-dbus_display_listener_constructed(GObject *object)\n-{\n- DBusDisplayListener *ddl = DBUS_DISPLAY_LISTENER(object);\n-\n- ddl->dcl.ops = &dbus_dcl_ops;\n-#ifdef CONFIG_OPENGL\n- if (display_opengl) {\n- ddl->dcl.ops = &dbus_gl_dcl_ops;\n- }\n-#endif\n-\n- G_OBJECT_CLASS(dbus_display_listener_parent_class)->constructed(object);\n-}\n-\n static void\n dbus_display_listener_class_init(DBusDisplayListenerClass *klass)\n {\n GObjectClass *object_class = G_OBJECT_CLASS(klass);\n \n object_class->dispose = dbus_display_listener_dispose;\n- object_class->constructed = dbus_display_listener_constructed;\n }\n \n static void\n@@ -1258,6 +1242,7 @@ dbus_display_listener_new(const char *bus_name,\n GDBusConnection *conn,\n DBusDisplayConsole *console)\n {\n+ const DisplayChangeListenerOps *ops = &dbus_dcl_ops;\n DBusDisplayListener *ddl;\n QemuConsole *con;\n g_autoptr(GError) err = NULL;\n@@ -1290,8 +1275,12 @@ dbus_display_listener_new(const char *bus_name,\n \n con = qemu_console_lookup_by_index(dbus_display_console_get_index(console));\n assert(con);\n- ddl->dcl.con = con;\n- register_displaychangelistener(&ddl->dcl);\n+#ifdef CONFIG_OPENGL\n+ if (display_opengl) {\n+ ops = &dbus_gl_dcl_ops;\n+ }\n+#endif\n+ qemu_console_register_listener(con, &ddl->dcl, ops);\n \n return ddl;\n }\ndiff --git a/ui/egl-headless.c b/ui/egl-headless.c\nindex 352b30b43fb..4f046c975a9 100644\n--- a/ui/egl-headless.c\n+++ b/ui/egl-headless.c\n@@ -229,13 +229,11 @@ static void egl_headless_init(DisplayState *ds, DisplayOptions *opts)\n }\n \n edpy = g_new0(egl_dpy, 1);\n- edpy->dcl.con = con;\n- edpy->dcl.ops = &egl_ops;\n edpy->gls = qemu_gl_init_shader();\n ctx = g_new0(DisplayGLCtx, 1);\n ctx->ops = &eglctx_ops;\n qemu_console_set_display_gl_ctx(con, ctx);\n- register_displaychangelistener(&edpy->dcl);\n+ qemu_console_register_listener(con, &edpy->dcl, &egl_ops);\n }\n }\n \ndiff --git a/ui/gtk.c b/ui/gtk.c\nindex ec95f0f294a..ef3707b3634 100644\n--- a/ui/gtk.c\n+++ b/ui/gtk.c\n@@ -2251,6 +2251,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n QemuConsole *con, int idx,\n GSList *group, GtkWidget *view_menu)\n {\n+ const DisplayChangeListenerOps *ops = &dcl_ops;\n bool zoom_to_fit = false;\n int i;\n \n@@ -2275,7 +2276,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n vc->gfx.drawing_area = gtk_gl_area_new();\n g_signal_connect(vc->gfx.drawing_area, \"realize\",\n G_CALLBACK(gl_area_realize), vc);\n- vc->gfx.dcl.ops = &dcl_gl_area_ops;\n+ ops = &dcl_gl_area_ops;\n vc->gfx.dgc.ops = &gl_area_ctx_ops;\n } else {\n #ifdef CONFIG_X11\n@@ -2290,7 +2291,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n #pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);\n #pragma GCC diagnostic pop\n- vc->gfx.dcl.ops = &dcl_egl_ops;\n+ ops = &dcl_egl_ops;\n vc->gfx.dgc.ops = &egl_ctx_ops;\n vc->gfx.has_dmabuf = qemu_egl_has_dmabuf();\n #else\n@@ -2301,7 +2302,6 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n #endif\n {\n vc->gfx.drawing_area = gtk_drawing_area_new();\n- vc->gfx.dcl.ops = &dcl_ops;\n }\n \n \n@@ -2325,12 +2325,10 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,\n vc->tab_item, gtk_label_new(vc->label));\n \n vc->gfx.kbd = qkbd_state_init(con);\n- vc->gfx.dcl.con = con;\n-\n if (display_opengl) {\n qemu_console_set_display_gl_ctx(con, &vc->gfx.dgc);\n }\n- register_displaychangelistener(&vc->gfx.dcl);\n+ qemu_console_register_listener(con, &vc->gfx.dcl, ops);\n \n gd_connect_vc_gfx_signals(vc);\n group = gd_vc_menu_init(s, vc, idx, group, view_menu);\ndiff --git a/ui/sdl2.c b/ui/sdl2.c\nindex 5dd612d9a6a..89516f95c41 100644\n--- a/ui/sdl2.c\n+++ b/ui/sdl2.c\n@@ -934,6 +934,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)\n sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);\n for (i = 0; i < sdl2_num_outputs; i++) {\n QemuConsole *con = qemu_console_lookup_by_index(i);\n+ const DisplayChangeListenerOps *ops = &dcl_2d_ops;\n assert(con != NULL);\n if (!qemu_console_is_graphic(con) &&\n qemu_console_get_index(con) != 0) {\n@@ -943,13 +944,11 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)\n sdl2_console[i].opts = o;\n #ifdef CONFIG_OPENGL\n sdl2_console[i].opengl = display_opengl;\n- sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;\n sdl2_console[i].dgc.ops = display_opengl ? &gl_ctx_ops : NULL;\n+ ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;\n #else\n sdl2_console[i].opengl = 0;\n- sdl2_console[i].dcl.ops = &dcl_2d_ops;\n #endif\n- sdl2_console[i].dcl.con = con;\n sdl2_console[i].kbd = qkbd_state_init(con);\n #ifdef CONFIG_OPENGL\n if (display_opengl) {\n@@ -957,8 +956,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)\n sdl2_gl_console_init(&sdl2_console[i]);\n }\n #endif\n- register_displaychangelistener(&sdl2_console[i].dcl);\n-\n+ qemu_console_register_listener(con, &sdl2_console[i].dcl, ops);\n #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11)\n if (SDL_GetWindowWMInfo(sdl2_console[i].real_window, &info)) {\n #if defined(SDL_VIDEO_DRIVER_WINDOWS)\ndiff --git a/ui/spice-display.c b/ui/spice-display.c\nindex 87cc193cdee..56d8140fad8 100644\n--- a/ui/spice-display.c\n+++ b/ui/spice-display.c\n@@ -1387,13 +1387,13 @@ static void qemu_spice_display_init_one(QemuConsole *con)\n SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);\n Error *err = NULL;\n char device_address[256] = \"\";\n+ const DisplayChangeListenerOps *ops = &display_listener_ops;\n \n qemu_spice_display_init_common(ssd);\n \n- ssd->dcl.ops = &display_listener_ops;\n #ifdef HAVE_SPICE_GL\n if (spice_opengl) {\n- ssd->dcl.ops = &display_listener_gl_ops;\n+ ops = &display_listener_gl_ops;\n ssd->dgc.ops = &gl_ctx_ops;\n ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);\n ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,\n@@ -1403,8 +1403,6 @@ static void qemu_spice_display_init_one(QemuConsole *con)\n ssd->have_scanout = false;\n }\n #endif\n- ssd->dcl.con = con;\n-\n ssd->qxl.base.sif = &dpy_interface.base;\n qemu_spice_add_display_interface(&ssd->qxl, con);\n \n@@ -1422,7 +1420,7 @@ static void qemu_spice_display_init_one(QemuConsole *con)\n if (spice_opengl) {\n qemu_console_set_display_gl_ctx(con, &ssd->dgc);\n }\n- register_displaychangelistener(&ssd->dcl);\n+ qemu_console_register_listener(con, &ssd->dcl, ops);\n }\n \n void qemu_spice_display_init(void)\ndiff --git a/ui/vnc.c b/ui/vnc.c\nindex 154b07e2e4e..e8c8773a36e 100644\n--- a/ui/vnc.c\n+++ b/ui/vnc.c\n@@ -1860,10 +1860,9 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)\n qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) {\n QemuConsole *con = qemu_console_lookup_by_index(qcode - Q_KEY_CODE_1);\n if (con) {\n- unregister_displaychangelistener(&vs->vd->dcl);\n+ qemu_console_unregister_listener(&vs->vd->dcl);\n qkbd_state_switch_console(vs->vd->kbd, con);\n- vs->vd->dcl.con = con;\n- register_displaychangelistener(&vs->vd->dcl);\n+ qemu_console_register_listener(con, &vs->vd->dcl, vs->vd->dcl.ops);\n }\n return;\n }\n@@ -3434,7 +3433,6 @@ VncDisplay *vnc_display_new(const char *id, Error **errp)\n vd = g_new0(VncDisplay, 1);\n qemu_mutex_init(&vd->mutex);\n vd->id = g_strdup(id);\n- vd->dcl.ops = &dcl_ops;\n \n QTAILQ_INIT(&vd->clients);\n vd->expires = TIME_MAX;\n@@ -3524,7 +3522,7 @@ void vnc_display_free(VncDisplay *vd)\n }\n \n vnc_stop_worker_thread(vd);\n- unregister_displaychangelistener(&vd->dcl);\n+ qemu_console_unregister_listener(&vd->dcl);\n qkbd_state_free(vd->kbd);\n qemu_del_vm_change_state_handler(vd->vmstate_handler_entry);\n kbd_layout_free(vd->kbd_layout);\n@@ -4267,8 +4265,7 @@ static bool vnc_display_open(VncDisplay *vd, Error **errp)\n con = qemu_console_lookup_default();\n }\n \n- vd->dcl.con = con;\n- register_displaychangelistener(&vd->dcl);\n+ qemu_console_register_listener(con, &vd->dcl, &dcl_ops);\n vd->kbd = qkbd_state_init(vd->dcl.con);\n qkbd_state_set_delay(vd->kbd, key_delay_ms);\n \ndiff --git a/ui/cocoa.m b/ui/cocoa.m\nindex 9093d1e408f..aaf82421589 100644\n--- a/ui/cocoa.m\n+++ b/ui/cocoa.m\n@@ -93,9 +93,7 @@ static void cocoa_switch(DisplayChangeListener *dcl,\n .dpy_mouse_set = cocoa_mouse_set,\n .dpy_cursor_define = cocoa_cursor_define,\n };\n-static DisplayChangeListener dcl = {\n- .ops = &dcl_ops,\n-};\n+static DisplayChangeListener dcl;\n static QKbdState *kbd;\n static int cursor_hide = 1;\n static int left_command_key_enabled = 1;\n@@ -425,8 +423,7 @@ - (void) selectConsoleLocked:(unsigned int)index\n \n unregister_displaychangelistener(&dcl);\n qkbd_state_switch_console(kbd, con);\n- dcl.con = con;\n- register_displaychangelistener(&dcl);\n+ qemu_console_register_listener(con, &dcl, &dcl_ops);\n [self notifyMouseModeChange];\n [self updateUIInfo];\n }\n@@ -2145,11 +2142,9 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)\n add_console_menu_entries();\n addRemovableDevicesMenuItems();\n \n- dcl.con = qemu_console_lookup_default();\n+ qemu_console_register_listener(qemu_console_lookup_default(),\n+ &dcl, &dcl_ops);\n kbd = qkbd_state_init(dcl.con);\n-\n- // register vga output callbacks\n- register_displaychangelistener(&dcl);\n qemu_add_mouse_mode_change_notifier(&mouse_mode_change_notifier);\n [cocoaView notifyMouseModeChange];\n [cocoaView updateUIInfo];\n", "prefixes": [ "v3", "20/26" ] }