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. Signed-off-by: Marc-André Lureau <[email protected]> --- 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(-) diff --git a/include/ui/console.h b/include/ui/console.h index 3189788fb5f..c695b433fe3 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -305,10 +305,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); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 3d4b5635568..02e8c1435be 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2252,9 +2252,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) diff --git a/ui/console.c b/ui/console.c index baffdeb22b1..3ab987add34 100644 --- a/ui/console.c +++ b/ui/console.c @@ -642,10 +642,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); @@ -670,10 +675,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; } diff --git a/ui/curses.c b/ui/curses.c index 78f21d940e3..4e2a0b25955 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -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; } diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 85e215ef233..249760d82aa 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -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); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 3e2b4adf41f..45b8cc74a6b 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -956,7 +956,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); @@ -977,28 +977,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 @@ -1241,6 +1225,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; @@ -1272,8 +1257,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; } diff --git a/ui/egl-headless.c b/ui/egl-headless.c index 352b30b43fb..4f046c975a9 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -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); } } diff --git a/ui/gtk.c b/ui/gtk.c index 9ebe7e8df0d..3aaa44ff3e2 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -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); diff --git a/ui/sdl2.c b/ui/sdl2.c index 3ffb8acaff8..105e1ee9399 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -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) diff --git a/ui/spice-display.c b/ui/spice-display.c index 5052f371f44..44e8637ea4f 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -1380,13 +1380,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, @@ -1396,8 +1396,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); @@ -1415,7 +1413,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) diff --git a/ui/vnc.c b/ui/vnc.c index fe2659a39ca..9daf295a763 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1858,10 +1858,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; } @@ -3435,7 +3434,6 @@ VncDisplay *vnc_display_new(const char *id, Error **errp) qemu_mutex_init(&vd->mutex); vd->id = g_strdup(id); - vd->dcl.ops = &dcl_ops; QTAILQ_INIT(&vd->clients); vd->expires = TIME_MAX; @@ -3518,7 +3516,7 @@ void vnc_display_free(VncDisplay *vd) return; } vnc_display_close(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); @@ -4261,8 +4259,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); diff --git a/ui/cocoa.m b/ui/cocoa.m index 9093d1e408f..aaf82421589 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -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]; -- 2.53.0
