From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633813997852274.63850926316366; Sat, 9 Oct 2021 14:13:17 -0700 (PDT) Received: from localhost ([::1]:45398 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJee-0002QQ-Qu for importer@patchew.org; Sat, 09 Oct 2021 17:13:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37618) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJac-00051g-8Z for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:06 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:33957) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJaa-0008G6-Ab for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:05 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-224-xRAu9noCNoS6F0DYmfiELg-1; Sat, 09 Oct 2021 17:09:02 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 43E6B8042C3 for ; Sat, 9 Oct 2021 21:09:01 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id EA1105C1B4; Sat, 9 Oct 2021 21:08:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813743; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nlGQH7tT+dv3NlEIwKaVuvZxQ8G3doM3wk5rMJgTbVk=; b=KPpP2vQX6hy3aFCSuHVMAn3KzEOj6ubC+XOlTXCe7gXEWSFlX7GyTsllVUvsmQU82fiwm1 JQzdEl/HJ0p+wIvWUWVGkGs0YGWK9Dwn1TsUjGa5ARRsqWmLa43j/GadNVyJy9pi6v82f0 b8lorxg2S5JAgsL+VQ6qI6sQ6YwxDTo= X-MC-Unique: xRAu9noCNoS6F0DYmfiELg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 01/37] build-sys: move Spice configure handling to meson Date: Sun, 10 Oct 2021 01:08:02 +0400 Message-Id: <20211009210838.2219430-2-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633813999639100001 From: Marc-Andr=C3=A9 Lureau Add meson feature options for Spice and Spice protocol, and move detection logic out of configure. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- configure | 48 ++------------------------------------------- meson.build | 27 ++++++++++++------------- chardev/meson.build | 2 +- meson_options.txt | 4 ++++ ui/meson.build | 4 ++-- 5 files changed, 22 insertions(+), 63 deletions(-) diff --git a/configure b/configure index 877bf3d76a..375cde2b44 100755 --- a/configure +++ b/configure @@ -372,7 +372,7 @@ pie=3D"" qom_cast_debug=3D"yes" trace_backends=3D"log" trace_file=3D"trace" -spice=3D"$default_feature" +spice=3D"auto" spice_protocol=3D"auto" rbd=3D"auto" smartcard=3D"auto" @@ -3525,41 +3525,6 @@ EOF fi fi =20 -########################################## -# spice probe -if test "$spice_protocol" !=3D "no" ; then - spice_protocol_cflags=3D$($pkg_config --cflags spice-protocol 2>/dev/nul= l) - if $pkg_config --atleast-version=3D0.12.3 spice-protocol; then - spice_protocol=3D"yes" - else - if test "$spice_protocol" =3D "yes" ; then - feature_not_found "spice_protocol" \ - "Install spice-protocol(>=3D0.12.3) devel" - fi - spice_protocol=3D"no" - fi -fi - -if test "$spice" !=3D "no" ; then - cat > $TMPC << EOF -#include -int main(void) { spice_server_new(); return 0; } -EOF - spice_cflags=3D$($pkg_config --cflags spice-protocol spice-server 2>/dev= /null) - spice_libs=3D$($pkg_config --libs spice-protocol spice-server 2>/dev/nul= l) - if $pkg_config --atleast-version=3D0.12.5 spice-server && \ - test "$spice_protocol" =3D "yes" && \ - compile_prog "$spice_cflags" "$spice_libs" ; then - spice=3D"yes" - else - if test "$spice" =3D "yes" ; then - feature_not_found "spice" \ - "Install spice-server(>=3D0.12.5) devel" - fi - spice=3D"no" - fi -fi - ########################################## # check if we have VSS SDK headers for win =20 @@ -4659,16 +4624,6 @@ if test "$tcg" =3D "enabled" -a "$tcg_interpreter" = =3D "true" ; then echo "CONFIG_TCG_INTERPRETER=3Dy" >> $config_host_mak fi =20 -if test "$spice_protocol" =3D "yes" ; then - echo "CONFIG_SPICE_PROTOCOL=3Dy" >> $config_host_mak - echo "SPICE_PROTOCOL_CFLAGS=3D$spice_protocol_cflags" >> $config_host_mak -fi -if test "$spice" =3D "yes" ; then - echo "CONFIG_SPICE=3Dy" >> $config_host_mak - echo "SPICE_CFLAGS=3D$spice_cflags $spice_protocol_cflags" >> $config_ho= st_mak - echo "SPICE_LIBS=3D$spice_libs" >> $config_host_mak -fi - if test "$opengl" =3D "yes" ; then echo "CONFIG_OPENGL=3Dy" >> $config_host_mak echo "OPENGL_CFLAGS=3D$opengl_cflags" >> $config_host_mak @@ -5202,6 +5157,7 @@ if test "$skip_meson" =3D no; then -Ddocs=3D$docs -Dsphinx_build=3D$sphinx_build -Dinstall_blobs=3D$b= lobs \ -Dvhost_user_blk_server=3D$vhost_user_blk_server -Dmultiprocess=3D= $multiprocess \ -Dfuse=3D$fuse -Dfuse_lseek=3D$fuse_lseek -Dguest_agent_msi=3D$gue= st_agent_msi -Dbpf=3D$bpf\ + -Dspice=3D$spice -Dspice_protocol=3D$spice_protocol \ $(if test "$default_feature" =3D no; then echo "-Dauto_features=3D= disabled"; fi) \ -Dtcg_interpreter=3D$tcg_interpreter \ $cross_arg \ diff --git a/meson.build b/meson.build index 99a0a3e689..fe621413a4 100644 --- a/meson.build +++ b/meson.build @@ -442,17 +442,14 @@ jack =3D not_found if 'CONFIG_LIBJACK' in config_host jack =3D declare_dependency(link_args: config_host['JACK_LIBS'].split()) endif -spice =3D not_found -spice_headers =3D not_found -spice_protocol =3D not_found -if 'CONFIG_SPICE' in config_host - spice =3D declare_dependency(compile_args: config_host['SPICE_CFLAGS'].s= plit(), - link_args: config_host['SPICE_LIBS'].split()) - spice_headers =3D declare_dependency(compile_args: config_host['SPICE_CF= LAGS'].split()) -endif -if 'CONFIG_SPICE_PROTOCOL' in config_host - spice_protocol =3D declare_dependency(compile_args: config_host['SPICE_P= ROTOCOL_CFLAGS'].split()) -endif +spice_protocol =3D dependency('spice-protocol', version: '>=3D0.12.3', + required: get_option('spice_protocol')) +spice =3D dependency('spice-server', version: '>=3D0.12.5', + required: get_option('spice')) +if spice.found() + config_host +=3D { 'CONFIG_SPICE': 'y' } # for audio/meson.build +endif +spice_headers =3D spice.partial_dependency(compile_args: true, includes: t= rue) rt =3D cc.find_library('rt', required: false) libdl =3D not_found if 'CONFIG_PLUGIN' in config_host @@ -1293,6 +1290,9 @@ config_host_data.set('CONFIG_ZSTD', zstd.found()) config_host_data.set('CONFIG_FUSE', fuse.found()) config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) config_host_data.set('CONFIG_X11', x11.found()) +config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) +config_host_data.set('CONFIG_SPICE', spice.found()) +config_host_data.set('CONFIG_X11', x11.found()) config_host_data.set('CONFIG_CFI', get_option('cfi')) config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version(= ))) config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('= .')[0]) @@ -1516,7 +1516,7 @@ endif have_ivshmem =3D config_host_data.get('CONFIG_EVENTFD') host_kconfig =3D \ ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=3Dy'] : []) + \ - ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=3Dy'] : []) + \ + (spice.found() ? ['CONFIG_SPICE=3Dy'] : []) + \ (have_ivshmem ? ['CONFIG_IVSHMEM=3Dy'] : []) + \ ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=3Dy'] : []) + \ (x11.found() ? ['CONFIG_X11=3Dy'] : []) + \ @@ -3082,8 +3082,7 @@ summary_info +=3D {'PVRDMA support': config_host.h= as_key('CONFIG_PVRDMA')} summary_info +=3D {'fdt support': fdt_opt =3D=3D 'disabled' ? false = : fdt_opt} summary_info +=3D {'libcap-ng support': libcap_ng} summary_info +=3D {'bpf support': libbpf} -# TODO: add back protocol and server version -summary_info +=3D {'spice support': config_host.has_key('CONFIG_SPICE'= )} +summary_info +=3D {'spice support': spice} summary_info +=3D {'rbd support': rbd} summary_info +=3D {'xfsctl support': config_host.has_key('CONFIG_XFS')} summary_info +=3D {'smartcard support': cacard} diff --git a/chardev/meson.build b/chardev/meson.build index 32377af383..325ba2bdb9 100644 --- a/chardev/meson.build +++ b/chardev/meson.build @@ -35,7 +35,7 @@ if brlapi.found() chardev_modules +=3D { 'baum': module_ss } endif =20 -if config_host.has_key('CONFIG_SPICE') +if spice.found() module_ss =3D ss.source_set() module_ss.add(when: [spice], if_true: files('spice.c')) chardev_modules +=3D { 'spice': module_ss } diff --git a/meson_options.txt b/meson_options.txt index 2c89e79e8b..b064b0b46c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -114,6 +114,10 @@ option('smartcard', type : 'feature', value : 'auto', description: 'CA smartcard emulation support') option('snappy', type : 'feature', value : 'auto', description: 'snappy compression support') +option('spice', type : 'feature', value : 'auto', + description: 'Spice support') +option('spice_protocol', type : 'feature', value : 'auto', + description: 'Spice protocol support') option('u2f', type : 'feature', value : 'auto', description: 'U2F emulation support') option('usb_redir', type : 'feature', value : 'auto', diff --git a/ui/meson.build b/ui/meson.build index a73beb0e54..ee8ef27714 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -89,7 +89,7 @@ if sdl.found() ui_modules +=3D {'sdl' : sdl_ss} endif =20 -if config_host.has_key('CONFIG_SPICE') +if spice.found() spice_core_ss =3D ss.source_set() spice_core_ss.add(spice, pixman, files( 'spice-core.c', @@ -99,7 +99,7 @@ if config_host.has_key('CONFIG_SPICE') ui_modules +=3D {'spice-core' : spice_core_ss} endif =20 -if config_host.has_key('CONFIG_SPICE') and config_host.has_key('CONFIG_GIO= ') +if spice.found() and config_host.has_key('CONFIG_GIO') spice_ss =3D ss.source_set() spice_ss.add(spice, gio, pixman, files('spice-app.c')) ui_modules +=3D {'spice-app': spice_ss} --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633813823250151.9578907681938; Sat, 9 Oct 2021 14:10:23 -0700 (PDT) Received: from localhost ([::1]:39540 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJbq-0006qR-4x for importer@patchew.org; Sat, 09 Oct 2021 17:10:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37630) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJag-00058M-Hk for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:10 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:43221) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJaf-0008GG-1e for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:10 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-445-sQxTzx9lONOswJSr5LIkUw-1; Sat, 09 Oct 2021 17:09:06 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1538A1808312 for ; Sat, 9 Oct 2021 21:09:06 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 118535C1B4; Sat, 9 Oct 2021 21:09:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813748; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aEzKvp6CrZi9sJoBG3qzIk1ikMFmUHF++SaXGnQu9uw=; b=TL072fuQOnrkPtJxtA27GdQWmpyi3dZDj+xC/zF5HHS4QzI7Yo4hZYkfLTU89JzCbhG4Qm 1NQ+bkZXjsy82AEEynhVmgVC2oK4udbqSyzabRTi7bmkbFpGz/yyxmiARbMCgbUoL3UVkA sQQQ36v5RfZmmI5MwKSyYXBijls5GNI= X-MC-Unique: sQxTzx9lONOswJSr5LIkUw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 02/37] ui/vdagent: add CHECK_SPICE_PROTOCOL_VERSION Date: Sun, 10 Oct 2021 01:08:03 +0400 Message-Id: <20211009210838.2219430-3-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633813824257100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- meson.build | 5 +++++ ui/vdagent.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/meson.build b/meson.build index fe621413a4..e1cddf5139 100644 --- a/meson.build +++ b/meson.build @@ -1291,6 +1291,11 @@ config_host_data.set('CONFIG_FUSE', fuse.found()) config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) config_host_data.set('CONFIG_X11', x11.found()) config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) +if spice_protocol.found() +config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version= ().split('.')[0]) +config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version= ().split('.')[1]) +config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version= ().split('.')[2]) +endif config_host_data.set('CONFIG_SPICE', spice.found()) config_host_data.set('CONFIG_X11', x11.found()) config_host_data.set('CONFIG_CFI', get_option('cfi')) diff --git a/ui/vdagent.c b/ui/vdagent.c index 19e8fbfc96..1f8fc77ee8 100644 --- a/ui/vdagent.c +++ b/ui/vdagent.c @@ -17,6 +17,14 @@ =20 #include "spice/vd_agent.h" =20 +#define CHECK_SPICE_PROTOCOL_VERSION(major, minor, micro) \ + (CONFIG_SPICE_PROTOCOL_MAJOR > (major) || \ + (CONFIG_SPICE_PROTOCOL_MAJOR =3D=3D (major) && \ + CONFIG_SPICE_PROTOCOL_MINOR > (minor)) || \ + (CONFIG_SPICE_PROTOCOL_MAJOR =3D=3D (major) && \ + CONFIG_SPICE_PROTOCOL_MINOR =3D=3D (minor) && \ + CONFIG_SPICE_PROTOCOL_MICRO >=3D (micro))) + #define VDAGENT_BUFFER_LIMIT (1 * MiB) #define VDAGENT_MOUSE_DEFAULT true #define VDAGENT_CLIPBOARD_DEFAULT false --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633813866262994.3871237089412; Sat, 9 Oct 2021 14:11:06 -0700 (PDT) Received: from localhost ([::1]:40954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJcX-0007nC-At for importer@patchew.org; Sat, 09 Oct 2021 17:11:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37654) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJas-0005cL-7g for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:24424) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJaq-0008Hs-OW for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:21 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-134-2jOi-y0ROIS7c4fD4sAORQ-1; Sat, 09 Oct 2021 17:09:18 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 56E5F1808304 for ; Sat, 9 Oct 2021 21:09:17 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 746165F4EE; Sat, 9 Oct 2021 21:09:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813760; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S9dnnky8Puw6TUxpeTXKz9l90VBu3DwcE18l6sNaD3w=; b=QSRo/wXTYAGlcTP9nZOrvEYlRWG13CgJn5T/zLLykCnounI0uuxlK4uF0Yc98lpNfh9Fpj tdOfMraxi6pjBWmoc3VI8bRZIdOJM/5Qww8FzH1hQVJGm/+OPZyxjJ2EBgYouc7Gd7ZEXV k/aJ9SkUM0Qm6YyrGcvikALg+iS9sEM= X-MC-Unique: 2jOi-y0ROIS7c4fD4sAORQ-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 03/37] ui/vdagent: replace #if 0 with protocol version check Date: Sun, 10 Oct 2021 01:08:04 +0400 Message-Id: <20211009210838.2219430-4-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633813867490100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- ui/vdagent.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ui/vdagent.c b/ui/vdagent.c index 1f8fc77ee8..64e0017001 100644 --- a/ui/vdagent.c +++ b/ui/vdagent.c @@ -87,8 +87,10 @@ static const char *cap_name[] =3D { [VD_AGENT_CAP_MONITORS_CONFIG_POSITION] =3D "monitors-config-pos= ition", [VD_AGENT_CAP_FILE_XFER_DISABLED] =3D "file-xfer-disabled", [VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS] =3D "file-xfer-detailed-= errors", -#if 0 +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 0) [VD_AGENT_CAP_GRAPHICS_DEVICE_INFO] =3D "graphics-device-inf= o", +#endif +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) [VD_AGENT_CAP_CLIPBOARD_NO_RELEASE_ON_REGRAB] =3D "clipboard-no-releas= e-on-regrab", [VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL] =3D "clipboard-grab-seri= al", #endif @@ -110,7 +112,7 @@ static const char *msg_name[] =3D { [VD_AGENT_CLIENT_DISCONNECTED] =3D "client-disconnected", [VD_AGENT_MAX_CLIPBOARD] =3D "max-clipboard", [VD_AGENT_AUDIO_VOLUME_SYNC] =3D "audio-volume-sync", -#if 0 +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 0) [VD_AGENT_GRAPHICS_DEVICE_INFO] =3D "graphics-device-info", #endif }; @@ -128,7 +130,7 @@ static const char *type_name[] =3D { [VD_AGENT_CLIPBOARD_IMAGE_BMP] =3D "bmp", [VD_AGENT_CLIPBOARD_IMAGE_TIFF] =3D "tiff", [VD_AGENT_CLIPBOARD_IMAGE_JPG] =3D "jpg", -#if 0 +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 3) [VD_AGENT_CLIPBOARD_FILE_LIST] =3D "files", #endif }; --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814014375635.826945200805; Sat, 9 Oct 2021 14:13:34 -0700 (PDT) Received: from localhost ([::1]:46944 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJev-0003UQ-9e for importer@patchew.org; Sat, 09 Oct 2021 17:13:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37690) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJbB-0006UT-T6 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:45424) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJb9-0008Ii-Qr for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:41 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-477-J-WpAb8mOeWBNWavExTzFQ-1; Sat, 09 Oct 2021 17:09:37 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7A2A48042EF for ; Sat, 9 Oct 2021 21:09:36 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 88D80179B3; Sat, 9 Oct 2021 21:09:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813779; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fXwzRpHiwwHViYexpW+i8Nl9ZynVj0FoKExsyPWFCBQ=; b=LMQGb/sNCjkbrBBbgXTuNAawS4nGzoa5Bmpi9WtKP5RupVWRHbF+zbv4x1EcA5TPpKYLcy oSxo5KXXunYyMSBUn9qeev7ngoGbdj5CWk4/560rrGccviPhwFv+nTH2HnbgVOlPRfdlLD Gcdn9G5ky6ZTVVpfnf3nLw06KflPjQY= X-MC-Unique: J-WpAb8mOeWBNWavExTzFQ-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 04/37] ui: generalize clipboard notifier Date: Sun, 10 Oct 2021 01:08:05 +0400 Message-Id: <20211009210838.2219430-5-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814015981100001 From: Marc-Andr=C3=A9 Lureau Use a QemuClipboardNotify union type for extendable clipboard events. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/clipboard.h | 32 ++++++++++++++++++++++++++++++-- ui/clipboard.c | 12 ++++++++---- ui/gtk-clipboard.c | 20 ++++++++++++++++---- ui/vdagent.c | 27 ++++++++++++++++++--------- ui/vnc-clipboard.c | 18 ++++++++++++++---- ui/vnc.c | 2 +- ui/cocoa.m | 17 +++++++++++++---- 7 files changed, 100 insertions(+), 28 deletions(-) diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h index 6298986b15..d82cf31481 100644 --- a/include/ui/clipboard.h +++ b/include/ui/clipboard.h @@ -20,8 +20,10 @@ */ =20 typedef enum QemuClipboardType QemuClipboardType; +typedef enum QemuClipboardNotifyType QemuClipboardNotifyType; typedef enum QemuClipboardSelection QemuClipboardSelection; typedef struct QemuClipboardPeer QemuClipboardPeer; +typedef struct QemuClipboardNotify QemuClipboardNotify; typedef struct QemuClipboardInfo QemuClipboardInfo; =20 /** @@ -55,18 +57,44 @@ enum QemuClipboardSelection { * struct QemuClipboardPeer * * @name: peer name. - * @update: notifier for clipboard updates. + * @notifier: notifier for clipboard updates. * @request: callback for clipboard data requests. * * Clipboard peer description. */ struct QemuClipboardPeer { const char *name; - Notifier update; + Notifier notifier; void (*request)(QemuClipboardInfo *info, QemuClipboardType type); }; =20 +/** + * enum QemuClipboardNotifyType + * + * @QEMU_CLIPBOARD_UPDATE_INFO: clipboard info update + * + * Clipboard notify type. + */ +enum QemuClipboardNotifyType { + QEMU_CLIPBOARD_UPDATE_INFO, +}; + +/** + * struct QemuClipboardNotify + * + * @type: the type of event. + * @info: a QemuClipboardInfo event. + * + * Clipboard notify data. + */ +struct QemuClipboardNotify { + QemuClipboardNotifyType type; + union { + QemuClipboardInfo *info; + }; +}; + /** * struct QemuClipboardInfo * diff --git a/ui/clipboard.c b/ui/clipboard.c index d7b008d62a..743b39edf4 100644 --- a/ui/clipboard.c +++ b/ui/clipboard.c @@ -8,7 +8,7 @@ static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__= COUNT]; =20 void qemu_clipboard_peer_register(QemuClipboardPeer *peer) { - notifier_list_add(&clipboard_notifiers, &peer->update); + notifier_list_add(&clipboard_notifiers, &peer->notifier); } =20 void qemu_clipboard_peer_unregister(QemuClipboardPeer *peer) @@ -18,8 +18,7 @@ void qemu_clipboard_peer_unregister(QemuClipboardPeer *pe= er) for (i =3D 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) { qemu_clipboard_peer_release(peer, i); } - - notifier_remove(&peer->update); + notifier_remove(&peer->notifier); } =20 bool qemu_clipboard_peer_owns(QemuClipboardPeer *peer, @@ -44,10 +43,15 @@ void qemu_clipboard_peer_release(QemuClipboardPeer *pee= r, =20 void qemu_clipboard_update(QemuClipboardInfo *info) { + QemuClipboardNotify notify =3D { + .type =3D QEMU_CLIPBOARD_UPDATE_INFO, + .info =3D info, + }; g_autoptr(QemuClipboardInfo) old =3D NULL; + assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT); =20 - notifier_list_notify(&clipboard_notifiers, info); + notifier_list_notify(&clipboard_notifiers, ¬ify); =20 old =3D cbinfo[info->selection]; cbinfo[info->selection] =3D qemu_clipboard_info_ref(info); diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c index 35b7a2c228..44ff810234 100644 --- a/ui/gtk-clipboard.c +++ b/ui/gtk-clipboard.c @@ -74,10 +74,9 @@ static void gd_clipboard_clear(GtkClipboard *clipboard, gd->cbowner[s] =3D false; } =20 -static void gd_clipboard_notify(Notifier *notifier, void *data) +static void gd_clipboard_update_info(GtkDisplayState *gd, + QemuClipboardInfo *info) { - GtkDisplayState *gd =3D container_of(notifier, GtkDisplayState, cbpeer= .update); - QemuClipboardInfo *info =3D data; QemuClipboardSelection s =3D info->selection; bool self_update =3D info->owner =3D=3D &gd->cbpeer; =20 @@ -118,6 +117,19 @@ static void gd_clipboard_notify(Notifier *notifier, vo= id *data) */ } =20 +static void gd_clipboard_notify(Notifier *notifier, void *data) +{ + GtkDisplayState *gd =3D + container_of(notifier, GtkDisplayState, cbpeer.notifier); + QemuClipboardNotify *notify =3D data; + + switch (notify->type) { + case QEMU_CLIPBOARD_UPDATE_INFO: + gd_clipboard_update_info(gd, notify->info); + return; + } +} + static void gd_clipboard_request(QemuClipboardInfo *info, QemuClipboardType type) { @@ -172,7 +184,7 @@ static void gd_owner_change(GtkClipboard *clipboard, void gd_clipboard_init(GtkDisplayState *gd) { gd->cbpeer.name =3D "gtk"; - gd->cbpeer.update.notify =3D gd_clipboard_notify; + gd->cbpeer.notifier.notify =3D gd_clipboard_notify; gd->cbpeer.request =3D gd_clipboard_request; qemu_clipboard_peer_register(&gd->cbpeer); =20 diff --git a/ui/vdagent.c b/ui/vdagent.c index 64e0017001..de827aad27 100644 --- a/ui/vdagent.c +++ b/ui/vdagent.c @@ -417,10 +417,9 @@ static void vdagent_send_empty_clipboard_data(VDAgentC= hardev *vd, vdagent_send_clipboard_data(vd, info, type); } =20 -static void vdagent_clipboard_notify(Notifier *notifier, void *data) +static void vdagent_clipboard_update_info(VDAgentChardev *vd, + QemuClipboardInfo *info) { - VDAgentChardev *vd =3D container_of(notifier, VDAgentChardev, cbpeer.u= pdate); - QemuClipboardInfo *info =3D data; QemuClipboardSelection s =3D info->selection; QemuClipboardType type; bool self_update =3D info->owner =3D=3D &vd->cbpeer; @@ -449,6 +448,19 @@ static void vdagent_clipboard_notify(Notifier *notifie= r, void *data) } } =20 +static void vdagent_clipboard_notify(Notifier *notifier, void *data) +{ + VDAgentChardev *vd =3D + container_of(notifier, VDAgentChardev, cbpeer.notifier); + QemuClipboardNotify *notify =3D data; + + switch (notify->type) { + case QEMU_CLIPBOARD_UPDATE_INFO: + vdagent_clipboard_update_info(vd, notify->info); + return; + } +} + static void vdagent_clipboard_request(QemuClipboardInfo *info, QemuClipboardType qtype) { @@ -658,9 +670,9 @@ static void vdagent_chr_recv_caps(VDAgentChardev *vd, V= DAgentMessage *msg) if (have_mouse(vd) && vd->mouse_hs) { qemu_input_handler_activate(vd->mouse_hs); } - if (have_clipboard(vd) && vd->cbpeer.update.notify =3D=3D NULL) { + if (have_clipboard(vd) && vd->cbpeer.notifier.notify =3D=3D NULL) { vd->cbpeer.name =3D "vdagent"; - vd->cbpeer.update.notify =3D vdagent_clipboard_notify; + vd->cbpeer.notifier.notify =3D vdagent_clipboard_notify; vd->cbpeer.request =3D vdagent_clipboard_request; qemu_clipboard_peer_register(&vd->cbpeer); } @@ -799,7 +811,7 @@ static void vdagent_disconnect(VDAgentChardev *vd) if (vd->mouse_hs) { qemu_input_handler_deactivate(vd->mouse_hs); } - if (vd->cbpeer.update.notify) { + if (vd->cbpeer.notifier.notify) { qemu_clipboard_peer_unregister(&vd->cbpeer); memset(&vd->cbpeer, 0, sizeof(vd->cbpeer)); } @@ -807,11 +819,8 @@ static void vdagent_disconnect(VDAgentChardev *vd) =20 static void vdagent_chr_set_fe_open(struct Chardev *chr, int fe_open) { - VDAgentChardev *vd =3D QEMU_VDAGENT_CHARDEV(chr); - if (!fe_open) { trace_vdagent_close(); - vdagent_disconnect(vd); return; } =20 diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c index 9f077965d0..41aeff1085 100644 --- a/ui/vnc-clipboard.c +++ b/ui/vnc-clipboard.c @@ -189,10 +189,8 @@ static void vnc_clipboard_provide(VncState *vs, vnc_flush(vs); } =20 -static void vnc_clipboard_notify(Notifier *notifier, void *data) +static void vnc_clipboard_update_info(VncState *vs, QemuClipboardInfo *inf= o) { - VncState *vs =3D container_of(notifier, VncState, cbpeer.update); - QemuClipboardInfo *info =3D data; QemuClipboardType type; bool self_update =3D info->owner =3D=3D &vs->cbpeer; uint32_t flags =3D 0; @@ -223,6 +221,18 @@ static void vnc_clipboard_notify(Notifier *notifier, v= oid *data) } } =20 +static void vnc_clipboard_notify(Notifier *notifier, void *data) +{ + VncState *vs =3D container_of(notifier, VncState, cbpeer.notifier); + QemuClipboardNotify *notify =3D data; + + switch (notify->type) { + case QEMU_CLIPBOARD_UPDATE_INFO: + vnc_clipboard_update_info(vs, notify->info); + return; + } +} + static void vnc_clipboard_request(QemuClipboardInfo *info, QemuClipboardType type) { @@ -317,7 +327,7 @@ void vnc_server_cut_text_caps(VncState *vs) vnc_clipboard_send(vs, 2, caps); =20 vs->cbpeer.name =3D "vnc"; - vs->cbpeer.update.notify =3D vnc_clipboard_notify; + vs->cbpeer.notifier.notify =3D vnc_clipboard_notify; vs->cbpeer.request =3D vnc_clipboard_request; qemu_clipboard_peer_register(&vs->cbpeer); } diff --git a/ui/vnc.c b/ui/vnc.c index af02522e84..9b603382e7 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1354,7 +1354,7 @@ void vnc_disconnect_finish(VncState *vs) /* last client gone */ vnc_update_server_surface(vs->vd); } - if (vs->cbpeer.update.notify) { + if (vs->cbpeer.notifier.notify) { qemu_clipboard_peer_unregister(&vs->cbpeer); } =20 diff --git a/ui/cocoa.m b/ui/cocoa.m index 68a6302184..6745e3fc8c 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1808,14 +1808,12 @@ static void cocoa_clipboard_request(QemuClipboardIn= fo *info, =20 static QemuClipboardPeer cbpeer =3D { .name =3D "cocoa", - .update =3D { .notify =3D cocoa_clipboard_notify }, + .notifier =3D { .notify =3D cocoa_clipboard_notify }, .request =3D cocoa_clipboard_request }; =20 -static void cocoa_clipboard_notify(Notifier *notifier, void *data) +static void cocoa_clipboard_update_info(QemuClipboardInfo *info) { - QemuClipboardInfo *info =3D data; - if (info->owner =3D=3D &cbpeer || info->selection !=3D QEMU_CLIPBOARD_= SELECTION_CLIPBOARD) { return; } @@ -1831,6 +1829,17 @@ static void cocoa_clipboard_notify(Notifier *notifie= r, void *data) qemu_event_set(&cbevent); } =20 +static void cocoa_clipboard_notify(Notifier *notifier, void *data) +{ + QemuClipboardNotify *notify =3D data; + + switch (notify->event) { + case QEMU_CLIPBOARD_UPDATE_INFO: + cocoa_clipboard_update_info(notify->info); + return; + } +} + static void cocoa_clipboard_request(QemuClipboardInfo *info, QemuClipboardType type) { --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814032291659.9734816503493; Sat, 9 Oct 2021 14:13:52 -0700 (PDT) Received: from localhost ([::1]:48754 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJfD-0004iS-96 for importer@patchew.org; Sat, 09 Oct 2021 17:13:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37716) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJbO-00076i-Ly for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:43697) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJbM-0008JN-OZ for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:09:54 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-496-0_jxM0dkMcm9Ev5FiGMu6Q-1; Sat, 09 Oct 2021 17:09:48 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8A112180830F for ; Sat, 9 Oct 2021 21:09:47 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id AD6BC5C1B4; Sat, 9 Oct 2021 21:09:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813792; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k4W21a76+QGMmZ2mVT1kSjr31Jy71dJE0yk7DKdWUwM=; b=BYIotTEQj7blOTwmLWWFTQaYZdAj8SBotA1gF/wfgj0e8a550+sWmzwUNKfUHBhiXPX665 gmToO68M3OP5lppUmyOdnM7FZ3N5KncCypF9xfqj4p0l0L+lyVIYC9bzo11DmZECIMQggy qDRC+z2ssjNLHylUocJe6fDVxhITX6w= X-MC-Unique: 0_jxM0dkMcm9Ev5FiGMu6Q-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 05/37] ui/vdagent: add serial capability support Date: Sun, 10 Oct 2021 01:08:06 +0400 Message-Id: <20211009210838.2219430-6-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814032634100001 From: Marc-Andr=C3=A9 Lureau The Spice agent implements a simple serial mechanism to avoid clipboard races between client & guest. See: https://gitlab.freedesktop.org/spice/spice-protocol/-/commit/045a6978d6dbbf= 7046affc5c321fa8177c8cce56 Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/clipboard.h | 4 ++++ ui/vdagent.c | 39 ++++++++++++++++++++++++++++++++++++++- ui/trace-events | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h index d82cf31481..e590b453c8 100644 --- a/include/ui/clipboard.h +++ b/include/ui/clipboard.h @@ -102,6 +102,8 @@ struct QemuClipboardNotify { * @owner: clipboard owner. * @selection: clipboard selection. * @types: clipboard data array (one entry per type). + * @has_serial: whether @serial is available. + * @serial: the grab serial counter. * * Clipboard content data and metadata. */ @@ -109,6 +111,8 @@ struct QemuClipboardInfo { uint32_t refcount; QemuClipboardPeer *owner; QemuClipboardSelection selection; + bool has_serial; + uint32_t serial; struct { bool available; bool requested; diff --git a/ui/vdagent.c b/ui/vdagent.c index de827aad27..b4fdae6917 100644 --- a/ui/vdagent.c +++ b/ui/vdagent.c @@ -59,6 +59,7 @@ struct VDAgentChardev { =20 /* clipboard */ QemuClipboardPeer cbpeer; + uint32_t last_serial[QEMU_CLIPBOARD_SELECTION__COUNT]; uint32_t cbpending[QEMU_CLIPBOARD_SELECTION__COUNT]; }; typedef struct VDAgentChardev VDAgentChardev; @@ -203,6 +204,9 @@ static void vdagent_send_caps(VDAgentChardev *vd) if (vd->clipboard) { caps->caps[0] |=3D (1 << VD_AGENT_CAP_CLIPBOARD_BY_DEMAND); caps->caps[0] |=3D (1 << VD_AGENT_CAP_CLIPBOARD_SELECTION); +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) + caps->caps[0] |=3D (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL); +#endif } =20 vdagent_send_msg(vd, msg); @@ -333,7 +337,8 @@ static void vdagent_send_clipboard_grab(VDAgentChardev = *vd, { g_autofree VDAgentMessage *msg =3D g_malloc0(sizeof(VDAgentMessage) + - sizeof(uint32_t) * (QEMU_CLIPBOARD_TYPE__COUNT + 1)); + sizeof(uint32_t) * (QEMU_CLIPBOARD_TYPE__COUNT + 1) + + sizeof(uint32_t)); uint8_t *s =3D msg->data; uint32_t *data =3D (uint32_t *)msg->data; uint32_t q, type; @@ -346,6 +351,19 @@ static void vdagent_send_clipboard_grab(VDAgentChardev= *vd, return; } =20 +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) + if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) { + if (!info->has_serial) { + /* client should win */ + info->serial =3D vd->last_serial[info->selection]++; + info->has_serial =3D true; + } + *data =3D info->serial; + data++; + msg->size +=3D sizeof(uint32_t); + } +#endif + for (q =3D 0; q < QEMU_CLIPBOARD_TYPE__COUNT; q++) { type =3D type_qemu_to_vdagent(q); if (type !=3D VD_AGENT_CLIPBOARD_NONE && info->types[q].available)= { @@ -494,6 +512,24 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev= *vd, uint8_t s, uint32_t =20 trace_vdagent_cb_grab_selection(GET_NAME(sel_name, s)); info =3D qemu_clipboard_info_new(&vd->cbpeer, s); +#if CHECK_SPICE_PROTOCOL_VERSION(0, 14, 1) + if (vd->caps & (1 << VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL)) { + if (size < sizeof(uint32_t)) { + /* this shouldn't happen! */ + return; + } + + info->has_serial =3D true; + info->serial =3D *(uint32_t *)data; + if (info->serial < vd->last_serial[s]) { + /* discard lower-ordering guest grab */ + return; + } + vd->last_serial[s] =3D info->serial; + data +=3D sizeof(uint32_t); + size -=3D sizeof(uint32_t); + } +#endif if (size > sizeof(uint32_t) * 10) { /* * spice has 6 types as of 2021. Limiting to 10 entries @@ -671,6 +707,7 @@ static void vdagent_chr_recv_caps(VDAgentChardev *vd, V= DAgentMessage *msg) qemu_input_handler_activate(vd->mouse_hs); } if (have_clipboard(vd) && vd->cbpeer.notifier.notify =3D=3D NULL) { + memset(vd->last_serial, 0, sizeof(vd->last_serial)); vd->cbpeer.name =3D "vdagent"; vd->cbpeer.notifier.notify =3D vdagent_clipboard_notify; vd->cbpeer.request =3D vdagent_clipboard_request; diff --git a/ui/trace-events b/ui/trace-events index b9c0dd0fa1..e832c3e365 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -135,3 +135,4 @@ vdagent_recv_msg(const char *name, uint32_t size) "msg = %s, size %d" vdagent_peer_cap(const char *name) "cap %s" vdagent_cb_grab_selection(const char *name) "selection %s" vdagent_cb_grab_type(const char *name) "type %s" +vdagent_cb_serial_discard(uint32_t current, uint32_t received) "current=3D= %u, received=3D%u" --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381424126775.18559525900378; Sat, 9 Oct 2021 14:17:21 -0700 (PDT) Received: from localhost ([::1]:55556 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJia-0000pM-1M for importer@patchew.org; Sat, 09 Oct 2021 17:17:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37756) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJbY-0007bf-1Y for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:10:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32227) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJbW-0008Jo-GJ for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:10:03 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-507-Jd_2OeTwMMCfSwLfgFfBGw-1; Sat, 09 Oct 2021 17:10:00 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B009CA0CAB for ; Sat, 9 Oct 2021 21:09:59 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 579345F4E1; Sat, 9 Oct 2021 21:09:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813802; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7fSMSZM4TPVrrQ3mQENgUc3s8/iOOvqCL31XcV9SFE8=; b=jU55MNf5/Jm3S1MgjY4uujQG3xYNNywqMWcbOHNTl5+bHh9NgyVrHfXGnNyZB1lxORJwbN hdvcWuXKYpCIu7EEHSh7j5W5sf+MVQso+vmaCXv9CB2x2dxYevI05K9M8zrvF1Tj79w3sv 0RyNyNznOOu6/3HoaysY9hvoyL1cE4Y= X-MC-Unique: Jd_2OeTwMMCfSwLfgFfBGw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 06/37] ui/clipboard: add qemu_clipboard_check_serial() Date: Sun, 10 Oct 2021 01:08:07 +0400 Message-Id: <20211009210838.2219430-7-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814242474100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/clipboard.h | 10 ++++++++++ ui/clipboard.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h index e590b453c8..2c6488c1ee 100644 --- a/include/ui/clipboard.h +++ b/include/ui/clipboard.h @@ -172,6 +172,16 @@ void qemu_clipboard_peer_release(QemuClipboardPeer *pe= er, */ QemuClipboardInfo *qemu_clipboard_info(QemuClipboardSelection selection); =20 +/** + * qemu_clipboard_check_serial + * + * @info: clipboard info. + * @client: whether to check from the client context and priority. + * + * Return TRUE if the @info has a higher serial than the current clipboard. + */ +bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client); + /** * qemu_clipboard_info_new * diff --git a/ui/clipboard.c b/ui/clipboard.c index 743b39edf4..ffbd80e5c6 100644 --- a/ui/clipboard.c +++ b/ui/clipboard.c @@ -41,6 +41,21 @@ void qemu_clipboard_peer_release(QemuClipboardPeer *peer, } } =20 +bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client) +{ + if (!info->has_serial || + !cbinfo[info->selection] || + !cbinfo[info->selection]->has_serial) { + return true; + } + + if (client) { + return cbinfo[info->selection]->serial >=3D info->serial; + } else { + return cbinfo[info->selection]->serial > info->serial; + } +} + void qemu_clipboard_update(QemuClipboardInfo *info) { QemuClipboardNotify notify =3D { --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814260719418.357809948263; Sat, 9 Oct 2021 14:17:40 -0700 (PDT) Received: from localhost ([::1]:57238 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJit-00024J-NZ for importer@patchew.org; Sat, 09 Oct 2021 17:17:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37860) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJc5-00082H-DV for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:10:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:22160) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJc3-0008Rw-Q7 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:10:37 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-497-C5wJ5g0UO-Wo5yGcHO9aXQ-1; Sat, 09 Oct 2021 17:10:32 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 60C23801AA7 for ; Sat, 9 Oct 2021 21:10:31 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id D2BDF5C23A; Sat, 9 Oct 2021 21:10:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813835; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q+AYzqe2rNkXZs4KLxV4tHf+k26nue+SEs9kxjMMhnk=; b=fIfxLgYL2bpt9anSfQzYTs/Bcny76rTttTpsOlLI80iVLCSu30W62ebojTJoRnvHdl4NYT qK99tbWmoPPtUAPq/RZX1iL5NpIKUhg7t1IWvwbGRPyh2zOolXD7bNGoOFYtB/+IwaNYS3 EAl0HIpJ8pQH1iEeYWFnqEfHviUZ18g= X-MC-Unique: C5wJ5g0UO-Wo5yGcHO9aXQ-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 07/37] ui/clipboard: add a clipboard reset serial event Date: Sun, 10 Oct 2021 01:08:08 +0400 Message-Id: <20211009210838.2219430-8-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814261034100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/clipboard.h | 9 +++++++++ ui/clipboard.c | 7 +++++++ ui/gtk-clipboard.c | 3 +++ ui/vdagent.c | 12 ++++++++++++ ui/vnc-clipboard.c | 3 +++ ui/cocoa.m | 3 +++ 6 files changed, 37 insertions(+) diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h index 2c6488c1ee..ce76aa451f 100644 --- a/include/ui/clipboard.h +++ b/include/ui/clipboard.h @@ -73,11 +73,13 @@ struct QemuClipboardPeer { * enum QemuClipboardNotifyType * * @QEMU_CLIPBOARD_UPDATE_INFO: clipboard info update + * @QEMU_CLIPBOARD_RESET_SERIAL: reset clipboard serial * * Clipboard notify type. */ enum QemuClipboardNotifyType { QEMU_CLIPBOARD_UPDATE_INFO, + QEMU_CLIPBOARD_RESET_SERIAL, }; =20 /** @@ -230,6 +232,13 @@ void qemu_clipboard_info_unref(QemuClipboardInfo *info= ); */ void qemu_clipboard_update(QemuClipboardInfo *info); =20 +/** + * qemu_clipboard_reset_serial + * + * Reset the clipboard serial. + */ +void qemu_clipboard_reset_serial(void); + /** * qemu_clipboard_request * diff --git a/ui/clipboard.c b/ui/clipboard.c index ffbd80e5c6..82572ea116 100644 --- a/ui/clipboard.c +++ b/ui/clipboard.c @@ -129,6 +129,13 @@ void qemu_clipboard_request(QemuClipboardInfo *info, info->owner->request(info, type); } =20 +void qemu_clipboard_reset_serial(void) +{ + QemuClipboardNotify notify =3D { .type =3D QEMU_CLIPBOARD_RESET_SERIAL= }; + + notifier_list_notify(&clipboard_notifiers, ¬ify); +} + void qemu_clipboard_set_data(QemuClipboardPeer *peer, QemuClipboardInfo *info, QemuClipboardType type, diff --git a/ui/gtk-clipboard.c b/ui/gtk-clipboard.c index 44ff810234..e0b8b283fe 100644 --- a/ui/gtk-clipboard.c +++ b/ui/gtk-clipboard.c @@ -127,6 +127,9 @@ static void gd_clipboard_notify(Notifier *notifier, voi= d *data) case QEMU_CLIPBOARD_UPDATE_INFO: gd_clipboard_update_info(gd, notify->info); return; + case QEMU_CLIPBOARD_RESET_SERIAL: + /* ignore */ + return; } } =20 diff --git a/ui/vdagent.c b/ui/vdagent.c index b4fdae6917..7ea4bc5d9a 100644 --- a/ui/vdagent.c +++ b/ui/vdagent.c @@ -466,6 +466,15 @@ static void vdagent_clipboard_update_info(VDAgentChard= ev *vd, } } =20 +static void vdagent_clipboard_reset_serial(VDAgentChardev *vd) +{ + Chardev *chr =3D CHARDEV(vd); + + /* reopen the agent connection to reset the serial state */ + qemu_chr_be_event(chr, CHR_EVENT_CLOSED); + qemu_chr_be_event(chr, CHR_EVENT_OPENED); +} + static void vdagent_clipboard_notify(Notifier *notifier, void *data) { VDAgentChardev *vd =3D @@ -476,6 +485,9 @@ static void vdagent_clipboard_notify(Notifier *notifier= , void *data) case QEMU_CLIPBOARD_UPDATE_INFO: vdagent_clipboard_update_info(vd, notify->info); return; + case QEMU_CLIPBOARD_RESET_SERIAL: + vdagent_clipboard_reset_serial(vd); + return; } } =20 diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c index 41aeff1085..8b2dd0a64a 100644 --- a/ui/vnc-clipboard.c +++ b/ui/vnc-clipboard.c @@ -230,6 +230,9 @@ static void vnc_clipboard_notify(Notifier *notifier, vo= id *data) case QEMU_CLIPBOARD_UPDATE_INFO: vnc_clipboard_update_info(vs, notify->info); return; + case QEMU_CLIPBOARD_RESET_SERIAL: + /* ignore */ + return; } } =20 diff --git a/ui/cocoa.m b/ui/cocoa.m index 6745e3fc8c..69b6c07d53 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -1837,6 +1837,9 @@ static void cocoa_clipboard_notify(Notifier *notifier= , void *data) case QEMU_CLIPBOARD_UPDATE_INFO: cocoa_clipboard_update_info(notify->info); return; + case QEMU_CLIPBOARD_RESET_SERIAL: + /* ignore */ + return; } } =20 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814390398449.0718622250539; Sat, 9 Oct 2021 14:19:50 -0700 (PDT) Received: from localhost ([::1]:35784 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJkz-0006cf-DZ for importer@patchew.org; Sat, 09 Oct 2021 17:19:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37912) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJcK-000077-6d for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:10:52 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:46889) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJcI-0008TV-MA for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:10:51 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-450-CA3ul612P--cRkxgGNUdwg-1; Sat, 09 Oct 2021 17:10:48 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DDD5B801A93 for ; Sat, 9 Oct 2021 21:10:47 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4CB9226E46; Sat, 9 Oct 2021 21:10:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813850; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RBR36B0rV4PBXBB599jiWXX7DU5gIB+WWqN9k6byUQo=; b=JfsvNrEGsXDhVcgYuzr6/d4hoVQ95gC47CrD8YSeiB9LMdnfgNnPOO5ka2bunb1e3wsN+Q n5lAok+ec6Z76qoPoXSNQ/BFEaaY0L4FiDTdWvyGAIenvki5MW5m7b7/Arh+hojvjYGAd+ TQs6AfDPtYNSM2/i1C9vWNWxoBCAxWw= X-MC-Unique: CA3ul612P--cRkxgGNUdwg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 08/37] hw/display: report an error if virgl initialization failed Date: Sun, 10 Oct 2021 01:08:09 +0400 Message-Id: <20211009210838.2219430-9-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814391999100001 From: Marc-Andr=C3=A9 Lureau Currently, virgl initialization error is silent. Make it verbose instead. (this is likely going to bug later on, as the device isn't fully initialized) Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/display/virtio-gpu-virgl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index 18d054922f..0d87de65d7 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -609,6 +609,7 @@ int virtio_gpu_virgl_init(VirtIOGPU *g) =20 ret =3D virgl_renderer_init(g, 0, &virtio_gpu_3d_cbs); if (ret !=3D 0) { + error_report("virgl could not be initialized: %d", ret); return ret; } =20 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814166760728.6050262042025; Sat, 9 Oct 2021 14:16:06 -0700 (PDT) Received: from localhost ([::1]:53966 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJhN-0008CU-DT for importer@patchew.org; Sat, 09 Oct 2021 17:16:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37956) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJcU-0000OD-AL for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:03 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:54113) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJcS-0008UU-Va for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:02 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-586-Z7XcpQgRPba-7PM2PQkKIQ-1; Sat, 09 Oct 2021 17:10:59 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 688C610A8E00 for ; Sat, 9 Oct 2021 21:10:58 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 260C15F4E1; Sat, 9 Oct 2021 21:10:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Btnj4ao/gY1G+m07j5eQKVHLr3Qe7nGXz6XiSPJlp88=; b=bp99QlTIU6DI2ie9rDN5941nQFrEmbyF3txlsjdYqRVFMWmwz300pMVQ02+TrvzlkrmFIh V+fXall9bRxQgMmxz2cIDKPR4nfFFvtJ/hS1Z7q/Oi9t5HIeV5o1u443iqnFrkxOAE78+Y J5xV1um3n7UJ+wHm0zLe6uHz4RPELDk= X-MC-Unique: Z7XcpQgRPba-7PM2PQkKIQ-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 09/37] virtio-gpu: use VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP Date: Sun, 10 Oct 2021 01:08:10 +0400 Message-Id: <20211009210838.2219430-10-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814168331100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/display/virtio-gpu-virgl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index 0d87de65d7..73cb92c8d5 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -175,7 +175,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g, virgl_renderer_force_ctx_0(); dpy_gl_scanout_texture( g->parent_obj.scanout[ss.scanout_id].con, info.tex_id, - info.flags & 1 /* FIXME: Y_0_TOP */, + 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); } else { --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381401663879.35874993188338; Sat, 9 Oct 2021 14:13:36 -0700 (PDT) Received: from localhost ([::1]:47200 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJex-0003fT-Lo for importer@patchew.org; Sat, 09 Oct 2021 17:13:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38010) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJco-0000sD-Od for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:34072) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJcn-00006x-4i for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:22 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-451-DIiNheUYP9G7wVyNBt8K8w-1; Sat, 09 Oct 2021 17:11:18 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 284FB10A8E00 for ; Sat, 9 Oct 2021 21:11:17 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id B62FE5C1B4; Sat, 9 Oct 2021 21:11:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813880; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h3wP3yItHwDLZmVr3uZOGCUnty9xxsP2Gx3TpfzMx0Y=; b=iyb8dhWXazEJQkpV3a/k2wHN2WAIj1fVPmHMriBob821iHuMur5V8TGFuPEf0znFPbt30e 1pXJFJXqY7SGREE6vKj2QMh3xfvkPbV6CS6IEhHo21vhz1SjS+oITJK5j0IoxkGP2A5fow kOqwQB23TbwcSXUh0X6chxmpXTcwASo= X-MC-Unique: DIiNheUYP9G7wVyNBt8K8w-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 10/37] ui: do not delay further remote resize Date: Sun, 10 Oct 2021 01:08:11 +0400 Message-Id: <20211009210838.2219430-11-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814018030100001 From: Marc-Andr=C3=A9 Lureau A remote client, such as Spice, will already avoid flooding the stream by delaying the resize requests. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/console.h | 2 +- ui/console.c | 5 +++-- ui/gtk.c | 2 +- ui/sdl2.c | 2 +- ui/spice-display.c | 2 +- ui/vnc.c | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 244664d727..7b2f624e93 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -287,7 +287,7 @@ void unregister_displaychangelistener(DisplayChangeList= ener *dcl); =20 bool dpy_ui_info_supported(QemuConsole *con); const QemuUIInfo *dpy_get_ui_info(const QemuConsole *con); -int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info); +int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info, bool delay); =20 void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h); void dpy_gfx_update_full(QemuConsole *con); diff --git a/ui/console.c b/ui/console.c index eabbbc951c..7eea1fc641 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1596,7 +1596,7 @@ const QemuUIInfo *dpy_get_ui_info(const QemuConsole *= con) return &con->ui_info; } =20 -int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info) +int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info, bool delay) { if (con =3D=3D NULL) { con =3D active_console; @@ -1616,7 +1616,8 @@ int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *inf= o) * go notify the guest. */ con->ui_info =3D *info; - timer_mod(con->ui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000= ); + timer_mod(con->ui_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + (delay ? 1000 : 0)); return 0; } =20 diff --git a/ui/gtk.c b/ui/gtk.c index b0564d80c1..163b6bcb6a 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -698,7 +698,7 @@ static void gd_set_ui_info(VirtualConsole *vc, gint wid= th, gint height) memset(&info, 0, sizeof(info)); info.width =3D width; info.height =3D height; - dpy_set_ui_info(vc->gfx.dcl.con, &info); + dpy_set_ui_info(vc->gfx.dcl.con, &info, true); } =20 #if defined(CONFIG_OPENGL) diff --git a/ui/sdl2.c b/ui/sdl2.c index 17c0ec30eb..9ba3bc49e7 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -561,7 +561,7 @@ static void handle_windowevent(SDL_Event *ev) memset(&info, 0, sizeof(info)); info.width =3D ev->window.data1; info.height =3D ev->window.data2; - dpy_set_ui_info(scon->dcl.con, &info); + dpy_set_ui_info(scon->dcl.con, &info, true); } sdl2_redraw(scon); break; diff --git a/ui/spice-display.c b/ui/spice-display.c index f59c69882d..52d9f3260a 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -692,7 +692,7 @@ static int interface_client_monitors_config(QXLInstance= *sin, } =20 trace_qemu_spice_ui_info(ssd->qxl.id, info.width, info.height); - dpy_set_ui_info(ssd->dcl.con, &info); + dpy_set_ui_info(ssd->dcl.con, &info, false); return 1; } =20 diff --git a/ui/vnc.c b/ui/vnc.c index 9b603382e7..1ed1c7efc6 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2596,7 +2596,7 @@ static int protocol_client_msg(VncState *vs, uint8_t = *data, size_t len) memset(&info, 0, sizeof(info)); info.width =3D w; info.height =3D h; - dpy_set_ui_info(vs->vd->dcl.con, &info); + dpy_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 */); --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814243515199.6676115019808; Sat, 9 Oct 2021 14:17:23 -0700 (PDT) Received: from localhost ([::1]:55826 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJic-000118-Ej for importer@patchew.org; Sat, 09 Oct 2021 17:17:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38026) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJd1-0001cy-1N for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:60964) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJcz-00007a-Fm for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:34 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-101-nOnLOAfIMqSO4JyPlsQRrA-1; Sat, 09 Oct 2021 17:11:31 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A65FF1006AA3 for ; Sat, 9 Oct 2021 21:11:30 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5A04E60C13; Sat, 9 Oct 2021 21:11:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813892; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EeUva/Y26/C5tNNrKn3F2YJhjltyg+xWFW1hdLpJuN0=; b=d5tE8C0LiRTtM0En4KRbrL4vAjLfjgNrFvR2qrIiVtB6OLLIQpttrTLMU4vaAiHhfXo0uQ nLvzaEJ9w9yrwR3XMD8bkKtbJZpLSIUuKOta0dlA9ac69exXlwGUx0U0ihxpfwvEIuzMHx IMGmG19iBhvzR98UlyvnfjwbjXMEAHc= X-MC-Unique: nOnLOAfIMqSO4JyPlsQRrA-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 11/37] ui: factor out qemu_console_set_display_gl_ctx() Date: Sun, 10 Oct 2021 01:08:12 +0400 Message-Id: <20211009210838.2219430-12-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814244557100001 From: Marc-Andr=C3=A9 Lureau The next patch will make use of this function to dissociate DisplayChangeListener from GL context. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/ui/console.h | 3 +++ ui/console.c | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 7b2f624e93..1617b4c59a 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -406,6 +406,9 @@ void graphic_hw_gl_flushed(QemuConsole *con); =20 void qemu_console_early_init(void); =20 +void qemu_console_set_display_gl_ctx(QemuConsole *con, + DisplayChangeListener *dcl); + 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, diff --git a/ui/console.c b/ui/console.c index 7eea1fc641..64f35e163c 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1501,6 +1501,19 @@ static bool dpy_compatible_with(QemuConsole *con, return true; } =20 +void qemu_console_set_display_gl_ctx(QemuConsole *con, + DisplayChangeListener *dcl) +{ + /* display has opengl support */ + assert(dcl->con); + if (dcl->con->gl) { + fprintf(stderr, "can't register two opengl displays (%s, %s)\n", + dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name); + exit(1); + } + dcl->con->gl =3D dcl; +} + void register_displaychangelistener(DisplayChangeListener *dcl) { static const char nodev[] =3D @@ -1511,14 +1524,7 @@ void register_displaychangelistener(DisplayChangeLis= tener *dcl) assert(!dcl->ds); =20 if (dcl->ops->dpy_gl_ctx_create) { - /* display has opengl support */ - assert(dcl->con); - if (dcl->con->gl) { - fprintf(stderr, "can't register two opengl displays (%s, %s)\n= ", - dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name); - exit(1); - } - dcl->con->gl =3D dcl; + qemu_console_set_display_gl_ctx(dcl->con, dcl); } =20 if (dcl->con) { --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814405173575.1844426415084; Sat, 9 Oct 2021 14:20:05 -0700 (PDT) Received: from localhost ([::1]:36140 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJlD-0006sW-TD for importer@patchew.org; Sat, 09 Oct 2021 17:20:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38048) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdJ-00029U-H1 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:51666) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdG-00009x-Rb for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:11:53 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-74-wS3Ov_xdNbefBlpCUwFQtg-1; Sat, 09 Oct 2021 17:11:49 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 645348145E5 for ; Sat, 9 Oct 2021 21:11:48 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id A67355F707; Sat, 9 Oct 2021 21:11:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813910; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aYXEWkpz/G5frXzaBQHUrfLk7Vx5eg09b3UXZg1bJ/U=; b=FJ8JAa5xthMRjv2s15qNGxaeOccdWZWQ0f0PEodJP3HwZq9iNIRz1Qi4bMRrtz/yeO9gaF 916oU1mUHRcLzpBhlcgiprmh+Ix9zSoOAdWcwQWiVQh8WvH5IgW3fzSCJSQlyQMBlwRkOa /GJtIs2lR4PcWjRDz1n2pWPu/uYIWJo= X-MC-Unique: wS3Ov_xdNbefBlpCUwFQtg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 12/37] ui: associate GL context outside of display listener registration Date: Sun, 10 Oct 2021 01:08:13 +0400 Message-Id: <20211009210838.2219430-13-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814406404100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- ui/console.c | 7 +++++-- ui/egl-headless.c | 1 + ui/gtk.c | 3 +++ ui/sdl2.c | 3 +++ ui/spice-display.c | 3 +++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ui/console.c b/ui/console.c index 64f35e163c..3c4012271c 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1523,8 +1523,11 @@ void register_displaychangelistener(DisplayChangeLis= tener *dcl) =20 assert(!dcl->ds); =20 - if (dcl->ops->dpy_gl_ctx_create) { - qemu_console_set_display_gl_ctx(dcl->con, dcl); + if (dcl->con && dcl->con->gl && + dcl->con->gl !=3D dcl) { + error_report("Display %s is incompatible with the GL context", + dcl->ops->dpy_name); + exit(1); } =20 if (dcl->con) { diff --git a/ui/egl-headless.c b/ui/egl-headless.c index a26a2520c4..08327c40c6 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -197,6 +197,7 @@ static void egl_headless_init(DisplayState *ds, Display= Options *opts) edpy->dcl.con =3D con; edpy->dcl.ops =3D &egl_ops; edpy->gls =3D qemu_gl_init_shader(); + qemu_console_set_display_gl_ctx(con, &edpy->dcl); register_displaychangelistener(&edpy->dcl); } } diff --git a/ui/gtk.c b/ui/gtk.c index 163b6bcb6a..f8beddbb91 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -2057,6 +2057,9 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, vc->gfx.kbd =3D qkbd_state_init(con); vc->gfx.dcl.con =3D con; =20 + if (display_opengl) { + qemu_console_set_display_gl_ctx(con, &vc->gfx.dcl); + } register_displaychangelistener(&vc->gfx.dcl); =20 gd_connect_vc_gfx_signals(vc); diff --git a/ui/sdl2.c b/ui/sdl2.c index 9ba3bc49e7..bb186a381a 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -866,6 +866,9 @@ static void sdl2_display_init(DisplayState *ds, Display= Options *o) #endif sdl2_console[i].dcl.con =3D con; sdl2_console[i].kbd =3D qkbd_state_init(con); + if (display_opengl) { + qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dcl); + } register_displaychangelistener(&sdl2_console[i].dcl); =20 #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11) diff --git a/ui/spice-display.c b/ui/spice-display.c index 52d9f3260a..2c204bceee 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -1156,6 +1156,9 @@ static void qemu_spice_display_init_one(QemuConsole *= con) =20 qemu_spice_create_host_memslot(ssd); =20 + if (spice_opengl) { + qemu_console_set_display_gl_ctx(con, &ssd->dcl); + } register_displaychangelistener(&ssd->dcl); } =20 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814622636596.3144098777635; Sat, 9 Oct 2021 14:23:42 -0700 (PDT) Received: from localhost ([::1]:47504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJoj-00064b-Jg for importer@patchew.org; Sat, 09 Oct 2021 17:23:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38084) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdU-0002FS-Ir for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:05 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:26432) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdT-0000DV-5t for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:04 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-112-yIh9egYvM5iaFdTzlUc8fg-1; Sat, 09 Oct 2021 17:12:01 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 75715A0CAB for ; Sat, 9 Oct 2021 21:12:00 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id AB96757CA1; Sat, 9 Oct 2021 21:11:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813922; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YjcSxsxLZJrUoPXcFLF+bfTEiXLq6QXAzu3eDdzypuM=; b=USiNzy+kr+5T0pvllMSSrfxNPOJ34vOWV56CdXceZFgtFPC24I1qMrcntrxc5IRomQjeDg evrZ2xdToottaMXnGJIF0V5K/CjhwFrhuXKkXmbkjvC6T26HP4ZzpXu6btcg9AQPy01hPm T4vSg2OljOAFDAYtZZRh7a6RevMxpvY= X-MC-Unique: yIh9egYvM5iaFdTzlUc8fg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 13/37] ui: make gl_block use a counter Date: Sun, 10 Oct 2021 01:08:14 +0400 Message-Id: <20211009210838.2219430-14-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814623317100001 From: Marc-Andr=C3=A9 Lureau Track multiple callers blocking requests. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- ui/console.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ui/console.c b/ui/console.c index 3c4012271c..8d641b9530 100644 --- a/ui/console.c +++ b/ui/console.c @@ -128,7 +128,7 @@ struct QemuConsole { DisplaySurface *surface; int dcls; DisplayChangeListener *gl; - bool gl_block; + int gl_block; int window_id; =20 /* Graphic console state. */ @@ -288,10 +288,19 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) { assert(con !=3D NULL); =20 - con->gl_block =3D block; - if (con->hw_ops->gl_block) { - con->hw_ops->gl_block(con->hw, block); + if (block) { + con->gl_block++; + } else { + con->gl_block--; + } + assert(con->gl_block >=3D 0); + if (!con->hw_ops->gl_block) { + return; + } + if ((block && con->gl_block !=3D 1) || (!block && con->gl_block !=3D 0= )) { + return; } + con->hw_ops->gl_block(con->hw, block); } =20 void graphic_hw_gl_flushed(QemuConsole *con) --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814778087377.27012698771773; Sat, 9 Oct 2021 14:26:18 -0700 (PDT) Received: from localhost ([::1]:55896 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJrF-0003FH-4e for importer@patchew.org; Sat, 09 Oct 2021 17:26:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38098) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdk-0002pb-96 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:27371) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdi-0000GI-LZ for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:19 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-447-Gfu_NzP6N6WQZXqY0K-zfg-1; Sat, 09 Oct 2021 17:12:16 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4F63A10A8E00 for ; Sat, 9 Oct 2021 21:12:15 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id C30AE60622; Sat, 9 Oct 2021 21:12:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nk8jiC2IOuCDwDwRzB4dGaKF6jr+LGDIgyEX6S1LbYg=; b=eumiKl8YGfog/HWV77J2SDb0uM+yc3Idpkc97AKKN/oIci9XdNM+v8lLsCDeaoKKycZ3ko zkhjojMGQYd3jBqbCUfTN65Ebs+DMGmhWhPS23+AaMInjPnBLsQ7k7c5+N8KoybzjDEOsH LhSqBR2WhYGwQYyjo5stxKE0sc9Zu48= X-MC-Unique: Gfu_NzP6N6WQZXqY0K-zfg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 14/37] ui: add a gl-unblock warning timer Date: Sun, 10 Oct 2021 01:08:15 +0400 Message-Id: <20211009210838.2219430-15-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814779728100001 From: Marc-Andr=C3=A9 Lureau Similar to the one that exists for Spice, so we can investigate if something is locked. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- ui/console.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ui/console.c b/ui/console.c index 8d641b9530..c62a33b1ec 100644 --- a/ui/console.c +++ b/ui/console.c @@ -129,6 +129,7 @@ struct QemuConsole { int dcls; DisplayChangeListener *gl; int gl_block; + QEMUTimer *gl_unblock_timer; int window_id; =20 /* Graphic console state. */ @@ -284,8 +285,14 @@ void graphic_hw_update(QemuConsole *con) } } =20 +static void graphic_hw_gl_unblock_timer(void *opaque) +{ + warn_report("console: no gl-unblock within one second"); +} + void graphic_hw_gl_block(QemuConsole *con, bool block) { + uint64_t timeout; assert(con !=3D NULL); =20 if (block) { @@ -301,6 +308,14 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) return; } con->hw_ops->gl_block(con->hw, block); + + if (block) { + timeout =3D qemu_clock_get_ms(QEMU_CLOCK_REALTIME); + timeout +=3D 1000; /* one sec */ + timer_mod(con->gl_unblock_timer, timeout); + } else { + timer_del(con->gl_unblock_timer); + } } =20 void graphic_hw_gl_flushed(QemuConsole *con) @@ -2024,6 +2039,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, u= int32_t head, =20 surface =3D qemu_create_placeholder_surface(width, height, noinit); dpy_gfx_replace_surface(s, surface); + s->gl_unblock_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, + graphic_hw_gl_unblock_timer, s); return s; } =20 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814461188257.784035341861; Sat, 9 Oct 2021 14:21:01 -0700 (PDT) Received: from localhost ([::1]:37504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJm7-0007m5-LA for importer@patchew.org; Sat, 09 Oct 2021 17:21:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38120) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJdv-0002x5-2r for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:33 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:52604) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJds-0000Ge-Hf for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:30 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-199-FZ8Zj6h9PNaShzQYeDVfiw-1; Sat, 09 Oct 2021 17:12:26 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A40D610A8E00 for ; Sat, 9 Oct 2021 21:12:25 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 81ECA5D9D3; Sat, 9 Oct 2021 21:12:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813948; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NrZIqxWKSm+hxMI4Mo5BWcaqQx/ewz20BFFbLNHm73w=; b=SwDAXUvAQ4CwHN3ks9MesNIaFOHb4LbvNMya0mOpVSbr8YOeYqObn5FVXnOfP0mjm/kjh/ h+ElH7O5hxcyQ3GsHc6sIZdzFbcHYyLQCiMvvld8m1xsseGuOlvhiMDr7zyoI6JvAkRNHA fPEhRrFuGZ0X/J4yZJgiTN3p/KkSmkg= X-MC-Unique: FZ8Zj6h9PNaShzQYeDVfiw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 15/37] ui: simplify gl unblock & flush Date: Sun, 10 Oct 2021 01:08:16 +0400 Message-Id: <20211009210838.2219430-16-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814462546100001 From: Marc-Andr=C3=A9 Lureau GraphicHw.gl_flushed was introduced to notify the device (vhost-user-gpu) that the GL resources (the display scanout) are no longer needed. It was decoupled from QEMU own gl-blocking mechanism, but that difference isn't helping. Instead, we can reuse QEMU gl-blocking and notify virtio_gpu_gl_flushed() when unblocking (to unlock vhost-user-gpu). An extra block/unblock is added arount dpy_gl_update() so existing backends that don't block will have the flush event handled. It will also help when there are no backends associated. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/console.h | 2 -- hw/display/vhost-user-gpu.c | 2 +- hw/display/virtio-gpu-base.c | 5 ++++- hw/display/virtio-vga.c | 11 ----------- ui/console.c | 12 +++--------- ui/gtk-egl.c | 1 - ui/gtk-gl-area.c | 1 - ui/gtk.c | 1 - ui/sdl2-gl.c | 2 -- ui/spice-display.c | 1 - 10 files changed, 8 insertions(+), 30 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 1617b4c59a..cd6f103bd9 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -386,7 +386,6 @@ typedef struct GraphicHwOps { void (*update_interval)(void *opaque, uint64_t interval); int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info); void (*gl_block)(void *opaque, bool block); - void (*gl_flushed)(void *opaque); } GraphicHwOps; =20 QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, @@ -402,7 +401,6 @@ 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_gl_block(QemuConsole *con, bool block); -void graphic_hw_gl_flushed(QemuConsole *con); =20 void qemu_console_early_init(void); =20 diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 49df56cd14..09818231bd 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -254,8 +254,8 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUse= rGpuMsg *msg) vhost_user_gpu_unblock(g); break; } - dpy_gl_update(con, m->x, m->y, m->width, m->height); g->backend_blocked =3D true; + dpy_gl_update(con, m->x, m->y, m->width, m->height); break; } case VHOST_USER_GPU_UPDATE: { diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index c8da4806e0..fff0fb4a82 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -117,6 +117,10 @@ virtio_gpu_gl_block(void *opaque, bool block) g->renderer_blocked--; } assert(g->renderer_blocked >=3D 0); + + if (!block && g->renderer_blocked =3D=3D 0) { + virtio_gpu_gl_flushed(g); + } } =20 static int @@ -143,7 +147,6 @@ static const GraphicHwOps virtio_gpu_ops =3D { .text_update =3D virtio_gpu_text_update, .ui_info =3D virtio_gpu_ui_info, .gl_block =3D virtio_gpu_gl_block, - .gl_flushed =3D virtio_gpu_gl_flushed, }; =20 bool diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index 9e57f61e9e..b23a75a04b 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -68,16 +68,6 @@ static void virtio_vga_base_gl_block(void *opaque, bool = block) } } =20 -static void virtio_vga_base_gl_flushed(void *opaque) -{ - VirtIOVGABase *vvga =3D opaque; - VirtIOGPUBase *g =3D vvga->vgpu; - - if (g->hw_ops->gl_flushed) { - g->hw_ops->gl_flushed(g); - } -} - static int virtio_vga_base_get_flags(void *opaque) { VirtIOVGABase *vvga =3D opaque; @@ -93,7 +83,6 @@ static const GraphicHwOps virtio_vga_base_ops =3D { .text_update =3D virtio_vga_base_text_update, .ui_info =3D virtio_vga_base_ui_info, .gl_block =3D virtio_vga_base_gl_block, - .gl_flushed =3D virtio_vga_base_gl_flushed, }; =20 static const VMStateDescription vmstate_virtio_vga_base =3D { diff --git a/ui/console.c b/ui/console.c index c62a33b1ec..016ace5029 100644 --- a/ui/console.c +++ b/ui/console.c @@ -318,15 +318,6 @@ void graphic_hw_gl_block(QemuConsole *con, bool block) } } =20 -void graphic_hw_gl_flushed(QemuConsole *con) -{ - assert(con !=3D NULL); - - if (con->hw_ops->gl_flushed) { - con->hw_ops->gl_flushed(con->hw); - } -} - int qemu_console_get_window_id(QemuConsole *con) { return con->window_id; @@ -1952,7 +1943,10 @@ void dpy_gl_update(QemuConsole *con, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { assert(con->gl); + + graphic_hw_gl_block(con, true); con->gl->ops->dpy_gl_update(con->gl, x, y, w, h); + graphic_hw_gl_block(con, false); } =20 /***********************************************************/ diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 72ce5e1f8f..0f64baee63 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -107,7 +107,6 @@ void gd_egl_draw(VirtualConsole *vc) graphic_hw_gl_block(vc->gfx.dcl.con, false); } #endif - graphic_hw_gl_flushed(vc->gfx.dcl.con); } =20 void gd_egl_update(DisplayChangeListener *dcl, diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index b23523748e..5e79505291 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -91,7 +91,6 @@ void gd_gl_area_draw(VirtualConsole *vc) graphic_hw_gl_block(vc->gfx.dcl.con, false); } #endif - graphic_hw_gl_flushed(vc->gfx.dcl.con); } =20 void gd_gl_area_update(DisplayChangeListener *dcl, diff --git a/ui/gtk.c b/ui/gtk.c index f8beddbb91..71bfe29793 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -590,7 +590,6 @@ void gd_hw_gl_flushed(void *vcon) QemuDmaBuf *dmabuf =3D vc->gfx.guest_fb.dmabuf; =20 graphic_hw_gl_block(vc->gfx.dcl.con, false); - graphic_hw_gl_flushed(vc->gfx.dcl.con); qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL); close(dmabuf->fence_fd); dmabuf->fence_fd =3D -1; diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index a21d2deed9..5b950fbbea 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -58,7 +58,6 @@ static void sdl2_gl_render_surface(struct sdl2_console *s= con) =20 surface_gl_render_texture(scon->gls, scon->surface); SDL_GL_SwapWindow(scon->real_window); - graphic_hw_gl_flushed(scon->dcl.con); } =20 void sdl2_gl_update(DisplayChangeListener *dcl, @@ -241,5 +240,4 @@ void sdl2_gl_scanout_flush(DisplayChangeListener *dcl, egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top); =20 SDL_GL_SwapWindow(scon->real_window); - graphic_hw_gl_flushed(dcl->con); } diff --git a/ui/spice-display.c b/ui/spice-display.c index 2c204bceee..ec501f129f 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -830,7 +830,6 @@ static void qemu_spice_gl_unblock_bh(void *opaque) SimpleSpiceDisplay *ssd =3D opaque; =20 qemu_spice_gl_block(ssd, false); - graphic_hw_gl_flushed(ssd->dcl.con); } =20 static void qemu_spice_gl_block_timer(void *opaque) --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 16338145603637.610262868598966; Sat, 9 Oct 2021 14:22:40 -0700 (PDT) Received: from localhost ([::1]:44122 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJnj-0003of-2q for importer@patchew.org; Sat, 09 Oct 2021 17:22:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38152) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJeE-000392-25 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:50 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:25327) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJeC-0000Hc-Hj for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:12:49 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-142-V4f6iVAFOdScGsw-ZMF6dA-1; Sat, 09 Oct 2021 17:12:36 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 36E3B10A8E01 for ; Sat, 9 Oct 2021 21:12:36 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id B6C5F6091B; Sat, 9 Oct 2021 21:12:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813968; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0SxvZ7jR1mJPsjgZM9ZR/VTmW4G4ebInFaaukMmKsQU=; b=AdTnkFFuDaotPVfJDaEbEJ537bLWWztZfQ5LnwpHOtGjyt8GWANNf93HoI5KDDeimaZJK0 s11ee+S2LjHkdyy3TbQc26yzKPNOKySQFtvlQnDP/oKRKC06x2Cs8y8MlffAl6nTrSr2Vg 0j7xP9mYNmVSwaFXSzZTg4IGlft5tsw= X-MC-Unique: V4f6iVAFOdScGsw-ZMF6dA-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 16/37] ui: dispatch GL events to all listeners Date: Sun, 10 Oct 2021 01:08:17 +0400 Message-Id: <20211009210838.2219430-17-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814561491100001 From: Marc-Andr=C3=A9 Lureau For now, only one listener can receive GL events. Let's dispatch to all listeners. (preliminary check ensure there is a single listener now during regitration, and in next patches, compatible listeners only) Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- ui/console.c | 58 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/ui/console.c b/ui/console.c index 016ace5029..75e432106b 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1882,8 +1882,12 @@ int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGL= Context ctx) =20 void dpy_gl_scanout_disable(QemuConsole *con) { - assert(con->gl); - con->gl->ops->dpy_gl_scanout_disable(con->gl); + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; + + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_scanout_disable(dcl); + } } =20 void dpy_gl_scanout_texture(QemuConsole *con, @@ -1894,58 +1898,80 @@ void dpy_gl_scanout_texture(QemuConsole *con, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { - assert(con->gl); - con->gl->ops->dpy_gl_scanout_texture(con->gl, backing_id, + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; + + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_scanout_texture(dcl, backing_id, backing_y_0_top, backing_width, backing_height, x, y, width, height); + } } =20 void dpy_gl_scanout_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf) { - assert(con->gl); - con->gl->ops->dpy_gl_scanout_dmabuf(con->gl, dmabuf); + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; + + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_scanout_dmabuf(dcl, dmabuf); + } } =20 void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, bool have_hot, uint32_t hot_x, uint32_t hot_y) { - assert(con->gl); + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; =20 - if (con->gl->ops->dpy_gl_cursor_dmabuf) { - con->gl->ops->dpy_gl_cursor_dmabuf(con->gl, dmabuf, + QLIST_FOREACH(dcl, &s->listeners, next) { + if (dcl->ops->dpy_gl_cursor_dmabuf) { + dcl->ops->dpy_gl_cursor_dmabuf(dcl, dmabuf, have_hot, hot_x, hot_y); + } } } =20 void dpy_gl_cursor_position(QemuConsole *con, uint32_t pos_x, uint32_t pos_y) { - assert(con->gl); + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; =20 - if (con->gl->ops->dpy_gl_cursor_position) { - con->gl->ops->dpy_gl_cursor_position(con->gl, pos_x, pos_y); + QLIST_FOREACH(dcl, &s->listeners, next) { + if (dcl->ops->dpy_gl_cursor_position) { + dcl->ops->dpy_gl_cursor_position(dcl, pos_x, pos_y); + } } } =20 void dpy_gl_release_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf) { - assert(con->gl); + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; =20 - if (con->gl->ops->dpy_gl_release_dmabuf) { - con->gl->ops->dpy_gl_release_dmabuf(con->gl, dmabuf); + QLIST_FOREACH(dcl, &s->listeners, next) { + if (dcl->ops->dpy_gl_release_dmabuf) { + dcl->ops->dpy_gl_release_dmabuf(dcl, dmabuf); + } } } =20 void dpy_gl_update(QemuConsole *con, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { + DisplayState *s =3D con->ds; + DisplayChangeListener *dcl; + assert(con->gl); =20 graphic_hw_gl_block(con, true); - con->gl->ops->dpy_gl_update(con->gl, x, y, w, h); + QLIST_FOREACH(dcl, &s->listeners, next) { + dcl->ops->dpy_gl_update(dcl, x, y, w, h); + } graphic_hw_gl_block(con, false); } =20 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814594459139.59227218039473; Sat, 9 Oct 2021 14:23:14 -0700 (PDT) Received: from localhost ([::1]:45918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJoH-00051S-7g for importer@patchew.org; Sat, 09 Oct 2021 17:23:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38172) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJeR-0003NR-MQ for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:03 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:31251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJeO-0000IH-Up for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:03 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-589-AUEE8O91Pp2tN7g6a7seAg-1; Sat, 09 Oct 2021 17:12:57 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 79A0010A8E01 for ; Sat, 9 Oct 2021 21:12:56 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 680535C1B4; Sat, 9 Oct 2021 21:12:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813980; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ywbaU1V2fW7TiFORe1WiPNnKZFKy77Atow8j3ixu0QQ=; b=RN2XWfx0xVWMCDvm9+y6sRDxCNuWldEvYl9R9d32CtAhg6rWVGwWhDpYAptl0++Q43UvXv mhh3jvF8eDqZ5e9GDOWigI0NatkdWU7m3vnWOcKvBy2ZSqNFxH0yrKeZfpeBr63sRaWDYx Lke6UMde2BuqpJ+Li96HrGVSnZiz1ng= X-MC-Unique: AUEE8O91Pp2tN7g6a7seAg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 17/37] ui: split the GL context in a different object Date: Sun, 10 Oct 2021 01:08:18 +0400 Message-Id: <20211009210838.2219430-18-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814596447100001 From: Marc-Andr=C3=A9 Lureau This will allow to have one GL context but a variable number of listeners. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/console.h | 34 ++++++++++++++++++++++------------ include/ui/egl-context.h | 6 +++--- include/ui/gtk.h | 11 ++++++----- include/ui/sdl2.h | 7 ++++--- include/ui/spice-display.h | 1 + ui/console.c | 26 ++++++++++++++++---------- ui/egl-context.c | 6 +++--- ui/egl-headless.c | 21 ++++++++++++++------- ui/gtk-egl.c | 10 +++++----- ui/gtk-gl-area.c | 8 ++++---- ui/gtk.c | 24 ++++++++++++++++-------- ui/sdl2-gl.c | 10 +++++----- ui/sdl2.c | 13 +++++++++---- ui/spice-display.c | 18 +++++++++++------- 14 files changed, 119 insertions(+), 76 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index cd6f103bd9..7a35c4fc6a 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -174,6 +174,7 @@ typedef struct QemuDmaBuf { } QemuDmaBuf; =20 typedef struct DisplayState DisplayState; +typedef struct DisplayGLCtx DisplayGLCtx; =20 typedef struct DisplayChangeListenerOps { const char *dpy_name; @@ -208,16 +209,6 @@ typedef struct DisplayChangeListenerOps { void (*dpy_cursor_define)(DisplayChangeListener *dcl, QEMUCursor *cursor); =20 - /* required if GL */ - QEMUGLContext (*dpy_gl_ctx_create)(DisplayChangeListener *dcl, - QEMUGLParams *params); - /* required if GL */ - void (*dpy_gl_ctx_destroy)(DisplayChangeListener *dcl, - QEMUGLContext ctx); - /* required if GL */ - int (*dpy_gl_ctx_make_current)(DisplayChangeListener *dcl, - QEMUGLContext ctx); - /* required if GL */ void (*dpy_gl_scanout_disable)(DisplayChangeListener *dcl); /* required if GL */ @@ -258,6 +249,26 @@ struct DisplayChangeListener { QLIST_ENTRY(DisplayChangeListener) next; }; =20 +typedef struct DisplayGLCtxOps { + /* + * We only check if the GLCtx is compatible with a DCL via ops. A natu= ral + * evolution of this would be a callback to check some runtime require= ments + * and allow various DCL kinds. + */ + const DisplayChangeListenerOps *compatible_dcl; + + QEMUGLContext (*dpy_gl_ctx_create)(DisplayGLCtx *dgc, + QEMUGLParams *params); + void (*dpy_gl_ctx_destroy)(DisplayGLCtx *dgc, + QEMUGLContext ctx); + int (*dpy_gl_ctx_make_current)(DisplayGLCtx *dgc, + QEMUGLContext ctx); +} DisplayGLCtxOps; + +struct DisplayGLCtx { + const DisplayGLCtxOps *ops; +}; + DisplayState *init_displaystate(void); DisplaySurface *qemu_create_displaysurface_from(int width, int height, pixman_format_code_t forma= t, @@ -404,8 +415,7 @@ void graphic_hw_gl_block(QemuConsole *con, bool block); =20 void qemu_console_early_init(void); =20 -void qemu_console_set_display_gl_ctx(QemuConsole *con, - DisplayChangeListener *dcl); +void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *ctx); =20 QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head= ); diff --git a/include/ui/egl-context.h b/include/ui/egl-context.h index 9374fe41e3..c2761d747a 100644 --- a/include/ui/egl-context.h +++ b/include/ui/egl-context.h @@ -4,10 +4,10 @@ #include "ui/console.h" #include "ui/egl-helpers.h" =20 -QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); -void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ct= x); -int qemu_egl_make_context_current(DisplayChangeListener *dcl, +void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx); +int qemu_egl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx); =20 #endif /* EGL_CONTEXT_H */ diff --git a/include/ui/gtk.h b/include/ui/gtk.h index 7d22affd38..101b147d1b 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -35,6 +35,7 @@ typedef struct GtkDisplayState GtkDisplayState; =20 typedef struct VirtualGfxConsole { GtkWidget *drawing_area; + DisplayGLCtx dgc; DisplayChangeListener dcl; QKbdState *kbd; DisplaySurface *ds; @@ -165,7 +166,7 @@ void gd_egl_update(DisplayChangeListener *dcl, void gd_egl_refresh(DisplayChangeListener *dcl); void gd_egl_switch(DisplayChangeListener *dcl, DisplaySurface *surface); -QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); void gd_egl_scanout_disable(DisplayChangeListener *dcl); void gd_egl_scanout_texture(DisplayChangeListener *dcl, @@ -187,7 +188,7 @@ void gd_egl_flush(DisplayChangeListener *dcl, void gd_egl_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t h); void gtk_egl_init(DisplayGLMode mode); -int gd_egl_make_current(DisplayChangeListener *dcl, +int gd_egl_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx); =20 /* ui/gtk-gl-area.c */ @@ -198,9 +199,9 @@ void gd_gl_area_update(DisplayChangeListener *dcl, void gd_gl_area_refresh(DisplayChangeListener *dcl); void gd_gl_area_switch(DisplayChangeListener *dcl, DisplaySurface *surface); -QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); -void gd_gl_area_destroy_context(DisplayChangeListener *dcl, +void gd_gl_area_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx); void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl, QemuDmaBuf *dmabuf); @@ -215,7 +216,7 @@ void gd_gl_area_scanout_disable(DisplayChangeListener *= dcl); void gd_gl_area_scanout_flush(DisplayChangeListener *dcl, uint32_t x, uint32_t y, uint32_t w, uint32_t= h); void gtk_gl_area_init(void); -int gd_gl_area_make_current(DisplayChangeListener *dcl, +int gd_gl_area_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx); =20 /* gtk-clipboard.c */ diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index f85c117a78..71bcf7ebda 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -16,6 +16,7 @@ #endif =20 struct sdl2_console { + DisplayGLCtx dgc; DisplayChangeListener dcl; DisplaySurface *surface; DisplayOptions *opts; @@ -65,10 +66,10 @@ void sdl2_gl_switch(DisplayChangeListener *dcl, void sdl2_gl_refresh(DisplayChangeListener *dcl); void sdl2_gl_redraw(struct sdl2_console *scon); =20 -QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl, +QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params); -void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx= ); -int sdl2_gl_make_context_current(DisplayChangeListener *dcl, +void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx); +int sdl2_gl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx); =20 void sdl2_gl_scanout_disable(DisplayChangeListener *dcl); diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index ed298d58f0..a2fbf62c52 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -86,6 +86,7 @@ typedef struct SimpleSpiceCursor SimpleSpiceCursor; =20 struct SimpleSpiceDisplay { DisplaySurface *ds; + DisplayGLCtx dgc; DisplayChangeListener dcl; void *buf; int bufsize; diff --git a/ui/console.c b/ui/console.c index 75e432106b..e5a2c84dd9 100644 --- a/ui/console.c +++ b/ui/console.c @@ -127,7 +127,7 @@ struct QemuConsole { DisplayState *ds; DisplaySurface *surface; int dcls; - DisplayChangeListener *gl; + DisplayGLCtx *gl; int gl_block; QEMUTimer *gl_unblock_timer; int window_id; @@ -1516,17 +1516,24 @@ static bool dpy_compatible_with(QemuConsole *con, return true; } =20 -void qemu_console_set_display_gl_ctx(QemuConsole *con, - DisplayChangeListener *dcl) +void qemu_console_set_display_gl_ctx(QemuConsole *con, DisplayGLCtx *gl) { /* display has opengl support */ - assert(dcl->con); - if (dcl->con->gl) { - fprintf(stderr, "can't register two opengl displays (%s, %s)\n", - dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name); + assert(con); + if (con->gl) { + error_report("The console already has an OpenGL context."); exit(1); } - dcl->con->gl =3D dcl; + con->gl =3D gl; +} + +static bool dpy_gl_compatible_with(QemuConsole *con, DisplayChangeListener= *dcl) +{ + if (!con->gl) { + return true; + } + + return con->gl->ops->compatible_dcl =3D=3D dcl->ops; } =20 void register_displaychangelistener(DisplayChangeListener *dcl) @@ -1538,8 +1545,7 @@ void register_displaychangelistener(DisplayChangeList= ener *dcl) =20 assert(!dcl->ds); =20 - if (dcl->con && dcl->con->gl && - dcl->con->gl !=3D dcl) { + if (dcl->con && !dpy_gl_compatible_with(dcl->con, dcl)) { error_report("Display %s is incompatible with the GL context", dcl->ops->dpy_name); exit(1); diff --git a/ui/egl-context.c b/ui/egl-context.c index 368ffa49d8..eb5f520fc4 100644 --- a/ui/egl-context.c +++ b/ui/egl-context.c @@ -1,7 +1,7 @@ #include "qemu/osdep.h" #include "ui/egl-context.h" =20 -QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext qemu_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { EGLContext ctx; @@ -24,12 +24,12 @@ QEMUGLContext qemu_egl_create_context(DisplayChangeList= ener *dcl, return ctx; } =20 -void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ct= x) +void qemu_egl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx) { eglDestroyContext(qemu_egl_display, ctx); } =20 -int qemu_egl_make_context_current(DisplayChangeListener *dcl, +int qemu_egl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { return eglMakeCurrent(qemu_egl_display, diff --git a/ui/egl-headless.c b/ui/egl-headless.c index 08327c40c6..94082a9da9 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -38,12 +38,12 @@ static void egl_gfx_switch(DisplayChangeListener *dcl, edpy->ds =3D new_surface; } =20 -static QEMUGLContext egl_create_context(DisplayChangeListener *dcl, +static QEMUGLContext egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, qemu_egl_rn_ctx); - return qemu_egl_create_context(dcl, params); + return qemu_egl_create_context(dgc, params); } =20 static void egl_scanout_disable(DisplayChangeListener *dcl) @@ -157,10 +157,6 @@ static const DisplayChangeListenerOps egl_ops =3D { .dpy_gfx_update =3D egl_gfx_update, .dpy_gfx_switch =3D egl_gfx_switch, =20 - .dpy_gl_ctx_create =3D egl_create_context, - .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, - .dpy_gl_ctx_make_current =3D qemu_egl_make_context_current, - .dpy_gl_scanout_disable =3D egl_scanout_disable, .dpy_gl_scanout_texture =3D egl_scanout_texture, .dpy_gl_scanout_dmabuf =3D egl_scanout_dmabuf, @@ -170,6 +166,13 @@ static const DisplayChangeListenerOps egl_ops =3D { .dpy_gl_update =3D egl_scanout_flush, }; =20 +static const DisplayGLCtxOps eglctx_ops =3D { + .compatible_dcl =3D &egl_ops, + .dpy_gl_ctx_create =3D egl_create_context, + .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, + .dpy_gl_ctx_make_current =3D qemu_egl_make_context_current, +}; + static void early_egl_headless_init(DisplayOptions *opts) { display_opengl =3D 1; @@ -188,6 +191,8 @@ static void egl_headless_init(DisplayState *ds, Display= Options *opts) } =20 for (idx =3D 0;; idx++) { + DisplayGLCtx *ctx; + con =3D qemu_console_lookup_by_index(idx); if (!con || !qemu_console_is_graphic(con)) { break; @@ -197,7 +202,9 @@ static void egl_headless_init(DisplayState *ds, Display= Options *opts) edpy->dcl.con =3D con; edpy->dcl.ops =3D &egl_ops; edpy->gls =3D qemu_gl_init_shader(); - qemu_console_set_display_gl_ctx(con, &edpy->dcl); + ctx =3D g_new0(DisplayGLCtx, 1); + ctx->ops =3D &eglctx_ops; + qemu_console_set_display_gl_ctx(con, ctx); register_displaychangelistener(&edpy->dcl); } } diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 0f64baee63..7087e5a5cf 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -176,14 +176,14 @@ void gd_egl_switch(DisplayChangeListener *dcl, } } =20 -QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { - VirtualConsole *vc =3D container_of(dcl, VirtualConsole, gfx.dcl); + VirtualConsole *vc =3D container_of(dgc, VirtualConsole, gfx.dgc); =20 eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, vc->gfx.esurface, vc->gfx.ectx); - return qemu_egl_create_context(dcl, params); + return qemu_egl_create_context(dgc, params); } =20 void gd_egl_scanout_disable(DisplayChangeListener *dcl) @@ -335,10 +335,10 @@ void gtk_egl_init(DisplayGLMode mode) display_opengl =3D 1; } =20 -int gd_egl_make_current(DisplayChangeListener *dcl, +int gd_egl_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { - VirtualConsole *vc =3D container_of(dcl, VirtualConsole, gfx.dcl); + VirtualConsole *vc =3D container_of(dgc, VirtualConsole, gfx.dgc); =20 return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, vc->gfx.esurface, ctx); diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index 5e79505291..cd6c455f22 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -157,10 +157,10 @@ void gd_gl_area_switch(DisplayChangeListener *dcl, } } =20 -QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl, +QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { - VirtualConsole *vc =3D container_of(dcl, VirtualConsole, gfx.dcl); + VirtualConsole *vc =3D container_of(dgc, VirtualConsole, gfx.dgc); GdkWindow *window; GdkGLContext *ctx; GError *err =3D NULL; @@ -186,7 +186,7 @@ QEMUGLContext gd_gl_area_create_context(DisplayChangeLi= stener *dcl, return ctx; } =20 -void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext = ctx) +void gd_gl_area_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx) { /* FIXME */ } @@ -264,7 +264,7 @@ void gtk_gl_area_init(void) display_opengl =3D 1; } =20 -int gd_gl_area_make_current(DisplayChangeListener *dcl, +int gd_gl_area_make_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { gdk_gl_context_make_current(ctx); diff --git a/ui/gtk.c b/ui/gtk.c index 71bfe29793..db9bcb6f1a 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -606,9 +606,6 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = =3D { .dpy_mouse_set =3D gd_mouse_set, .dpy_cursor_define =3D gd_cursor_define, =20 - .dpy_gl_ctx_create =3D gd_gl_area_create_context, - .dpy_gl_ctx_destroy =3D gd_gl_area_destroy_context, - .dpy_gl_ctx_make_current =3D gd_gl_area_make_current, .dpy_gl_scanout_texture =3D gd_gl_area_scanout_texture, .dpy_gl_scanout_disable =3D gd_gl_area_scanout_disable, .dpy_gl_update =3D gd_gl_area_scanout_flush, @@ -617,8 +614,14 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = =3D { .dpy_has_dmabuf =3D gd_has_dmabuf, }; =20 -#ifdef CONFIG_X11 +static const DisplayGLCtxOps gl_area_ctx_ops =3D { + .compatible_dcl =3D &dcl_gl_area_ops, + .dpy_gl_ctx_create =3D gd_gl_area_create_context, + .dpy_gl_ctx_destroy =3D gd_gl_area_destroy_context, + .dpy_gl_ctx_make_current =3D gd_gl_area_make_current, +}; =20 +#ifdef CONFIG_X11 static const DisplayChangeListenerOps dcl_egl_ops =3D { .dpy_name =3D "gtk-egl", .dpy_gfx_update =3D gd_egl_update, @@ -628,9 +631,6 @@ static const DisplayChangeListenerOps dcl_egl_ops =3D { .dpy_mouse_set =3D gd_mouse_set, .dpy_cursor_define =3D gd_cursor_define, =20 - .dpy_gl_ctx_create =3D gd_egl_create_context, - .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, - .dpy_gl_ctx_make_current =3D gd_egl_make_current, .dpy_gl_scanout_disable =3D gd_egl_scanout_disable, .dpy_gl_scanout_texture =3D gd_egl_scanout_texture, .dpy_gl_scanout_dmabuf =3D gd_egl_scanout_dmabuf, @@ -641,6 +641,12 @@ static const DisplayChangeListenerOps dcl_egl_ops =3D { .dpy_has_dmabuf =3D gd_has_dmabuf, }; =20 +static const DisplayGLCtxOps egl_ctx_ops =3D { + .compatible_dcl =3D &dcl_egl_ops, + .dpy_gl_ctx_create =3D gd_egl_create_context, + .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, + .dpy_gl_ctx_make_current =3D gd_egl_make_current, +}; #endif =20 #endif /* CONFIG_OPENGL */ @@ -2008,6 +2014,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, g_signal_connect(vc->gfx.drawing_area, "realize", G_CALLBACK(gl_area_realize), vc); vc->gfx.dcl.ops =3D &dcl_gl_area_ops; + vc->gfx.dgc.ops =3D &gl_area_ctx_ops; } else { #ifdef CONFIG_X11 vc->gfx.drawing_area =3D gtk_drawing_area_new(); @@ -2022,6 +2029,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE); #pragma GCC diagnostic pop vc->gfx.dcl.ops =3D &dcl_egl_ops; + vc->gfx.dgc.ops =3D &egl_ctx_ops; vc->gfx.has_dmabuf =3D qemu_egl_has_dmabuf(); #else abort(); @@ -2057,7 +2065,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, vc->gfx.dcl.con =3D con; =20 if (display_opengl) { - qemu_console_set_display_gl_ctx(con, &vc->gfx.dcl); + qemu_console_set_display_gl_ctx(con, &vc->gfx.dgc); } register_displaychangelistener(&vc->gfx.dcl); =20 diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index 5b950fbbea..39cab8cde7 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -132,10 +132,10 @@ void sdl2_gl_redraw(struct sdl2_console *scon) } } =20 -QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl, +QEMUGLContext sdl2_gl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { - struct sdl2_console *scon =3D container_of(dcl, struct sdl2_console, d= cl); + struct sdl2_console *scon =3D container_of(dgc, struct sdl2_console, d= gc); SDL_GLContext ctx; =20 assert(scon->opengl); @@ -167,17 +167,17 @@ QEMUGLContext sdl2_gl_create_context(DisplayChangeLis= tener *dcl, return (QEMUGLContext)ctx; } =20 -void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx) +void sdl2_gl_destroy_context(DisplayGLCtx *dgc, QEMUGLContext ctx) { SDL_GLContext sdlctx =3D (SDL_GLContext)ctx; =20 SDL_GL_DeleteContext(sdlctx); } =20 -int sdl2_gl_make_context_current(DisplayChangeListener *dcl, +int sdl2_gl_make_context_current(DisplayGLCtx *dgc, QEMUGLContext ctx) { - struct sdl2_console *scon =3D container_of(dcl, struct sdl2_console, d= cl); + struct sdl2_console *scon =3D container_of(dgc, struct sdl2_console, d= gc); SDL_GLContext sdlctx =3D (SDL_GLContext)ctx; =20 assert(scon->opengl); diff --git a/ui/sdl2.c b/ui/sdl2.c index bb186a381a..0bd30504cf 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -778,13 +778,17 @@ static const DisplayChangeListenerOps dcl_gl_ops =3D { .dpy_mouse_set =3D sdl_mouse_warp, .dpy_cursor_define =3D sdl_mouse_define, =20 - .dpy_gl_ctx_create =3D sdl2_gl_create_context, - .dpy_gl_ctx_destroy =3D sdl2_gl_destroy_context, - .dpy_gl_ctx_make_current =3D sdl2_gl_make_context_current, .dpy_gl_scanout_disable =3D sdl2_gl_scanout_disable, .dpy_gl_scanout_texture =3D sdl2_gl_scanout_texture, .dpy_gl_update =3D sdl2_gl_scanout_flush, }; + +static const DisplayGLCtxOps gl_ctx_ops =3D { + .compatible_dcl =3D &dcl_gl_ops, + .dpy_gl_ctx_create =3D sdl2_gl_create_context, + .dpy_gl_ctx_destroy =3D sdl2_gl_destroy_context, + .dpy_gl_ctx_make_current =3D sdl2_gl_make_context_current, +}; #endif =20 static void sdl2_display_early_init(DisplayOptions *o) @@ -860,6 +864,7 @@ static void sdl2_display_init(DisplayState *ds, Display= Options *o) #ifdef CONFIG_OPENGL sdl2_console[i].opengl =3D display_opengl; sdl2_console[i].dcl.ops =3D display_opengl ? &dcl_gl_ops : &dcl_2d= _ops; + sdl2_console[i].dgc.ops =3D display_opengl ? &gl_ctx_ops : NULL; #else sdl2_console[i].opengl =3D 0; sdl2_console[i].dcl.ops =3D &dcl_2d_ops; @@ -867,7 +872,7 @@ static void sdl2_display_init(DisplayState *ds, Display= Options *o) sdl2_console[i].dcl.con =3D con; sdl2_console[i].kbd =3D qkbd_state_init(con); if (display_opengl) { - qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dcl); + qemu_console_set_display_gl_ctx(con, &sdl2_console[i].dgc); } register_displaychangelistener(&sdl2_console[i].dcl); =20 diff --git a/ui/spice-display.c b/ui/spice-display.c index ec501f129f..798e0f6167 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -908,12 +908,12 @@ static void spice_gl_switch(DisplayChangeListener *dc= l, } } =20 -static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *d= cl, +static QEMUGLContext qemu_spice_gl_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, qemu_egl_rn_ctx); - return qemu_egl_create_context(dcl, params); + return qemu_egl_create_context(dgc, params); } =20 static void qemu_spice_gl_scanout_disable(DisplayChangeListener *dcl) @@ -1105,10 +1105,6 @@ static const DisplayChangeListenerOps display_listen= er_gl_ops =3D { .dpy_mouse_set =3D display_mouse_set, .dpy_cursor_define =3D display_mouse_define, =20 - .dpy_gl_ctx_create =3D qemu_spice_gl_create_context, - .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, - .dpy_gl_ctx_make_current =3D qemu_egl_make_context_current, - .dpy_gl_scanout_disable =3D qemu_spice_gl_scanout_disable, .dpy_gl_scanout_texture =3D qemu_spice_gl_scanout_texture, .dpy_gl_scanout_dmabuf =3D qemu_spice_gl_scanout_dmabuf, @@ -1118,6 +1114,13 @@ static const DisplayChangeListenerOps display_listen= er_gl_ops =3D { .dpy_gl_update =3D qemu_spice_gl_update, }; =20 +static const DisplayGLCtxOps gl_ctx_ops =3D { + .compatible_dcl =3D &display_listener_gl_ops, + .dpy_gl_ctx_create =3D qemu_spice_gl_create_context, + .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, + .dpy_gl_ctx_make_current =3D qemu_egl_make_context_current, +}; + #endif /* HAVE_SPICE_GL */ =20 static void qemu_spice_display_init_one(QemuConsole *con) @@ -1130,6 +1133,7 @@ static void qemu_spice_display_init_one(QemuConsole *= con) #ifdef HAVE_SPICE_GL if (spice_opengl) { ssd->dcl.ops =3D &display_listener_gl_ops; + ssd->dgc.ops =3D &gl_ctx_ops; ssd->gl_unblock_bh =3D qemu_bh_new(qemu_spice_gl_unblock_bh, ssd); ssd->gl_unblock_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, qemu_spice_gl_block_timer, ss= d); @@ -1156,7 +1160,7 @@ static void qemu_spice_display_init_one(QemuConsole *= con) qemu_spice_create_host_memslot(ssd); =20 if (spice_opengl) { - qemu_console_set_display_gl_ctx(con, &ssd->dcl); + qemu_console_set_display_gl_ctx(con, &ssd->dgc); } register_displaychangelistener(&ssd->dcl); } --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814731705732.1485254459155; Sat, 9 Oct 2021 14:25:31 -0700 (PDT) Received: from localhost ([::1]:54666 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJqU-0002QZ-Lf for importer@patchew.org; Sat, 09 Oct 2021 17:25:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38204) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJec-0003cW-2N for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:15 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:40643) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJeZ-0000Jp-Uf for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:13 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-386-Kax4HaI2NF2Sv1xkKKTzeA-1; Sat, 09 Oct 2021 17:13:09 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 41732A0CAD for ; Sat, 9 Oct 2021 21:13:08 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id C3105179B3; Sat, 9 Oct 2021 21:13:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633813991; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NAKbSP70D6rRbhiCls4DUPYKmMXjZKuanCbhdFUQZiw=; b=ScYV8iHbLcxvyfITus8GdN1kdDlcpfBsfk8RwQMnMbH70zabasD0B2k/DH+H1+TryEaiAu DXDfOH4CoO6gswK3TixCPsgQcCvvBo6Z2/KgWXe+7fDG+5jnDAN6fz5amj53LQIZYfoCYv y0qK/1EIGxUKQZno9BLoT1LWGygdgRI= X-MC-Unique: Kax4HaI2NF2Sv1xkKKTzeA-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 18/37] ui: move qemu_spice_fill_device_address to ui/util.c Date: Sun, 10 Oct 2021 01:08:19 +0400 Message-Id: <20211009210838.2219430-19-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814732479100001 From: Marc-Andr=C3=A9 Lureau Other backends can use it. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/console.h | 6 +++ include/ui/spice-display.h | 4 -- hw/display/qxl.c | 7 +++- ui/spice-core.c | 50 ------------------------- ui/spice-display.c | 5 ++- ui/util.c | 75 ++++++++++++++++++++++++++++++++++++++ ui/meson.build | 1 + 7 files changed, 92 insertions(+), 56 deletions(-) create mode 100644 ui/util.c diff --git a/include/ui/console.h b/include/ui/console.h index 7a35c4fc6a..b23ae283be 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -490,4 +490,10 @@ int index_from_key(const char *key, size_t key_length); int udmabuf_fd(void); #endif =20 +/* util.c */ +bool qemu_console_fill_device_address(QemuConsole *con, + char *device_address, + size_t size, + Error **errp); + #endif diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index a2fbf62c52..e271e011da 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -184,8 +184,4 @@ void qemu_spice_display_start(void); void qemu_spice_display_stop(void); int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd); =20 -bool qemu_spice_fill_device_address(QemuConsole *con, - char *device_address, - size_t size); - #endif diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 29c80b4289..e2d6e317da 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2171,12 +2171,17 @@ static void qxl_realize_common(PCIQXLDevice *qxl, E= rror **errp) } =20 #if SPICE_SERVER_VERSION >=3D 0x000e02 /* release 0.14.2 */ + Error *err =3D NULL; char device_address[256] =3D ""; - if (qemu_spice_fill_device_address(qxl->vga.con, device_address, 256))= { + if (qemu_console_fill_device_address(qxl->vga.con, + device_address, sizeof(device_add= ress), + &err)) { spice_qxl_set_device_info(&qxl->ssd.qxl, device_address, 0, qxl->max_outputs); + } else { + error_report_err(err); } #endif =20 diff --git a/ui/spice-core.c b/ui/spice-core.c index 31974b8d6c..c3ac20ad43 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -884,56 +884,6 @@ bool qemu_spice_have_display_interface(QemuConsole *co= n) return false; } =20 -/* - * Recursively (in reverse order) appends addresses of PCI devices as it m= oves - * up in the PCI hierarchy. - * - * @returns true on success, false when the buffer wasn't large enough - */ -static bool append_pci_address(char *buf, size_t buf_size, const PCIDevice= *pci) -{ - PCIBus *bus =3D pci_get_bus(pci); - /* - * equivalent to if (!pci_bus_is_root(bus)), but the function is not b= uilt - * with PCI_CONFIG=3Dn, avoid using an #ifdef by checking directly - */ - if (bus->parent_dev !=3D NULL) { - append_pci_address(buf, buf_size, bus->parent_dev); - } - - size_t len =3D strlen(buf); - ssize_t written =3D snprintf(buf + len, buf_size - len, "/%02x.%x", - PCI_SLOT(pci->devfn), PCI_FUNC(pci->devfn)); - - return written > 0 && written < buf_size - len; -} - -bool qemu_spice_fill_device_address(QemuConsole *con, - char *device_address, - size_t size) -{ - DeviceState *dev =3D DEVICE(object_property_get_link(OBJECT(con), - "device", - &error_abort)); - PCIDevice *pci =3D (PCIDevice *) object_dynamic_cast(OBJECT(dev), - TYPE_PCI_DEVICE); - - if (pci =3D=3D NULL) { - warn_report("Setting device address of a display device to SPICE: " - "Not a PCI device."); - return false; - } - - strncpy(device_address, "pci/0000", size); - if (!append_pci_address(device_address, size, pci)) { - warn_report("Setting device address of a display device to SPICE: " - "Too many PCI devices in the chain."); - return false; - } - - return true; -} - int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con) { if (g_slist_find(spice_consoles, con)) { diff --git a/ui/spice-display.c b/ui/spice-display.c index 798e0f6167..1043f47f94 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -1148,12 +1148,15 @@ static void qemu_spice_display_init_one(QemuConsole= *con) qemu_spice_add_display_interface(&ssd->qxl, con); =20 #if SPICE_SERVER_VERSION >=3D 0x000e02 /* release 0.14.2 */ + Error *err =3D NULL; char device_address[256] =3D ""; - if (qemu_spice_fill_device_address(con, device_address, 256)) { + if (qemu_console_fill_device_address(con, device_address, 256, &err)) { spice_qxl_set_device_info(&ssd->qxl, device_address, qemu_console_get_head(con), 1); + } else { + error_report_err(err); } #endif =20 diff --git a/ui/util.c b/ui/util.c new file mode 100644 index 0000000000..7e8fc1ea53 --- /dev/null +++ b/ui/util.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" + +#include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" +#include "qapi/error.h" +#include "ui/console.h" + +/* + * Recursively (in reverse order) appends addresses of PCI devices as it m= oves + * up in the PCI hierarchy. + * + * @returns true on success, false when the buffer wasn't large enough + */ +static bool append_pci_address(char *buf, size_t buf_size, const PCIDevice= *pci) +{ + PCIBus *bus =3D pci_get_bus(pci); + /* + * equivalent to if (!pci_bus_is_root(bus)), but the function is not b= uilt + * with PCI_CONFIG=3Dn, avoid using an #ifdef by checking directly + */ + if (bus->parent_dev !=3D NULL) { + append_pci_address(buf, buf_size, bus->parent_dev); + } + + size_t len =3D strlen(buf); + ssize_t written =3D snprintf(buf + len, buf_size - len, "/%02x.%x", + PCI_SLOT(pci->devfn), PCI_FUNC(pci->devfn)); + + return written > 0 && written < buf_size - len; +} + +bool qemu_console_fill_device_address(QemuConsole *con, + char *device_address, + size_t size, + Error **errp) +{ + ERRP_GUARD(); + DeviceState *dev =3D DEVICE(object_property_get_link(OBJECT(con), + "device", + &error_abort)); + PCIDevice *pci =3D (PCIDevice *) object_dynamic_cast(OBJECT(dev), + TYPE_PCI_DEVICE); + + if (pci =3D=3D NULL) { + error_setg(errp, "Setting device address of a display device: " + "Not a PCI device."); + return false; + } + + strncpy(device_address, "pci/0000", size); + if (!append_pci_address(device_address, size, pci)) { + error_setg(errp, "Setting device address of a display device: " + "Too many PCI devices in the chain."); + return false; + } + + return true; +} diff --git a/ui/meson.build b/ui/meson.build index ee8ef27714..a9df5b911e 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -12,6 +12,7 @@ softmmu_ss.add(files( 'kbd-state.c', 'keymaps.c', 'qemu-pixman.c', + 'util.c', )) softmmu_ss.add([spice_headers, files('spice-module.c')]) softmmu_ss.add(when: spice_protocol, if_true: files('vdagent.c')) --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814374827865.7221203996068; Sat, 9 Oct 2021 14:19:34 -0700 (PDT) Received: from localhost ([::1]:34246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJkj-0005br-Ov for importer@patchew.org; Sat, 09 Oct 2021 17:19:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38220) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJep-0004N1-Ps for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:27 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:23773) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJen-0000Ka-Kh for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:27 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-179-pe4cHEoHMBGk2MfckisC3g-1; Sat, 09 Oct 2021 17:13:23 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CC165180830F for ; Sat, 9 Oct 2021 21:13:22 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8D08060622; Sat, 9 Oct 2021 21:13:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814005; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gdrh1WttbD9Ef6H6OHMMRjJzHyjSEtMuirKIItNL+tg=; b=Fuy1T3sE5RJeOk7TrFplO0+pWKxFJMnfAz39x5tmUR9AcIpGhPksN2+kAJTl6oh3O63rm+ 4X8eHT9TJ2iYtTer+a6k9ehSaG6IGEtwoPyLhkz9qYckeBvg2Ew/q5qTKghIrA3E5kMAhD agq7gmx9cx8V9bZTc5TiYyUjrZqBjwE= X-MC-Unique: pe4cHEoHMBGk2MfckisC3g-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 19/37] console: save current scanout details Date: Sun, 10 Oct 2021 01:08:20 +0400 Message-Id: <20211009210838.2219430-20-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814375794100001 From: Marc-Andr=C3=A9 Lureau Add a new DisplayScanout structure to save the current scanout details. This allows to attach later UI backends and set the scanout. Introduce displaychangelistener_display_console() helper function to handle the dpy_gfx_switch/gl_scanout() & dpy_gfx_update() calls. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- include/ui/console.h | 27 +++++++ ui/console.c | 165 +++++++++++++++++++++++++++++-------------- 2 files changed, 138 insertions(+), 54 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index b23ae283be..ab55d71894 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -108,6 +108,17 @@ struct QemuConsoleClass { #define QEMU_ALLOCATED_FLAG 0x01 #define QEMU_PLACEHOLDER_FLAG 0x02 =20 +typedef struct ScanoutTexture { + 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 width; + uint32_t height; +} ScanoutTexture; + typedef struct DisplaySurface { pixman_format_code_t format; pixman_image_t *image; @@ -173,6 +184,22 @@ typedef struct QemuDmaBuf { bool allow_fences; } QemuDmaBuf; =20 +enum display_scanout { + SCANOUT_NONE, + SCANOUT_SURFACE, + SCANOUT_TEXTURE, + SCANOUT_DMABUF, +}; + +typedef struct DisplayScanout { + enum display_scanout kind; + union { + /* DisplaySurface *surface; is kept in QemuConsole */ + ScanoutTexture texture; + QemuDmaBuf *dmabuf; + }; +} DisplayScanout; + typedef struct DisplayState DisplayState; typedef struct DisplayGLCtx DisplayGLCtx; =20 diff --git a/ui/console.c b/ui/console.c index e5a2c84dd9..a1c6a78523 100644 --- a/ui/console.c +++ b/ui/console.c @@ -126,6 +126,7 @@ struct QemuConsole { console_type_t console_type; DisplayState *ds; DisplaySurface *surface; + DisplayScanout scanout; int dcls; DisplayGLCtx *gl; int gl_block; @@ -197,6 +198,7 @@ static void dpy_refresh(DisplayState *s); static DisplayState *get_alloc_displaystate(void); static void text_console_update_cursor_timer(void); static void text_console_update_cursor(void *opaque); +static bool displaychangelistener_has_dmabuf(DisplayChangeListener *dcl); =20 static void gui_update(void *opaque) { @@ -532,6 +534,8 @@ static void text_console_resize(QemuConsole *s) TextCell *cells, *c, *c1; int w1, x, y, last_width; =20 + assert(s->scanout.kind =3D=3D SCANOUT_SURFACE); + last_width =3D s->width; s->width =3D surface_width(s->surface) / FONT_WIDTH; s->height =3D surface_height(s->surface) / FONT_HEIGHT; @@ -1103,6 +1107,48 @@ static void console_putchar(QemuConsole *s, int ch) } } =20 +static void displaychangelistener_display_console(DisplayChangeListener *d= cl, + QemuConsole *con) +{ + static const char nodev[] =3D + "This VM has no graphic display device."; + static DisplaySurface *dummy; + + if (!con) { + if (!dcl->ops->dpy_gfx_switch) { + return; + } + if (!dummy) { + dummy =3D qemu_create_placeholder_surface(640, 480, nodev); + } + dcl->ops->dpy_gfx_switch(dcl, dummy); + return; + } + + if (con->scanout.kind =3D=3D SCANOUT_DMABUF && + displaychangelistener_has_dmabuf(dcl)) { + dcl->ops->dpy_gl_scanout_dmabuf(dcl, con->scanout.dmabuf); + } else if (con->scanout.kind =3D=3D SCANOUT_TEXTURE && + dcl->ops->dpy_gl_scanout_texture) { + dcl->ops->dpy_gl_scanout_texture(dcl, + con->scanout.texture.backing_id, + con->scanout.texture.backing_y_0_= top, + con->scanout.texture.backing_widt= h, + con->scanout.texture.backing_heig= ht, + con->scanout.texture.x, + con->scanout.texture.y, + con->scanout.texture.width, + con->scanout.texture.height); + } else if (con->scanout.kind =3D=3D SCANOUT_SURFACE && + dcl->ops->dpy_gfx_switch) { + dcl->ops->dpy_gfx_switch(dcl, con->surface); + } + + dcl->ops->dpy_gfx_update(dcl, 0, 0, + qemu_console_get_width(con, 0), + qemu_console_get_height(con, 0)); +} + void console_select(unsigned int index) { DisplayChangeListener *dcl; @@ -1119,13 +1165,7 @@ void console_select(unsigned int index) if (dcl->con !=3D NULL) { continue; } - if (dcl->ops->dpy_gfx_switch) { - dcl->ops->dpy_gfx_switch(dcl, s->surface); - } - } - if (s->surface) { - dpy_gfx_update(s, 0, 0, surface_width(s->surface), - surface_height(s->surface)); + displaychangelistener_display_console(dcl, s); } } if (ds->have_text) { @@ -1538,9 +1578,6 @@ static bool dpy_gl_compatible_with(QemuConsole *con, = DisplayChangeListener *dcl) =20 void register_displaychangelistener(DisplayChangeListener *dcl) { - static const char nodev[] =3D - "This VM has no graphic display device."; - static DisplaySurface *dummy; QemuConsole *con; =20 assert(!dcl->ds); @@ -1565,16 +1602,7 @@ void register_displaychangelistener(DisplayChangeLis= tener *dcl) } else { con =3D active_console; } - if (dcl->ops->dpy_gfx_switch) { - if (con) { - dcl->ops->dpy_gfx_switch(dcl, con->surface); - } else { - if (!dummy) { - dummy =3D qemu_create_placeholder_surface(640, 480, nodev); - } - dcl->ops->dpy_gfx_switch(dcl, dummy); - } - } + displaychangelistener_display_console(dcl, con); text_console_update_cursor(NULL); } =20 @@ -1655,13 +1683,9 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, = int w, int h) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; - int width =3D w; - int height =3D h; + int width =3D qemu_console_get_width(con, x + w); + int height =3D qemu_console_get_height(con, y + h); =20 - if (con->surface) { - width =3D surface_width(con->surface); - height =3D surface_height(con->surface); - } x =3D MAX(x, 0); y =3D MAX(y, 0); x =3D MIN(x, width); @@ -1684,12 +1708,10 @@ void dpy_gfx_update(QemuConsole *con, int x, int y,= int w, int h) =20 void dpy_gfx_update_full(QemuConsole *con) { - if (!con->surface) { - return; - } - dpy_gfx_update(con, 0, 0, - surface_width(con->surface), - surface_height(con->surface)); + int w =3D qemu_console_get_width(con, 0); + int h =3D qemu_console_get_height(con, 0); + + dpy_gfx_update(con, 0, 0, w, h); } =20 void dpy_gfx_replace_surface(QemuConsole *con, @@ -1716,6 +1738,7 @@ void dpy_gfx_replace_surface(QemuConsole *con, =20 assert(old_surface !=3D surface); =20 + con->scanout.kind =3D SCANOUT_SURFACE; con->surface =3D surface; QLIST_FOREACH(dcl, &s->listeners, next) { if (con !=3D (dcl->con ? dcl->con : active_console)) { @@ -1891,6 +1914,9 @@ void dpy_gl_scanout_disable(QemuConsole *con) DisplayState *s =3D con->ds; DisplayChangeListener *dcl; =20 + if (con->scanout.kind !=3D SCANOUT_SURFACE) { + con->scanout.kind =3D SCANOUT_NONE; + } QLIST_FOREACH(dcl, &s->listeners, next) { dcl->ops->dpy_gl_scanout_disable(dcl); } @@ -1907,6 +1933,11 @@ void dpy_gl_scanout_texture(QemuConsole *con, DisplayState *s =3D con->ds; DisplayChangeListener *dcl; =20 + con->scanout.kind =3D SCANOUT_TEXTURE; + con->scanout.texture =3D (ScanoutTexture) { + backing_id, backing_y_0_top, backing_width, backing_height, + x, y, width, height + }; QLIST_FOREACH(dcl, &s->listeners, next) { dcl->ops->dpy_gl_scanout_texture(dcl, backing_id, backing_y_0_top, @@ -1921,6 +1952,8 @@ void dpy_gl_scanout_dmabuf(QemuConsole *con, DisplayState *s =3D con->ds; DisplayChangeListener *dcl; =20 + con->scanout.kind =3D SCANOUT_DMABUF; + con->scanout.dmabuf =3D dmabuf; QLIST_FOREACH(dcl, &s->listeners, next) { dcl->ops->dpy_gl_scanout_dmabuf(dcl, dmabuf); } @@ -2047,10 +2080,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, = uint32_t head, 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); - } + width =3D qemu_console_get_width(s, 0); + height =3D qemu_console_get_height(s, 0); } else { trace_console_gfx_new(); s =3D new_console(ds, GRAPHIC_CONSOLE, head); @@ -2079,13 +2110,8 @@ 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); - } + int width =3D qemu_console_get_width(con, 640); + int height =3D qemu_console_get_height(con, 480); =20 trace_console_gfx_close(con->index); object_property_set_link(OBJECT(con), "device", NULL, &error_abort); @@ -2237,7 +2263,19 @@ int qemu_console_get_width(QemuConsole *con, int fal= lback) if (con =3D=3D NULL) { con =3D active_console; } - return con ? surface_width(con->surface) : fallback; + if (con =3D=3D NULL) { + return fallback; + } + switch (con->scanout.kind) { + case SCANOUT_DMABUF: + return con->scanout.dmabuf->width; + case SCANOUT_TEXTURE: + return con->scanout.texture.width; + case SCANOUT_SURFACE: + return surface_width(con->surface); + default: + return fallback; + } } =20 int qemu_console_get_height(QemuConsole *con, int fallback) @@ -2245,7 +2283,19 @@ int qemu_console_get_height(QemuConsole *con, int fa= llback) if (con =3D=3D NULL) { con =3D active_console; } - return con ? surface_height(con->surface) : fallback; + if (con =3D=3D NULL) { + return fallback; + } + switch (con->scanout.kind) { + case SCANOUT_DMABUF: + return con->scanout.dmabuf->height; + case SCANOUT_TEXTURE: + return con->scanout.texture.height; + case SCANOUT_SURFACE: + return surface_height(con->surface); + default: + return fallback; + } } =20 static void vc_chr_set_echo(Chardev *chr, bool echo) @@ -2305,12 +2355,13 @@ static void text_console_do_init(Chardev *chr, Disp= layState *ds) s->total_height =3D DEFAULT_BACKSCROLL; s->x =3D 0; s->y =3D 0; - if (!s->surface) { - if (active_console && active_console->surface) { - g_width =3D surface_width(active_console->surface); - g_height =3D surface_height(active_console->surface); + if (s->scanout.kind !=3D SCANOUT_SURFACE) { + if (active_console && active_console->scanout.kind =3D=3D SCANOUT_= SURFACE) { + g_width =3D qemu_console_get_width(active_console, g_width); + g_height =3D qemu_console_get_height(active_console, g_height); } s->surface =3D qemu_create_displaysurface(g_width, g_height); + s->scanout.kind =3D SCANOUT_SURFACE; } =20 s->hw_ops =3D &text_console_ops; @@ -2369,6 +2420,7 @@ static void vc_chr_open(Chardev *chr, s =3D new_console(NULL, TEXT_CONSOLE, 0); } else { s =3D new_console(NULL, TEXT_CONSOLE_FIXED_SIZE, 0); + s->scanout.kind =3D SCANOUT_SURFACE; s->surface =3D qemu_create_displaysurface(width, height); } =20 @@ -2392,13 +2444,13 @@ static void vc_chr_open(Chardev *chr, =20 void qemu_console_resize(QemuConsole *s, int width, int height) { - DisplaySurface *surface; + DisplaySurface *surface =3D qemu_console_surface(s); =20 assert(s->console_type =3D=3D GRAPHIC_CONSOLE); =20 - if (s->surface && (s->surface->flags & QEMU_ALLOCATED_FLAG) && - pixman_image_get_width(s->surface->image) =3D=3D width && - pixman_image_get_height(s->surface->image) =3D=3D height) { + if (surface && (surface->flags & QEMU_ALLOCATED_FLAG) && + pixman_image_get_width(surface->image) =3D=3D width && + pixman_image_get_height(surface->image) =3D=3D height) { return; } =20 @@ -2408,7 +2460,12 @@ void qemu_console_resize(QemuConsole *s, int width, = int height) =20 DisplaySurface *qemu_console_surface(QemuConsole *console) { - return console->surface; + switch (console->scanout.kind) { + case SCANOUT_SURFACE: + return console->surface; + default: + return NULL; + } } =20 PixelFormat qemu_default_pixelformat(int bpp) --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814695800166.41061484708575; Sat, 9 Oct 2021 14:24:55 -0700 (PDT) Received: from localhost ([::1]:52468 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJpu-0000yF-MO for importer@patchew.org; Sat, 09 Oct 2021 17:24:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38256) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJez-000517-8w for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:37 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28278) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJex-0000LU-P7 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:13:36 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-337-Zofsrn8cMButWMXxykXSSQ-1; Sat, 09 Oct 2021 17:13:33 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E5C00801A93 for ; Sat, 9 Oct 2021 21:13:32 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id C7DC819D9B; Sat, 9 Oct 2021 21:13:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814015; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cXp4ws8fpsKdYMnaXXfujeAQnXIZ55NnulDoRO09ta4=; b=fB3Xq4Y3KnGudgaqIELf8ufr7g9rOAX8q6l2clwyN+6eEZ4vRl86gI38oi/ezWAxvthVeP ET6UTYL53ia6PUVgND4ED4UpPl37AiZDiqvpC9RtsiRfvB0P0UKXgIxc1xn/Bm4vhqz0I1 bF3waA7R7y+mNck+WGLi7+q85zmNLxw= X-MC-Unique: Zofsrn8cMButWMXxykXSSQ-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 20/37] scripts: teach modinfo to skip non-C sources Date: Sun, 10 Oct 2021 01:08:21 +0400 Message-Id: <20211009210838.2219430-21-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814697288100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- scripts/modinfo-collect.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/modinfo-collect.py b/scripts/modinfo-collect.py index 4acb188c3e..61b90688c6 100755 --- a/scripts/modinfo-collect.py +++ b/scripts/modinfo-collect.py @@ -51,6 +51,9 @@ def main(args): with open('compile_commands.json') as f: compile_commands =3D json.load(f) for src in args: + if not src.endswith('.c'): + print("MODINFO_DEBUG skip %s" % src) + continue print("MODINFO_DEBUG src %s" % src) command =3D find_command(src, target, compile_commands) cmdline =3D process_command(src, command) --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381454083116.517542010324973; Sat, 9 Oct 2021 14:22:20 -0700 (PDT) Received: from localhost ([::1]:43024 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJnP-00035N-LK for importer@patchew.org; Sat, 09 Oct 2021 17:22:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38304) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJfV-0006MB-33 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28475) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJfQ-0000NA-UC for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:08 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-121-TapA5lRjOJ29VSOtS99ggA-1; Sat, 09 Oct 2021 17:13:58 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CC7D31005547 for ; Sat, 9 Oct 2021 21:13:57 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3EEC460622; Sat, 9 Oct 2021 21:13:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814043; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gLqQEnIVYXoPp5WVwrqg0JzZ7J5L89RFyLW9c3WO+GE=; b=CcNGuV3zHZny5ZgWLC2npC1EkWCG3Tw6sTJ/FhsacC9vyYjYt/7R3XuzuD1uBLUEZ3Ql6d CANVl9Q5uutHyOU4hJtpp9XemY8vWOoDb7iZUM+p2ETzDznR4yUl97w4SGLoPttCUzIgN4 sfpxusDKrDk5bDq6YKvGvIY+jutz5b0= X-MC-Unique: TapA5lRjOJ29VSOtS99ggA-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 21/37] docs/sphinx: add sphinx modules to include D-Bus documentation Date: Sun, 10 Oct 2021 01:08:22 +0400 Message-Id: <20211009210838.2219430-22-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_SHORT=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814543226100001 From: Marc-Andr=C3=A9 Lureau Add a new dbus-doc directive to import D-Bus interfaces documentation from the introspection XML. The comments annotations follow the gtkdoc/kerneldoc style, and should be formatted with reST. Note: I realize after the fact that I was implementing those modules with sphinx 4, and that we have much lower requirements. Instead of lowering the features and code (removing type annotations etc), I propose to have a warning in the documentation when the D-Bus modules can't be used, and point to the source XML file in that case. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- docs/conf.py | 8 + docs/sphinx/dbusdoc.py | 166 +++++++++++++++ docs/sphinx/dbusdomain.py | 406 +++++++++++++++++++++++++++++++++++++ docs/sphinx/dbusparser.py | 373 ++++++++++++++++++++++++++++++++++ docs/sphinx/fakedbusdoc.py | 25 +++ 5 files changed, 978 insertions(+) create mode 100644 docs/sphinx/dbusdoc.py create mode 100644 docs/sphinx/dbusdomain.py create mode 100644 docs/sphinx/dbusparser.py create mode 100644 docs/sphinx/fakedbusdoc.py diff --git a/docs/conf.py b/docs/conf.py index ff6e92c6e2..71e2369026 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -73,6 +73,12 @@ # ones. extensions =3D ['kerneldoc', 'qmp_lexer', 'hxtool', 'depfile', 'qapidoc'] =20 +if sphinx.version_info[:3] > (4, 0, 0): + tags.add('sphinx4') + extensions +=3D ['dbusdoc'] +else: + extensions +=3D ['fakedbusdoc'] + # Add any paths that contain templates here, relative to this directory. templates_path =3D ['_templates'] =20 @@ -301,3 +307,5 @@ kerneldoc_srctree =3D os.path.join(qemu_docdir, '..') hxtool_srctree =3D os.path.join(qemu_docdir, '..') qapidoc_srctree =3D os.path.join(qemu_docdir, '..') +dbusdoc_srctree =3D os.path.join(qemu_docdir, '..') +dbus_index_common_prefix =3D ["org.qemu."] diff --git a/docs/sphinx/dbusdoc.py b/docs/sphinx/dbusdoc.py new file mode 100644 index 0000000000..be284ed08f --- /dev/null +++ b/docs/sphinx/dbusdoc.py @@ -0,0 +1,166 @@ +# D-Bus XML documentation extension +# +# Copyright (C) 2021, Red Hat Inc. +# +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Author: Marc-Andr=C3=A9 Lureau +"""dbus-doc is a Sphinx extension that provides documentation from D-Bus X= ML.""" + +import os +import re +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Iterator, + List, + Optional, + Sequence, + Set, + Tuple, + Type, + TypeVar, + Union, +) + +import sphinx +from docutils import nodes +from docutils.nodes import Element, Node +from docutils.parsers.rst import Directive, directives +from docutils.parsers.rst.states import RSTState +from docutils.statemachine import StringList, ViewList +from sphinx.application import Sphinx +from sphinx.errors import ExtensionError +from sphinx.util import logging +from sphinx.util.docstrings import prepare_docstring +from sphinx.util.docutils import SphinxDirective, switch_source_input +from sphinx.util.nodes import nested_parse_with_titles + +import dbusdomain +from dbusparser import parse_dbus_xml + +logger =3D logging.getLogger(__name__) + +__version__ =3D "1.0" + + +class DBusDoc: + def __init__(self, sphinx_directive, dbusfile): + self._cur_doc =3D None + self._sphinx_directive =3D sphinx_directive + self._dbusfile =3D dbusfile + self._top_node =3D nodes.section() + self.result =3D StringList() + self.indent =3D "" + + def add_line(self, line: str, *lineno: int) -> None: + """Append one line of generated reST to the output.""" + if line.strip(): # not a blank line + self.result.append(self.indent + line, self._dbusfile, *lineno) + else: + self.result.append("", self._dbusfile, *lineno) + + def add_method(self, method): + self.add_line(f".. dbus:method:: {method.name}") + self.add_line("") + self.indent +=3D " " + for arg in method.in_args: + self.add_line(f":arg {arg.signature} {arg.name}: {arg.doc_stri= ng}") + for arg in method.out_args: + self.add_line(f":ret {arg.signature} {arg.name}: {arg.doc_stri= ng}") + self.add_line("") + for line in prepare_docstring("\n" + method.doc_string): + self.add_line(line) + self.indent =3D self.indent[:-3] + + def add_signal(self, signal): + self.add_line(f".. dbus:signal:: {signal.name}") + self.add_line("") + self.indent +=3D " " + for arg in signal.args: + self.add_line(f":arg {arg.signature} {arg.name}: {arg.doc_stri= ng}") + self.add_line("") + for line in prepare_docstring("\n" + signal.doc_string): + self.add_line(line) + self.indent =3D self.indent[:-3] + + def add_property(self, prop): + self.add_line(f".. dbus:property:: {prop.name}") + self.indent +=3D " " + self.add_line(f":type: {prop.signature}") + access =3D {"read": "readonly", "write": "writeonly", "readwrite":= "readwrite"}[ + prop.access + ] + self.add_line(f":{access}:") + if prop.emits_changed_signal: + self.add_line(f":emits-changed: yes") + self.add_line("") + for line in prepare_docstring("\n" + prop.doc_string): + self.add_line(line) + self.indent =3D self.indent[:-3] + + def add_interface(self, iface): + self.add_line(f".. dbus:interface:: {iface.name}") + self.add_line("") + self.indent +=3D " " + for line in prepare_docstring("\n" + iface.doc_string): + self.add_line(line) + for method in iface.methods: + self.add_method(method) + for sig in iface.signals: + self.add_signal(sig) + for prop in iface.properties: + self.add_property(prop) + self.indent =3D self.indent[:-3] + + +def parse_generated_content(state: RSTState, content: StringList) -> List[= Node]: + """Parse a generated content by Documenter.""" + with switch_source_input(state, content): + node =3D nodes.paragraph() + node.document =3D state.document + state.nested_parse(content, 0, node) + + return node.children + + +class DBusDocDirective(SphinxDirective): + """Extract documentation from the specified D-Bus XML file""" + + has_content =3D True + required_arguments =3D 1 + optional_arguments =3D 0 + final_argument_whitespace =3D True + + def run(self): + reporter =3D self.state.document.reporter + + try: + source, lineno =3D reporter.get_source_and_line(self.lineno) = # type: ignore + except AttributeError: + source, lineno =3D (None, None) + + logger.debug("[dbusdoc] %s:%s: input:\n%s", source, lineno, self.b= lock_text) + + env =3D self.state.document.settings.env + dbusfile =3D env.config.qapidoc_srctree + "/" + self.arguments[0] + with open(dbusfile, "rb") as f: + xml_data =3D f.read() + xml =3D parse_dbus_xml(xml_data) + doc =3D DBusDoc(self, dbusfile) + for iface in xml: + doc.add_interface(iface) + + result =3D parse_generated_content(self.state, doc.result) + return result + + +def setup(app: Sphinx) -> Dict[str, Any]: + """Register dbus-doc directive with Sphinx""" + app.add_config_value("dbusdoc_srctree", None, "env") + app.add_directive("dbus-doc", DBusDocDirective) + dbusdomain.setup(app) + + return dict(version=3D__version__, parallel_read_safe=3DTrue, parallel= _write_safe=3DTrue) diff --git a/docs/sphinx/dbusdomain.py b/docs/sphinx/dbusdomain.py new file mode 100644 index 0000000000..2ea95af623 --- /dev/null +++ b/docs/sphinx/dbusdomain.py @@ -0,0 +1,406 @@ +# D-Bus sphinx domain extension +# +# Copyright (C) 2021, Red Hat Inc. +# +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Author: Marc-Andr=C3=A9 Lureau + +from typing import ( + Any, + Dict, + Iterable, + Iterator, + List, + NamedTuple, + Optional, + Tuple, + cast, +) + +from docutils import nodes +from docutils.nodes import Element, Node +from docutils.parsers.rst import directives +from sphinx import addnodes +from sphinx.addnodes import desc_signature, pending_xref +from sphinx.directives import ObjectDescription +from sphinx.domains import Domain, Index, IndexEntry, ObjType +from sphinx.locale import _ +from sphinx.roles import XRefRole +from sphinx.util import nodes as node_utils +from sphinx.util.docfields import Field, TypedField +from sphinx.util.typing import OptionSpec + + +class DBusDescription(ObjectDescription[str]): + """Base class for DBus objects""" + + option_spec: OptionSpec =3D ObjectDescription.option_spec.copy() + option_spec.update( + { + "deprecated": directives.flag, + } + ) + + def get_index_text(self, modname: str, name: str) -> str: + """Return the text for the index entry of the object.""" + raise NotImplementedError("must be implemented in subclasses") + + def add_target_and_index( + self, name: str, sig: str, signode: desc_signature + ) -> None: + ifacename =3D self.env.ref_context.get("dbus:interface") + node_id =3D name + if ifacename: + node_id =3D f"{ifacename}.{node_id}" + + signode["names"].append(name) + signode["ids"].append(node_id) + + if "noindexentry" not in self.options: + indextext =3D self.get_index_text(ifacename, name) + if indextext: + self.indexnode["entries"].append( + ("single", indextext, node_id, "", None) + ) + + domain =3D cast(DBusDomain, self.env.get_domain("dbus")) + domain.note_object(name, self.objtype, node_id, location=3Dsignode) + + +class DBusInterface(DBusDescription): + """ + Implementation of ``dbus:interface``. + """ + + def get_index_text(self, ifacename: str, name: str) -> str: + return ifacename + + def before_content(self) -> None: + self.env.ref_context["dbus:interface"] =3D self.arguments[0] + + def after_content(self) -> None: + self.env.ref_context.pop("dbus:interface") + + def handle_signature(self, sig: str, signode: desc_signature) -> str: + signode +=3D addnodes.desc_annotation("interface ", "interface ") + signode +=3D addnodes.desc_name(sig, sig) + return sig + + def run(self) -> List[Node]: + _, node =3D super().run() + name =3D self.arguments[0] + section =3D nodes.section(ids=3D[name + "-section"]) + section +=3D nodes.title(name, "%s interface" % name) + section +=3D node + return [self.indexnode, section] + + +class DBusMember(DBusDescription): + + signal =3D False + + +class DBusMethod(DBusMember): + """ + Implementation of ``dbus:method``. + """ + + option_spec: OptionSpec =3D DBusMember.option_spec.copy() + option_spec.update( + { + "noreply": directives.flag, + } + ) + + doc_field_types: List[Field] =3D [ + TypedField( + "arg", + label=3D_("Arguments"), + names=3D("arg",), + rolename=3D"arg", + typerolename=3DNone, + typenames=3D("argtype", "type"), + ), + TypedField( + "ret", + label=3D_("Returns"), + names=3D("ret",), + rolename=3D"ret", + typerolename=3DNone, + typenames=3D("rettype", "type"), + ), + ] + + def get_index_text(self, ifacename: str, name: str) -> str: + return _("%s() (%s method)") % (name, ifacename) + + def handle_signature(self, sig: str, signode: desc_signature) -> str: + params =3D addnodes.desc_parameterlist() + returns =3D addnodes.desc_parameterlist() + + contentnode =3D addnodes.desc_content() + self.state.nested_parse(self.content, self.content_offset, content= node) + for child in contentnode: + if isinstance(child, nodes.field_list): + for field in child: + ty, sg, name =3D field[0].astext().split(None, 2) + param =3D addnodes.desc_parameter() + param +=3D addnodes.desc_sig_keyword_type(sg, sg) + param +=3D addnodes.desc_sig_space() + param +=3D addnodes.desc_sig_name(name, name) + if ty =3D=3D "arg": + params +=3D param + elif ty =3D=3D "ret": + returns +=3D param + + anno =3D "signal " if self.signal else "method " + signode +=3D addnodes.desc_annotation(anno, anno) + signode +=3D addnodes.desc_name(sig, sig) + signode +=3D params + if not self.signal and "noreply" not in self.options: + ret =3D addnodes.desc_returns() + ret +=3D returns + signode +=3D ret + + return sig + + +class DBusSignal(DBusMethod): + """ + Implementation of ``dbus:signal``. + """ + + doc_field_types: List[Field] =3D [ + TypedField( + "arg", + label=3D_("Arguments"), + names=3D("arg",), + rolename=3D"arg", + typerolename=3DNone, + typenames=3D("argtype", "type"), + ), + ] + signal =3D True + + def get_index_text(self, ifacename: str, name: str) -> str: + return _("%s() (%s signal)") % (name, ifacename) + + +class DBusProperty(DBusMember): + """ + Implementation of ``dbus:property``. + """ + + option_spec: OptionSpec =3D DBusMember.option_spec.copy() + option_spec.update( + { + "type": directives.unchanged, + "readonly": directives.flag, + "writeonly": directives.flag, + "readwrite": directives.flag, + "emits-changed": directives.unchanged, + } + ) + + doc_field_types: List[Field] =3D [] + + def get_index_text(self, ifacename: str, name: str) -> str: + return _("%s (%s property)") % (name, ifacename) + + def transform_content(self, contentnode: addnodes.desc_content) -> Non= e: + fieldlist =3D nodes.field_list() + access =3D None + if "readonly" in self.options: + access =3D _("read-only") + if "writeonly" in self.options: + access =3D _("write-only") + if "readwrite" in self.options: + access =3D _("read & write") + if access: + content =3D nodes.Text(access) + fieldname =3D nodes.field_name("", _("Access")) + fieldbody =3D nodes.field_body("", nodes.paragraph("", "", con= tent)) + field =3D nodes.field("", fieldname, fieldbody) + fieldlist +=3D field + emits =3D self.options.get("emits-changed", None) + if emits: + content =3D nodes.Text(emits) + fieldname =3D nodes.field_name("", _("Emits Changed")) + fieldbody =3D nodes.field_body("", nodes.paragraph("", "", con= tent)) + field =3D nodes.field("", fieldname, fieldbody) + fieldlist +=3D field + if len(fieldlist) > 0: + contentnode.insert(0, fieldlist) + + def handle_signature(self, sig: str, signode: desc_signature) -> str: + contentnode =3D addnodes.desc_content() + self.state.nested_parse(self.content, self.content_offset, content= node) + ty =3D self.options.get("type") + + signode +=3D addnodes.desc_annotation("property ", "property ") + signode +=3D addnodes.desc_name(sig, sig) + signode +=3D addnodes.desc_sig_punctuation("", ":") + signode +=3D addnodes.desc_sig_keyword_type(ty, ty) + return sig + + def run(self) -> List[Node]: + self.name =3D "dbus:member" + return super().run() + + +class DBusXRef(XRefRole): + def process_link(self, env, refnode, has_explicit_title, title, target= ): + refnode["dbus:interface"] =3D env.ref_context.get("dbus:interface") + if not has_explicit_title: + title =3D title.lstrip(".") # only has a meaning for the targ= et + target =3D target.lstrip("~") # only has a meaning for the ti= tle + # if the first character is a tilde, don't display the module/= class + # parts of the contents + if title[0:1] =3D=3D "~": + title =3D title[1:] + dot =3D title.rfind(".") + if dot !=3D -1: + title =3D title[dot + 1 :] + # if the first character is a dot, search more specific namespaces= first + # else search builtins first + if target[0:1] =3D=3D ".": + target =3D target[1:] + refnode["refspecific"] =3D True + return title, target + + +class DBusIndex(Index): + """ + Index subclass to provide a D-Bus interfaces index. + """ + + name =3D "dbusindex" + localname =3D _("D-Bus Interfaces Index") + shortname =3D _("dbus") + + def generate( + self, docnames: Iterable[str] =3D None + ) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]: + content: Dict[str, List[IndexEntry]] =3D {} + # list of prefixes to ignore + ignores: List[str] =3D self.domain.env.config["dbus_index_common_p= refix"] + ignores =3D sorted(ignores, key=3Dlen, reverse=3DTrue) + + ifaces =3D sorted( + [ + x + for x in self.domain.data["objects"].items() + if x[1].objtype =3D=3D "interface" + ], + key=3Dlambda x: x[0].lower(), + ) + for name, (docname, node_id, _) in ifaces: + if docnames and docname not in docnames: + continue + + for ignore in ignores: + if name.startswith(ignore): + name =3D name[len(ignore) :] + stripped =3D ignore + break + else: + stripped =3D "" + + entries =3D content.setdefault(name[0].lower(), []) + entries.append(IndexEntry(stripped + name, 0, docname, node_id= , "", "", "")) + + # sort by first letter + sorted_content =3D sorted(content.items()) + + return sorted_content, False + + +class ObjectEntry(NamedTuple): + docname: str + node_id: str + objtype: str + + +class DBusDomain(Domain): + """ + Implementation of the D-Bus domain. + """ + + name =3D "dbus" + label =3D "D-Bus" + object_types: Dict[str, ObjType] =3D { + "interface": ObjType(_("interface"), "iface", "obj"), + "method": ObjType(_("method"), "meth", "obj"), + "signal": ObjType(_("signal"), "sig", "obj"), + "property": ObjType(_("property"), "attr", "_prop", "obj"), + } + directives =3D { + "interface": DBusInterface, + "method": DBusMethod, + "signal": DBusSignal, + "property": DBusProperty, + } + roles =3D { + "iface": DBusXRef(), + "meth": DBusXRef(), + "sig": DBusXRef(), + "prop": DBusXRef(), + } + initial_data: Dict[str, Dict[str, Tuple[Any]]] =3D { + "objects": {}, # fullname -> ObjectEntry + } + indices =3D [ + DBusIndex, + ] + + @property + def objects(self) -> Dict[str, ObjectEntry]: + return self.data.setdefault("objects", {}) # fullname -> ObjectEn= try + + def note_object( + self, name: str, objtype: str, node_id: str, location: Any =3D None + ) -> None: + self.objects[name] =3D ObjectEntry(self.env.docname, node_id, objt= ype) + + def clear_doc(self, docname: str) -> None: + for fullname, obj in list(self.objects.items()): + if obj.docname =3D=3D docname: + del self.objects[fullname] + + def find_obj(self, typ: str, name: str) -> Optional[Tuple[str, ObjectE= ntry]]: + # skip parens + if name[-2:] =3D=3D "()": + name =3D name[:-2] + if typ in ("meth", "sig", "prop"): + try: + ifacename, name =3D name.rsplit(".", 1) + except ValueError: + pass + return self.objects.get(name) + + def resolve_xref( + self, + env: "BuildEnvironment", + fromdocname: str, + builder: "Builder", + typ: str, + target: str, + node: pending_xref, + contnode: Element, + ) -> Optional[Element]: + """Resolve the pending_xref *node* with the given *typ* and *targe= t*.""" + objdef =3D self.find_obj(typ, target) + if objdef: + return node_utils.make_refnode( + builder, fromdocname, objdef.docname, objdef.node_id, cont= node + ) + + def get_objects(self) -> Iterator[Tuple[str, str, str, str, str, int]]: + for refname, obj in self.objects.items(): + yield (refname, refname, obj.objtype, obj.docname, obj.node_id= , 1) + + +def setup(app): + app.add_domain(DBusDomain) + app.add_config_value("dbus_index_common_prefix", [], "env") diff --git a/docs/sphinx/dbusparser.py b/docs/sphinx/dbusparser.py new file mode 100644 index 0000000000..024553eae7 --- /dev/null +++ b/docs/sphinx/dbusparser.py @@ -0,0 +1,373 @@ +# Based from "GDBus - GLib D-Bus Library": +# +# Copyright (C) 2008-2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library; if not, see . +# +# Author: David Zeuthen + +import xml.parsers.expat + + +class Annotation: + def __init__(self, key, value): + self.key =3D key + self.value =3D value + self.annotations =3D [] + self.since =3D "" + + +class Arg: + def __init__(self, name, signature): + self.name =3D name + self.signature =3D signature + self.annotations =3D [] + self.doc_string =3D "" + self.since =3D "" + + +class Method: + def __init__(self, name, h_type_implies_unix_fd=3DTrue): + self.name =3D name + self.h_type_implies_unix_fd =3D h_type_implies_unix_fd + self.in_args =3D [] + self.out_args =3D [] + self.annotations =3D [] + self.doc_string =3D "" + self.since =3D "" + self.deprecated =3D False + self.unix_fd =3D False + + +class Signal: + def __init__(self, name): + self.name =3D name + self.args =3D [] + self.annotations =3D [] + self.doc_string =3D "" + self.since =3D "" + self.deprecated =3D False + + +class Property: + def __init__(self, name, signature, access): + self.name =3D name + self.signature =3D signature + self.access =3D access + self.annotations =3D [] + self.arg =3D Arg("value", self.signature) + self.arg.annotations =3D self.annotations + self.readable =3D False + self.writable =3D False + if self.access =3D=3D "readwrite": + self.readable =3D True + self.writable =3D True + elif self.access =3D=3D "read": + self.readable =3D True + elif self.access =3D=3D "write": + self.writable =3D True + else: + raise ValueError('Invalid access type "{}"'.format(self.access= )) + self.doc_string =3D "" + self.since =3D "" + self.deprecated =3D False + self.emits_changed_signal =3D True + + +class Interface: + def __init__(self, name): + self.name =3D name + self.methods =3D [] + self.signals =3D [] + self.properties =3D [] + self.annotations =3D [] + self.doc_string =3D "" + self.doc_string_brief =3D "" + self.since =3D "" + self.deprecated =3D False + + +class DBusXMLParser: + STATE_TOP =3D "top" + STATE_NODE =3D "node" + STATE_INTERFACE =3D "interface" + STATE_METHOD =3D "method" + STATE_SIGNAL =3D "signal" + STATE_PROPERTY =3D "property" + STATE_ARG =3D "arg" + STATE_ANNOTATION =3D "annotation" + STATE_IGNORED =3D "ignored" + + def __init__(self, xml_data, h_type_implies_unix_fd=3DTrue): + self._parser =3D xml.parsers.expat.ParserCreate() + self._parser.CommentHandler =3D self.handle_comment + self._parser.CharacterDataHandler =3D self.handle_char_data + self._parser.StartElementHandler =3D self.handle_start_element + self._parser.EndElementHandler =3D self.handle_end_element + + self.parsed_interfaces =3D [] + self._cur_object =3D None + + self.state =3D DBusXMLParser.STATE_TOP + self.state_stack =3D [] + self._cur_object =3D None + self._cur_object_stack =3D [] + + self.doc_comment_last_symbol =3D "" + + self._h_type_implies_unix_fd =3D h_type_implies_unix_fd + + self._parser.Parse(xml_data) + + COMMENT_STATE_BEGIN =3D "begin" + COMMENT_STATE_PARAMS =3D "params" + COMMENT_STATE_BODY =3D "body" + COMMENT_STATE_SKIP =3D "skip" + + def handle_comment(self, data): + comment_state =3D DBusXMLParser.COMMENT_STATE_BEGIN + lines =3D data.split("\n") + symbol =3D "" + body =3D "" + in_para =3D False + params =3D {} + for line in lines: + orig_line =3D line + line =3D line.lstrip() + if comment_state =3D=3D DBusXMLParser.COMMENT_STATE_BEGIN: + if len(line) > 0: + colon_index =3D line.find(": ") + if colon_index =3D=3D -1: + if line.endswith(":"): + symbol =3D line[0 : len(line) - 1] + comment_state =3D DBusXMLParser.COMMENT_STATE_= PARAMS + else: + comment_state =3D DBusXMLParser.COMMENT_STATE_= SKIP + else: + symbol =3D line[0:colon_index] + rest_of_line =3D line[colon_index + 2 :].strip() + if len(rest_of_line) > 0: + body +=3D rest_of_line + "\n" + comment_state =3D DBusXMLParser.COMMENT_STATE_PARA= MS + elif comment_state =3D=3D DBusXMLParser.COMMENT_STATE_PARAMS: + if line.startswith("@"): + colon_index =3D line.find(": ") + if colon_index =3D=3D -1: + comment_state =3D DBusXMLParser.COMMENT_STATE_BODY + if not in_para: + in_para =3D True + body +=3D orig_line + "\n" + else: + param =3D line[1:colon_index] + docs =3D line[colon_index + 2 :] + params[param] =3D docs + else: + comment_state =3D DBusXMLParser.COMMENT_STATE_BODY + if len(line) > 0: + if not in_para: + in_para =3D True + body +=3D orig_line + "\n" + elif comment_state =3D=3D DBusXMLParser.COMMENT_STATE_BODY: + if len(line) > 0: + if not in_para: + in_para =3D True + body +=3D orig_line + "\n" + else: + if in_para: + body +=3D "\n" + in_para =3D False + if in_para: + body +=3D "\n" + + if symbol !=3D "": + self.doc_comment_last_symbol =3D symbol + self.doc_comment_params =3D params + self.doc_comment_body =3D body + + def handle_char_data(self, data): + # print 'char_data=3D%s'%data + pass + + def handle_start_element(self, name, attrs): + old_state =3D self.state + old_cur_object =3D self._cur_object + if self.state =3D=3D DBusXMLParser.STATE_IGNORED: + self.state =3D DBusXMLParser.STATE_IGNORED + elif self.state =3D=3D DBusXMLParser.STATE_TOP: + if name =3D=3D DBusXMLParser.STATE_NODE: + self.state =3D DBusXMLParser.STATE_NODE + else: + self.state =3D DBusXMLParser.STATE_IGNORED + elif self.state =3D=3D DBusXMLParser.STATE_NODE: + if name =3D=3D DBusXMLParser.STATE_INTERFACE: + self.state =3D DBusXMLParser.STATE_INTERFACE + iface =3D Interface(attrs["name"]) + self._cur_object =3D iface + self.parsed_interfaces.append(iface) + elif name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if "name" in attrs and self.doc_comment_last_symbol =3D=3D att= rs["name"]: + self._cur_object.doc_string =3D self.doc_comment_body + if "short_description" in self.doc_comment_params: + short_description =3D self.doc_comment_params["short_d= escription"] + self._cur_object.doc_string_brief =3D short_description + if "since" in self.doc_comment_params: + self._cur_object.since =3D self.doc_comment_params["si= nce"].strip() + + elif self.state =3D=3D DBusXMLParser.STATE_INTERFACE: + if name =3D=3D DBusXMLParser.STATE_METHOD: + self.state =3D DBusXMLParser.STATE_METHOD + method =3D Method( + attrs["name"], h_type_implies_unix_fd=3Dself._h_type_i= mplies_unix_fd + ) + self._cur_object.methods.append(method) + self._cur_object =3D method + elif name =3D=3D DBusXMLParser.STATE_SIGNAL: + self.state =3D DBusXMLParser.STATE_SIGNAL + signal =3D Signal(attrs["name"]) + self._cur_object.signals.append(signal) + self._cur_object =3D signal + elif name =3D=3D DBusXMLParser.STATE_PROPERTY: + self.state =3D DBusXMLParser.STATE_PROPERTY + prop =3D Property(attrs["name"], attrs["type"], attrs["acc= ess"]) + self._cur_object.properties.append(prop) + self._cur_object =3D prop + elif name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if "name" in attrs and self.doc_comment_last_symbol =3D=3D att= rs["name"]: + self._cur_object.doc_string =3D self.doc_comment_body + if "since" in self.doc_comment_params: + self._cur_object.since =3D self.doc_comment_params["si= nce"].strip() + + elif self.state =3D=3D DBusXMLParser.STATE_METHOD: + if name =3D=3D DBusXMLParser.STATE_ARG: + self.state =3D DBusXMLParser.STATE_ARG + arg_name =3D None + if "name" in attrs: + arg_name =3D attrs["name"] + arg =3D Arg(arg_name, attrs["type"]) + direction =3D attrs.get("direction", "in") + if direction =3D=3D "in": + self._cur_object.in_args.append(arg) + elif direction =3D=3D "out": + self._cur_object.out_args.append(arg) + else: + raise ValueError('Invalid direction "{}"'.format(direc= tion)) + self._cur_object =3D arg + elif name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if self.doc_comment_last_symbol =3D=3D old_cur_object.name: + if "name" in attrs and attrs["name"] in self.doc_comment_p= arams: + doc_string =3D self.doc_comment_params[attrs["name"]] + if doc_string is not None: + self._cur_object.doc_string =3D doc_string + if "since" in self.doc_comment_params: + self._cur_object.since =3D self.doc_comment_params[ + "since" + ].strip() + + elif self.state =3D=3D DBusXMLParser.STATE_SIGNAL: + if name =3D=3D DBusXMLParser.STATE_ARG: + self.state =3D DBusXMLParser.STATE_ARG + arg_name =3D None + if "name" in attrs: + arg_name =3D attrs["name"] + arg =3D Arg(arg_name, attrs["type"]) + self._cur_object.args.append(arg) + self._cur_object =3D arg + elif name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + # assign docs, if any + if self.doc_comment_last_symbol =3D=3D old_cur_object.name: + if "name" in attrs and attrs["name"] in self.doc_comment_p= arams: + doc_string =3D self.doc_comment_params[attrs["name"]] + if doc_string is not None: + self._cur_object.doc_string =3D doc_string + if "since" in self.doc_comment_params: + self._cur_object.since =3D self.doc_comment_params[ + "since" + ].strip() + + elif self.state =3D=3D DBusXMLParser.STATE_PROPERTY: + if name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + elif self.state =3D=3D DBusXMLParser.STATE_ARG: + if name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + elif self.state =3D=3D DBusXMLParser.STATE_ANNOTATION: + if name =3D=3D DBusXMLParser.STATE_ANNOTATION: + self.state =3D DBusXMLParser.STATE_ANNOTATION + anno =3D Annotation(attrs["name"], attrs["value"]) + self._cur_object.annotations.append(anno) + self._cur_object =3D anno + else: + self.state =3D DBusXMLParser.STATE_IGNORED + + else: + raise ValueError( + 'Unhandled state "{}" while entering element with name "{}= "'.format( + self.state, name + ) + ) + + self.state_stack.append(old_state) + self._cur_object_stack.append(old_cur_object) + + def handle_end_element(self, name): + self.state =3D self.state_stack.pop() + self._cur_object =3D self._cur_object_stack.pop() + + +def parse_dbus_xml(xml_data): + parser =3D DBusXMLParser(xml_data, True) + return parser.parsed_interfaces diff --git a/docs/sphinx/fakedbusdoc.py b/docs/sphinx/fakedbusdoc.py new file mode 100644 index 0000000000..a680b25754 --- /dev/null +++ b/docs/sphinx/fakedbusdoc.py @@ -0,0 +1,25 @@ +# D-Bus XML documentation extension, compatibility gunk for +"""dbus-doc is a Sphinx extension that provides documentation from D-Bus X= ML.""" + +from sphinx.application import Sphinx +from sphinx.util.docutils import SphinxDirective +from typing import Any, Dict + + +class FakeDBusDocDirective(SphinxDirective): + has_content =3D True + required_arguments =3D 1 + + def run(self): + return [] + + +def setup(app: Sphinx) -> Dict[str, Any]: + """Register a fake dbus-doc directive with Sphinx""" + app.add_directive("dbus-doc", FakeDBusDocDirective) --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381468977128.36361955999689; Sat, 9 Oct 2021 14:24:49 -0700 (PDT) Received: from localhost ([::1]:51864 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJpo-0000YY-Rm for importer@patchew.org; Sat, 09 Oct 2021 17:24:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38316) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJfd-0006b4-FP for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:17 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:24299) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJfc-0000OV-0g for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:17 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-333-GMFGvpCWOjKvMTO45kEq1g-1; Sat, 09 Oct 2021 17:14:14 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 62948801AA7 for ; Sat, 9 Oct 2021 21:14:13 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1FA821A7E9; Sat, 9 Oct 2021 21:14:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814055; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UR8QiP1/NLjRtRQBWTVjsQftNf9uQPBYQoCwT5y5Ki8=; b=es42jiCZTeqnZIKYcGo8YPqYb2P3keaY7WdJM82Rq2XROaYDlx9zwlnnURri+CCxNNvK3a OubjIMA0xJDTaMtckYdYYoJ7cINxQ7s92K+nmV8uphoo8yi/PiCk47gZVP4yIfRndUoSVk SDapYy2yaawu8EQGtn+uF7wB3sUD2NY= X-MC-Unique: GMFGvpCWOjKvMTO45kEq1g-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 22/37] backends: move dbus-vmstate1.xml to backends/ Date: Sun, 10 Oct 2021 01:08:23 +0400 Message-Id: <20211009210838.2219430-23-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814691273100001 From: Marc-Andr=C3=A9 Lureau Although not used by the backend itself, use a common location for documentation and sharing purposes. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- {tests/qtest =3D> backends}/dbus-vmstate1.xml | 0 tests/qtest/meson.build | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {tests/qtest =3D> backends}/dbus-vmstate1.xml (100%) diff --git a/tests/qtest/dbus-vmstate1.xml b/backends/dbus-vmstate1.xml similarity index 100% rename from tests/qtest/dbus-vmstate1.xml rename to backends/dbus-vmstate1.xml diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index c9d8458062..b6016aee48 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -93,7 +93,7 @@ if dbus_daemon.found() and config_host.has_key('GDBUS_COD= EGEN') #qtests_i386 +=3D ['dbus-vmstate-test'] dbus_vmstate1 =3D custom_target('dbus-vmstate description', output: ['dbus-vmstate1.h', 'dbus-vmstate1= .c'], - input: files('dbus-vmstate1.xml'), + input: meson.source_root() / 'backends/dbu= s-vmstate1.xml', command: [config_host['GDBUS_CODEGEN'], '@INPUT@', '--interface-prefix', 'org.qemu', --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814873623247.90201947637797; Sat, 9 Oct 2021 14:27:53 -0700 (PDT) Received: from localhost ([::1]:60842 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJsm-0006fM-DP for importer@patchew.org; Sat, 09 Oct 2021 17:27:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38338) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJfr-0006vB-5R for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:31 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22596) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJfp-0000Om-EN for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:30 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-192-LmiSAI0eNqy16dNPrwMC9Q-1; Sat, 09 Oct 2021 17:14:24 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CEC945127 for ; Sat, 9 Oct 2021 21:14:23 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 05D985D9D3; Sat, 9 Oct 2021 21:14:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814068; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M3MnAM7QGLPQ8V0VGhUrbupto7S5xAyYpN4I+NLF4YE=; b=AYjzKTdyrJG1P/Br2JtHg/p7lA5jNtfDCBVv60npcb6XT7JtbaLGXRuQlT0Tn2u08ho2+h DgGrypmTB8uXCSyo6OAsI+5bIUTDha9oKZB09IXc3e1lHImVqm8anvrwX/AklcaEsxWAzR YbjN221pZMT9EVmZlFNeI2nq5AHM/vs= X-MC-Unique: LmiSAI0eNqy16dNPrwMC9Q-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 23/37] docs: move D-Bus VMState documentation to source XML Date: Sun, 10 Oct 2021 01:08:24 +0400 Message-Id: <20211009210838.2219430-24-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814874728100001 From: Marc-Andr=C3=A9 Lureau Use the source XML document as single reference, importing its documentation via the dbus-doc directive. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- docs/interop/dbus-vmstate.rst | 52 ++++++----------------------------- backends/dbus-vmstate1.xml | 42 +++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/docs/interop/dbus-vmstate.rst b/docs/interop/dbus-vmstate.rst index 1d719c1c60..5fb3f279e2 100644 --- a/docs/interop/dbus-vmstate.rst +++ b/docs/interop/dbus-vmstate.rst @@ -2,9 +2,6 @@ D-Bus VMState =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -Introduction -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - The QEMU dbus-vmstate object's aim is to migrate helpers' data running on a QEMU D-Bus bus. (refer to the :doc:`dbus` document for some recommendations on D-Bus usage) @@ -26,49 +23,16 @@ dbus-vmstate object can be configured with the expected= list of helpers by setting its ``id-list`` property, with a comma-separated ``Id`` list. =20 -Interface -=3D=3D=3D=3D=3D=3D=3D=3D=3D - -On object path ``/org/qemu/VMState1``, the following -``org.qemu.VMState1`` interface should be implemented: - -.. code:: xml - - - - - - - - - - - -"Id" property -------------- - -A string that identifies the helper uniquely. (maximum 256 bytes -including terminating NUL byte) - -.. note:: - - The helper ID namespace is a separate namespace. In particular, it is n= ot - related to QEMU "id" used in -object/-device objects. - -Load(in u8[] bytes) method --------------------------- - -The method called on destination with the state to restore. +.. only:: sphinx4 =20 -The helper may be initially started in a waiting state (with -an --incoming argument for example), and it may resume on success. + .. dbus-doc:: backends/dbus-vmstate1.xml =20 -An error may be returned to the caller. +.. only:: not sphinx4 =20 -Save(out u8[] bytes) method ---------------------------- + .. warning:: + Sphinx 4 is required to build D-Bus documentation. =20 -The method called on the source to get the current state to be -migrated. The helper should continue to run normally. + This is the content of ``backends/dbus-vmstate1.xml``: =20 -An error may be returned to the caller. + .. literalinclude:: ../../backends/dbus-vmstate1.xml + :language: xml diff --git a/backends/dbus-vmstate1.xml b/backends/dbus-vmstate1.xml index cc8563be4c..601ee8dc7e 100644 --- a/backends/dbus-vmstate1.xml +++ b/backends/dbus-vmstate1.xml @@ -1,10 +1,50 @@ - + + + + + + + + --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814839796866.989818289137; Sat, 9 Oct 2021 14:27:19 -0700 (PDT) Received: from localhost ([::1]:60328 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJsE-0006KR-MF for importer@patchew.org; Sat, 09 Oct 2021 17:27:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38380) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJg1-0007Oa-Vp for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:42 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:55689) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJg0-0000Pk-D8 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:41 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-43-Fy-ocET6M6eBzCi4uKNvAg-1; Sat, 09 Oct 2021 17:14:30 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 284DA8042BD for ; Sat, 9 Oct 2021 21:14:29 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 142665D9D3; Sat, 9 Oct 2021 21:14:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814079; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XJFNsLpjy9wQdlDr1tGhOKnJwSWPeE6N57r1L7KLMQU=; b=ZYiQg5+fIdW9fywxB0zIlAm/YdvAh/pQ16U31TtLq9gW9oX9/xLBOdaXGvzZkfqYxD14gV AM5l9fb5OsIZBpohShge0UQLaLqMm4U2/Yu88MqIT1L/DjzdgChEdnjywdpG6+o1jwHrLS jPDVqQVSQAwsL6u4xHuTCAkNn4Db2ik= X-MC-Unique: Fy-ocET6M6eBzCi4uKNvAg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 24/37] docs: add dbus-display documentation Date: Sun, 10 Oct 2021 01:08:25 +0400 Message-Id: <20211009210838.2219430-25-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -8 X-Spam_score: -0.9 X-Spam_bar: / X-Spam_report: (-0.9 / 5.0 requ) DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814841619100001 From: Marc-Andr=C3=A9 Lureau Wire up the dbus-display documentation. The interface and feature is implemented next. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- docs/interop/dbus-display.rst | 31 +++++++++++++++++++++++++++++++ docs/interop/dbus.rst | 2 ++ docs/interop/index.rst | 1 + ui/dbus-display1.xml | 0 4 files changed, 34 insertions(+) create mode 100644 docs/interop/dbus-display.rst create mode 100644 ui/dbus-display1.xml diff --git a/docs/interop/dbus-display.rst b/docs/interop/dbus-display.rst new file mode 100644 index 0000000000..8c6e8e0f5a --- /dev/null +++ b/docs/interop/dbus-display.rst @@ -0,0 +1,31 @@ +D-Bus display +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +QEMU can export the VM display through D-Bus (when started with ``-display +dbus``), to allow out-of-process UIs, remote protocol servers or other +interactive display usages. + +Various specialized D-Bus interfaces are available on different object pat= hs +under ``/org/qemu/Display1/``, depending on the VM configuration. + +QEMU also implements the standard interfaces, such as +`org.freedesktop.DBus.Introspectable +`_. + +.. contents:: + :local: + :depth: 1 + +.. only:: sphinx4 + + .. dbus-doc:: ui/dbus-display1.xml + +.. only:: not sphinx4 + + .. warning:: + Sphinx 4 is required to build D-Bus documentation. + + This is the content of ``ui/dbus-display1.xml``: + + .. literalinclude:: ../../ui/dbus-display1.xml + :language: xml diff --git a/docs/interop/dbus.rst b/docs/interop/dbus.rst index be596d3f41..427debc9c5 100644 --- a/docs/interop/dbus.rst +++ b/docs/interop/dbus.rst @@ -108,3 +108,5 @@ QEMU Interfaces =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 :doc:`dbus-vmstate` + +:doc:`dbus-display` diff --git a/docs/interop/index.rst b/docs/interop/index.rst index 47b9ed82bb..c59bac9834 100644 --- a/docs/interop/index.rst +++ b/docs/interop/index.rst @@ -12,6 +12,7 @@ are useful for making QEMU interoperate with other softwa= re. bitmaps dbus dbus-vmstate + dbus-display live-block-operations pr-helper qemu-ga diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml new file mode 100644 index 0000000000..e69de29bb2 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633814933640236.1385649284822; Sat, 9 Oct 2021 14:28:53 -0700 (PDT) Received: from localhost ([::1]:36254 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJtk-0000jG-Gm for importer@patchew.org; Sat, 09 Oct 2021 17:28:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38378) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJg1-0007OQ-V2 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:47673) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJg0-0000Pi-AN for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:41 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-205-7YjMPvlMMg26Hdcvr0G9Pw-1; Sat, 09 Oct 2021 17:14:34 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BDA3B1080865 for ; Sat, 9 Oct 2021 21:14:33 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id D66875D9D3; Sat, 9 Oct 2021 21:14:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814079; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=H3ik/yIu1/xC00Odm209tNA/i2uNVSXvuVYFcqb0QVg=; b=Vc4vIGu9eYc7vB9xp8eOCGaQNalyEjvw3sc1PL/HihoFbwbWIHDzDBpZdC9zR1BqeZagNo qrlh+a+o4aBzd5MxwWcp21iArEjC2af3TuPHxbZJKDXWyJIuoJm/CiL4Gf3hlSBMXrZl8/ hxgoPXK/bkEjZVgy7MvLSqeQOTDFm8c= X-MC-Unique: 7YjMPvlMMg26Hdcvr0G9Pw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 25/37] build-sys: set glib dependency version Date: Sun, 10 Oct 2021 01:08:26 +0400 Message-Id: <20211009210838.2219430-26-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814935210100001 From: Marc-Andr=C3=A9 Lureau Further meson configuration tests are to be added based on the glib version. Also correct the version reporting in the config log. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- configure | 1 + meson.build | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 375cde2b44..57e363fd73 100755 --- a/configure +++ b/configure @@ -4889,6 +4889,7 @@ echo "QEMU_CFLAGS=3D$QEMU_CFLAGS" >> $config_host_mak echo "QEMU_CXXFLAGS=3D$QEMU_CXXFLAGS" >> $config_host_mak echo "GLIB_CFLAGS=3D$glib_cflags" >> $config_host_mak echo "GLIB_LIBS=3D$glib_libs" >> $config_host_mak +echo "GLIB_VERSION=3D$(pkg-config --modversion glib-2.0)" >> $config_host_= mak echo "QEMU_LDFLAGS=3D$QEMU_LDFLAGS" >> $config_host_mak echo "LD_I386_EMULATION=3D$ld_i386_emulation" >> $config_host_mak echo "EXESUF=3D$EXESUF" >> $config_host_mak diff --git a/meson.build b/meson.build index e1cddf5139..9494590aa2 100644 --- a/meson.build +++ b/meson.build @@ -311,14 +311,16 @@ endif add_project_arguments(config_host['GLIB_CFLAGS'].split(), native: false, language: ['c', 'cpp', 'objc']) glib =3D declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split= (), - link_args: config_host['GLIB_LIBS'].split()) + link_args: config_host['GLIB_LIBS'].split(), + version: config_host['GLIB_VERSION']) # override glib dep with the configure results (for subprojects) meson.override_dependency('glib-2.0', glib) =20 gio =3D not_found if 'CONFIG_GIO' in config_host gio =3D declare_dependency(compile_args: config_host['GIO_CFLAGS'].split= (), - link_args: config_host['GIO_LIBS'].split()) + link_args: config_host['GIO_LIBS'].split(), + version: config_host['GLIB_VERSION']) endif lttng =3D not_found if 'CONFIG_TRACE_UST' in config_host --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633815069509690.1161360823753; Sat, 9 Oct 2021 14:31:09 -0700 (PDT) Received: from localhost ([::1]:41520 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJvw-0004Fg-DU for importer@patchew.org; Sat, 09 Oct 2021 17:31:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38398) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJgI-0007n1-2q for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:41290) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJgE-0000QM-3E for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:14:57 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-575-e1sTbihzPoq4c999Gf9Qqg-1; Sat, 09 Oct 2021 17:14:50 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2157F1080865 for ; Sat, 9 Oct 2021 21:14:49 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id A51CE179B3; Sat, 9 Oct 2021 21:14:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814093; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DryHIn4WDvwv0cbzC08KvQebuXWBe8FV6MirE6537Bc=; b=BlT9tFbY0gJ3s9RuDsBtU8cMem5T8ZTeBKN0z7Mhct/iHXr3AP2YNPVVK1X2pQs1Oxom7S xWSkppmbPJfapYTH3INM8YyXPhJ1k/UKI9xjzCcz2cEla33mSIgkxDJYe4hYRtMfLUoMbY LZZ/zTA5azxjPUU9TrCNkccudeSUbog= X-MC-Unique: e1sTbihzPoq4c999Gf9Qqg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 26/37] ui: add a D-Bus display backend Date: Sun, 10 Oct 2021 01:08:27 +0400 Message-Id: <20211009210838.2219430-27-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815071632100001 From: Marc-Andr=C3=A9 Lureau The "dbus" display backend exports the QEMU consoles and other UI-related interfaces over D-Bus. By default, the connection is established on the session bus, but you can specify a different bus with the "addr" option. The backend takes the "org.qemu" service name, while still allowing further instances to queue on the same name (so you can lookup all the available instances too). It accepts any number of clients at this point, although this is expected to evolve with options to restrict clients, or only accept p2p via fd passing. The interface is intentionally very close to the internal QEMU API, and can be introspected or interacted with busctl/dfeet etc: $ ./qemu-system-x86_64 -name MyVM -display dbus $ busctl --user introspect org.qemu /org/qemu/Display1/Console_0 org.qemu.Display1.Console interface - - - .RegisterListener method h - - .SetUIInfo method qqiiuu - - .DeviceAddress property s "pci/0000/01.0" emi= ts-change .Head property u 0 emi= ts-change .Height property u 480 emi= ts-change .Label property s "VGA" emi= ts-change .Type property s "Graphic" emi= ts-change .Width property u 640 emi= ts-change [...] See the interfaces XML source file and Sphinx docs for the generated API documentations. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- meson.build | 12 +- qapi/ui.json | 27 ++- include/qemu/dbus.h | 19 ++ ui/dbus.h | 83 ++++++++ ui/dbus-console.c | 497 +++++++++++++++++++++++++++++++++++++++++++ ui/dbus-error.c | 48 +++++ ui/dbus-listener.c | 486 ++++++++++++++++++++++++++++++++++++++++++ ui/dbus.c | 262 +++++++++++++++++++++++ meson_options.txt | 2 + qemu-options.hx | 15 ++ ui/dbus-display1.xml | 378 ++++++++++++++++++++++++++++++++ ui/meson.build | 22 ++ ui/trace-events | 11 + 13 files changed, 1859 insertions(+), 3 deletions(-) create mode 100644 ui/dbus.h create mode 100644 ui/dbus-console.c create mode 100644 ui/dbus-error.c create mode 100644 ui/dbus-listener.c create mode 100644 ui/dbus.c diff --git a/meson.build b/meson.build index 9494590aa2..b571fde310 100644 --- a/meson.build +++ b/meson.build @@ -1198,6 +1198,15 @@ endif have_host_block_device =3D (targetos !=3D 'darwin' or cc.has_header('IOKit/storage/IOMedia.h')) =20 +dbus_display =3D false +if not get_option('dbus_display').disabled() + # FIXME enable_modules shouldn't be necessary, but: https://github.com/m= esonbuild/meson/issues/8333 + dbus_display =3D gio.version().version_compare('>=3D2.64') and config_ho= st.has_key('GDBUS_CODEGEN') and enable_modules + if get_option('dbus_display').enabled() and not dbus_display + error('Requirements missing to enable -display dbus') + endif +endif + ################# # config-host.h # ################# @@ -1299,7 +1308,7 @@ config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', s= pice_protocol.version().spl config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version= ().split('.')[2]) endif config_host_data.set('CONFIG_SPICE', spice.found()) -config_host_data.set('CONFIG_X11', x11.found()) +config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) config_host_data.set('CONFIG_CFI', get_option('cfi')) config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version(= ))) config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('= .')[0]) @@ -2892,6 +2901,7 @@ summary_info +=3D {'fuzzing support': config_host.h= as_key('CONFIG_FUZZ')} if have_system summary_info +=3D {'Audio drivers': config_host['CONFIG_AUDIO_DRIVER= S']} endif +summary_info +=3D {'D-Bus display': dbus_display} summary_info +=3D {'Trace backends': config_host['TRACE_BACKENDS']} if config_host['TRACE_BACKENDS'].split().contains('simple') summary_info +=3D {'Trace output file': config_host['CONFIG_TRACE_FILE']= + '-'} diff --git a/qapi/ui.json b/qapi/ui.json index d7567ac866..5ca604bd90 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1121,6 +1121,23 @@ { 'struct' : 'DisplayEGLHeadless', 'data' : { '*rendernode' : 'str' } } =20 +## +# @DisplayDBus: +# +# DBus display options. +# +# @addr: The D-Bus bus address (default to the session bus). +# +# @rendernode: Which DRM render node should be used. Default is the first +# available node on the host. +# +# Since: 6.2 +# +## +{ 'struct' : 'DisplayDBus', + 'data' : { '*rendernode' : 'str', + '*addr': 'str' } } + ## # @DisplayGLMode: # @@ -1186,6 +1203,8 @@ # application to connect to it. The server will redirect # the serial console and QEMU monitors. (Since 4.0) # +# @dbus: Start a D-Bus service for the display. (Since 6.2) +# # Since: 2.12 # ## @@ -1199,7 +1218,10 @@ 'if': { 'all': ['CONFIG_OPENGL', 'CONFIG_GBM'] } }, { 'name': 'curses', 'if': 'CONFIG_CURSES' }, { 'name': 'cocoa', 'if': 'CONFIG_COCOA' }, - { 'name': 'spice-app', 'if': 'CONFIG_SPICE'} ] } + { 'name': 'spice-app', 'if': 'CONFIG_SPICE' }, + { 'name': 'dbus', 'if': 'CONFIG_DBUS_DISPLAY' } + ] +} =20 ## # @DisplayOptions: @@ -1227,7 +1249,8 @@ 'gtk': { 'type': 'DisplayGTK', 'if': 'CONFIG_GTK' }, 'curses': { 'type': 'DisplayCurses', 'if': 'CONFIG_CURSES' }, 'egl-headless': { 'type': 'DisplayEGLHeadless', - 'if': { 'all': ['CONFIG_OPENGL', 'CONFIG_GBM'] } } + 'if': { 'all': ['CONFIG_OPENGL', 'CONFIG_GBM'] } }, + 'dbus': { 'type': 'DisplayDBus', 'if': 'CONFIG_DBUS_DISPLAY' } } } =20 diff --git a/include/qemu/dbus.h b/include/qemu/dbus.h index 9d591f9ee4..c0cbb1ca44 100644 --- a/include/qemu/dbus.h +++ b/include/qemu/dbus.h @@ -12,6 +12,25 @@ =20 #include =20 +/* glib/gio 2.68 */ +#define DBUS_METHOD_INVOCATION_HANDLED TRUE +#define DBUS_METHOD_INVOCATION_UNHANDLED FALSE + +/* in msec */ +#define DBUS_DEFAULT_TIMEOUT 1000 + +#define DBUS_DISPLAY1_ROOT "/org/qemu/Display1" + +#define DBUS_DISPLAY_ERROR (dbus_display_error_quark()) +GQuark dbus_display_error_quark(void); + +typedef enum { + DBUS_DISPLAY_ERROR_FAILED, + DBUS_DISPLAY_ERROR_INVALID, + DBUS_DISPLAY_ERROR_UNSUPPORTED, + DBUS_DISPLAY_N_ERRORS, +} DBusDisplayError; + GStrv qemu_dbus_get_queued_owners(GDBusConnection *connection, const char *name, Error **errp); diff --git a/ui/dbus.h b/ui/dbus.h new file mode 100644 index 0000000000..d3c9598dd1 --- /dev/null +++ b/ui/dbus.h @@ -0,0 +1,83 @@ +/* + * QEMU DBus display + * + * Copyright (c) 2021 Marc-Andr=C3=A9 Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#ifndef UI_DBUS_H_ +#define UI_DBUS_H_ + +#include "qemu/dbus.h" +#include "qom/object.h" +#include "ui/console.h" + +#include "dbus-display1.h" + +struct DBusDisplay { + Object parent; + + DisplayGLMode gl_mode; + char *dbus_addr; + DisplayGLCtx glctx; + + GDBusConnection *bus; + GDBusObjectManagerServer *server; + QemuDBusDisplay1VM *iface; + GPtrArray *consoles; +}; + +#define TYPE_DBUS_DISPLAY "dbus-display" +OBJECT_DECLARE_SIMPLE_TYPE(DBusDisplay, DBUS_DISPLAY) + +#define DBUS_DISPLAY_TYPE_CONSOLE dbus_display_console_get_type() +G_DECLARE_FINAL_TYPE(DBusDisplayConsole, + dbus_display_console, + DBUS_DISPLAY, + CONSOLE, + GDBusObjectSkeleton) + +DBusDisplayConsole * +dbus_display_console_new(DBusDisplay *display, QemuConsole *con); + +int +dbus_display_console_get_index(DBusDisplayConsole *ddc); + +#define DBUS_DISPLAY_TYPE_LISTENER dbus_display_listener_get_type() +G_DECLARE_FINAL_TYPE(DBusDisplayListener, + dbus_display_listener, + DBUS_DISPLAY, + LISTENER, + GObject) + +DBusDisplayListener * +dbus_display_listener_new(const char *bus_name, + GDBusConnection *conn, + DBusDisplayConsole *console); + +DBusDisplayConsole * +dbus_display_listener_get_console(DBusDisplayListener *ddl); + +const char * +dbus_display_listener_get_bus_name(DBusDisplayListener *ddl); + +extern const DisplayChangeListenerOps dbus_gl_dcl_ops; +extern const DisplayChangeListenerOps dbus_dcl_ops; + +#endif /* UI_DBUS_H_ */ diff --git a/ui/dbus-console.c b/ui/dbus-console.c new file mode 100644 index 0000000000..1ccf638c10 --- /dev/null +++ b/ui/dbus-console.c @@ -0,0 +1,497 @@ +/* + * QEMU DBus display console + * + * Copyright (c) 2021 Marc-Andr=C3=A9 Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "ui/input.h" +#include "ui/kbd-state.h" +#include "trace.h" + +#include + +#include "dbus.h" + +struct _DBusDisplayConsole { + GDBusObjectSkeleton parent_instance; + DisplayChangeListener dcl; + + DBusDisplay *display; + QemuConsole *con; + GHashTable *listeners; + QemuDBusDisplay1Console *iface; + + QemuDBusDisplay1Keyboard *iface_kbd; + QKbdState *kbd; + + QemuDBusDisplay1Mouse *iface_mouse; + gboolean last_set; + guint last_x; + guint last_y; + Notifier mouse_mode_notifier; +}; + +G_DEFINE_TYPE(DBusDisplayConsole, + dbus_display_console, + G_TYPE_DBUS_OBJECT_SKELETON) + +static void +dbus_display_console_set_size(DBusDisplayConsole *ddc, + uint32_t width, uint32_t height) +{ + g_object_set(ddc->iface, + "width", width, + "height", height, + NULL); +} + +static void +dbus_gfx_switch(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface) +{ + DBusDisplayConsole *ddc =3D container_of(dcl, DBusDisplayConsole, dcl); + + dbus_display_console_set_size(ddc, + surface_width(new_surface), + surface_height(new_surface)); +} + +static void +dbus_gfx_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ +} + +static void +dbus_gl_scanout_disable(DisplayChangeListener *dcl) +{ +} + +static void +dbus_gl_scanout_texture(DisplayChangeListener *dcl, + uint32_t tex_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) +{ + DBusDisplayConsole *ddc =3D container_of(dcl, DBusDisplayConsole, dcl); + + dbus_display_console_set_size(ddc, w, h); +} + +static void +dbus_gl_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + DBusDisplayConsole *ddc =3D container_of(dcl, DBusDisplayConsole, dcl); + + dbus_display_console_set_size(ddc, + dmabuf->width, + dmabuf->height); +} + +static void +dbus_gl_scanout_update(DisplayChangeListener *dcl, + uint32_t x, uint32_t y, + uint32_t w, uint32_t h) +{ +} + +static const DisplayChangeListenerOps dbus_console_dcl_ops =3D { + .dpy_name =3D "dbus-console", + .dpy_gfx_switch =3D dbus_gfx_switch, + .dpy_gfx_update =3D dbus_gfx_update, + .dpy_gl_scanout_disable =3D dbus_gl_scanout_disable, + .dpy_gl_scanout_texture =3D dbus_gl_scanout_texture, + .dpy_gl_scanout_dmabuf =3D dbus_gl_scanout_dmabuf, + .dpy_gl_update =3D dbus_gl_scanout_update, +}; + +static void +dbus_display_console_init(DBusDisplayConsole *object) +{ + DBusDisplayConsole *ddc =3D DBUS_DISPLAY_CONSOLE(object); + + ddc->listeners =3D g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, g_object_unref); + ddc->dcl.ops =3D &dbus_console_dcl_ops; +} + +static void +dbus_display_console_dispose(GObject *object) +{ + DBusDisplayConsole *ddc =3D DBUS_DISPLAY_CONSOLE(object); + + unregister_displaychangelistener(&ddc->dcl); + g_clear_object(&ddc->iface_kbd); + g_clear_object(&ddc->iface); + g_clear_pointer(&ddc->listeners, g_hash_table_unref); + g_clear_pointer(&ddc->kbd, qkbd_state_free); + + G_OBJECT_CLASS(dbus_display_console_parent_class)->dispose(object); +} + +static void +dbus_display_console_class_init(DBusDisplayConsoleClass *klass) +{ + GObjectClass *gobject_class =3D G_OBJECT_CLASS(klass); + + gobject_class->dispose =3D dbus_display_console_dispose; +} + +static void +listener_vanished_cb(DBusDisplayListener *listener) +{ + DBusDisplayConsole *ddc =3D dbus_display_listener_get_console(listener= ); + const char *name =3D dbus_display_listener_get_bus_name(listener); + + trace_dbus_listener_vanished(name); + + g_hash_table_remove(ddc->listeners, name); + qkbd_state_lift_all_keys(ddc->kbd); +} + +static gboolean +dbus_console_set_ui_info(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint16 arg_width_mm, + guint16 arg_height_mm, + gint arg_xoff, + gint arg_yoff, + guint arg_width, + guint arg_height) +{ + QemuUIInfo info =3D { + .width_mm =3D arg_width_mm, + .height_mm =3D arg_height_mm, + .xoff =3D arg_xoff, + .yoff =3D arg_yoff, + .width =3D arg_width, + .height =3D arg_height, + }; + + if (!dpy_ui_info_supported(ddc->con)) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_UNSUPPORT= ED, + "SetUIInfo is not supported"= ); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + dpy_set_ui_info(ddc->con, &info, false); + qemu_dbus_display1_console_complete_set_uiinfo(ddc->iface, invocation); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_console_register_listener(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener) +{ + const char *sender =3D g_dbus_method_invocation_get_sender(invocation); + GDBusConnection *listener_conn; + g_autoptr(GError) err =3D NULL; + g_autoptr(GSocket) socket =3D NULL; + g_autoptr(GSocketConnection) socket_conn =3D NULL; + g_autofree char *guid =3D g_dbus_generate_guid(); + DBusDisplayListener *listener; + int fd; + + if (g_hash_table_contains(ddc->listeners, sender)) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "`%s` is already registered!", + sender); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + fd =3D g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener),= &err); + if (err) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't get peer fd: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + socket =3D g_socket_new_from_fd(fd, &err); + if (err) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't make a socket: %s", err->message); + close(fd); + return DBUS_METHOD_INVOCATION_HANDLED; + } + socket_conn =3D g_socket_connection_factory_create_connection(socket); + + qemu_dbus_display1_console_complete_register_listener( + ddc->iface, invocation, NULL); + + listener_conn =3D g_dbus_connection_new_sync( + G_IO_STREAM(socket_conn), + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, NULL, &err); + if (err) { + error_report("Failed to setup peer connection: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + listener =3D dbus_display_listener_new(sender, listener_conn, ddc); + if (!listener) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + + g_hash_table_insert(ddc->listeners, + (gpointer)dbus_display_listener_get_bus_name(liste= ner), + listener); + g_object_connect(listener_conn, + "swapped-signal::closed", listener_vanished_cb, liste= ner, + NULL); + + trace_dbus_registered_listener(sender); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_kbd_press(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint arg_keycode) +{ + QKeyCode qcode =3D qemu_input_key_number_to_qcode(arg_keycode); + + trace_dbus_kbd_press(arg_keycode); + + qkbd_state_key_event(ddc->kbd, qcode, true); + + qemu_dbus_display1_keyboard_complete_press(ddc->iface_kbd, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_kbd_release(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint arg_keycode) +{ + QKeyCode qcode =3D qemu_input_key_number_to_qcode(arg_keycode); + + trace_dbus_kbd_release(arg_keycode); + + qkbd_state_key_event(ddc->kbd, qcode, false); + + qemu_dbus_display1_keyboard_complete_release(ddc->iface_kbd, invocatio= n); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static void +dbus_kbd_qemu_leds_updated(void *data, int ledstate) +{ + DBusDisplayConsole *ddc =3D DBUS_DISPLAY_CONSOLE(data); + + qemu_dbus_display1_keyboard_set_modifiers(ddc->iface_kbd, ledstate); +} + +static gboolean +dbus_mouse_rel_motion(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + int dx, int dy) +{ + trace_dbus_mouse_rel_motion(dx, dy); + + if (qemu_input_is_absolute()) { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Mouse is not relative"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + qemu_input_queue_rel(ddc->con, INPUT_AXIS_X, dx); + qemu_input_queue_rel(ddc->con, INPUT_AXIS_Y, dy); + qemu_input_event_sync(); + + qemu_dbus_display1_mouse_complete_rel_motion(ddc->iface_mouse, + invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_mouse_set_pos(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint x, guint y) +{ + int width, height; + + trace_dbus_mouse_set_pos(x, y); + + if (!qemu_input_is_absolute()) { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Mouse is not absolute"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + width =3D qemu_console_get_width(ddc->con, 0); + height =3D qemu_console_get_height(ddc->con, 0); + if (x >=3D width || y >=3D height) { + g_dbus_method_invocation_return_error( + invocation, DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "Invalid mouse position"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + qemu_input_queue_abs(ddc->con, INPUT_AXIS_X, x, 0, width); + qemu_input_queue_abs(ddc->con, INPUT_AXIS_Y, y, 0, height); + qemu_input_event_sync(); + + qemu_dbus_display1_mouse_complete_set_abs_position(ddc->iface_mouse, + invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_mouse_press(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint button) +{ + trace_dbus_mouse_press(button); + + qemu_input_queue_btn(ddc->con, button, true); + qemu_input_event_sync(); + + qemu_dbus_display1_mouse_complete_press(ddc->iface_mouse, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_mouse_release(DBusDisplayConsole *ddc, + GDBusMethodInvocation *invocation, + guint button) +{ + trace_dbus_mouse_release(button); + + qemu_input_queue_btn(ddc->con, button, false); + qemu_input_event_sync(); + + qemu_dbus_display1_mouse_complete_release(ddc->iface_mouse, invocation= ); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static void +dbus_mouse_mode_change(Notifier *notify, void *data) +{ + DBusDisplayConsole *ddc =3D + container_of(notify, DBusDisplayConsole, mouse_mode_notifier); + + g_object_set(ddc->iface_mouse, + "is-absolute", qemu_input_is_absolute(), + NULL); +} + +int dbus_display_console_get_index(DBusDisplayConsole *ddc) +{ + return qemu_console_get_index(ddc->con); +} + +DBusDisplayConsole * +dbus_display_console_new(DBusDisplay *display, QemuConsole *con) +{ + g_autofree char *path =3D NULL; + g_autofree char *label =3D NULL; + char device_addr[256] =3D ""; + DBusDisplayConsole *ddc; + int idx; + + assert(display); + assert(con); + + label =3D qemu_console_get_label(con); + idx =3D qemu_console_get_index(con); + path =3D g_strdup_printf(DBUS_DISPLAY1_ROOT "/Console_%d", idx); + ddc =3D g_object_new(DBUS_DISPLAY_TYPE_CONSOLE, + "g-object-path", path, + NULL); + ddc->display =3D display; + ddc->con =3D con; + /* handle errors, and skip non graphics? */ + qemu_console_fill_device_address( + con, device_addr, sizeof(device_addr), NULL); + + ddc->iface =3D qemu_dbus_display1_console_skeleton_new(); + g_object_set(ddc->iface, + "label", label, + "type", qemu_console_is_graphic(con) ? "Graphic" : "Text", + "head", qemu_console_get_head(con), + "width", qemu_console_get_width(con, 0), + "height", qemu_console_get_height(con, 0), + "device-address", device_addr, + NULL); + g_object_connect(ddc->iface, + "swapped-signal::handle-register-listener", + dbus_console_register_listener, ddc, + "swapped-signal::handle-set-uiinfo", + dbus_console_set_ui_info, ddc, + NULL); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), + G_DBUS_INTERFACE_SKELETON(ddc->iface)); + + ddc->kbd =3D qkbd_state_init(con); + ddc->iface_kbd =3D qemu_dbus_display1_keyboard_skeleton_new(); + qemu_add_led_event_handler(dbus_kbd_qemu_leds_updated, ddc); + g_object_connect(ddc->iface_kbd, + "swapped-signal::handle-press", dbus_kbd_press, ddc, + "swapped-signal::handle-release", dbus_kbd_release, ddc, + NULL); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), + G_DBUS_INTERFACE_SKELETON(ddc->iface_kbd)); + + ddc->iface_mouse =3D qemu_dbus_display1_mouse_skeleton_new(); + g_object_connect(ddc->iface_mouse, + "swapped-signal::handle-set-abs-position", dbus_mouse_set_pos, ddc, + "swapped-signal::handle-rel-motion", dbus_mouse_rel_motion, ddc, + "swapped-signal::handle-press", dbus_mouse_press, ddc, + "swapped-signal::handle-release", dbus_mouse_release, ddc, + NULL); + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(ddc), + G_DBUS_INTERFACE_SKELETON(ddc->iface_mouse)); + + register_displaychangelistener(&ddc->dcl); + ddc->mouse_mode_notifier.notify =3D dbus_mouse_mode_change; + qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier); + + return ddc; +} diff --git a/ui/dbus-error.c b/ui/dbus-error.c new file mode 100644 index 0000000000..85a9194d57 --- /dev/null +++ b/ui/dbus-error.c @@ -0,0 +1,48 @@ +/* + * QEMU DBus display errors + * + * Copyright (c) 2021 Marc-Andr=C3=A9 Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "dbus.h" + +static const GDBusErrorEntry dbus_display_error_entries[] =3D { + { DBUS_DISPLAY_ERROR_FAILED, "org.qemu.Display1.Error.Failed" }, + { DBUS_DISPLAY_ERROR_INVALID, "org.qemu.Display1.Error.Invalid" }, + { DBUS_DISPLAY_ERROR_UNSUPPORTED, "org.qemu.Display1.Error.Unsupported= " }, +}; + +G_STATIC_ASSERT(G_N_ELEMENTS(dbus_display_error_entries) =3D=3D + DBUS_DISPLAY_N_ERRORS); + +GQuark +dbus_display_error_quark(void) +{ + static gsize quark; + + g_dbus_error_register_error_domain( + "dbus-display-error-quark", + &quark, + dbus_display_error_entries, + G_N_ELEMENTS(dbus_display_error_entries)); + + return (GQuark)quark; +} diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c new file mode 100644 index 0000000000..20094fc18a --- /dev/null +++ b/ui/dbus-listener.c @@ -0,0 +1,486 @@ +/* + * QEMU DBus display console + * + * Copyright (c) 2021 Marc-Andr=C3=A9 Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "sysemu/sysemu.h" +#include "dbus.h" +#include + +#include "ui/shader.h" +#include "ui/egl-helpers.h" +#include "ui/egl-context.h" +#include "trace.h" + +struct _DBusDisplayListener { + GObject parent; + + char *bus_name; + DBusDisplayConsole *console; + GDBusConnection *conn; + + QemuDBusDisplay1Listener *proxy; + + DisplayChangeListener dcl; + DisplaySurface *ds; + QemuGLShader *gls; + int gl_updates; +}; + +G_DEFINE_TYPE(DBusDisplayListener, dbus_display_listener, G_TYPE_OBJECT) + +static void dbus_update_gl_cb(GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err =3D NULL; + DBusDisplayListener *ddl =3D user_data; + + if (!qemu_dbus_display1_listener_call_update_dmabuf_finish(ddl->proxy, + res, &err))= { + error_report("Failed to call update: %s", err->message); + } + + graphic_hw_gl_block(ddl->dcl.con, false); + g_object_unref(ddl); +} + +static void dbus_call_update_gl(DBusDisplayListener *ddl, + int x, int y, int w, int h) +{ + graphic_hw_gl_block(ddl->dcl.con, true); + glFlush(); + qemu_dbus_display1_listener_call_update_dmabuf(ddl->proxy, + x, y, w, h, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, + dbus_update_gl_cb, + g_object_ref(ddl)); +} + +static void dbus_scanout_disable(DisplayChangeListener *dcl) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + ddl->ds =3D NULL; + qemu_dbus_display1_listener_call_disable( + ddl->proxy, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void dbus_scanout_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + g_autoptr(GError) err =3D NULL; + g_autoptr(GUnixFDList) fd_list =3D NULL; + + fd_list =3D g_unix_fd_list_new(); + if (g_unix_fd_list_append(fd_list, dmabuf->fd, &err) !=3D 0) { + error_report("Failed to setup dmabuf fdlist: %s", err->message); + return; + } + + qemu_dbus_display1_listener_call_scanout_dmabuf( + ddl->proxy, + g_variant_new_handle(0), + dmabuf->width, + dmabuf->height, + dmabuf->stride, + dmabuf->fourcc, + dmabuf->modifier, + dmabuf->y0_top, + G_DBUS_CALL_FLAGS_NONE, + -1, + fd_list, + NULL, NULL, NULL); +} + +static void dbus_scanout_texture(DisplayChangeListener *dcl, + uint32_t tex_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) +{ + QemuDmaBuf dmabuf =3D { + .width =3D backing_width, + .height =3D backing_height, + .y0_top =3D backing_y_0_top, + }; + + assert(tex_id); + dmabuf.fd =3D egl_get_fd_for_texture( + tex_id, (EGLint *)&dmabuf.stride, + (EGLint *)&dmabuf.fourcc, + &dmabuf.modifier); + if (dmabuf.fd < 0) { + error_report("%s: failed to get fd for texture", __func__); + return; + } + + dbus_scanout_dmabuf(dcl, &dmabuf); + close(dmabuf.fd); +} + +static void dbus_cursor_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf, bool have_hot, + uint32_t hot_x, uint32_t hot_y) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + DisplaySurface *ds; + GVariant *v_data =3D NULL; + egl_fb cursor_fb; + + if (!dmabuf) { + qemu_dbus_display1_listener_call_mouse_set( + ddl->proxy, 0, 0, false, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + return; + } + + egl_dmabuf_import_texture(dmabuf); + if (!dmabuf->texture) { + return; + } + egl_fb_setup_for_tex(&cursor_fb, dmabuf->width, dmabuf->height, + dmabuf->texture, false); + ds =3D qemu_create_displaysurface(dmabuf->width, dmabuf->height); + egl_fb_read(ds, &cursor_fb); + + v_data =3D g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + surface_data(ds), + surface_width(ds) * surface_height(ds) * 4, + TRUE, + (GDestroyNotify)qemu_free_displaysurface, + ds); + qemu_dbus_display1_listener_call_cursor_define( + ddl->proxy, + surface_width(ds), + surface_height(ds), + hot_x, + hot_y, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); +} + +static void dbus_cursor_position(DisplayChangeListener *dcl, + uint32_t pos_x, uint32_t pos_y) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + qemu_dbus_display1_listener_call_mouse_set( + ddl->proxy, pos_x, pos_y, true, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void dbus_release_dmabuf(DisplayChangeListener *dcl, + QemuDmaBuf *dmabuf) +{ + dbus_scanout_disable(dcl); +} + +static void dbus_scanout_update(DisplayChangeListener *dcl, + uint32_t x, uint32_t y, + uint32_t w, uint32_t h) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + dbus_call_update_gl(ddl, x, y, w, h); +} + +static void dbus_gl_refresh(DisplayChangeListener *dcl) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + graphic_hw_update(dcl->con); + + if (!ddl->ds || qemu_console_is_gl_blocked(ddl->dcl.con)) { + return; + } + + if (ddl->gl_updates) { + dbus_call_update_gl(ddl, 0, 0, + surface_width(ddl->ds), surface_height(ddl->ds= )); + ddl->gl_updates =3D 0; + } +} + +static void dbus_refresh(DisplayChangeListener *dcl) +{ + graphic_hw_update(dcl->con); +} + +static void dbus_gl_gfx_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + if (ddl->ds) { + surface_gl_update_texture(ddl->gls, ddl->ds, x, y, w, h); + } + + ddl->gl_updates++; +} + +static void dbus_gfx_update(DisplayChangeListener *dcl, + int x, int y, int w, int h) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + pixman_image_t *img; + GVariant *v_data; + size_t stride; + + assert(ddl->ds); + stride =3D w * DIV_ROUND_UP(PIXMAN_FORMAT_BPP(surface_format(ddl->ds))= , 8); + + trace_dbus_update(x, y, w, h); + + /* make a copy, since gvariant only handles linear data */ + img =3D pixman_image_create_bits(surface_format(ddl->ds), + w, h, NULL, stride); + pixman_image_composite(PIXMAN_OP_SRC, ddl->ds->image, NULL, img, + x, y, 0, 0, 0, 0, w, h); + + v_data =3D g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + pixman_image_get_data(img), + pixman_image_get_stride(img) * h, + TRUE, + (GDestroyNotify)pixman_image_unref, + img); + qemu_dbus_display1_listener_call_update(ddl->proxy, + x, y, w, h, pixman_image_get_stride(img), pixman_image_get_format(= img), + v_data, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +} + +static void dbus_gl_gfx_switch(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + if (ddl->ds) { + surface_gl_destroy_texture(ddl->gls, ddl->ds); + } + ddl->ds =3D new_surface; + if (ddl->ds) { + int width =3D surface_width(ddl->ds); + int height =3D surface_height(ddl->ds); + + surface_gl_create_texture(ddl->gls, ddl->ds); + /* TODO: lazy send dmabuf (there are unnecessary sent otherwise) */ + dbus_scanout_texture(&ddl->dcl, ddl->ds->texture, false, + width, height, 0, 0, width, height); + } +} + +static void dbus_gfx_switch(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + GVariant *v_data =3D NULL; + + ddl->ds =3D new_surface; + if (!ddl->ds) { + /* why not call disable instead? */ + return; + } + + v_data =3D g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + surface_data(ddl->ds), + surface_stride(ddl->ds) * surface_height(ddl->ds), + TRUE, + (GDestroyNotify)pixman_image_unref, + pixman_image_ref(ddl->ds->image)); + qemu_dbus_display1_listener_call_scanout(ddl->proxy, + surface_width(ddl->ds), + surface_height(ddl->ds), + surface_stride(ddl->ds), + surface_format(ddl->ds), + v_data, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +} + +static void dbus_mouse_set(DisplayChangeListener *dcl, + int x, int y, int on) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + + qemu_dbus_display1_listener_call_mouse_set( + ddl->proxy, x, y, on, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL= ); +} + +static void dbus_cursor_define(DisplayChangeListener *dcl, + QEMUCursor *c) +{ + DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); + GVariant *v_data =3D NULL; + + cursor_get(c); + v_data =3D g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + c->data, + c->width * c->height * 4, + TRUE, + (GDestroyNotify)cursor_put, + c); + + qemu_dbus_display1_listener_call_cursor_define( + ddl->proxy, + c->width, + c->height, + c->hot_x, + c->hot_y, + v_data, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); +} + +const DisplayChangeListenerOps dbus_gl_dcl_ops =3D { + .dpy_name =3D "dbus-gl", + .dpy_gfx_update =3D dbus_gl_gfx_update, + .dpy_gfx_switch =3D dbus_gl_gfx_switch, + .dpy_gfx_check_format =3D console_gl_check_format, + .dpy_refresh =3D dbus_gl_refresh, + .dpy_mouse_set =3D dbus_mouse_set, + .dpy_cursor_define =3D dbus_cursor_define, + + .dpy_gl_scanout_disable =3D dbus_scanout_disable, + .dpy_gl_scanout_texture =3D dbus_scanout_texture, + .dpy_gl_scanout_dmabuf =3D dbus_scanout_dmabuf, + .dpy_gl_cursor_dmabuf =3D dbus_cursor_dmabuf, + .dpy_gl_cursor_position =3D dbus_cursor_position, + .dpy_gl_release_dmabuf =3D dbus_release_dmabuf, + .dpy_gl_update =3D dbus_scanout_update, +}; + +const DisplayChangeListenerOps dbus_dcl_ops =3D { + .dpy_name =3D "dbus", + .dpy_gfx_update =3D dbus_gfx_update, + .dpy_gfx_switch =3D dbus_gfx_switch, + .dpy_refresh =3D dbus_refresh, + .dpy_mouse_set =3D dbus_mouse_set, + .dpy_cursor_define =3D dbus_cursor_define, +}; + +static void +dbus_display_listener_dispose(GObject *object) +{ + DBusDisplayListener *ddl =3D DBUS_DISPLAY_LISTENER(object); + + unregister_displaychangelistener(&ddl->dcl); + g_clear_object(&ddl->conn); + g_clear_pointer(&ddl->bus_name, g_free); + g_clear_object(&ddl->proxy); + g_clear_pointer(&ddl->gls, qemu_gl_fini_shader); + + G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object); +} + +static void +dbus_display_listener_constructed(GObject *object) +{ + DBusDisplayListener *ddl =3D DBUS_DISPLAY_LISTENER(object); + + if (display_opengl) { + ddl->gls =3D qemu_gl_init_shader(); + ddl->dcl.ops =3D &dbus_gl_dcl_ops; + } else { + ddl->dcl.ops =3D &dbus_dcl_ops; + } + + G_OBJECT_CLASS(dbus_display_listener_parent_class)->constructed(object= ); +} + +static void +dbus_display_listener_class_init(DBusDisplayListenerClass *klass) +{ + GObjectClass *object_class =3D G_OBJECT_CLASS(klass); + + object_class->dispose =3D dbus_display_listener_dispose; + object_class->constructed =3D dbus_display_listener_constructed; +} + +static void +dbus_display_listener_init(DBusDisplayListener *ddl) +{ +} + +const char * +dbus_display_listener_get_bus_name(DBusDisplayListener *ddl) +{ + return ddl->bus_name; +} + +DBusDisplayConsole * +dbus_display_listener_get_console(DBusDisplayListener *ddl) +{ + return ddl->console; +} + +DBusDisplayListener * +dbus_display_listener_new(const char *bus_name, + GDBusConnection *conn, + DBusDisplayConsole *console) +{ + DBusDisplayListener *ddl; + QemuConsole *con; + g_autoptr(GError) err =3D NULL; + + ddl =3D g_object_new(DBUS_DISPLAY_TYPE_LISTENER, NULL); + ddl->proxy =3D + qemu_dbus_display1_listener_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/Listener", + NULL, + &err); + if (!ddl->proxy) { + error_report("Failed to setup proxy: %s", err->message); + g_object_unref(conn); + g_object_unref(ddl); + return NULL; + } + + ddl->bus_name =3D g_strdup(bus_name); + ddl->conn =3D conn; + ddl->console =3D console; + + con =3D qemu_console_lookup_by_index(dbus_display_console_get_index(co= nsole)); + assert(con); + ddl->dcl.con =3D con; + register_displaychangelistener(&ddl->dcl); + + return ddl; +} diff --git a/ui/dbus.c b/ui/dbus.c new file mode 100644 index 0000000000..12da8ffe31 --- /dev/null +++ b/ui/dbus.c @@ -0,0 +1,262 @@ +/* + * QEMU DBus display + * + * Copyright (c) 2021 Marc-Andr=C3=A9 Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "qemu/dbus.h" +#include "qemu/option.h" +#include "qom/object_interfaces.h" +#include "sysemu/sysemu.h" +#include "ui/egl-helpers.h" +#include "ui/egl-context.h" +#include "qapi/error.h" +#include "trace.h" + +#include "dbus.h" + +static QEMUGLContext dbus_create_context(DisplayGLCtx *dgc, + QEMUGLParams *params) +{ + eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + qemu_egl_rn_ctx); + return qemu_egl_create_context(dgc, params); +} + +static const DisplayGLCtxOps dbus_gl_ops =3D { + .compatible_dcl =3D &dbus_gl_dcl_ops, + .dpy_gl_ctx_create =3D dbus_create_context, + .dpy_gl_ctx_destroy =3D qemu_egl_destroy_context, + .dpy_gl_ctx_make_current =3D qemu_egl_make_context_current, +}; + +static void +dbus_display_init(Object *o) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + g_autoptr(GDBusObjectSkeleton) vm =3D NULL; + + dd->glctx.ops =3D &dbus_gl_ops; + dd->iface =3D qemu_dbus_display1_vm_skeleton_new(); + dd->consoles =3D g_ptr_array_new_with_free_func(g_object_unref); + + dd->server =3D g_dbus_object_manager_server_new(DBUS_DISPLAY1_ROOT); + + vm =3D g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT "/VM"); + g_dbus_object_skeleton_add_interface( + vm, G_DBUS_INTERFACE_SKELETON(dd->iface)); + g_dbus_object_manager_server_export(dd->server, vm); +} + +static void +dbus_display_finalize(Object *o) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + g_clear_object(&dd->server); + g_clear_pointer(&dd->consoles, g_ptr_array_unref); + g_clear_object(&dd->bus); + g_clear_object(&dd->iface); + g_free(dd->dbus_addr); +} + +static bool +dbus_display_add_console(DBusDisplay *dd, int idx, Error **errp) +{ + QemuConsole *con; + DBusDisplayConsole *dbus_console; + + con =3D qemu_console_lookup_by_index(idx); + assert(con); + + if (qemu_console_is_graphic(con) && + dd->gl_mode !=3D DISPLAYGL_MODE_OFF) { + qemu_console_set_display_gl_ctx(con, &dd->glctx); + } + + dbus_console =3D dbus_display_console_new(dd, con); + g_ptr_array_insert(dd->consoles, idx, dbus_console); + g_dbus_object_manager_server_export(dd->server, + G_DBUS_OBJECT_SKELETON(dbus_consol= e)); + return true; +} + +static void +dbus_display_complete(UserCreatable *uc, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(uc); + g_autoptr(GError) err =3D NULL; + g_autofree char *uuid =3D qemu_uuid_unparse_strdup(&qemu_uuid); + g_autoptr(GArray) consoles =3D NULL; + GVariant *console_ids; + int idx; + + if (!object_resolve_path_type("", TYPE_DBUS_DISPLAY, NULL)) { + error_setg(errp, "There is already an instance of %s", + TYPE_DBUS_DISPLAY); + return; + } + + if (dd->dbus_addr && *dd->dbus_addr) { + dd->bus =3D g_dbus_connection_new_for_address_sync(dd->dbus_addr, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, NULL, &err); + } else { + dd->bus =3D g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err); + } + if (err) { + error_setg(errp, "failed to connect to DBus: %s", err->message); + return; + } + + + consoles =3D g_array_new(FALSE, FALSE, sizeof(guint32)); + for (idx =3D 0;; idx++) { + if (!qemu_console_lookup_by_index(idx)) { + break; + } + if (!dbus_display_add_console(dd, idx, errp)) { + return; + } + g_array_append_val(consoles, idx); + } + + console_ids =3D g_variant_new_from_data( + G_VARIANT_TYPE("au"), + consoles->data, consoles->len * sizeof(guint32), TRUE, + (GDestroyNotify)g_array_unref, consoles); + g_steal_pointer(&consoles); + g_object_set(dd->iface, + "name", qemu_name ?: "QEMU " QEMU_VERSION, + "uuid", uuid, + "console-ids", console_ids, + NULL); + + g_dbus_object_manager_server_set_connection(dd->server, dd->bus); + g_bus_own_name_on_connection(dd->bus, "org.qemu", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL); +} + +static char * +get_dbus_addr(Object *o, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + return g_strdup(dd->dbus_addr); +} + +static void +set_dbus_addr(Object *o, const char *str, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + g_free(dd->dbus_addr); + dd->dbus_addr =3D g_strdup(str); +} + +static int +get_gl_mode(Object *o, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + return dd->gl_mode; +} + +static void +set_gl_mode(Object *o, int val, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + dd->gl_mode =3D val; +} + +static void +dbus_display_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); + + ucc->complete =3D dbus_display_complete; + object_class_property_add_str(oc, "addr", get_dbus_addr, set_dbus_addr= ); + object_class_property_add_enum(oc, "gl-mode", + "DisplayGLMode", &DisplayGLMode_lookup, + get_gl_mode, set_gl_mode); +} + +static void +early_dbus_init(DisplayOptions *opts) +{ + DisplayGLMode mode =3D opts->has_gl ? opts->gl : DISPLAYGL_MODE_OFF; + + if (mode !=3D DISPLAYGL_MODE_OFF) { + if (egl_rendernode_init(opts->u.dbus.rendernode, mode) < 0) { + error_report("dbus: render node init failed"); + exit(1); + } + + display_opengl =3D 1; + } +} + +static void +dbus_init(DisplayState *ds, DisplayOptions *opts) +{ + DisplayGLMode mode =3D opts->has_gl ? opts->gl : DISPLAYGL_MODE_OFF; + + object_new_with_props(TYPE_DBUS_DISPLAY, + object_get_objects_root(), + "dbus-display", &error_fatal, + "addr", opts->u.dbus.addr ?: "", + "gl-mode", DisplayGLMode_str(mode), + NULL); +} + +static const TypeInfo dbus_display_info =3D { + .name =3D TYPE_DBUS_DISPLAY, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(DBusDisplay), + .instance_init =3D dbus_display_init, + .instance_finalize =3D dbus_display_finalize, + .class_init =3D dbus_display_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static QemuDisplay qemu_display_dbus =3D { + .type =3D DISPLAY_TYPE_DBUS, + .early_init =3D early_dbus_init, + .init =3D dbus_init, +}; + +static void register_dbus(void) +{ + type_register_static(&dbus_display_info); + qemu_display_register(&qemu_display_dbus); +} + +type_init(register_dbus); + +#ifdef CONFIG_OPENGL +module_dep("ui-opengl"); +#endif diff --git a/meson_options.txt b/meson_options.txt index b064b0b46c..0a6abb311e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -49,6 +49,8 @@ option('cfi_debug', type: 'boolean', value: 'false', description: 'Verbose errors in case of CFI violation') option('multiprocess', type: 'feature', value: 'auto', description: 'Out of process device emulation support') +option('dbus_display', type: 'feature', value: 'auto', + description: '-display dbus support') =20 option('attr', type : 'feature', value : 'auto', description: 'attr/xattr support') diff --git a/qemu-options.hx b/qemu-options.hx index 5f375bbfa6..1a927458e6 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1862,6 +1862,10 @@ DEF("display", HAS_ARG, QEMU_OPTION_display, #endif #if defined(CONFIG_OPENGL) "-display egl-headless[,rendernode=3D]\n" +#endif +#if defined(CONFIG_DBUS_DISPLAY) + "-display dbus[,addr=3D]\n" + " [,gl=3Don|core|es|off][,rendernode=3D]\n" #endif "-display none\n" " select display backend type\n" @@ -1889,6 +1893,17 @@ SRST application. The Spice server will redirect the serial consoles and QEMU monitors. (Since 4.0) =20 + ``dbus`` + Export the display over D-Bus interfaces. (Since 6.2) + + The connection is registered with the "org.qemu" name (and queued = when + already owned). + + ``addr=3D`` : D-Bus bus address to connect to. + + ``gl=3Don|off|core|es`` : Use OpenGL for rendering (the D-interfac= e will + share framebuffers with DMABUF file descriptors). + ``sdl`` Display video output via SDL (usually in a separate graphics window; see the SDL documentation for other possibilities). diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index e69de29bb2..0f0ae92e4d 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/meson.build b/ui/meson.build index a9df5b911e..6270aa768b 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -65,6 +65,28 @@ if config_host.has_key('CONFIG_OPENGL') and gbm.found() ui_modules +=3D {'egl-headless' : egl_headless_ss} endif =20 +if dbus_display + dbus_ss =3D ss.source_set() + dbus_display1 =3D custom_target('dbus-display gdbus-codegen', + output: ['dbus-display1.h', 'dbus-display1= .c'], + input: files('dbus-display1.xml'), + command: [config_host['GDBUS_CODEGEN'], + '@INPUT@', + '--glib-min-required', '2.64', + '--output-directory', meson.curr= ent_build_dir(), + '--interface-prefix', 'org.qemu.= ', + '--c-namespace', 'QemuDBus', + '--generate-c-code', '@BASENAME@= ']) + dbus_ss.add(when: [gio, pixman, opengl, 'CONFIG_GIO'], + if_true: [files( + 'dbus-console.c', + 'dbus-error.c', + 'dbus-listener.c', + 'dbus.c', + ), dbus_display1]) + ui_modules +=3D {'dbus' : dbus_ss} +endif + if gtk.found() softmmu_ss.add(when: 'CONFIG_WIN32', if_true: files('win32-kbd-hook.c')) =20 diff --git a/ui/trace-events b/ui/trace-events index e832c3e365..b1ae30159a 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -136,3 +136,14 @@ vdagent_peer_cap(const char *name) "cap %s" vdagent_cb_grab_selection(const char *name) "selection %s" vdagent_cb_grab_type(const char *name) "type %s" vdagent_cb_serial_discard(uint32_t current, uint32_t received) "current=3D= %u, received=3D%u" + +# dbus.c +dbus_registered_listener(const char *bus_name) "peer %s" +dbus_listener_vanished(const char *bus_name) "peer %s" +dbus_kbd_press(unsigned int keycode) "keycode %u" +dbus_kbd_release(unsigned int keycode) "keycode %u" +dbus_mouse_press(unsigned int button) "button %u" +dbus_mouse_release(unsigned int button) "button %u" +dbus_mouse_set_pos(unsigned int x, unsigned int y) "x=3D%u, y=3D%u" +dbus_mouse_rel_motion(int dx, int dy) "dx=3D%d, dy=3D%d" +dbus_update(int x, int y, int w, int h) "x=3D%d, y=3D%d, w=3D%d, h=3D%d" --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381500981918.47674270361597; Sat, 9 Oct 2021 14:30:09 -0700 (PDT) Received: from localhost ([::1]:40450 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJuy-0003Uw-CW for importer@patchew.org; Sat, 09 Oct 2021 17:30:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38442) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJgS-0007st-Ic for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:15:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:55231) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJgQ-0000SC-3w for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:15:08 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-307-3gA0U_a7PyG6Sc_g0eW9aw-1; Sat, 09 Oct 2021 17:15:03 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9FE731005E4D for ; Sat, 9 Oct 2021 21:15:02 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 45C115D9D3; Sat, 9 Oct 2021 21:14:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814104; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rkVh0AN+w9Ii+TsDFvYEr2ubaOfCPuSF5lQ4wYtThbs=; b=gB5OgL4xNuWEKvSNa7uUjESF1kzHAkI8IfZaLrYCtKoYqyYVgPARGzeGJJKdP3AVJTm3AD 115B/SK9Uaj5X2M5N9IJXN+5N3mFAihyzxZo0oia3vsmCPfxK1FNuP/VW9WFH4Prp694F2 LN+Uoo9nICxYI2utkMxdxM4pMkWtmpo= X-MC-Unique: 3gA0U_a7PyG6Sc_g0eW9aw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 27/37] ui/dbus: add p2p=on/off option Date: Sun, 10 Oct 2021 01:08:28 +0400 Message-Id: <20211009210838.2219430-28-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815011327100001 From: Marc-Andr=C3=A9 Lureau Add an option to use direct connections instead of via the bus. Clients are accepted via QMP add_client. This allows to provide the D-Bus display without a bus. It also simplifies the testing setup (some CI have issues to setup a D-Bus bus in a container). Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- qapi/misc.json | 4 +- qapi/ui.json | 6 ++- include/qemu/cutils.h | 5 ++ include/ui/dbus-display.h | 17 +++++++ include/ui/dbus-module.h | 11 ++++ ui/dbus.h | 2 + monitor/qmp-cmds.c | 13 +++++ ui/dbus-console.c | 2 +- ui/dbus-listener.c | 2 +- ui/dbus-module.c | 35 +++++++++++++ ui/dbus.c | 104 ++++++++++++++++++++++++++++++++++++-- qemu-options.hx | 2 + ui/meson.build | 3 ++ 13 files changed, 196 insertions(+), 10 deletions(-) create mode 100644 include/ui/dbus-display.h create mode 100644 include/ui/dbus-module.h create mode 100644 ui/dbus-module.c diff --git a/qapi/misc.json b/qapi/misc.json index 5c2ca3b556..887bcf54bb 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -14,8 +14,8 @@ # Allow client connections for VNC, Spice and socket based # character devices to be passed in to QEMU via SCM_RIGHTS. # -# @protocol: protocol name. Valid names are "vnc", "spice" or the -# name of a character device (eg. from -chardev id=3DXXXX) +# @protocol: protocol name. Valid names are "vnc", "spice", "@dbus-display= " or +# the name of a character device (eg. from -chardev id=3DXXXX) # # @fdname: file descriptor name previously passed via 'getfd' command # diff --git a/qapi/ui.json b/qapi/ui.json index 5ca604bd90..f23d012cb8 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1131,12 +1131,16 @@ # @rendernode: Which DRM render node should be used. Default is the first # available node on the host. # +# @p2p: Whether to use peer-to-peer connections (accepted through +# ``add_client``). +# # Since: 6.2 # ## { 'struct' : 'DisplayDBus', 'data' : { '*rendernode' : 'str', - '*addr': 'str' } } + '*addr': 'str', + '*p2p': 'bool' } } =20 ## # @DisplayGLMode: diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h index 986ed8e15f..320543950c 100644 --- a/include/qemu/cutils.h +++ b/include/qemu/cutils.h @@ -209,4 +209,9 @@ int qemu_pstrcmp0(const char **str1, const char **str2); */ char *get_relocated_path(const char *dir); =20 +static inline const char *yes_no(bool b) +{ + return b ? "yes" : "no"; +} + #endif diff --git a/include/ui/dbus-display.h b/include/ui/dbus-display.h new file mode 100644 index 0000000000..88f153c237 --- /dev/null +++ b/include/ui/dbus-display.h @@ -0,0 +1,17 @@ +#ifndef DBUS_DISPLAY_H_ +#define DBUS_DISPLAY_H_ + +#include "qapi/error.h" +#include "ui/dbus-module.h" + +static inline bool qemu_using_dbus_display(Error **errp) +{ + if (!using_dbus_display) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE, + "D-Bus display is not in use"); + return false; + } + return true; +} + +#endif /* DBUS_DISPLAY_H_ */ diff --git a/include/ui/dbus-module.h b/include/ui/dbus-module.h new file mode 100644 index 0000000000..ace4a17a5c --- /dev/null +++ b/include/ui/dbus-module.h @@ -0,0 +1,11 @@ +#ifndef DBUS_MODULE_H_ +#define DBUS_MODULE_H_ + +struct QemuDBusDisplayOps { + bool (*add_client)(int csock, Error **errp); +}; + +extern int using_dbus_display; +extern struct QemuDBusDisplayOps qemu_dbus_display; + +#endif /* DBUS_MODULE_H_*/ diff --git a/ui/dbus.h b/ui/dbus.h index d3c9598dd1..4698d32463 100644 --- a/ui/dbus.h +++ b/ui/dbus.h @@ -34,6 +34,7 @@ struct DBusDisplay { Object parent; =20 DisplayGLMode gl_mode; + bool p2p; char *dbus_addr; DisplayGLCtx glctx; =20 @@ -41,6 +42,7 @@ struct DBusDisplay { GDBusObjectManagerServer *server; QemuDBusDisplay1VM *iface; GPtrArray *consoles; + GCancellable *add_client_cancellable; }; =20 #define TYPE_DBUS_DISPLAY "dbus-display" diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 5c0d5e116b..aa6b012313 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -24,6 +24,7 @@ #include "chardev/char.h" #include "ui/qemu-spice.h" #include "ui/console.h" +#include "ui/dbus-display.h" #include "sysemu/kvm.h" #include "sysemu/runstate.h" #include "sysemu/runstate-action.h" @@ -281,6 +282,18 @@ void qmp_add_client(const char *protocol, const char *= fdname, skipauth =3D has_skipauth ? skipauth : false; vnc_display_add_client(NULL, fd, skipauth); return; +#endif +#ifdef CONFIG_DBUS_DISPLAY + } else if (strcmp(protocol, "@dbus-display") =3D=3D 0) { + if (!qemu_using_dbus_display(errp)) { + close(fd); + return; + } + if (!qemu_dbus_display.add_client(fd, errp)) { + close(fd); + return; + } + return; #endif } else if ((s =3D qemu_chr_find(protocol)) !=3D NULL) { if (qemu_chr_add_client(s, fd) < 0) { diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 1ccf638c10..e062f721d7 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -219,7 +219,7 @@ dbus_console_register_listener(DBusDisplayConsole *ddc, DBusDisplayListener *listener; int fd; =20 - if (g_hash_table_contains(ddc->listeners, sender)) { + if (sender && g_hash_table_contains(ddc->listeners, sender)) { g_dbus_method_invocation_return_error( invocation, DBUS_DISPLAY_ERROR, diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 20094fc18a..81c119b13a 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -440,7 +440,7 @@ dbus_display_listener_init(DBusDisplayListener *ddl) const char * dbus_display_listener_get_bus_name(DBusDisplayListener *ddl) { - return ddl->bus_name; + return ddl->bus_name ?: "p2p"; } =20 DBusDisplayConsole * diff --git a/ui/dbus-module.c b/ui/dbus-module.c new file mode 100644 index 0000000000..c8771fe48c --- /dev/null +++ b/ui/dbus-module.c @@ -0,0 +1,35 @@ +/* + * D-Bus module support. + * + * Copyright (C) 2021 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "ui/dbus-module.h" + +int using_dbus_display; + +static bool +qemu_dbus_display_add_client(int csock, Error **errp) +{ + error_setg(errp, "D-Bus display isn't enabled"); + return false; +} + +struct QemuDBusDisplayOps qemu_dbus_display =3D { + .add_client =3D qemu_dbus_display_add_client, +}; diff --git a/ui/dbus.c b/ui/dbus.c index 12da8ffe31..56e284fb97 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -22,10 +22,12 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "qemu/dbus.h" #include "qemu/option.h" #include "qom/object_interfaces.h" #include "sysemu/sysemu.h" +#include "ui/dbus-module.h" #include "ui/egl-helpers.h" #include "ui/egl-context.h" #include "qapi/error.h" @@ -33,6 +35,8 @@ =20 #include "dbus.h" =20 +static DBusDisplay *dbus_display; + static QEMUGLContext dbus_create_context(DisplayGLCtx *dgc, QEMUGLParams *params) { @@ -73,9 +77,14 @@ dbus_display_finalize(Object *o) =20 g_clear_object(&dd->server); g_clear_pointer(&dd->consoles, g_ptr_array_unref); + if (dd->add_client_cancellable) { + g_cancellable_cancel(dd->add_client_cancellable); + } + g_clear_object(&dd->add_client_cancellable); g_clear_object(&dd->bus); g_clear_object(&dd->iface); g_free(dd->dbus_addr); + dbus_display =3D NULL; } =20 static bool @@ -115,7 +124,10 @@ dbus_display_complete(UserCreatable *uc, Error **errp) return; } =20 - if (dd->dbus_addr && *dd->dbus_addr) { + if (dd->p2p) { + /* wait for dbus_display_add_client() */ + dbus_display =3D dd; + } else if (dd->dbus_addr && *dd->dbus_addr) { dd->bus =3D g_dbus_connection_new_for_address_sync(dd->dbus_addr, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, @@ -151,10 +163,80 @@ dbus_display_complete(UserCreatable *uc, Error **errp) "console-ids", console_ids, NULL); =20 - g_dbus_object_manager_server_set_connection(dd->server, dd->bus); - g_bus_own_name_on_connection(dd->bus, "org.qemu", - G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL); + if (dd->bus) { + g_dbus_object_manager_server_set_connection(dd->server, dd->bus); + g_bus_own_name_on_connection(dd->bus, "org.qemu", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL); + } +} + +static void +dbus_display_add_client_ready(GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err =3D NULL; + g_autoptr(GDBusConnection) conn =3D NULL; + + g_clear_object(&dbus_display->add_client_cancellable); + + conn =3D g_dbus_connection_new_finish(res, &err); + if (!conn) { + error_printf("Failed to accept D-Bus client: %s", err->message); + } + + g_dbus_object_manager_server_set_connection(dbus_display->server, conn= ); +} + + +static bool +dbus_display_add_client(int csock, Error **errp) +{ + g_autoptr(GError) err =3D NULL; + g_autoptr(GSocket) socket =3D NULL; + g_autoptr(GSocketConnection) conn =3D NULL; + g_autofree char *guid =3D g_dbus_generate_guid(); + + if (dbus_display->add_client_cancellable) { + g_cancellable_cancel(dbus_display->add_client_cancellable); + } + + socket =3D g_socket_new_from_fd(csock, &err); + if (!socket) { + error_setg(errp, "Failed to setup D-Bus socket: %s", err->message); + return false; + } + + conn =3D g_socket_connection_factory_create_connection(socket); + + dbus_display->add_client_cancellable =3D g_cancellable_new(); + + g_dbus_connection_new(G_IO_STREAM(conn), + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, + dbus_display->add_client_cancellable, + dbus_display_add_client_ready, + NULL); + + return true; +} + +static bool +get_dbus_p2p(Object *o, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + return dd->p2p; +} + +static void +set_dbus_p2p(Object *o, bool p2p, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + dd->p2p =3D p2p; } =20 static char * @@ -196,6 +278,7 @@ dbus_display_class_init(ObjectClass *oc, void *data) UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); =20 ucc->complete =3D dbus_display_complete; + object_class_property_add_bool(oc, "p2p", get_dbus_p2p, set_dbus_p2p); object_class_property_add_str(oc, "addr", get_dbus_addr, set_dbus_addr= ); object_class_property_add_enum(oc, "gl-mode", "DisplayGLMode", &DisplayGLMode_lookup, @@ -222,11 +305,19 @@ dbus_init(DisplayState *ds, DisplayOptions *opts) { DisplayGLMode mode =3D opts->has_gl ? opts->gl : DISPLAYGL_MODE_OFF; =20 + if (opts->u.dbus.addr && opts->u.dbus.p2p) { + error_report("dbus: can't accept both addr=3DX and p2p=3Dyes optio= ns"); + exit(1); + } + + using_dbus_display =3D 1; + object_new_with_props(TYPE_DBUS_DISPLAY, object_get_objects_root(), "dbus-display", &error_fatal, "addr", opts->u.dbus.addr ?: "", "gl-mode", DisplayGLMode_str(mode), + "p2p", yes_no(opts->u.dbus.p2p), NULL); } =20 @@ -251,6 +342,9 @@ static QemuDisplay qemu_display_dbus =3D { =20 static void register_dbus(void) { + qemu_dbus_display =3D (struct QemuDBusDisplayOps) { + .add_client =3D dbus_display_add_client, + }; type_register_static(&dbus_display_info); qemu_display_register(&qemu_display_dbus); } diff --git a/qemu-options.hx b/qemu-options.hx index 1a927458e6..b3352a7fbc 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1901,6 +1901,8 @@ SRST =20 ``addr=3D`` : D-Bus bus address to connect to. =20 + ``p2p=3Dyes|no`` : Use peer-to-peer connection, accepted via QMP `= `add_client``. + ``gl=3Don|off|core|es`` : Use OpenGL for rendering (the D-interfac= e will share framebuffers with DMABUF file descriptors). =20 diff --git a/ui/meson.build b/ui/meson.build index 6270aa768b..80f21704ad 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -14,6 +14,9 @@ softmmu_ss.add(files( 'qemu-pixman.c', 'util.c', )) +if dbus_display + softmmu_ss.add(files('dbus-module.c')) +endif softmmu_ss.add([spice_headers, files('spice-module.c')]) softmmu_ss.add(when: spice_protocol, if_true: files('vdagent.c')) =20 --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381511589747.57394164539039; Sat, 9 Oct 2021 14:31:55 -0700 (PDT) Received: from localhost ([::1]:44394 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJwf-0006Hr-8T for importer@patchew.org; Sat, 09 Oct 2021 17:31:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38476) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJgy-0008FR-2o for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:15:40 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:24732) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJgw-0000er-Hu for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:15:39 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-240-k9HYE73KM16Qd4Q-M4zqNQ-1; Sat, 09 Oct 2021 17:15:36 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 07B5F1005E68 for ; Sat, 9 Oct 2021 21:15:36 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1E15D5C1B4; Sat, 9 Oct 2021 21:15:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814138; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PRkXeSP6ETCUdxwQfTaFba7yDVJU9soHf1hHPoFa6yg=; b=DJa109zitw+aD18ePkE/3BE55Gf/gYEo0Is5yLsHpkO+aevvOWlo0jMk9hnS6wBI/mDVny PEM1paZn7LlSKYj8Qu1dw+YKAZkccMRC6VAP3+y33VTkPISlqWxQOCwuVSjiK4Z9J3esm4 9E+8VwSs1UVwDyplF6PJs6mB8ljJWog= X-MC-Unique: k9HYE73KM16Qd4Q-M4zqNQ-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 28/37] tests/qtests: add qtest_qmp_add_client() Date: Sun, 10 Oct 2021 01:08:29 +0400 Message-Id: <20211009210838.2219430-29-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815116977100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- tests/qtest/libqos/libqtest.h | 10 ++++++++++ tests/qtest/libqtest.c | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/tests/qtest/libqos/libqtest.h b/tests/qtest/libqos/libqtest.h index a68dcd79d4..9e5f9118f3 100644 --- a/tests/qtest/libqos/libqtest.h +++ b/tests/qtest/libqos/libqtest.h @@ -728,6 +728,16 @@ void qtest_qmp_device_add_qdict(QTestState *qts, const= char *drv, void qtest_qmp_device_add(QTestState *qts, const char *driver, const char = *id, const char *fmt, ...) GCC_FMT_ATTR(4, 5); =20 +/** + * qtest_qmp_add_client: + * @qts: QTestState instance to operate on + * @protocol: the protocol to add to + * @fd: the client file-descriptor + * + * Call QMP `getfd` followed by `add_client` with the given @fd. + */ +void qtest_qmp_add_client(QTestState *qts, const char *protocol, int fd); + /** * qtest_qmp_device_del: * @qts: QTestState instance to operate on diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 73f6b977a6..c8ea5499a0 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -1367,6 +1367,25 @@ void qtest_qmp_device_add(QTestState *qts, const cha= r *driver, const char *id, qobject_unref(args); } =20 +void qtest_qmp_add_client(QTestState *qts, const char *protocol, int fd) +{ + QDict *resp; + + resp =3D qtest_qmp_fds(qts, &fd, 1, "{'execute': 'getfd'," + "'arguments': {'fdname': 'fdname'}}"); + g_assert(resp); + g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events = */ + g_assert(!qdict_haskey(resp, "error")); + qobject_unref(resp); + + resp =3D qtest_qmp( + qts, "{'execute': 'add_client'," + "'arguments': {'protocol': %s, 'fdname': 'fdname'}}", protocol); + g_assert(resp); + g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events = */ + g_assert(!qdict_haskey(resp, "error")); + qobject_unref(resp); +} =20 /* * Generic hot-unplugging test via the device_del QMP command. --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633815234779710.1599993696752; Sat, 9 Oct 2021 14:33:54 -0700 (PDT) Received: from localhost ([::1]:50348 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJyX-0001yK-Sk for importer@patchew.org; Sat, 09 Oct 2021 17:33:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38552) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJhJ-0000jD-Ld for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:16:01 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32444) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJhH-0000hu-JX for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:16:01 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-241-2nvpRerePo2gd0sxw_6LEw-1; Sat, 09 Oct 2021 17:15:56 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 798588042F0 for ; Sat, 9 Oct 2021 21:15:55 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1BCF160C17; Sat, 9 Oct 2021 21:15:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814157; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qPOAj8G4/SYGYNv2Esr+9UYa8TpRMpc4BGEYdmpzQgo=; b=ZOB6O1wMLj9Qnk+s1aVc+tVM+2eMr+6NUaj6J1mytKUxneX9dL5PMO14d/CII3u9oFrR+p RLYiXmow8RCplTbNgnwSSVEaX2WGINga4PEXn6wCppVTUipAAeOpNd7EoFJR2pEs7gfZ9s U6M07RPqlu4iRX6i0Nxn+j1RJN2xL8A= X-MC-Unique: 2nvpRerePo2gd0sxw_6LEw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 29/37] tests: start dbus-display-test Date: Sun, 10 Oct 2021 01:08:30 +0400 Message-Id: <20211009210838.2219430-30-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815236709100001 From: Marc-Andr=C3=A9 Lureau Cover basic display interface usage. More cases to be added to cover disconnections, multiple connections, corner cases. At this point, they would be better written in Rust or Python though. The proxy also covers reading the properties, since they are automatically loaded at creation. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- tests/qtest/dbus-display-test.c | 281 ++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 8 + 2 files changed, 289 insertions(+) create mode 100644 tests/qtest/dbus-display-test.c diff --git a/tests/qtest/dbus-display-test.c b/tests/qtest/dbus-display-tes= t.c new file mode 100644 index 0000000000..84278d2da6 --- /dev/null +++ b/tests/qtest/dbus-display-test.c @@ -0,0 +1,281 @@ +#include "qemu/osdep.h" +#include "qemu/dbus.h" +#include +#include +#include "libqos/libqtest.h" +#include "qemu-common.h" +#include "dbus-display1.h" + +static GDBusConnection* +test_dbus_p2p_from_fd(int fd) +{ + g_autoptr(GError) err =3D NULL; + g_autoptr(GSocket) socket =3D NULL; + g_autoptr(GSocketConnection) socketc =3D NULL; + GDBusConnection *conn; + + socket =3D g_socket_new_from_fd(fd, &err); + g_assert_no_error(err); + + socketc =3D g_socket_connection_factory_create_connection(socket); + g_assert(socketc !=3D NULL); + + conn =3D g_dbus_connection_new_sync( + G_IO_STREAM(socketc), NULL, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, + NULL, NULL, &err); + g_assert_no_error(err); + + return conn; +} + +static void +test_setup(QTestState **qts, GDBusConnection **conn) +{ + int pair[2]; + + *qts =3D qtest_init("-display dbus,p2p=3Dyes -name dbus-test"); + + g_assert_cmpint(socketpair(AF_UNIX, SOCK_STREAM, 0, pair), =3D=3D, 0); + + qtest_qmp_add_client(*qts, "@dbus-display", pair[1]); + + *conn =3D test_dbus_p2p_from_fd(pair[0]); + g_dbus_connection_start_message_processing(*conn); +} + +static void +test_dbus_display_vm(void) +{ + g_autoptr(GError) err =3D NULL; + g_autoptr(GDBusConnection) conn =3D NULL; + g_autoptr(QemuDBusDisplay1VMProxy) vm =3D NULL; + QTestState *qts =3D NULL; + + test_setup(&qts, &conn); + + vm =3D QEMU_DBUS_DISPLAY1_VM_PROXY( + qemu_dbus_display1_vm_proxy_new_sync( + conn, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + DBUS_DISPLAY1_ROOT "/VM", + NULL, + &err)); + g_assert_no_error(err); + + g_assert_cmpstr( + qemu_dbus_display1_vm_get_name(QEMU_DBUS_DISPLAY1_VM(vm)), + =3D=3D, + "dbus-test"); + qtest_quit(qts); +} + +typedef struct TestDBusConsoleRegister { + GMainLoop *loop; + GThread *thread; + GDBusConnection *listener_conn; + GDBusObjectManagerServer *server; +} TestDBusConsoleRegister; + +static gboolean listener_handle_scanout( + QemuDBusDisplay1Listener *object, + GDBusMethodInvocation *invocation, + guint arg_width, + guint arg_height, + guint arg_stride, + guint arg_pixman_format, + GVariant *arg_data, + TestDBusConsoleRegister *test) +{ + g_main_loop_quit(test->loop); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static void +test_dbus_console_setup_listener(TestDBusConsoleRegister *test) +{ + g_autoptr(GDBusObjectSkeleton) listener =3D NULL; + g_autoptr(QemuDBusDisplay1ListenerSkeleton) iface =3D NULL; + + test->server =3D g_dbus_object_manager_server_new(DBUS_DISPLAY1_ROOT); + listener =3D g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT "/Listener"= ); + iface =3D QEMU_DBUS_DISPLAY1_LISTENER_SKELETON( + qemu_dbus_display1_listener_skeleton_new()); + g_object_connect(iface, + "signal::handle-scanout", listener_handle_scanout, te= st, + NULL); + g_dbus_object_skeleton_add_interface(listener, + G_DBUS_INTERFACE_SKELETON(iface)); + g_dbus_object_manager_server_export(test->server, listener); + g_dbus_object_manager_server_set_connection(test->server, + test->listener_conn); + + g_dbus_connection_start_message_processing(test->listener_conn); +} + +static void +test_dbus_console_registered(GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + TestDBusConsoleRegister *test =3D user_data; + g_autoptr(GError) err =3D NULL; + + qemu_dbus_display1_console_call_register_listener_finish( + QEMU_DBUS_DISPLAY1_CONSOLE(source_object), + NULL, res, &err); + g_assert_no_error(err); + + test->listener_conn =3D g_thread_join(test->thread); + test_dbus_console_setup_listener(test); +} + +static gpointer +test_dbus_p2p_server_setup_thread(gpointer data) +{ + return test_dbus_p2p_from_fd(GPOINTER_TO_INT(data)); +} + +static void +test_dbus_display_console(void) +{ + g_autoptr(GError) err =3D NULL; + g_autoptr(GDBusConnection) conn =3D NULL; + g_autoptr(QemuDBusDisplay1ConsoleProxy) console =3D NULL; + g_autoptr(GUnixFDList) fd_list =3D NULL; + g_autoptr(GMainLoop) loop =3D NULL; + QTestState *qts =3D NULL; + int pair[2], idx; + TestDBusConsoleRegister test; + + test_setup(&qts, &conn); + + g_assert_cmpint(socketpair(AF_UNIX, SOCK_STREAM, 0, pair), =3D=3D, 0); + fd_list =3D g_unix_fd_list_new(); + idx =3D g_unix_fd_list_append(fd_list, pair[1], NULL); + + console =3D QEMU_DBUS_DISPLAY1_CONSOLE_PROXY( + qemu_dbus_display1_console_proxy_new_sync( + conn, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "/org/qemu/Display1/Console_0", + NULL, + &err)); + g_assert_no_error(err); + + test.loop =3D loop =3D g_main_loop_new(NULL, FALSE); + test.thread =3D g_thread_new(NULL, test_dbus_p2p_server_setup_thread, + GINT_TO_POINTER(pair[0])); + + qemu_dbus_display1_console_call_register_listener( + QEMU_DBUS_DISPLAY1_CONSOLE(console), + g_variant_new_handle(idx), + G_DBUS_CALL_FLAGS_NONE, + -1, + fd_list, + NULL, + test_dbus_console_registered, + &test); + + g_main_loop_run(loop); + + g_clear_object(&test.server); + g_clear_object(&test.listener_conn); + qtest_quit(qts); +} + +static void +test_dbus_display_keyboard_on_modifiers_changed( + QemuDBusDisplay1KeyboardProxy *keyboard, + GParamSpec *pspec, + GMainLoop *loop) +{ + /* there might be initial events first */ + if (qemu_dbus_display1_keyboard_get_modifiers( + QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard)) =3D=3D 0x2) + g_main_loop_quit(loop); +} + +static void +test_dbus_display_keyboard(void) +{ + g_autoptr(GError) err =3D NULL; + g_autoptr(GDBusConnection) conn =3D NULL; + g_autoptr(QemuDBusDisplay1KeyboardProxy) keyboard =3D NULL; + g_autoptr(GMainLoop) loop =3D NULL; + QTestState *qts =3D NULL; + + test_setup(&qts, &conn); + + keyboard =3D QEMU_DBUS_DISPLAY1_KEYBOARD_PROXY( + qemu_dbus_display1_keyboard_proxy_new_sync( + conn, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "/org/qemu/Display1/Console_0", + NULL, + &err)); + g_assert_no_error(err); + + + g_assert_cmpint(qtest_inb(qts, 0x64) & 0x1, =3D=3D, 0); + g_assert_cmpint(qtest_inb(qts, 0x60), =3D=3D, 0); + + qemu_dbus_display1_keyboard_call_press_sync( + QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard), + 0x1C, /* qnum enter */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + g_assert_no_error(err); + + /* may be should wait for interrupt? */ + g_assert_cmpint(qtest_inb(qts, 0x64) & 0x1, =3D=3D, 1); + g_assert_cmpint(qtest_inb(qts, 0x60), =3D=3D, 0x5A); /* scan code 2 en= ter */ + + qemu_dbus_display1_keyboard_call_release_sync( + QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard), + 0x1C, /* qnum enter */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + g_assert_no_error(err); + + g_assert_cmpint(qtest_inb(qts, 0x64) & 0x1, =3D=3D, 1); + g_assert_cmpint(qtest_inb(qts, 0x60), =3D=3D, 0xF0); /* scan code 2 re= lease */ + g_assert_cmpint(qtest_inb(qts, 0x60), =3D=3D, 0x5A); /* scan code 2 en= ter */ + + g_assert_cmpint(qemu_dbus_display1_keyboard_get_modifiers( + QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard)), =3D=3D, 0); + + loop =3D g_main_loop_new(NULL, FALSE); + + g_signal_connect( + keyboard, "notify::modifiers", + G_CALLBACK(test_dbus_display_keyboard_on_modifiers_changed), + loop); + + qemu_dbus_display1_keyboard_set_modifiers( + QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard), 0x2); + + g_main_loop_run(loop); + qtest_quit(qts); +} + +int +main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/dbus-display/vm", test_dbus_display_vm); + qtest_add_func("/dbus-display/console", test_dbus_display_console); + qtest_add_func("/dbus-display/keyboard", test_dbus_display_keyboard); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index b6016aee48..5cf7e54e1b 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -87,6 +87,10 @@ qtests_i386 =3D \ 'test-x86-cpuid-compat', 'numa-test'] =20 +if dbus_display + qtests_i386 +=3D ['dbus-display-test'] +endif + dbus_daemon =3D find_program('dbus-daemon', required: false) if dbus_daemon.found() and config_host.has_key('GDBUS_CODEGEN') # Temporarily disabled due to Patchew failures: @@ -259,6 +263,10 @@ qtests =3D { 'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'), } =20 +if dbus_display +qtests +=3D {'dbus-display-test': [dbus_display1, gio]} +endif + qtest_executables =3D {} foreach dir : target_dirs if not dir.endswith('-softmmu') --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 163381495673829.763794049479884; Sat, 9 Oct 2021 14:29:16 -0700 (PDT) Received: from localhost ([::1]:38264 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJu7-00023P-K2 for importer@patchew.org; Sat, 09 Oct 2021 17:29:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38598) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJhe-0001UX-BR for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:16:24 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:58367) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJha-0001cj-S9 for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:16:22 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-128-DnE2GsbENvW7fRiY1G5jrg-1; Sat, 09 Oct 2021 17:16:16 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 66BF8104ECE6 for ; Sat, 9 Oct 2021 21:16:15 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 47D4F5F4E9; Sat, 9 Oct 2021 21:15:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814178; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NhqW+aDQqTaTyDz2/+tVo34NatFNbnSTy4bD5EJx+QM=; b=e+TGygG7KDRhzqmxMHfBTx3MMUcepoULk27dBvfqyvDTsNYGFNBzU8+Fp18dkrlcTZPInq 7QwwAPqVUw81acHXFdBvE2FkVHXQv/sUpqOlZG5ufUYyiiXa60e5TilSfnDEzUecNu1jhf W/8eixqluBgY1BjtpDxziab18kvWsJk= X-MC-Unique: DnE2GsbENvW7fRiY1G5jrg-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 30/37] audio: add "dbus" audio backend Date: Sun, 10 Oct 2021 01:08:31 +0400 Message-Id: <20211009210838.2219430-31-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633814957788100001 From: Marc-Andr=C3=A9 Lureau Add a new -audio backend that accepts D-Bus clients/listeners to handle playback & recording, to be exported via the -display dbus. Example usage: -audiodev dbus,in.mixing-engine=3Doff,out.mixing-engine=3Doff,id=3Ddbus -display dbus,audiodev=3Ddbus Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- qapi/audio.json | 3 +- qapi/ui.json | 5 +- audio/audio_int.h | 7 + audio/audio_template.h | 2 + ui/dbus.h | 1 + audio/audio.c | 1 + audio/dbusaudio.c | 654 +++++++++++++++++++++++++++++++++++++++++ ui/dbus.c | 35 +++ audio/meson.build | 8 +- audio/trace-events | 5 + qemu-options.hx | 3 + ui/dbus-display1.xml | 211 +++++++++++++ 12 files changed, 932 insertions(+), 3 deletions(-) create mode 100644 audio/dbusaudio.c diff --git a/qapi/audio.json b/qapi/audio.json index 9cba0df8a4..693e327c6b 100644 --- a/qapi/audio.json +++ b/qapi/audio.json @@ -386,7 +386,7 @@ # Since: 4.0 ## { 'enum': 'AudiodevDriver', - 'data': [ 'none', 'alsa', 'coreaudio', 'dsound', 'jack', 'oss', 'pa', + 'data': [ 'none', 'alsa', 'coreaudio', 'dbus', 'dsound', 'jack', 'oss', = 'pa', 'sdl', 'spice', 'wav' ] } =20 ## @@ -412,6 +412,7 @@ 'none': 'AudiodevGenericOptions', 'alsa': 'AudiodevAlsaOptions', 'coreaudio': 'AudiodevCoreaudioOptions', + 'dbus': 'AudiodevGenericOptions', 'dsound': 'AudiodevDsoundOptions', 'jack': 'AudiodevJackOptions', 'oss': 'AudiodevOssOptions', diff --git a/qapi/ui.json b/qapi/ui.json index f23d012cb8..b9262ae1d9 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -1134,13 +1134,16 @@ # @p2p: Whether to use peer-to-peer connections (accepted through # ``add_client``). # +# @audiodev: Use the specified DBus audiodev to export audio. +# # Since: 6.2 # ## { 'struct' : 'DisplayDBus', 'data' : { '*rendernode' : 'str', '*addr': 'str', - '*p2p': 'bool' } } + '*p2p': 'bool', + '*audiodev': 'str' } } =20 ## # @DisplayGLMode: diff --git a/audio/audio_int.h b/audio/audio_int.h index 6d685e24a3..428a091d05 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -31,6 +31,10 @@ #endif #include "mixeng.h" =20 +#ifdef CONFIG_GIO +#include +#endif + struct audio_pcm_ops; =20 struct audio_callback { @@ -140,6 +144,9 @@ struct audio_driver { const char *descr; void *(*init) (Audiodev *); void (*fini) (void *); +#ifdef CONFIG_GIO + void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *mana= ger); +#endif struct audio_pcm_ops *pcm_ops; int can_be_default; int max_voices_out; diff --git a/audio/audio_template.h b/audio/audio_template.h index c6714946aa..d2d348638b 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -327,6 +327,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)= (Audiodev *dev) case AUDIODEV_DRIVER_COREAUDIO: return qapi_AudiodevCoreaudioPerDirectionOptions_base( dev->u.coreaudio.TYPE); + case AUDIODEV_DRIVER_DBUS: + return dev->u.dbus.TYPE; case AUDIODEV_DRIVER_DSOUND: return dev->u.dsound.TYPE; case AUDIODEV_DRIVER_JACK: diff --git a/ui/dbus.h b/ui/dbus.h index 4698d32463..ca1f0f4ab9 100644 --- a/ui/dbus.h +++ b/ui/dbus.h @@ -36,6 +36,7 @@ struct DBusDisplay { DisplayGLMode gl_mode; bool p2p; char *dbus_addr; + char *audiodev; DisplayGLCtx glctx; =20 GDBusConnection *bus; diff --git a/audio/audio.c b/audio/audio.c index 54a153c0ef..dc28685d22 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -2000,6 +2000,7 @@ void audio_create_pdos(Audiodev *dev) CASE(NONE, none, ); CASE(ALSA, alsa, Alsa); CASE(COREAUDIO, coreaudio, Coreaudio); + CASE(DBUS, dbus, ); CASE(DSOUND, dsound, ); CASE(JACK, jack, Jack); CASE(OSS, oss, Oss); diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c new file mode 100644 index 0000000000..f178b47dee --- /dev/null +++ b/audio/dbusaudio.c @@ -0,0 +1,654 @@ +/* + * QEMU DBus audio + * + * Copyright (c) 2021 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/host-utils.h" +#include "qemu/module.h" +#include "qemu/timer.h" +#include "qemu/dbus.h" + +#include +#include "ui/dbus-display1.h" + +#define AUDIO_CAP "dbus" +#include "audio.h" +#include "audio_int.h" +#include "trace.h" + +#define DBUS_DISPLAY1_AUDIO_PATH DBUS_DISPLAY1_ROOT "/Audio" + +#define DBUS_AUDIO_NSAMPLES 1024 /* could be configured? */ + +typedef struct DBusAudio { + GDBusObjectManagerServer *server; + GDBusObjectSkeleton *audio; + QemuDBusDisplay1Audio *iface; + GHashTable *out_listeners; + GHashTable *in_listeners; +} DBusAudio; + +typedef struct DBusVoiceOut { + HWVoiceOut hw; + bool enabled; + RateCtl rate; + + void *buf; + size_t buf_pos; + size_t buf_size; + + bool has_volume; + Volume volume; +} DBusVoiceOut; + +typedef struct DBusVoiceIn { + HWVoiceIn hw; + bool enabled; + RateCtl rate; + + bool has_volume; + Volume volume; +} DBusVoiceIn; + +static void *dbus_get_buffer_out(HWVoiceOut *hw, size_t *size) +{ + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + + if (!vo->buf) { + vo->buf_size =3D hw->samples * hw->info.bytes_per_frame; + vo->buf =3D g_malloc(vo->buf_size); + vo->buf_pos =3D 0; + } + + *size =3D MIN(vo->buf_size - vo->buf_pos, *size); + *size =3D audio_rate_get_bytes(&hw->info, &vo->rate, *size); + + return vo->buf + vo->buf_pos; + +} + +static size_t dbus_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioOutListener *listener =3D NULL; + g_autoptr(GBytes) bytes =3D NULL; + g_autoptr(GVariant) v_data =3D NULL; + + assert(buf =3D=3D vo->buf + vo->buf_pos && vo->buf_pos + size <=3D vo-= >buf_size); + vo->buf_pos +=3D size; + + trace_dbus_audio_put_buffer_out(size); + + if (vo->buf_pos < vo->buf_size) { + return size; + } + + bytes =3D g_bytes_new_take(g_steal_pointer(&vo->buf), vo->buf_size); + v_data =3D g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE); + g_variant_ref_sink(v_data); + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + qemu_dbus_display1_audio_out_listener_call_write( + listener, + (uintptr_t)hw, + v_data, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + + return size; +} + +#ifdef HOST_WORDS_BIGENDIAN +#define AUDIO_HOST_BE TRUE +#else +#define AUDIO_HOST_BE FALSE +#endif + +static void +dbus_init_out_listener(QemuDBusDisplay1AudioOutListener *listener, + HWVoiceOut *hw) +{ + qemu_dbus_display1_audio_out_listener_call_init( + listener, + (uintptr_t)hw, + hw->info.bits, + hw->info.is_signed, + hw->info.is_float, + hw->info.freq, + hw->info.nchannels, + hw->info.bytes_per_frame, + hw->info.bytes_per_second, + hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static int +dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioOutListener *listener =3D NULL; + + audio_pcm_init_info(&hw->info, as); + hw->samples =3D DBUS_AUDIO_NSAMPLES; + audio_rate_start(&vo->rate); + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_init_out_listener(listener, hw); + } + return 0; +} + +static void +dbus_fini_out(HWVoiceOut *hw) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioOutListener *listener =3D NULL; + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + qemu_dbus_display1_audio_out_listener_call_fini( + listener, + (uintptr_t)hw, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + + g_clear_pointer(&vo->buf, g_free); +} + +static void +dbus_enable_out(HWVoiceOut *hw, bool enable) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioOutListener *listener =3D NULL; + + vo->enabled =3D enable; + if (enable) { + audio_rate_start(&vo->rate); + } + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + qemu_dbus_display1_audio_out_listener_call_set_enabled( + listener, (uintptr_t)hw, enable, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } +} + +static void +dbus_volume_out_listener(HWVoiceOut *hw, + QemuDBusDisplay1AudioOutListener *listener) +{ + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + Volume *vol =3D &vo->volume; + g_autoptr(GBytes) bytes =3D NULL; + GVariant *v_vol =3D NULL; + + if (!vo->has_volume) { + return; + } + + assert(vol->channels < sizeof(vol->vol)); + bytes =3D g_bytes_new(vol->vol, vol->channels); + v_vol =3D g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE); + qemu_dbus_display1_audio_out_listener_call_set_volume( + listener, (uintptr_t)hw, vol->mute, v_vol, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +dbus_volume_out(HWVoiceOut *hw, Volume *vol) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioOutListener *listener =3D NULL; + + vo->has_volume =3D true; + vo->volume =3D *vol; + + g_hash_table_iter_init(&iter, da->out_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_volume_out_listener(hw, listener); + } +} + +static void +dbus_init_in_listener(QemuDBusDisplay1AudioInListener *listener, HWVoiceIn= *hw) +{ + qemu_dbus_display1_audio_in_listener_call_init( + listener, + (uintptr_t)hw, + hw->info.bits, + hw->info.is_signed, + hw->info.is_float, + hw->info.freq, + hw->info.nchannels, + hw->info.bytes_per_frame, + hw->info.bytes_per_second, + hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static int +dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceIn *vo =3D container_of(hw, DBusVoiceIn, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioInListener *listener =3D NULL; + + audio_pcm_init_info(&hw->info, as); + hw->samples =3D DBUS_AUDIO_NSAMPLES; + audio_rate_start(&vo->rate); + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_init_in_listener(listener, hw); + } + return 0; +} + +static void +dbus_fini_in(HWVoiceIn *hw) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + GHashTableIter iter; + QemuDBusDisplay1AudioInListener *listener =3D NULL; + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + qemu_dbus_display1_audio_in_listener_call_fini( + listener, + (uintptr_t)hw, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } +} + +static void +dbus_volume_in_listener(HWVoiceIn *hw, + QemuDBusDisplay1AudioInListener *listener) +{ + DBusVoiceIn *vo =3D container_of(hw, DBusVoiceIn, hw); + Volume *vol =3D &vo->volume; + g_autoptr(GBytes) bytes =3D NULL; + GVariant *v_vol =3D NULL; + + if (!vo->has_volume) { + return; + } + + assert(vol->channels < sizeof(vol->vol)); + bytes =3D g_bytes_new(vol->vol, vol->channels); + v_vol =3D g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE); + qemu_dbus_display1_audio_in_listener_call_set_volume( + listener, (uintptr_t)hw, vol->mute, v_vol, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); +} + +static void +dbus_volume_in(HWVoiceIn *hw, Volume *vol) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceIn *vo =3D container_of(hw, DBusVoiceIn, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioInListener *listener =3D NULL; + + vo->has_volume =3D true; + vo->volume =3D *vol; + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + dbus_volume_in_listener(hw, listener); + } +} + +static size_t +dbus_read(HWVoiceIn *hw, void *buf, size_t size) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + /* DBusVoiceIn *vo =3D container_of(hw, DBusVoiceIn, hw); */ + GHashTableIter iter; + QemuDBusDisplay1AudioInListener *listener =3D NULL; + + trace_dbus_audio_read(size); + + /* size =3D audio_rate_get_bytes(&hw->info, &vo->rate, size); */ + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + g_autoptr(GVariant) v_data =3D NULL; + const char *data; + gsize n =3D 0; + + if (qemu_dbus_display1_audio_in_listener_call_read_sync( + listener, + (uintptr_t)hw, + size, + G_DBUS_CALL_FLAGS_NONE, -1, + &v_data, NULL, NULL)) { + data =3D g_variant_get_fixed_array(v_data, &n, 1); + g_warn_if_fail(n <=3D size); + size =3D MIN(n, size); + memcpy(buf, data, size); + break; + } + } + + return size; +} + +static void +dbus_enable_in(HWVoiceIn *hw, bool enable) +{ + DBusAudio *da =3D (DBusAudio *)hw->s->drv_opaque; + DBusVoiceIn *vo =3D container_of(hw, DBusVoiceIn, hw); + GHashTableIter iter; + QemuDBusDisplay1AudioInListener *listener =3D NULL; + + vo->enabled =3D enable; + if (enable) { + audio_rate_start(&vo->rate); + } + + g_hash_table_iter_init(&iter, da->in_listeners); + while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) { + qemu_dbus_display1_audio_in_listener_call_set_enabled( + listener, (uintptr_t)hw, enable, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } +} + +static void * +dbus_audio_init(Audiodev *dev) +{ + DBusAudio *da =3D g_new0(DBusAudio, 1); + + da->out_listeners =3D g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_object_unref); + da->in_listeners =3D g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_object_unref); + return da; +} + +static void +dbus_audio_fini(void *opaque) +{ + DBusAudio *da =3D opaque; + + if (da->server) { + g_dbus_object_manager_server_unexport(da->server, + DBUS_DISPLAY1_AUDIO_PATH); + } + g_clear_object(&da->audio); + g_clear_object(&da->iface); + g_clear_pointer(&da->in_listeners, g_hash_table_unref); + g_clear_pointer(&da->out_listeners, g_hash_table_unref); + g_clear_object(&da->server); + g_free(da); +} + +static void +listener_out_vanished_cb(GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + DBusAudio *da) +{ + char *name =3D g_object_get_data(G_OBJECT(connection), "name"); + + g_hash_table_remove(da->out_listeners, name); +} + +static void +listener_in_vanished_cb(GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + DBusAudio *da) +{ + char *name =3D g_object_get_data(G_OBJECT(connection), "name"); + + g_hash_table_remove(da->in_listeners, name); +} + +static gboolean +dbus_audio_register_listener(AudioState *s, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener, + bool out) +{ + DBusAudio *da =3D s->drv_opaque; + const char *sender =3D g_dbus_method_invocation_get_sender(invocation); + g_autoptr(GDBusConnection) listener_conn =3D NULL; + g_autoptr(GError) err =3D NULL; + g_autoptr(GSocket) socket =3D NULL; + g_autoptr(GSocketConnection) socket_conn =3D NULL; + g_autofree char *guid =3D g_dbus_generate_guid(); + GHashTable *listeners =3D out ? da->out_listeners : da->in_listeners; + GObject *listener; + int fd; + + trace_dbus_audio_register(sender, out ? "out" : "in"); + + if (g_hash_table_contains(listeners, sender)) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_INVALID, + "`%s` is already registered!= ", + sender); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + fd =3D g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener),= &err); + if (err) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't get peer fd: %s", + err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + socket =3D g_socket_new_from_fd(fd, &err); + if (err) { + g_dbus_method_invocation_return_error(invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Couldn't make a socket: %s", + err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + socket_conn =3D g_socket_connection_factory_create_connection(socket); + if (out) { + qemu_dbus_display1_audio_complete_register_out_listener( + da->iface, invocation, NULL); + } else { + qemu_dbus_display1_audio_complete_register_in_listener( + da->iface, invocation, NULL); + } + + listener_conn =3D + g_dbus_connection_new_sync( + G_IO_STREAM(socket_conn), + guid, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER, + NULL, NULL, &err); + if (err) { + error_report("Failed to setup peer connection: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + listener =3D out ? + G_OBJECT(qemu_dbus_display1_audio_out_listener_proxy_new_sync( + listener_conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/AudioOutListener", + NULL, + &err)) : + G_OBJECT(qemu_dbus_display1_audio_in_listener_proxy_new_sync( + listener_conn, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + "/org/qemu/Display1/AudioInListener", + NULL, + &err)); + if (!listener) { + error_report("Failed to setup proxy: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (out) { + HWVoiceOut *hw; + + QLIST_FOREACH(hw, &s->hw_head_out, entries) { + DBusVoiceOut *vo =3D container_of(hw, DBusVoiceOut, hw); + QemuDBusDisplay1AudioOutListener *l =3D + QEMU_DBUS_DISPLAY1_AUDIO_OUT_LISTENER(listener); + + dbus_init_out_listener(l, hw); + qemu_dbus_display1_audio_out_listener_call_set_enabled( + l, (uintptr_t)hw, vo->enabled, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + } else { + HWVoiceIn *hw; + + QLIST_FOREACH(hw, &s->hw_head_in, entries) { + DBusVoiceIn *vo =3D container_of(hw, DBusVoiceIn, hw); + QemuDBusDisplay1AudioInListener *l =3D + QEMU_DBUS_DISPLAY1_AUDIO_IN_LISTENER(listener); + + dbus_init_in_listener( + QEMU_DBUS_DISPLAY1_AUDIO_IN_LISTENER(listener), hw); + qemu_dbus_display1_audio_in_listener_call_set_enabled( + l, (uintptr_t)hw, vo->enabled, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + } + + g_object_set_data_full(G_OBJECT(listener_conn), "name", + g_strdup(sender), g_free); + g_hash_table_insert(listeners, g_strdup(sender), listener); + g_object_connect(listener_conn, + "signal::closed", + out ? listener_out_vanished_cb : listener_in_vanished= _cb, + da, + NULL); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_audio_register_out_listener(AudioState *s, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener) +{ + return dbus_audio_register_listener(s, invocation, + fd_list, arg_listener, true); + +} + +static gboolean +dbus_audio_register_in_listener(AudioState *s, + GDBusMethodInvocation *invocation, + GUnixFDList *fd_list, + GVariant *arg_listener) +{ + return dbus_audio_register_listener(s, invocation, + fd_list, arg_listener, false); +} + +static void +dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server) +{ + DBusAudio *da =3D s->drv_opaque; + + g_assert(da); + g_assert(!da->server); + + da->server =3D g_object_ref(server); + + da->audio =3D g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO_PATH); + da->iface =3D qemu_dbus_display1_audio_skeleton_new(); + g_object_connect(da->iface, + "swapped-signal::handle-register-in-listener", + dbus_audio_register_in_listener, s, + "swapped-signal::handle-register-out-listener", + dbus_audio_register_out_listener, s, + NULL); + + g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio), + G_DBUS_INTERFACE_SKELETON(da->ifa= ce)); + g_dbus_object_manager_server_export(da->server, da->audio); +} + +static struct audio_pcm_ops dbus_pcm_ops =3D { + .init_out =3D dbus_init_out, + .fini_out =3D dbus_fini_out, + .write =3D audio_generic_write, + .get_buffer_out =3D dbus_get_buffer_out, + .put_buffer_out =3D dbus_put_buffer_out, + .enable_out =3D dbus_enable_out, + .volume_out =3D dbus_volume_out, + + .init_in =3D dbus_init_in, + .fini_in =3D dbus_fini_in, + .read =3D dbus_read, + .run_buffer_in =3D audio_generic_run_buffer_in, + .enable_in =3D dbus_enable_in, + .volume_in =3D dbus_volume_in, +}; + +static struct audio_driver dbus_audio_driver =3D { + .name =3D "dbus", + .descr =3D "Timer based audio exposed with DBus interface", + .init =3D dbus_audio_init, + .fini =3D dbus_audio_fini, + .set_dbus_server =3D dbus_audio_set_server, + .pcm_ops =3D &dbus_pcm_ops, + .can_be_default =3D 1, + .max_voices_out =3D INT_MAX, + .max_voices_in =3D INT_MAX, + .voice_size_out =3D sizeof(DBusVoiceOut), + .voice_size_in =3D sizeof(DBusVoiceIn) +}; + +static void register_audio_dbus(void) +{ + audio_driver_register(&dbus_audio_driver); +} +type_init(register_audio_dbus); + +module_dep("ui-dbus") diff --git a/ui/dbus.c b/ui/dbus.c index 56e284fb97..7cfbf1a80c 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -30,6 +30,8 @@ #include "ui/dbus-module.h" #include "ui/egl-helpers.h" #include "ui/egl-context.h" +#include "audio/audio.h" +#include "audio/audio_int.h" #include "qapi/error.h" #include "trace.h" =20 @@ -84,6 +86,7 @@ dbus_display_finalize(Object *o) g_clear_object(&dd->bus); g_clear_object(&dd->iface); g_free(dd->dbus_addr); + g_free(dd->audiodev); dbus_display =3D NULL; } =20 @@ -140,6 +143,19 @@ dbus_display_complete(UserCreatable *uc, Error **errp) return; } =20 + if (dd->audiodev && *dd->audiodev) { + AudioState *audio_state =3D audio_state_by_name(dd->audiodev); + if (!audio_state) { + error_setg(errp, "Audiodev '%s' not found", dd->audiodev); + return; + } + if (!g_str_equal(audio_state->drv->name, "dbus")) { + error_setg(errp, "Audiodev '%s' is not compatible with DBus", + dd->audiodev); + return; + } + audio_state->drv->set_dbus_server(audio_state, dd->server); + } =20 consoles =3D g_array_new(FALSE, FALSE, sizeof(guint32)); for (idx =3D 0;; idx++) { @@ -256,6 +272,23 @@ set_dbus_addr(Object *o, const char *str, Error **errp) dd->dbus_addr =3D g_strdup(str); } =20 +static char * +get_audiodev(Object *o, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + return g_strdup(dd->audiodev); +} + +static void +set_audiodev(Object *o, const char *str, Error **errp) +{ + DBusDisplay *dd =3D DBUS_DISPLAY(o); + + g_free(dd->audiodev); + dd->audiodev =3D g_strdup(str); +} + static int get_gl_mode(Object *o, Error **errp) { @@ -280,6 +313,7 @@ dbus_display_class_init(ObjectClass *oc, void *data) ucc->complete =3D dbus_display_complete; object_class_property_add_bool(oc, "p2p", get_dbus_p2p, set_dbus_p2p); object_class_property_add_str(oc, "addr", get_dbus_addr, set_dbus_addr= ); + object_class_property_add_str(oc, "audiodev", get_audiodev, set_audiod= ev); object_class_property_add_enum(oc, "gl-mode", "DisplayGLMode", &DisplayGLMode_lookup, get_gl_mode, set_gl_mode); @@ -316,6 +350,7 @@ dbus_init(DisplayState *ds, DisplayOptions *opts) object_get_objects_root(), "dbus-display", &error_fatal, "addr", opts->u.dbus.addr ?: "", + "audiodev", opts->u.dbus.audiodev ?: "", "gl-mode", DisplayGLMode_str(mode), "p2p", yes_no(opts->u.dbus.p2p), NULL); diff --git a/audio/meson.build b/audio/meson.build index 7d53b0f920..13d499bcbb 100644 --- a/audio/meson.build +++ b/audio/meson.build @@ -18,7 +18,7 @@ foreach m : [ ['CONFIG_AUDIO_PA', 'pa', pulse, 'paaudio.c'], ['CONFIG_AUDIO_SDL', 'sdl', sdl, 'sdlaudio.c'], ['CONFIG_AUDIO_JACK', 'jack', jack, 'jackaudio.c'], - ['CONFIG_SPICE', 'spice', spice, 'spiceaudio.c'] + ['CONFIG_SPICE', 'spice', spice, 'spiceaudio.c'], ] if config_host.has_key(m[0]) module_ss =3D ss.source_set() @@ -27,4 +27,10 @@ foreach m : [ endif endforeach =20 +if dbus_display + module_ss =3D ss.source_set() + module_ss.add(when: gio, if_true: files('dbusaudio.c')) + audio_modules +=3D {'dbus': module_ss} +endif + modules +=3D {'audio': audio_modules} diff --git a/audio/trace-events b/audio/trace-events index 957c92337b..e1ab643add 100644 --- a/audio/trace-events +++ b/audio/trace-events @@ -13,6 +13,11 @@ alsa_resume_out(void) "Resuming suspended output stream" # ossaudio.c oss_version(int version) "OSS version =3D 0x%x" =20 +# dbusaudio.c +dbus_audio_register(const char *s, const char *dir) "sender =3D %s, dir = =3D %s" +dbus_audio_put_buffer_out(size_t len) "len =3D %zu" +dbus_audio_read(size_t len) "len =3D %zu" + # audio.c audio_timer_start(int interval) "interval %d ms" audio_timer_stop(void) "" diff --git a/qemu-options.hx b/qemu-options.hx index b3352a7fbc..060fafdf51 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -659,6 +659,9 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev, #endif #ifdef CONFIG_SPICE "-audiodev spice,id=3Did[,prop[=3Dvalue][,...]]\n" +#endif +#ifdef CONFIG_DBUS_DISPLAY + "-audiodev dbus,id=3Did[,prop[=3Dvalue][,...]]\n" #endif "-audiodev wav,id=3Did[,prop[=3Dvalue][,...]]\n" " path=3D path of wav file to record\n", diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index 0f0ae92e4d..aff645220c 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -375,4 +375,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633815214062306.7921103853723; Sat, 9 Oct 2021 14:33:34 -0700 (PDT) Received: from localhost ([::1]:49238 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZJyG-0001EU-R7 for importer@patchew.org; Sat, 09 Oct 2021 17:33:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38620) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJho-0001cj-Qt for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:16:34 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:27130) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJhm-0002SD-9B for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:16:32 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-84-pJvefdm6N52qOFBmQ3ks2w-1; Sat, 09 Oct 2021 17:16:27 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E1187801A93 for ; Sat, 9 Oct 2021 21:16:26 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5F90D10016FF; Sat, 9 Oct 2021 21:16:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OJiD4qWq/cNCm47ccbMY/Ya6jANhPeTD4eAANh5Gvbc=; b=DWQEriWjXpSCA86gswHZxy0BPpNOEXipAbfvRNdhpFOWY9N9ewJ0hO7Jk7d/aXaINh9k6v +HRm8GBwrhnV3KOkyhPIDmQB6WjZM056zonpKAaEysgKUvWkzbn3D4eL9LrZXGG4OMxoOV vsHOPWsG3b4uo3vdZKG45MMcKlnDHes= X-MC-Unique: pJvefdm6N52qOFBmQ3ks2w-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 31/37] ui/dbus: add clipboard interface Date: Sun, 10 Oct 2021 01:08:32 +0400 Message-Id: <20211009210838.2219430-32-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815216113100001 From: Marc-Andr=C3=A9 Lureau Expose the clipboard API over D-Bus. See the interface documentation for further details. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- ui/dbus.h | 14 ++ ui/dbus-clipboard.c | 457 +++++++++++++++++++++++++++++++++++++++++++ ui/dbus.c | 7 + ui/dbus-display1.xml | 97 +++++++++ ui/meson.build | 1 + ui/trace-events | 3 + 6 files changed, 579 insertions(+) create mode 100644 ui/dbus-clipboard.c diff --git a/ui/dbus.h b/ui/dbus.h index ca1f0f4ab9..3e89eafcab 100644 --- a/ui/dbus.h +++ b/ui/dbus.h @@ -27,9 +27,16 @@ #include "qemu/dbus.h" #include "qom/object.h" #include "ui/console.h" +#include "ui/clipboard.h" =20 #include "dbus-display1.h" =20 +typedef struct DBusClipboardRequest { + GDBusMethodInvocation *invocation; + QemuClipboardType type; + guint timeout_id; +} DBusClipboardRequest; + struct DBusDisplay { Object parent; =20 @@ -44,6 +51,11 @@ struct DBusDisplay { QemuDBusDisplay1VM *iface; GPtrArray *consoles; GCancellable *add_client_cancellable; + + QemuClipboardPeer clipboard_peer; + QemuDBusDisplay1Clipboard *clipboard; + QemuDBusDisplay1Clipboard *clipboard_proxy; + DBusClipboardRequest clipboard_request[QEMU_CLIPBOARD_SELECTION__COUNT= ]; }; =20 #define TYPE_DBUS_DISPLAY "dbus-display" @@ -83,4 +95,6 @@ dbus_display_listener_get_bus_name(DBusDisplayListener *d= dl); extern const DisplayChangeListenerOps dbus_gl_dcl_ops; extern const DisplayChangeListenerOps dbus_dcl_ops; =20 +void dbus_clipboard_init(DBusDisplay *dpy); + #endif /* UI_DBUS_H_ */ diff --git a/ui/dbus-clipboard.c b/ui/dbus-clipboard.c new file mode 100644 index 0000000000..5843d26cd2 --- /dev/null +++ b/ui/dbus-clipboard.c @@ -0,0 +1,457 @@ +/* + * QEMU DBus display + * + * Copyright (c) 2021 Marc-Andr=C3=A9 Lureau + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#include "qemu/osdep.h" +#include "qemu/dbus.h" +#include "qemu/main-loop.h" +#include "qom/object_interfaces.h" +#include "sysemu/sysemu.h" +#include "qapi/error.h" +#include "trace.h" + +#include "dbus.h" + +#define MIME_TEXT_PLAIN_UTF8 "text/plain;charset=3Dutf-8" + +static void +dbus_clipboard_complete_request( + DBusDisplay *dpy, + GDBusMethodInvocation *invocation, + QemuClipboardInfo *info, + QemuClipboardType type) +{ + GVariant *v_data =3D g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + info->types[type].data, + info->types[type].size, + TRUE, + (GDestroyNotify)qemu_clipboard_info_unref, + qemu_clipboard_info_ref(info)); + + qemu_dbus_display1_clipboard_complete_request( + dpy->clipboard, invocation, + MIME_TEXT_PLAIN_UTF8, v_data); +} + +static void +dbus_clipboard_update_info(DBusDisplay *dpy, QemuClipboardInfo *info) +{ + bool self_update =3D info->owner =3D=3D &dpy->clipboard_peer; + const char *mime[QEMU_CLIPBOARD_TYPE__COUNT + 1] =3D { 0, }; + DBusClipboardRequest *req; + int i =3D 0; + + if (info->owner =3D=3D NULL) { + if (dpy->clipboard_proxy) { + qemu_dbus_display1_clipboard_call_release( + dpy->clipboard_proxy, + info->selection, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + return; + } + + if (self_update || !info->has_serial) { + return; + } + + req =3D &dpy->clipboard_request[info->selection]; + if (req->invocation && info->types[req->type].data) { + dbus_clipboard_complete_request(dpy, req->invocation, info, req->t= ype); + g_clear_object(&req->invocation); + g_source_remove(req->timeout_id); + req->timeout_id =3D 0; + return; + } + + if (info->types[QEMU_CLIPBOARD_TYPE_TEXT].available) { + mime[i++] =3D MIME_TEXT_PLAIN_UTF8; + } + + if (i > 0) { + if (dpy->clipboard_proxy) { + qemu_dbus_display1_clipboard_call_grab( + dpy->clipboard_proxy, + info->selection, + info->serial, + mime, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + } + } +} + +static void +dbus_clipboard_reset_serial(DBusDisplay *dpy) +{ + if (dpy->clipboard_proxy) { + qemu_dbus_display1_clipboard_call_register( + dpy->clipboard_proxy, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + } +} + +static void +dbus_clipboard_notify(Notifier *notifier, void *data) +{ + DBusDisplay *dpy =3D + container_of(notifier, DBusDisplay, clipboard_peer.notifier); + QemuClipboardNotify *notify =3D data; + + switch (notify->type) { + case QEMU_CLIPBOARD_UPDATE_INFO: + dbus_clipboard_update_info(dpy, notify->info); + return; + case QEMU_CLIPBOARD_RESET_SERIAL: + dbus_clipboard_reset_serial(dpy); + return; + } +} + +static void +dbus_clipboard_qemu_request(QemuClipboardInfo *info, + QemuClipboardType type) +{ + DBusDisplay *dpy =3D container_of(info->owner, DBusDisplay, clipboard_= peer); + g_autofree char *mime =3D NULL; + g_autoptr(GVariant) v_data =3D NULL; + g_autoptr(GError) err =3D NULL; + const char *data =3D NULL; + const char *mimes[] =3D { MIME_TEXT_PLAIN_UTF8, NULL }; + size_t n; + + if (type !=3D QEMU_CLIPBOARD_TYPE_TEXT) { + /* unsupported atm */ + return; + } + + if (dpy->clipboard_proxy) { + if (!qemu_dbus_display1_clipboard_call_request_sync( + dpy->clipboard_proxy, + info->selection, + mimes, + G_DBUS_CALL_FLAGS_NONE, -1, &mime, &v_data, NULL, &err)) { + error_report("Failed to request clipboard: %s", err->message); + return; + } + + if (g_strcmp0(mime, MIME_TEXT_PLAIN_UTF8)) { + error_report("Unsupported returned MIME: %s", mime); + return; + } + + data =3D g_variant_get_fixed_array(v_data, &n, 1); + qemu_clipboard_set_data(&dpy->clipboard_peer, info, type, + n, data, true); + } +} + +static void +dbus_clipboard_request_cancelled(DBusClipboardRequest *req) +{ + if (!req->invocation) { + return; + } + + g_dbus_method_invocation_return_error( + req->invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Cancelled clipboard request"); + + g_clear_object(&req->invocation); + g_source_remove(req->timeout_id); + req->timeout_id =3D 0; +} + +static void +dbus_clipboard_unregister_proxy(DBusDisplay *dpy) +{ + const char *name =3D NULL; + int i; + + for (i =3D 0; i < G_N_ELEMENTS(dpy->clipboard_request); ++i) { + dbus_clipboard_request_cancelled(&dpy->clipboard_request[i]); + } + + if (!dpy->clipboard_proxy) { + return; + } + + name =3D g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy)); + trace_dbus_clipboard_unregister(name); + g_clear_object(&dpy->clipboard_proxy); +} + +static void +dbus_on_clipboard_proxy_name_owner_changed( + DBusDisplay *dpy, + GObject *object, + GParamSpec *pspec) +{ + dbus_clipboard_unregister_proxy(dpy); +} + +static gboolean +dbus_clipboard_register( + DBusDisplay *dpy, + GDBusMethodInvocation *invocation) +{ + g_autoptr(GError) err =3D NULL; + const char *name =3D NULL; + + if (dpy->clipboard_proxy) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Clipboard peer already registered!"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + dpy->clipboard_proxy =3D + qemu_dbus_display1_clipboard_proxy_new_sync( + g_dbus_method_invocation_get_connection(invocation), + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + g_dbus_method_invocation_get_sender(invocation), + "/org/qemu/Display1/Clipboard", + NULL, + &err); + if (!dpy->clipboard_proxy) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Failed to setup proxy: %s", err->message); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + name =3D g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy)); + trace_dbus_clipboard_register(name); + + g_object_connect(dpy->clipboard_proxy, + "swapped-signal::notify::g-name-owner", + dbus_on_clipboard_proxy_name_owner_changed, dpy, + NULL); + qemu_clipboard_reset_serial(); + + qemu_dbus_display1_clipboard_complete_register(dpy->clipboard, invocat= ion); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_clipboard_check_caller(DBusDisplay *dpy, GDBusMethodInvocation *invoc= ation) +{ + if (!dpy->clipboard_proxy || + g_strcmp0(g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy)= ), + g_dbus_method_invocation_get_sender(invocation))) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Unregistered caller"); + return FALSE; + } + + return TRUE; +} + +static gboolean +dbus_clipboard_unregister( + DBusDisplay *dpy, + GDBusMethodInvocation *invocation) +{ + if (!dbus_clipboard_check_caller(dpy, invocation)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + + dbus_clipboard_unregister_proxy(dpy); + + qemu_dbus_display1_clipboard_complete_unregister( + dpy->clipboard, invocation); + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_clipboard_grab( + DBusDisplay *dpy, + GDBusMethodInvocation *invocation, + gint arg_selection, + guint arg_serial, + const gchar *const *arg_mimes) +{ + QemuClipboardSelection s =3D arg_selection; + g_autoptr(QemuClipboardInfo) info =3D NULL; + + if (!dbus_clipboard_check_caller(dpy, invocation)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (s >=3D QEMU_CLIPBOARD_SELECTION__COUNT) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Invalid clipboard selection: %d", arg_selection); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + info =3D qemu_clipboard_info_new(&dpy->clipboard_peer, s); + if (g_strv_contains(arg_mimes, MIME_TEXT_PLAIN_UTF8)) { + info->types[QEMU_CLIPBOARD_TYPE_TEXT].available =3D true; + } + info->serial =3D arg_serial; + info->has_serial =3D true; + if (qemu_clipboard_check_serial(info, true)) { + qemu_clipboard_update(info); + } else { + trace_dbus_clipboard_grab_failed(); + } + + qemu_dbus_display1_clipboard_complete_grab(dpy->clipboard, invocation); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_clipboard_release( + DBusDisplay *dpy, + GDBusMethodInvocation *invocation, + gint arg_selection) +{ + if (!dbus_clipboard_check_caller(dpy, invocation)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + + qemu_clipboard_peer_release(&dpy->clipboard_peer, arg_selection); + + qemu_dbus_display1_clipboard_complete_release(dpy->clipboard, invocati= on); + return DBUS_METHOD_INVOCATION_HANDLED; +} + +static gboolean +dbus_clipboard_request_timeout(gpointer user_data) +{ + dbus_clipboard_request_cancelled(user_data); + return G_SOURCE_REMOVE; +} + +static gboolean +dbus_clipboard_request( + DBusDisplay *dpy, + GDBusMethodInvocation *invocation, + gint arg_selection, + const gchar *const *arg_mimes) +{ + QemuClipboardSelection s =3D arg_selection; + QemuClipboardType type =3D QEMU_CLIPBOARD_TYPE_TEXT; + QemuClipboardInfo *info =3D NULL; + + if (!dbus_clipboard_check_caller(dpy, invocation)) { + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (s >=3D QEMU_CLIPBOARD_SELECTION__COUNT) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Invalid clipboard selection: %d", arg_selection); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (dpy->clipboard_request[s].invocation) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Pending request"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + info =3D qemu_clipboard_info(s); + if (!info || !info->owner || info->owner =3D=3D &dpy->clipboard_peer) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Empty clipboard"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (!g_strv_contains(arg_mimes, MIME_TEXT_PLAIN_UTF8) || + !info->types[type].available) { + g_dbus_method_invocation_return_error( + invocation, + DBUS_DISPLAY_ERROR, + DBUS_DISPLAY_ERROR_FAILED, + "Unhandled MIME types requested"); + return DBUS_METHOD_INVOCATION_HANDLED; + } + + if (info->types[type].data) { + dbus_clipboard_complete_request(dpy, invocation, info, type); + } else { + qemu_clipboard_request(info, type); + + dpy->clipboard_request[s].invocation =3D g_object_ref(invocation); + dpy->clipboard_request[s].type =3D type; + dpy->clipboard_request[s].timeout_id =3D + g_timeout_add_seconds(5, dbus_clipboard_request_timeout, + &dpy->clipboard_request[s]); + } + + return DBUS_METHOD_INVOCATION_HANDLED; +} + +void +dbus_clipboard_init(DBusDisplay *dpy) +{ + g_autoptr(GDBusObjectSkeleton) clipboard =3D NULL; + + assert(!dpy->clipboard); + + clipboard =3D g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT "/Clipboar= d"); + dpy->clipboard =3D qemu_dbus_display1_clipboard_skeleton_new(); + g_object_connect(dpy->clipboard, + "swapped-signal::handle-register", + dbus_clipboard_register, dpy, + "swapped-signal::handle-unregister", + dbus_clipboard_unregister, dpy, + "swapped-signal::handle-grab", + dbus_clipboard_grab, dpy, + "swapped-signal::handle-release", + dbus_clipboard_release, dpy, + "swapped-signal::handle-request", + dbus_clipboard_request, dpy, + NULL); + + g_dbus_object_skeleton_add_interface( + G_DBUS_OBJECT_SKELETON(clipboard), + G_DBUS_INTERFACE_SKELETON(dpy->clipboard)); + g_dbus_object_manager_server_export(dpy->server, clipboard); + dpy->clipboard_peer.name =3D "dbus"; + dpy->clipboard_peer.notifier.notify =3D dbus_clipboard_notify; + dpy->clipboard_peer.request =3D dbus_clipboard_qemu_request; + qemu_clipboard_peer_register(&dpy->clipboard_peer); +} diff --git a/ui/dbus.c b/ui/dbus.c index 7cfbf1a80c..ac34fab3cb 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/cutils.h" #include "qemu/dbus.h" +#include "qemu/main-loop.h" #include "qemu/option.h" #include "qom/object_interfaces.h" #include "sysemu/sysemu.h" @@ -70,6 +71,8 @@ dbus_display_init(Object *o) g_dbus_object_skeleton_add_interface( vm, G_DBUS_INTERFACE_SKELETON(dd->iface)); g_dbus_object_manager_server_export(dd->server, vm); + + dbus_clipboard_init(dd); } =20 static void @@ -77,6 +80,9 @@ dbus_display_finalize(Object *o) { DBusDisplay *dd =3D DBUS_DISPLAY(o); =20 + qemu_clipboard_peer_unregister(&dd->clipboard_peer); + g_clear_object(&dd->clipboard); + g_clear_object(&dd->server); g_clear_pointer(&dd->consoles, g_ptr_array_unref); if (dd->add_client_cancellable) { @@ -289,6 +295,7 @@ set_audiodev(Object *o, const char *str, Error **errp) dd->audiodev =3D g_strdup(str); } =20 + static int get_gl_mode(Object *o, Error **errp) { diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index aff645220c..767562ad1e 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -376,6 +376,103 @@ =20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/meson.build b/ui/meson.build index 8982ab63c4..64286ba150 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -82,6 +82,7 @@ if dbus_display '--generate-c-code', '@BASENAME@= ']) dbus_ss.add(when: [gio, pixman, opengl, 'CONFIG_GIO'], if_true: [files( + 'dbus-chardev.c', 'dbus-clipboard.c', 'dbus-console.c', 'dbus-error.c', --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633815556596820.8380004755434; Sat, 9 Oct 2021 14:39:16 -0700 (PDT) Received: from localhost ([::1]:60468 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZK3n-0000pc-Fx for importer@patchew.org; Sat, 09 Oct 2021 17:39:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38758) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJir-000388-0l for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:17:37 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:22573) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJip-0002de-FW for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:17:36 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-225-RtPStId6MN6jK6nTLw1Y1A-1; Sat, 09 Oct 2021 17:17:33 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BE4C7180830F for ; Sat, 9 Oct 2021 21:17:32 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id C089319729; Sat, 9 Oct 2021 21:17:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814254; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ylGqsmrwEbiHQ6b11M8f27Vu9LcXipQBy+MGOyWaZBI=; b=WsdhjfYFkLEx2kFsid/oyjtHvOhVpf4/gHMOIqbzWvmdpR7+mYqAJQ6VnXNb1p1JxpkILM H8dtL21qqG/sKpeXRcZ4eBQKEXSdUZQkE1/Os583wgkPIzQ9P04OcK7MwTvfm5CORVs27h JrWNhImoMED0V1VLhgbR9JWJYmFI5Ro= X-MC-Unique: RtPStId6MN6jK6nTLw1Y1A-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 36/37] ui/dbus: register D-Bus VC handler Date: Sun, 10 Oct 2021 01:08:37 +0400 Message-Id: <20211009210838.2219430-37-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815557093100001 From: Marc-Andr=C3=A9 Lureau Export the default consoles over the D-Bus chardev. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- ui/dbus.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/ui/dbus.c b/ui/dbus.c index 38d6ccc607..97248ceadb 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -352,6 +352,57 @@ dbus_display_class_init(ObjectClass *oc, void *data) get_gl_mode, set_gl_mode); } =20 +#define TYPE_CHARDEV_VC "chardev-vc" + +typedef struct DBusVCClass { + DBusChardevClass parent_class; + + void (*parent_parse)(QemuOpts *opts, ChardevBackend *b, Error **errp); +} DBusVCClass; + +DECLARE_CLASS_CHECKERS(DBusVCClass, DBUS_VC, + TYPE_CHARDEV_VC) + +static void +dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend, + Error **errp) +{ + DBusVCClass *klass =3D DBUS_VC_CLASS(object_class_by_name(TYPE_CHARDEV= _VC)); + const char *name =3D qemu_opt_get(opts, "name"); + const char *id =3D qemu_opts_id(opts); + + if (name =3D=3D NULL) { + name =3D ""; + if (g_str_has_prefix(id, "compat_monitor")) { + name =3D "org.qemu.monitor.hmp.0"; + } + if (g_str_has_prefix(id, "serial")) { + name =3D "org.qemu.console.serial.0"; + } + if (!qemu_opt_set(opts, "name", name, errp)) { + return; + } + } + + klass->parent_parse(opts, backend, errp); +} + +static void +dbus_vc_class_init(ObjectClass *oc, void *data) +{ + DBusVCClass *klass =3D DBUS_VC_CLASS(oc); + ChardevClass *cc =3D CHARDEV_CLASS(oc); + + klass->parent_parse =3D cc->parse; + cc->parse =3D dbus_vc_parse; +} + +static const TypeInfo dbus_vc_type_info =3D { + .name =3D TYPE_CHARDEV_VC, + .parent =3D TYPE_CHARDEV_DBUS, + .class_init =3D dbus_vc_class_init, +}; + static void early_dbus_init(DisplayOptions *opts) { @@ -365,6 +416,8 @@ early_dbus_init(DisplayOptions *opts) =20 display_opengl =3D 1; } + + type_register(&dbus_vc_type_info); } =20 static void --=20 2.33.0.721.g106298f7f9 From nobody Thu May 16 20:22:53 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1633815681340656.7203365910003; Sat, 9 Oct 2021 14:41:21 -0700 (PDT) Received: from localhost ([::1]:35426 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mZK5o-000370-6V for importer@patchew.org; Sat, 09 Oct 2021 17:41:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38786) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJj7-0003fW-1S for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:17:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32262) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mZJj5-0002el-Ar for qemu-devel@nongnu.org; Sat, 09 Oct 2021 17:17:52 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-329-nNCXxf1sN0OX9MiCL8eELw-1; Sat, 09 Oct 2021 17:17:49 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9E3431006AA3 for ; Sat, 9 Oct 2021 21:17:48 +0000 (UTC) Received: from localhost (unknown [10.39.208.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id B26195D9D3; Sat, 9 Oct 2021 21:17:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1633814270; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n5xIfbeqTlptRK8N+FegRQDEx6bDW7HwxzcmplSnJfo=; b=GoMFqr/g2ky+20alVtXfyHPE2lHNSfmIyYGgWDwg/jqV6OT7PIwtscOkGNSQf4Lx/yhj8l dtYX74r/A6hxrb/qIVpjvfEkS7T0lvIDUI/sh6XUf5TdmRdAAEE4EaQPqKE1Go6/fJ7aHJ Z37ZXYZzT28a4MboXZd3f8SwRiGQdX8= X-MC-Unique: nNCXxf1sN0OX9MiCL8eELw-1 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Subject: [PATCH v2 37/37] MAINTAINERS: update D-Bus section Date: Sun, 10 Oct 2021 01:08:38 +0400 Message-Id: <20211009210838.2219430-38-marcandre.lureau@redhat.com> In-Reply-To: <20211009210838.2219430-1-marcandre.lureau@redhat.com> References: <20211009210838.2219430-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=marcandre.lureau@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=216.205.24.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.049, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=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.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1633815682559100001 From: Marc-Andr=C3=A9 Lureau Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Gerd Hoffmann --- MAINTAINERS | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 50435b8d2f..b429afba33 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2839,11 +2839,15 @@ D-Bus M: Marc-Andr=C3=A9 Lureau S: Maintained F: backends/dbus-vmstate.c -F: tests/dbus-vmstate* +F: ui/dbus* +F: audio/dbus* F: util/dbus.c +F: include/ui/dbus* F: include/qemu/dbus.h -F: docs/interop/dbus.rst -F: docs/interop/dbus-vmstate.rst +F: docs/interop/dbus* +F: docs/sphinx/dbus* +F: docs/sphinx/fakedbusdoc.py +F: tests/qtest/dbus* =20 Seccomp M: Eduardo Otubo --=20 2.33.0.721.g106298f7f9