From nobody Sat Oct 25 08:50:06 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1520330029998681.1606707010965; Tue, 6 Mar 2018 01:53:49 -0800 (PST) Received: from localhost ([::1]:54436 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1et9I2-0001OP-48 for importer@patchew.org; Tue, 06 Mar 2018 04:53:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60642) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1et9GD-0000Aj-L1 for qemu-devel@nongnu.org; Tue, 06 Mar 2018 04:51:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1et9GC-00051m-7t for qemu-devel@nongnu.org; Tue, 06 Mar 2018 04:51:53 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:57528 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1et9GC-00051K-1V for qemu-devel@nongnu.org; Tue, 06 Mar 2018 04:51:52 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6A2A74040856; Tue, 6 Mar 2018 09:51:40 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-39.ams2.redhat.com [10.36.116.39]) by smtp.corp.redhat.com (Postfix) with ESMTP id C8C1A2024CAB; Tue, 6 Mar 2018 09:51:35 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 49D2817533; Tue, 6 Mar 2018 10:51:35 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 6 Mar 2018 10:51:30 +0100 Message-Id: <20180306095135.21285-5-kraxel@redhat.com> In-Reply-To: <20180306095135.21285-1-kraxel@redhat.com> References: <20180306095135.21285-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Tue, 06 Mar 2018 09:51:41 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Tue, 06 Mar 2018 09:51:41 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v7 4/9] console: minimal hotplug suport X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alex Williamson , intel-gvt-dev@lists.freedesktop.org, Gerd Hoffmann , Kirti Wankhede , Tina Zhang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch allows to unbind devices from QemuConsoles, using the new graphic_console_close() function. The QemuConsole will show a static display then, saying the device was unplugged. When re-plugging a display later on the QemuConsole will be reused. Eventually we will allocate and release QemuConsoles dynamically at some point in the future, that'll need more infrastructure though to notify user interfaces (gtk, sdl, spice, ...) about QemuConsoles coming and going. Signed-off-by: Gerd Hoffmann --- include/ui/console.h | 2 ++ ui/console.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++= ---- ui/trace-events | 2 ++ 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index aae9e44cb3..22dada9ca1 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -384,6 +384,7 @@ QemuConsole *graphic_console_init(DeviceState *dev, uin= t32_t head, void graphic_console_set_hwops(QemuConsole *con, const GraphicHwOps *hw_ops, void *opaque); +void graphic_console_close(QemuConsole *con); =20 void graphic_hw_update(QemuConsole *con); void graphic_hw_invalidate(QemuConsole *con); @@ -396,6 +397,7 @@ QemuConsole *qemu_console_lookup_by_index(unsigned int = index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head= ); QemuConsole *qemu_console_lookup_by_device_name(const char *device_id, uint32_t head, Error **err= p); +QemuConsole *qemu_console_lookup_unused(void); bool qemu_console_is_visible(QemuConsole *con); bool qemu_console_is_graphic(QemuConsole *con); bool qemu_console_is_fixedsize(QemuConsole *con); diff --git a/ui/console.c b/ui/console.c index 6ab4ff3baf..f91aa71357 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1266,11 +1266,16 @@ static QemuConsole *new_console(DisplayState *ds, c= onsole_type_t console_type, s->console_type =3D console_type; =20 consoles =3D g_realloc(consoles, sizeof(*consoles) * (nb_consoles+1)); - if (console_type !=3D GRAPHIC_CONSOLE) { + if (console_type !=3D GRAPHIC_CONSOLE || qdev_hotplug) { s->index =3D nb_consoles; consoles[nb_consoles++] =3D s; } else { - /* HACK: Put graphical consoles before text consoles. */ + /* + * HACK: Put graphical consoles before text consoles. + * + * Only do that for coldplugged devices. After initial device + * initialization we will not renumber the consoles any more. + */ for (i =3D nb_consoles; i > 0; i--) { if (consoles[i - 1]->console_type =3D=3D GRAPHIC_CONSOLE) break; @@ -1858,21 +1863,61 @@ QemuConsole *graphic_console_init(DeviceState *dev,= uint32_t head, int height =3D 480; QemuConsole *s; DisplayState *ds; + DisplaySurface *surface; =20 ds =3D get_alloc_displaystate(); - trace_console_gfx_new(); - s =3D new_console(ds, GRAPHIC_CONSOLE, head); - s->ui_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, dpy_set_ui_info_time= r, s); + s =3D qemu_console_lookup_unused(); + if (s) { + trace_console_gfx_reuse(s->index); + if (s->surface) { + width =3D surface_width(s->surface); + height =3D surface_height(s->surface); + } + } else { + trace_console_gfx_new(); + s =3D new_console(ds, GRAPHIC_CONSOLE, head); + s->ui_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, + dpy_set_ui_info_timer, s); + } graphic_console_set_hwops(s, hw_ops, opaque); if (dev) { object_property_set_link(OBJECT(s), OBJECT(dev), "device", &error_abort); } =20 - s->surface =3D qemu_create_message_surface(width, height, noinit); + surface =3D qemu_create_message_surface(width, height, noinit); + dpy_gfx_replace_surface(s, surface); return s; } =20 +static const GraphicHwOps unused_ops =3D { + /* no callbacks */ +}; + +void graphic_console_close(QemuConsole *con) +{ + static const char unplugged[] =3D + "Guest display has been unplugged"; + DisplaySurface *surface; + int width =3D 640; + int height =3D 480; + + if (con->surface) { + width =3D surface_width(con->surface); + height =3D surface_height(con->surface); + } + + trace_console_gfx_close(con->index); + object_property_set_link(OBJECT(con), NULL, "device", &error_abort); + graphic_console_set_hwops(con, &unused_ops, NULL); + + if (con->gl) { + dpy_gl_scanout_disable(con); + } + surface =3D qemu_create_message_surface(width, height, unplugged); + dpy_gfx_replace_surface(con, surface); +} + QemuConsole *qemu_console_lookup_by_index(unsigned int index) { if (index >=3D nb_consoles) { @@ -1929,6 +1974,28 @@ QemuConsole *qemu_console_lookup_by_device_name(cons= t char *device_id, return con; } =20 +QemuConsole *qemu_console_lookup_unused(void) +{ + Object *obj; + int i; + + for (i =3D 0; i < nb_consoles; i++) { + if (!consoles[i]) { + continue; + } + if (consoles[i]->hw_ops !=3D &unused_ops) { + continue; + } + obj =3D object_property_get_link(OBJECT(consoles[i]), + "device", &error_abort); + if (obj !=3D NULL) { + continue; + } + return consoles[i]; + } + return NULL; +} + bool qemu_console_is_visible(QemuConsole *con) { return (con =3D=3D active_console) || (con->dcls > 0); diff --git a/ui/trace-events b/ui/trace-events index 861b68a305..b22ec558f7 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -2,6 +2,8 @@ =20 # ui/console.c console_gfx_new(void) "" +console_gfx_reuse(int index) "%d" +console_gfx_close(int index) "%d" console_putchar_csi(int esc_param0, int esc_param1, int ch, int nb_esc_par= ams) "escape sequence CSI%d;%d%c, %d parameters" console_putchar_unhandled(int ch) "unhandled escape character '%c'" console_txt_new(int w, int h) "%dx%d" --=20 2.9.3