From nobody Fri Oct 24 12:46:26 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 (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519821370635985.7853491166703; Wed, 28 Feb 2018 04:36:10 -0800 (PST) Received: from localhost ([::1]:43734 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er0xn-00068Y-5x for importer@patchew.org; Wed, 28 Feb 2018 07:36:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36669) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er0tK-0002XX-Ot for qemu-devel@nongnu.org; Wed, 28 Feb 2018 07:31:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1er0tF-0000UZ-S6 for qemu-devel@nongnu.org; Wed, 28 Feb 2018 07:31:26 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:35064 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 1er0tF-0000Tb-LW for qemu-devel@nongnu.org; Wed, 28 Feb 2018 07:31:21 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1F5E440FB659; Wed, 28 Feb 2018 12:31:20 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-147.ams2.redhat.com [10.36.116.147]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9C51B10B0F48; Wed, 28 Feb 2018 12:31:11 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id EEBB1A1FD; Wed, 28 Feb 2018 13:31:10 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 28 Feb 2018 13:31:05 +0100 Message-Id: <20180228123110.6507-5-kraxel@redhat.com> In-Reply-To: <20180228123110.6507-1-kraxel@redhat.com> References: <20180228123110.6507-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 28 Feb 2018 12:31:20 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Wed, 28 Feb 2018 12:31:20 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.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 v6 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 , Gerd Hoffmann , intel-gvt-dev@lists.freedesktop.org, 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 | 78 ++++++++++++++++++++++++++++++++++++++++++++++++= ---- ui/trace-events | 2 ++ 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index f29bacd625..adca7954e5 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -383,6 +383,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); @@ -395,6 +396,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 e22931a396..3b0e6cd6e1 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,60 @@ 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 +1973,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