From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496634; cv=none; d=zohomail.com; s=zohoarc; b=Dr8KqdCMAUmBUAybulPMX9hy+GxjZCkMeRr2zjb21iSo2eAlnl9IiCszDSk9fMsmMRfzYqT9PfqAl6lWk/kEm4a7qhwHcR2YqYnEYZHiqsPFbzuPt7ccqOpe/T/cCkfghyIwxARkfZCYaLyd0vSiLJoz8ozBvMG4lUV5n+qDcKo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496634; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=59PFEgMXfzUbVp1BVkysKDYZbBbk20cj4itZloqYX+8=; b=FJLjawYWW8AJt8DbHNwjAhDuiK9DVfywgivpP2FsXKVLYXttc6pfS/DaUjkhCZBNRpHAQjcgAwAEtjaD9rNJ1Xl85hiyQS6unpo5Qvrhvx96ya5aSvybXlcbyFXVJzFcTZc1ctawuvqA1l+VZGKGazHJPoEXRIu7yTnHHAmiBR8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496634507799.800860386113; Wed, 29 Apr 2026 14:03:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC49-0003TQ-9c; Wed, 29 Apr 2026 17:03:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC46-0003TD-HH for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:27 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC45-0003C9-2j for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:26 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-443-nIp_h41NMvuzNubEwvxHrg-1; Wed, 29 Apr 2026 17:03:21 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 226C61956094 for ; Wed, 29 Apr 2026 21:03:20 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C10B319560B6; Wed, 29 Apr 2026 21:03:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496602; 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=59PFEgMXfzUbVp1BVkysKDYZbBbk20cj4itZloqYX+8=; b=hZ4LZghERj/IqxdjTh4GekiU8WjChdBg4JwHXh/Y7cg9ZbSCwRj+zFAbvrc42wzrLmh5I1 R51DCwI/O28hddKsBRXOaP4jy1l2YMLjueeqyj0/YNi+lb3W+/1OP2yM4FY/IFP6q05ydt F633j6DuM+Zd6fawmGo9qWjCbkq26MQ= X-MC-Unique: nIp_h41NMvuzNubEwvxHrg-1 X-Mimecast-MFC-AGG-ID: nIp_h41NMvuzNubEwvxHrg_1777496600 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:34 +0400 Subject: [PATCH v3 01/26] qemu-options.hx: document -chardev vc backend-specific behavior MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-1-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=1375; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=TCKGeNX61zdbvMDhyprN1vYtrHLQam3/ghGCoyv8Sxs=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILkRBxIeIoQ4+LsCD5F6x5RBXr0ViTmuPHS dnYPz6Jj1aJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5SdYEACSqBybqqDslqKprC2aPEPWqWOat0Z6rlOVHfjGtALK+w6PZXX0AiHzwOTZ/xRcHGLYcoR G8Ffq/xBVgwmgVE1ZLnrPScPkkMNofJpm+Yoldrzf+UL0qYSMlHABVAtwH03ZkLW2GgdJlQRcRj XdePk7+YLabKyeave/IMVYOE/W9LAOeUHZmdDwe0P7K1sdocgO+MLH+fRIWEvM/w+9QkfvxzxAX ictlpZguMX4RCxkgbuTRLhPs40WKGd1yfcuiCOwq3DFah6p1tacpy3floECNJXTNEdWBcYyoP6b JFSSZE6RZ/FsdlXWJyLd3sOHH/wQTlm9wHurYjK/4h8b+jAAapr88jAGAnHjJc4EXCBeaGiynos U6xlu8bxUrZfY1AlJb9NR4BnEkiiUUpA2R4vtYsD8YrqhFyq/ORvK/dFZL+EqmJLCSJVVhlyoue aWTjcyfaQvW7S/qKauUbu+Ip+ypHl1414LprtIt7wNUZLspyXnDzBs92RgtSwEKO1bxfF68n8tA wSv/u8vYWRLPWmf6F7T3SQJZHiyrjFs8r/GaRskdq5Id+TGHRzN9/vHo8nwzKO7GoFG1p4q+HcB PTceyRrIyO0L61x2s/7kf8NP1D2Dhdyb4J4HvodBq+fhtcTcGPl1N3X1B6OfS9zCX32O+WudS/W KmgIBmtJ8J9Y6oQ== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496636938158500 The -chardev vc documentation only mentioned the built-in console with optional size parameters, but the actual behavior depends on the display backend. Document the GTK (libvte), D-Bus and spice-app cases. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- qemu-options.hx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index e780bc2ac06..efffeaaf55e 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4277,8 +4277,17 @@ The available backends are: and hub devices is not supported as well. =20 ``-chardev vc,id=3Did[[,width=3Dwidth][,height=3Dheight]][[,cols=3Dcols][,= rows=3Drows]]`` - Connect to a QEMU text console. ``vc`` may optionally be given a - specific size. + Connect to a QEMU text console. The implementation and supported featu= re + set depend on the selected display backend. + + - The GTK backend uses libvte for the emulation and display (when avai= lable). + + - The D-Bus backend exports the character device as a Chardev object. + + - spice-app backend exports it as a Spice port. + + In other cases, QEMU uses its own emulated VT100, and ``vc`` may optio= nally be + given a specific size. =20 ``width`` and ``height`` specify the width and height respectively of the console, in pixels. --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496674; cv=none; d=zohomail.com; s=zohoarc; b=jucmeme6JSj6/UkI52XKDpTReqFL6+qV1s7D7YNY/S2A70XNRjkw/CUrL0MbRo4gBLMAKzA9u/v8ucbqCf2HjR86tNvx2FTFCLJcLoriVukZY4l1Wz0JoUBpECscCr2j0MlUF8vw51CSf2l3jt7AFFjfohwwTfsLViapy6lxYeQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496674; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=aEGhBdo4FIrkpLD+9d7/P2GvS/cJYUI8tGJGysFprBg=; b=Qa/gVG8AZ08Vi1MBdi6SqkVW5gh5zPORcXCgefES7ZhGa5+fJUqlM4TZ552nkv7izDNq1HwJn06QI4bipnbdj+sT5Sk/Ts/kSvQ2F8zZj/VqPDJM3WMdD8Glp1WA89aAEwTQbyG6uvwfhlA7aHwsytLWK1iIdKwsHI8D9k0ZuQ0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496674760732.1228857788268; Wed, 29 Apr 2026 14:04:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4H-0003Ui-Fu; Wed, 29 Apr 2026 17:03:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4B-0003TZ-7O for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC49-0003Cc-9t for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:30 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-13-bvst9hv-PSOd6ARi-Iug2g-1; Wed, 29 Apr 2026 17:03:26 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C202519560A3 for ; Wed, 29 Apr 2026 21:03:25 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7441019560B6; Wed, 29 Apr 2026 21:03:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496608; 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=aEGhBdo4FIrkpLD+9d7/P2GvS/cJYUI8tGJGysFprBg=; b=KzSTebnFt2hweqyAZAkQuNN7Su4wFzrqiufX3Odfyy7pdzwG7y8l4fM2moNqNpqWoXP4T5 S8NHfYjZanks4qX4zdnpmt8qqRF4GQcoxB5wJNLMhYuwouluO7h6dasS7tRL8jRZR9oto1 cXHFj3s8M3BlwKgNuvi5tVSiVJQMKVk= X-MC-Unique: bvst9hv-PSOd6ARi-Iug2g-1 X-Mimecast-MFC-AGG-ID: bvst9hv-PSOd6ARi-Iug2g_1777496605 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:35 +0400 Subject: [PATCH v3 02/26] char: error out if given unhandled size options MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-2-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=3309; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=I4+LryVaXPKdaH8bJajB6Zo4PYtkb+nVwNduq5g7EEw=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILYMDi4EBmkn27F8+IAKd9qhV7vxX4QSqty 0hO+L3o6MaJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5SjCD/wOzsjPXuVASot173e4hj7ZuEumW5idb3Rxx1nA8vVwMi/HhXT89OuUElliB0awSAj60to YMYy3JD55g2P9jKlP+kb2Pvn5cUjv3C/9kX2HRgLr54Fr20iM/7AFyKl9qzYAz2CcyNOwF3TN1l sI6g9LdSuqwJngXpv4Miy3ZWTnjNZezwbuZLahkttDXqtnS+zIS5BIso7Cd70vf2Z6j3cDGycYb /fkYew6OwX9GMFG/cfSuvIlKbrrbrYz33HXIkOmhaxgNL0IWrO33e+vY5zDRpV7Nmj1HvvrqWBG 5PMRmYrEVzoqQdkfhXtmbJYI8y9NAzLeh+9dV2d+8tJfN3k7ZCaftuCApHd4cE8XdelAC7E3lgb Hkk7hxGjEfi5cznpCL7J+gVtZzpX4XJ5bw2ZisOMLlpfgkHGe8M2cVAP4W3C4PEr9UoGy814MWC zBegkPLSckN/WdCogpO8Ozpl2WIWR5y6HNeZsSOD3Hjzk6oyk0WnfCIdnGm523nj/WSaSXdbrTI z/u+9dcwseDqUn0V7Y07iLJAAqKTc4sYp2DmAjR7KknB7p/6KFzRQcO9MLQylLLwX2qwcY4QQru HO+tj16oxud37I4QK1ukQ3Ma2HU3mYJWUZ9lFAJPxhJTp2vep0P3kSykhOE1p0mFI8/3pmrlHLX iS78/hInZUPdidA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496676358154100 This is a small help, because in fact all combined chardev options are accepted by qemu_chardev_opts[]. But given that a user may legitimately want to use the size options with a VC backend, we can report an error when we know the backend doesn't support it. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- include/chardev/char.h | 1 + include/qemu/option.h | 1 + chardev/char.c | 12 ++++++++++++ ui/console-vc.c | 1 + util/qemu-option.c | 13 +++++++++++++ 5 files changed, 28 insertions(+) diff --git a/include/chardev/char.h b/include/chardev/char.h index c2c42e4b7a3..51995f06a82 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -254,6 +254,7 @@ struct ChardevClass { =20 bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ bool supports_yank; + bool supports_size_opts; =20 /* parse command line options and populate QAPI @backend */ void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error **err= p); diff --git a/include/qemu/option.h b/include/qemu/option.h index 01e673ae03f..9a00ac0a356 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -73,6 +73,7 @@ struct QemuOptsList { =20 const char *qemu_opt_get(QemuOpts *opts, const char *name); char *qemu_opt_get_del(QemuOpts *opts, const char *name); +bool qemu_opt_has_any(QemuOpts *opts, const char * const *names); /** * qemu_opt_has_help_opt: * @opts: options to search for a help request diff --git a/chardev/char.c b/chardev/char.c index 48b326d57b9..55dce9725e8 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -639,6 +639,18 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Er= ror **errp) return NULL; } =20 + if (!cc->supports_size_opts) { + const char * const invalid_opts[] =3D { + "width", "height", "cols", "rows", NULL + }; + + if (qemu_opt_has_any(opts, invalid_opts)) { + error_setg(errp, "chardev '%s' does not support size options", + qemu_opts_id(opts)); + return NULL; + } + } + backend =3D g_new0(ChardevBackend, 1); backend->type =3D CHARDEV_BACKEND_KIND_NULL; =20 diff --git a/ui/console-vc.c b/ui/console-vc.c index 6163e21d2c6..62a5e3caf57 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -1251,6 +1251,7 @@ static void char_vc_class_init(ObjectClass *oc, const= void *data) cc->chr_write =3D vc_chr_write; cc->chr_accept_input =3D vc_chr_accept_input; cc->chr_set_echo =3D vc_chr_set_echo; + cc->supports_size_opts =3D true; } =20 static const TypeInfo char_vc_type_info =3D { diff --git a/util/qemu-option.c b/util/qemu-option.c index 770300dff12..9fbf425f86e 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -271,6 +271,19 @@ const char *qemu_opt_get(QemuOpts *opts, const char *n= ame) return opt->str; } =20 +bool qemu_opt_has_any(QemuOpts *opts, const char * const *names) +{ + int it; + + for (it =3D 0; names[it]; it++) { + if (qemu_opt_get(opts, names[it])) { + return true; + } + } + return false; +} + + void qemu_opt_iter_init(QemuOptsIter *iter, QemuOpts *opts, const char *na= me) { iter->opts =3D opts; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496675; cv=none; d=zohomail.com; s=zohoarc; b=XClNC3AO9CTvXUaQZeSkw+rtbZpnuNC1RQQqhwzw5RRRuSi3XPrGVLcnvquS5q/bbj1WiojFt4FnmWJtYlBGb7DOK8eRxLcvpPkYrQJ8flWqdX6ZktlPPrSq7g8wTGhCWBVO0Tw+BiU+y1te0+Rzk8eUP24aTgU9XAtCjDB8pqw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496675; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Cno5h8iE+Ze095lareXK4yoKI0EkSMjjNdtAoCEZ2Xk=; b=E2szCK4w4kFeX1MkJ2zcS7+wQJlA/vyQ+l3PryCOtFR85qpXT1YxuiZuj2O+3Lf9lmDWRH/LNcjuC+WkiM5ZUE9LZZ66oXkgg01AMmwp8dnAt7if0ZcI8IPZdSxjozNWYCO6pUCRn0CVThHBuZ8IfMz1Jk1gnefhpShKr29ggYY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496675661722.9037401631656; Wed, 29 Apr 2026 14:04:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4K-0003VT-8R; Wed, 29 Apr 2026 17:03:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4I-0003Uz-3P for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4G-0003Dp-7p for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:37 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-74-_FgDjdECOwO9IYYMQNCqXQ-1; Wed, 29 Apr 2026 17:03:32 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8DD8E19560B5 for ; Wed, 29 Apr 2026 21:03:31 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5476619560AB; Wed, 29 Apr 2026 21:03:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496615; 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=Cno5h8iE+Ze095lareXK4yoKI0EkSMjjNdtAoCEZ2Xk=; b=OyhTkVYdua8x3jN8ykDQfsZZFFnIthWVLiDKCOijwPmnaZdZpDCNMScF170D172Xj6Dmgh VpIUzO4MaLaoYbjgKzduAatJ2Hf91w/wEo2/V01EbCC3KumaqZGkY5EGjufvJPaAwbbYzn gAqRN8cBj/fLhFNP/HsiLLF/4sy9J04= X-MC-Unique: _FgDjdECOwO9IYYMQNCqXQ-1 X-Mimecast-MFC-AGG-ID: _FgDjdECOwO9IYYMQNCqXQ_1777496611 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:36 +0400 Subject: [PATCH v3 03/26] ui/console: add vc encoding=utf8/cp437 option MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-3-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=8065; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=plQyXHsWEQ86pudBX8gWIrgkqQYgfrJswIQWOyKUTEg=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILCnWPdXZvxRFodwIiAEjcj560A237mj203 +Rn6d3eGJuJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5W6hD/sFj10bw7CDXeBmjVTHNo26HWvtO23JSWXQGZQXam2FPfmBAM56ZwQmaQuy29iWroCml5n 7Eig9FrXdhYUVUCy9gk2rSHs3ggpzauAlrUHWvs11WAVD+Tw5VEHEHCOdxsL9hE/wKqYaQhxwV/ MHtMAb6qSqurz3jliIh47pVsteGatdFeFSl2Z4ywZESlcdeXgIAwLpughd1GPMeAAkzmP7QcNBU xlTZ1hMCDBekQsKYXkC45LD0QhKDIWOffAxykjg8JwMlAPC+qDXiK9VuGY/0fBT7LbDS0DbGYBP yEMWPrhz/yrOWrF79CVV+zuukJjmORhvP34oGQ0wf4lE2y/HorTpmrWI8pMkTCw2FwmjmAW/W15 nyesSW/OKDhsbIwR+zCLLd+pjwmE4cBjRgDusRYrMSjyWSTB4d1bqYgMp4Nni3jETtLF06ym/Oj z260OJGPQq9hXNuAEw5oidz5s1yE5JmI2acGwznKmPDpZZYyt8yaLt4pkdgovP2C+SfjyupnbAx DY/H+LVDSyd1jC6VmaNqxw+7VFV3OiTc5g8T/Fhn58iZ1PFkgVCg26Vq0/f4qN3lLpveKklaUHb rykXnEBeoqCoDgO5RFEjUBxYwWfoEXwi0cmk4G7G/pIinWCJlfuynO/ha3YYGgB4d7NR3ZOQImV ftUreP4q8QZZ9BQ== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496676624158500 Expose a new "encoding" QemuOpt option. Add the corresponding QAPI type and properties. This is going to be wired in the following commits. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- qapi/char.json | 30 ++++++++++++++++++++++++++++-- include/chardev/char.h | 1 + chardev/char.c | 10 ++++++++++ ui/console-vc.c | 12 ++++++++++++ ui/dbus.c | 13 +++++++++++++ qemu-options.hx | 7 +++++-- 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/qapi/char.json b/qapi/char.json index a4abafa6803..aa5ee9ffcd0 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -377,6 +377,24 @@ 'base': 'ChardevCommon', 'if': 'CONFIG_SPICE' } =20 +## +# @ChardevVCEncoding: +# +# Character encoding expected from the guest on a virtual console. +# +# @cp437: CP437 (8-bit Extended ASCII / VGA). Every byte maps +# directly to a glyph; suitable for DOS or other guests that +# output raw CP437. +# +# @utf8: UTF-8. Multi-byte sequences are decoded and then mapped +# back to CP437 glyphs for display; unmappable codepoints are +# shown as '?'. Suitable for modern Linux guests. +# +# Since: 11.1 +## +{ 'enum': 'ChardevVCEncoding', + 'data': [ 'cp437', 'utf8' ] } + ## # @ChardevDBus: # @@ -384,10 +402,14 @@ # # @name: name of the channel (following docs/spice-port-fqdn.txt) # +# @encoding: character encoding the guest is expected to use +# (since 11.1) +# # Since: 7.0 ## { 'struct': 'ChardevDBus', - 'data': { 'name': 'str' }, + 'data': { 'name': 'str', + '*encoding': 'ChardevVCEncoding' }, 'base': 'ChardevCommon', 'if': 'CONFIG_DBUS_DISPLAY' } =20 @@ -404,6 +426,9 @@ # # @rows: console height, in chars # +# @encoding: character encoding the guest is expected to use +# (since 11.1) +# # .. note:: The options are only effective when the VNC or SDL # graphical display backend is active. They are ignored with the # GTK, Spice, VNC and D-Bus display backends. @@ -414,7 +439,8 @@ 'data': { '*width': 'int', '*height': 'int', '*cols': 'int', - '*rows': 'int' }, + '*rows': 'int', + '*encoding': 'ChardevVCEncoding' }, 'base': 'ChardevCommon' } =20 ## diff --git a/include/chardev/char.h b/include/chardev/char.h index 51995f06a82..f05e8dba0a9 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -255,6 +255,7 @@ struct ChardevClass { bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ bool supports_yank; bool supports_size_opts; + bool supports_encoding_opts; =20 /* parse command line options and populate QAPI @backend */ void (*chr_parse)(QemuOpts *opts, ChardevBackend *backend, Error **err= p); diff --git a/chardev/char.c b/chardev/char.c index 55dce9725e8..ca8b37ed8d7 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -650,6 +650,13 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Er= ror **errp) return NULL; } } + if (!cc->supports_encoding_opts) { + if (qemu_opt_get(opts, "encoding")) { + error_setg(errp, "chardev '%s' does not support encoding optio= n", + qemu_opts_id(opts)); + return NULL; + } + } =20 backend =3D g_new0(ChardevBackend, 1); backend->type =3D CHARDEV_BACKEND_KIND_NULL; @@ -972,6 +979,9 @@ QemuOptsList qemu_chardev_opts =3D { },{ .name =3D "rows", .type =3D QEMU_OPT_NUMBER, + },{ + .name =3D "encoding", + .type =3D QEMU_OPT_STRING, },{ .name =3D "mux", .type =3D QEMU_OPT_BOOL, diff --git a/ui/console-vc.c b/ui/console-vc.c index 62a5e3caf57..7bb6a483753 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -1211,6 +1211,7 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend = *backend, Error **errp) static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **= errp) { int val; + const char *str; ChardevVC *vc; =20 backend->type =3D CHARDEV_BACKEND_KIND_VC; @@ -1240,6 +1241,16 @@ static void vc_chr_parse(QemuOpts *opts, ChardevBack= end *backend, Error **errp) vc->has_rows =3D true; vc->rows =3D val; } + + str =3D qemu_opt_get(opts, "encoding"); + if (str) { + int cs =3D qapi_enum_parse(&ChardevVCEncoding_lookup, str, -1, err= p); + if (cs < 0) { + return; + } + vc->has_encoding =3D true; + vc->encoding =3D cs; + } } =20 static void char_vc_class_init(ObjectClass *oc, const void *data) @@ -1252,6 +1263,7 @@ static void char_vc_class_init(ObjectClass *oc, const= void *data) cc->chr_accept_input =3D vc_chr_accept_input; cc->chr_set_echo =3D vc_chr_set_echo; cc->supports_size_opts =3D true; + cc->supports_encoding_opts =3D true; } =20 static const TypeInfo char_vc_type_info =3D { diff --git a/ui/dbus.c b/ui/dbus.c index 794b65c4ada..721cc71d39b 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -471,6 +471,8 @@ dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend, 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); + const char *str; + ChardevDBus *dbus; =20 if (name =3D=3D NULL) { if (g_str_has_prefix(id, "compat_monitor")) { @@ -486,6 +488,16 @@ dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend, } =20 klass->parent_parse(opts, backend, errp); + dbus =3D backend->u.dbus.data; + str =3D qemu_opt_get(opts, "encoding"); + if (str) { + int cs =3D qapi_enum_parse(&ChardevVCEncoding_lookup, str, -1, err= p); + if (cs < 0) { + return; + } + dbus->has_encoding =3D true; + dbus->encoding =3D cs; + } } =20 static void @@ -496,6 +508,7 @@ dbus_vc_class_init(ObjectClass *oc, const void *data) =20 klass->parent_parse =3D cc->chr_parse; cc->chr_parse =3D dbus_vc_parse; + cc->supports_encoding_opts =3D true; } =20 static const TypeInfo dbus_vc_type_info =3D { diff --git a/qemu-options.hx b/qemu-options.hx index efffeaaf55e..44aa3a4cd3b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4044,7 +4044,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev, " [,logfile=3DPATH][,logappend=3Don|off]\n" "-chardev msmouse,id=3Did[,mux=3Don|off][,logfile=3DPATH][,logappend= =3Don|off]\n" "-chardev vc,id=3Did[[,width=3Dwidth][,height=3Dheight]][[,cols=3Dcols= ][,rows=3Drows]]\n" - " [,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|off]\n" + " [,mux=3Don|off][,logfile=3DPATH][,logappend=3Don|off][,encod= ing=3DENCODING]\n" "-chardev ringbuf,id=3Did[,size=3Dsize][,logfile=3DPATH][,logappend=3D= on|off]\n" "-chardev file,id=3Did,path=3Dpath[,input-path=3Dinput-file][,mux=3Don= |off][,logfile=3DPATH][,logappend=3Don|off]\n" "-chardev pipe,id=3Did,path=3Dpath[,mux=3Don|off][,logfile=3DPATH][,lo= gappend=3Don|off]\n" @@ -4276,7 +4276,7 @@ The available backends are: Several frontend devices is not supported. Stacking of multiplexers and hub devices is not supported as well. =20 -``-chardev vc,id=3Did[[,width=3Dwidth][,height=3Dheight]][[,cols=3Dcols][,= rows=3Drows]]`` +``-chardev vc,id=3Did[[,width=3Dwidth][,height=3Dheight]][[,cols=3Dcols][,= rows=3Drows]][,encoding=3DENCODING]`` Connect to a QEMU text console. The implementation and supported featu= re set depend on the selected display backend. =20 @@ -4295,6 +4295,9 @@ The available backends are: ``cols`` and ``rows`` specify that the console be sized to fit a text console with the given dimensions. =20 + ``encoding`` specifies the character set expected from the guest: + ``utf8`` or ``cp437`` (8-bit Extended ASCII / VGA). + ``-chardev ringbuf,id=3Did[,size=3Dsize]`` Create a ring buffer with fixed size ``size``. size must be a power of two and defaults to ``64K``. --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496748; cv=none; d=zohomail.com; s=zohoarc; b=LRcbochWpduAEbwqr0Rf8ZCT8MSzmX2f4ZTbV/ayuc2Z24HLbFxyNmOsF3O8D6JsYNWcCx1qHY3B/WMp/kQbBnweA8CTkS+gmlCmeAk5xwbPcY0vNn6QyucR4RVhVz1r6HDSGBJKfyvy6tfZ9VH8b2p7F6CXV+cQkUgkmRKl6Gc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496748; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=lOr5ZL7bHRKd8fAlE/hxuW/GBXSIWog+NxkF9A50Knk=; b=cPt7fysFqDv6N0/i+f0m0Q3wLRAFf0J/KMEE/pCPhcz1lfbXmwmFrC97kaIFGWJuRLI4xUwvvbek2vEBWBJpJpZ+FhrFbGKFe6c/OO/rr6xM7qEFiNwQgS4SKuu04OS95V7BSv3xjFSbmb7GDi/HbKXkTOjeUGkMm10fJtaBCgY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496748060395.1054563854509; Wed, 29 Apr 2026 14:05:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4P-0003WM-4N; Wed, 29 Apr 2026 17:03:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4M-0003Vd-Rq for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4K-0003EY-RH for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:42 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-624-hqAMBod7PvOZbYgooL0sVA-1; Wed, 29 Apr 2026 17:03:38 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5BDEB1800366 for ; Wed, 29 Apr 2026 21:03:37 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EE350300019F; Wed, 29 Apr 2026 21:03:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496619; 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=lOr5ZL7bHRKd8fAlE/hxuW/GBXSIWog+NxkF9A50Knk=; b=UVy3Y1RaMun9rFKNOJtjJF3xVtkDJDPewdD/pkusjP1ju/RTGC2jU1o3bLQZ5X58MBX9vL 3DseK6z8EskjZTG/52p43dbGtlQ3r6i+LoqHP2ywEjxNDpa96PaA87bJXeeoEarhfL2xL0 lsKQ2rBYEpK8I5cGU0/UedA7kXyLyUU= X-MC-Unique: hqAMBod7PvOZbYgooL0sVA-1 X-Mimecast-MFC-AGG-ID: hqAMBod7PvOZbYgooL0sVA_1777496617 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:37 +0400 Subject: [PATCH v3 04/26] ui/console: default vc encoding to cp437 for machine < 11.1 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-4-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=6927; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=QReFTyG+sKmftwnoD428OyLIJhjEp+YtsXRj2SNT6aw=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILC+QFxP9v1wHNLcMQja/O3xPIpBQaBTdem EZpDR/J9pOJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5UFuEACfiBbvgfObJ3KBPIt1rBrK39CxH/hyLv5FBojhBh/GXLSuI+y3ktRMqm0YBS26wVv6b+F cF6juhUNXgKK5h4GL8yES/kmpFOi8nO0mqp+23KaEQzdrcM6KEGKcw6kf0Pc8ZGF/ARN9EgJJBb DlAFq5Hbw8NC8hcOCGG5jN0oJ/WlL7Gmc2tsdFJoLAeZrbfO851UNgSg2EcwN3UGVDRrzvuFK6N PEgLNT1RYUaO68RtfE0Du7sxB4pdbl9/iD+1b+cJ1rFUG4ydDWc1zxLCLZnEyK8rAS5cpqmE3qJ v3YrR5d0+7pedPIfCN3Cf5JhpROFk0JyF/S+3ydFHISyGqSfQrnS9n51tOJxb+ti7EO+Xrn0jWZ x/+7GxPXI1D6kdJ6IUsqzSzsX62VlkZdAXTKzbKhkXb717irEuvFtrE6gOKhIN+6FUY+Ifn6aiw 9PTxOkUSsAc5UzBEF1yFg6pDiz77nVK79q+gOV62Q54NUqKJAWKKCRJPj+HUwBTY38W6sFtJB9v QaJaje3vHUpqi6J50FdWfNLRtP3S/7OUUMosqWcb/pQxZA0hJobgS8EtvUUVdiuwvm/rVo8iyzH wqVdPbJodScds9lpklgUAN6PT3LV53EUtEC1eGns9RLfivpFtOrjfC7kx4+/d3aCVSAL54ByJAa DrhZ4O+JEVMOgGA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496748904158501 Add a QOM "encoding" enum property to some chardev-vc backends (console-vc & dbus - gtk and spice don't make use of it) so that the machine compat mechanism can override the default. For machine versions prior to 11.1, the charset defaults to cp437 (raw 8-bit VGA) instead of utf8, preserving the historical behaviour. The following commits are going to wire this to VT100 emulation code and an extra exported D-Bus property. Note that GTK libvte uses utf8 unconditionally, and Spice doesn't have a way to set the encoding, and typically just use libvte in client too. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- include/chardev/char.h | 19 +++++++++++++++++++ hw/core/machine.c | 4 +++- ui/console-vc.c | 18 ++++++++++++++++++ ui/dbus.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/include/chardev/char.h b/include/chardev/char.h index f05e8dba0a9..7377d8e60a0 100644 --- a/include/chardev/char.h +++ b/include/chardev/char.h @@ -332,4 +332,23 @@ void resume_mux_open(void); char *qemu_chr_get_pty_name(Chardev *chr); char *qemu_chr_get_filename(Chardev *chr); =20 +#define CHARDEV_VC_ENCODING_PROPERTY_DEFINE(cast_func) \ +static int get_encoding(Object *obj, Error **errp) \ +{ \ + return cast_func(obj)->encoding; \ +} \ + \ +static void set_encoding(Object *obj, int value, Error **errp) \ +{ \ + cast_func(obj)->encoding =3D value; \ +} + +static inline void chardev_vc_add_encoding_prop(ObjectClass *oc, + int (*get)(Object *, Error **), + void (*set)(Object *, int, Error **)) +{ + object_class_property_add_enum(oc, "encoding", "ChardevVCEncoding", + &ChardevVCEncoding_lookup, get, set); +} + #endif diff --git a/hw/core/machine.c b/hw/core/machine.c index 1b661fd36ae..63baff859f3 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -39,7 +39,9 @@ #include "hw/acpi/generic_event_device.h" #include "qemu/audio.h" =20 -GlobalProperty hw_compat_11_0[] =3D {}; +GlobalProperty hw_compat_11_0[] =3D { + { "chardev-vc", "encoding", "cp437" }, +}; const size_t hw_compat_11_0_len =3D G_N_ELEMENTS(hw_compat_11_0); =20 GlobalProperty hw_compat_10_2[] =3D { diff --git a/ui/console-vc.c b/ui/console-vc.c index 7bb6a483753..fd7e6fb7b06 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -9,6 +9,7 @@ #include "qemu/fifo8.h" #include "qemu/option.h" #include "qemu/queue.h" +#include "qom/compat-properties.h" #include "ui/console.h" #include "ui/vgafont.h" =20 @@ -109,6 +110,7 @@ struct VCChardev { TextAttributes t_attrib; /* currently active text attributes */ TextAttributes t_attrib_saved; int x_saved, y_saved; + ChardevVCEncoding encoding; }; typedef struct VCChardev VCChardev; =20 @@ -1189,6 +1191,9 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend = *backend, Error **errp) =20 s->chr =3D chr; drv->console =3D s; + if (vc->has_encoding) { + drv->encoding =3D vc->encoding; + } =20 /* set current text attributes to default */ drv->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; @@ -1253,6 +1258,8 @@ static void vc_chr_parse(QemuOpts *opts, ChardevBacke= nd *backend, Error **errp) } } =20 +CHARDEV_VC_ENCODING_PROPERTY_DEFINE(VC_CHARDEV) + static void char_vc_class_init(ObjectClass *oc, const void *data) { ChardevClass *cc =3D CHARDEV_CLASS(oc); @@ -1264,12 +1271,23 @@ static void char_vc_class_init(ObjectClass *oc, con= st void *data) cc->chr_set_echo =3D vc_chr_set_echo; cc->supports_size_opts =3D true; cc->supports_encoding_opts =3D true; + + chardev_vc_add_encoding_prop(oc, get_encoding, set_encoding); +} + +static void char_vc_init(Object *obj) +{ + VCChardev *vc =3D VC_CHARDEV(obj); + + vc->encoding =3D CHARDEV_VC_ENCODING_UTF8; } =20 static const TypeInfo char_vc_type_info =3D { .name =3D TYPE_CHARDEV_VC, .parent =3D TYPE_CHARDEV, .instance_size =3D sizeof(VCChardev), + .instance_init =3D char_vc_init, + .instance_post_init =3D object_apply_compat_props, .class_init =3D char_vc_class_init, }; =20 diff --git a/ui/dbus.c b/ui/dbus.c index 721cc71d39b..59b73e0aa94 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -28,6 +28,7 @@ #include "qemu/main-loop.h" #include "qemu/option.h" #include "qom/object_interfaces.h" +#include "qapi-types-char.h" #include "system/system.h" #include "ui/dbus-module.h" #ifdef CONFIG_OPENGL @@ -455,12 +456,20 @@ dbus_display_class_init(ObjectClass *oc, const void *= data) =20 #define TYPE_CHARDEV_VC "chardev-vc" =20 +typedef struct DBusVCChardev { + DBusChardev parent; + + ChardevVCEncoding encoding; +} DBusVCChardev; + typedef struct DBusVCClass { DBusChardevClass parent_class; =20 void (*parent_parse)(QemuOpts *opts, ChardevBackend *b, Error **errp); } DBusVCClass; =20 +DECLARE_INSTANCE_CHECKER(DBusVCChardev, DBUS_VC_CHARDEV, + TYPE_CHARDEV_VC) DECLARE_CLASS_CHECKERS(DBusVCClass, DBUS_VC, TYPE_CHARDEV_VC) =20 @@ -500,6 +509,23 @@ dbus_vc_parse(QemuOpts *opts, ChardevBackend *backend, } } =20 +CHARDEV_VC_ENCODING_PROPERTY_DEFINE(DBUS_VC_CHARDEV) + +static bool +dbus_vc_open(Chardev *chr, ChardevBackend *backend, Error **errp) +{ + DBusVCChardev *vc =3D DBUS_VC_CHARDEV(chr); + ChardevClass *parent =3D + CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_DBUS)); + ChardevDBus *be =3D backend->u.dbus.data; + + if (be->has_encoding) { + vc->encoding =3D be->encoding; + } + + return parent->chr_open(chr, backend, errp); +} + static void dbus_vc_class_init(ObjectClass *oc, const void *data) { @@ -508,12 +534,26 @@ dbus_vc_class_init(ObjectClass *oc, const void *data) =20 klass->parent_parse =3D cc->chr_parse; cc->chr_parse =3D dbus_vc_parse; + cc->chr_open =3D dbus_vc_open; cc->supports_encoding_opts =3D true; + + chardev_vc_add_encoding_prop(oc, get_encoding, set_encoding); +} + +static void +dbus_vc_init(Object *obj) +{ + DBusVCChardev *vc =3D DBUS_VC_CHARDEV(obj); + + vc->encoding =3D CHARDEV_VC_ENCODING_UTF8; } =20 static const TypeInfo dbus_vc_type_info =3D { .name =3D TYPE_CHARDEV_VC, .parent =3D TYPE_CHARDEV_DBUS, + .instance_size =3D sizeof(DBusVCChardev), + .instance_init =3D dbus_vc_init, + .instance_post_init =3D object_apply_compat_props, .class_size =3D sizeof(DBusVCClass), .class_init =3D dbus_vc_class_init, }; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496643; cv=none; d=zohomail.com; s=zohoarc; b=fz2C2vmWdOpBxzYOh6qZPUK8R0uiQ2mGSlvYqDqR7+LWivIGiMrByvc7T0NuurbNR9n8Hl+Dgcm6mDR78Xkk94iaCDd5BUAwVe8L3WU4ClWezEjW73Y8Mn35MrJVzwm+of/PCabwtpi38+cBo9Ca0YYW9XIE0fzYjsqrbvcJpR0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496643; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=14U39x3hKFcnEg9txnoTC7C763WGgzRgszbuzkY7lcQ=; b=Tp3bKcwgLfNSH8GLttGPYfZnEDJ0+x1OWT4ovFJrVAQKc1WTd+rTHOboJtYll7UTv7G+5KkdWpjkT0K+SFRqZUND1qNHEDkri1OHNQQ4NgOcneT/DKJr2hQzslTRQwsZTW7vt30NJ42F7xQodBwEr23uFvLyPF/mU03iPlaTwrM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496643673384.140254289607; Wed, 29 Apr 2026 14:04:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4S-0003Wq-Jj; Wed, 29 Apr 2026 17:03:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4R-0003Wg-DJ for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4P-0003FE-R0 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:47 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-668-RZi9exQ6OrSDEYfSLEEtnw-1; Wed, 29 Apr 2026 17:03:43 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B113A180049F for ; Wed, 29 Apr 2026 21:03:42 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4E2B019560AB; Wed, 29 Apr 2026 21:03:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496625; 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=14U39x3hKFcnEg9txnoTC7C763WGgzRgszbuzkY7lcQ=; b=hmXOw+3I0xGo8syRB+WjBI1qwTFQgYIQ4JlOm27NkGR2ZPLgyEXo080ooBVKPKzkWBTILX 2JuVGT5QiwLJ1AWpyRGnBNNTQsNziv5eVSVZKZ6dLtY9UIGqmyGZ3PgtiPdHLnDlVV7Wtr wUnfTk3xSHaEck5rh+/amENCy23r+/8= X-MC-Unique: RZi9exQ6OrSDEYfSLEEtnw-1 X-Mimecast-MFC-AGG-ID: RZi9exQ6OrSDEYfSLEEtnw_1777496622 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:38 +0400 Subject: [PATCH v3 05/26] ui/dbus: expose vc encoding via D-Bus Chardev.VCEncoding interface MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-5-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=3680; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=4EvqtYupk8nS0o0eXyT42yY2zQZ9lVjuqZl5ryTPKwI=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILijNBE/833XnKNw7MvHsLUq0h7LpZJLgqK YrSrO/KUX6JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5dMXEAC36VxpStOMXAtCIhW2AWL3KO4CNfOx1GQYAfVvXvTgsPX7KDQL8EKglUznZW4Z4A2ykjw i4Vt8ajHAnhwtNu4JHhg8AHdHV/51OXgiQGawCmy+I4mvxe+E2rSy0t2VtwtZpyqyka3o5MVgLS kuitP6hskqeo3N99pD+k9J3HotONnWdut2xORLKGCelDvsjzi+tokJDlpO3ku1S5c+6mXu4vFWt /60aDF1+Edv/hGSOSYs/+w+Mwxaq10gq4PhrA/CoqlVpuevkskcCQoW6JLPHomhLCitSs5xY7Lc f8HY1uqmsBNF+Yf6QoHcvpyXoe79aiMV+sjPcOlmL1jIyoUTduZSAXXdcfAbJyq43qwoGa6gAhQ pyyCF0uBim9cw/r5IY1kSiBaMqvxZKPQIB659uovbaZ0cGco/UiNvRkDRDDA1XlEZekTJJT1kh+ SMTsZ2f9XOdAwubqNpnrU5/QUhDPiZz4IDmEnDaEMua8suViMxav89CdG5MNZxRbDhjZmrr+u9X q9y9ufOt3KB6I5kUi2XlA12aMuOwqt5USQYUsA5Z1u3dc6s3VyzOoPpSccmwq8sQia0EdFVK90O KivZ6I2SCUIfedq5PSYZyFhezCZwBiZoKr7NJPV5XZLKIYftmNURpYg75e3ds34xnkEn/AZb2qe oJtDNinP0p44DnA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496644429158500 When a D-Bus VC chardev is instantiated, export an extra org.qemu.Display1.Chardev.VCEncoding interface on the chardev object. This lets D-Bus display clients discover the encoding (cp437 or utf8) in use by the virtual console. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- ui/dbus.h | 1 + ui/dbus-chardev.c | 10 ++++++++++ ui/dbus.c | 6 ++++++ ui/dbus-display1.xml | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/ui/dbus.h b/ui/dbus.h index 986d7774601..e4e78590b49 100644 --- a/ui/dbus.h +++ b/ui/dbus.h @@ -126,6 +126,7 @@ typedef struct DBusChardev { =20 bool exported; QemuDBusDisplay1Chardev *iface; + QemuDBusDisplay1ChardevVCEncoding *iface_vc_encoding; } DBusChardev; =20 DECLARE_INSTANCE_CHECKER(DBusChardev, DBUS_CHARDEV, TYPE_CHARDEV_DBUS) diff --git a/ui/dbus-chardev.c b/ui/dbus-chardev.c index 9442b475517..55117029acc 100644 --- a/ui/dbus-chardev.c +++ b/ui/dbus-chardev.c @@ -53,6 +53,15 @@ dbus_display_chardev_export(DBusDisplay *dpy, DBusCharde= v *chr) sk =3D g_dbus_object_skeleton_new(path); g_dbus_object_skeleton_add_interface( sk, G_DBUS_INTERFACE_SKELETON(chr->iface)); + if (chr->iface_vc_encoding) { + const char *interfaces[] =3D { + "org.qemu.Display1.Chardev.VCEncoding", + NULL + }; + g_dbus_object_skeleton_add_interface( + sk, G_DBUS_INTERFACE_SKELETON(chr->iface_vc_encoding)); + g_object_set(chr->iface, "interfaces", interfaces, NULL); + } g_dbus_object_manager_server_export(dpy->server, sk); chr->exported =3D true; } @@ -290,6 +299,7 @@ char_dbus_finalize(Object *obj) }; =20 dbus_display_notify(&event); + g_clear_object(&dc->iface_vc_encoding); g_clear_object(&dc->iface); } =20 diff --git a/ui/dbus.c b/ui/dbus.c index 59b73e0aa94..e02a94df2f3 100644 --- a/ui/dbus.c +++ b/ui/dbus.c @@ -514,6 +514,7 @@ CHARDEV_VC_ENCODING_PROPERTY_DEFINE(DBUS_VC_CHARDEV) static bool dbus_vc_open(Chardev *chr, ChardevBackend *backend, Error **errp) { + DBusChardev *dc =3D DBUS_CHARDEV(chr); DBusVCChardev *vc =3D DBUS_VC_CHARDEV(chr); ChardevClass *parent =3D CHARDEV_CLASS(object_class_by_name(TYPE_CHARDEV_DBUS)); @@ -522,6 +523,11 @@ dbus_vc_open(Chardev *chr, ChardevBackend *backend, Er= ror **errp) if (be->has_encoding) { vc->encoding =3D be->encoding; } + dc->iface_vc_encoding =3D + qemu_dbus_display1_chardev_vcencoding_skeleton_new(); + qemu_dbus_display1_chardev_vcencoding_set_encoding( + dc->iface_vc_encoding, + qapi_enum_lookup(&ChardevVCEncoding_lookup, vc->encoding)); =20 return parent->chr_open(chr, backend, errp); } diff --git a/ui/dbus-display1.xml b/ui/dbus-display1.xml index 4a41a7e0f34..d96bae2ed64 100644 --- a/ui/dbus-display1.xml +++ b/ui/dbus-display1.xml @@ -1141,4 +1141,22 @@ --> + + + + + + --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496675; cv=none; d=zohomail.com; s=zohoarc; b=n5RAQdWOY2tNWfZyEnkASwOx1Q22xl+cnPZ+S/GqFa7xysNvKhVt4bPSOVAM/StmMDC66MHi2CfbZS8ipsBuA9N4Bs8HzbyJRa9UZOkcXdUI1xr/AdbmA5txTpMvPv97Py8RSWxXBlymFGXhP3femkJOTacwODDpXvJ/VTlMfdc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496675; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=br6O70QqSh3iMebi0q4aEn3g4fakvlyFmIO/p4QCw7E=; b=mxRMt6ee4PzquAh1tzQam0n/cO7y0fzBgOINCQZcYHRHq7F8FGCA+iOfN327T3oWAjq4jqVot4K9ynl51C8u5Wuea1EoB1X8LwWtff8MtE93mH3pS11lzVR5wT5al6hkk8CVIPfBSbs1s5H6ds9+rX0ytWfLFn2ZdKLpEup3UMY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496675361667.7043042087683; Wed, 29 Apr 2026 14:04:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4a-0003dx-BN; Wed, 29 Apr 2026 17:03:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4Y-0003cq-UT for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4W-0003G4-7j for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:03:54 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-451-apjD2SkKNcKHIi-8aEue5g-1; Wed, 29 Apr 2026 17:03:49 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D3A91180034A for ; Wed, 29 Apr 2026 21:03:48 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2AACA1800480; Wed, 29 Apr 2026 21:03:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496631; 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=br6O70QqSh3iMebi0q4aEn3g4fakvlyFmIO/p4QCw7E=; b=igxdI2uKG/BX3h70bmyBeUSrlcZTcByt0dtlSynHlUg9gBBgXMransfXqnkdh4Slr7Zcl1 c8djsTrQyf7N1yQtFWCNpk+zfcLkpkVH9mNEWT46y8yqF1QKSxUFuzJY+wQsLEZEEkfL7f qRrJ0XKVz3sGizh5WilZ8k5T2/5Oius= X-MC-Unique: apjD2SkKNcKHIi-8aEue5g-1 X-Mimecast-MFC-AGG-ID: apjD2SkKNcKHIi-8aEue5g_1777496629 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:39 +0400 Subject: [PATCH v3 06/26] ui/console-vc: add UTF-8 input decoding with CP437 rendering MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-6-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=16562; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=JYNnRUWG0VBen5PTVa/2yqsD8r/7OZ/l9vn5JdesOqY=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILOg8LQpBLh+eIKRG0vbuTj7Sy+ao11L5l5 fBznk1r+XKJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5T2sD/sF5mnMP1PAR45p6APYSPJlyPMjNNJ1wgXldsSTp4tvMqM4U5GiRfr8yf1OQMqZOxaE73Q ENZLlvc7nXrV0+nl4LSVPjwuHsF5vYHkvdJsjddQUHbpMa2ybuIknUNcq1tb3e+32XmJyHC/cth fIF+7WeZrgxKp3hKYT8Wy+6hswQ1fpcnMI1hVILjtJGzeOgLk9y6zhbhb8JPMTquZERlFzBExNS x+JquYgj3a8OVI+eNQcagVR7V1ermu3EJHnYw7es8VkmdtXXPD0H4tJuM/PadSPmotxabqzbtK/ AhUZEADWdSFYppdQ2PID1av0Y6IffO54jS73wJEV4JXPY4U0+y31Eg7Mw9CM8B47vwRdEwnghF6 +IgN0XqjB38hoUdGPaiyOP5T9clBb0V7fcKPrwzM2mIJcD42hlljswKJRfHGwI7mPugjplY/vax t7DeBm6C6Sg0XnJVWZjyDQiolgApQkD+2NOSQI+oAzQd28qmLB9apfU/rBQNx+e/OOfvbmjhI/u p4A3UTKruLzfOWIN6ycYX1vk5dAUKnZX/qAShccq1XtgMbterhMv5SkQHhaT9oJ64aWolMfRhBQ OLj7ymil1zCpBfSlBR83JEFXVMCtLYiCSP+qPMXpUBjuFlOLsMWBQn5LW1XK7Eb+UlfBOeRp6bF L5PfrWDUt2CL17Q== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496676513158500 The text console receives bytes that may be UTF-8 encoded (e.g. from a guest running a modern distro), but currently treats each byte as a raw character index into the VGA/CP437 font, producing garbled output for any multi-byte sequence. Add a UTF-8 decoder using Bjoern Hoehrmann's DFA. The DFA inherently rejects overlong encodings, surrogates, and codepoints above U+10FFFF. Completed codepoints are then mapped to CP437, unmappable characters are displayed as '?'. Note that QEMU has a "buffered" utf8 decoder in util/unicode.c, but it is not a good fit for byte-per-byte decoding. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- ui/cp437.h | 13 ++++ ui/console-vc.c | 59 ++++++++++++++++ ui/cp437.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ ui/meson.build | 2 +- 4 files changed, 278 insertions(+), 1 deletion(-) diff --git a/ui/cp437.h b/ui/cp437.h new file mode 100644 index 00000000000..81ace8317c7 --- /dev/null +++ b/ui/cp437.h @@ -0,0 +1,13 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) QEMU contributors + */ +#ifndef QEMU_CP437_H +#define QEMU_CP437_H + +#include + +int unicode_to_cp437(uint32_t codepoint); + +#endif /* QEMU_CP437_H */ diff --git a/ui/console-vc.c b/ui/console-vc.c index fd7e6fb7b06..42d642afebb 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -12,6 +12,7 @@ #include "qom/compat-properties.h" #include "ui/console.h" #include "ui/vgafont.h" +#include "ui/cp437.h" =20 #include "pixman.h" #include "trace.h" @@ -107,6 +108,8 @@ struct VCChardev { enum TTYState state; int esc_params[MAX_ESC_PARAMS]; int nb_esc_params; + uint32_t utf8_state; /* UTF-8 DFA decoder state */ + uint32_t utf8_codepoint; /* accumulated UTF-8 code point */ TextAttributes t_attrib; /* currently active text attributes */ TextAttributes t_attrib_saved; int x_saved, y_saved; @@ -624,6 +627,46 @@ static void vc_clear_xy(VCChardev *vc, int x, int y) vc_update_xy(vc, x, y); } =20 +/* + * UTF-8 DFA decoder by Bjoern Hoehrmann. + * Copyright (c) 2008-2010 Bjoern Hoehrmann + * See https://github.com/polijan/utf8_decode for details. + * + * SPDX-License-Identifier: MIT + */ +#define BH_UTF8_ACCEPT 0 +#define BH_UTF8_REJECT 12 + +static uint32_t bh_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t = byte) +{ + static const uint8_t utf8d[] =3D { + /* character class lookup */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + /* state transition lookup */ + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,= 12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24= ,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24= ,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36= ,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, + }; + uint32_t type =3D utf8d[byte]; + + *codep =3D (*state !=3D BH_UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xffu >> type) & (byte); + + *state =3D utf8d[256 + *state + type]; + return *state; +} + static void vc_put_one(VCChardev *vc, int ch) { QemuTextConsole *s =3D vc->console; @@ -787,6 +830,22 @@ static void vc_putchar(VCChardev *vc, int ch) =20 switch(vc->state) { case TTY_STATE_NORM: + if (ch >=3D 0x80 && vc->encoding =3D=3D CHARDEV_VC_ENCODING_UTF8) { + switch (bh_utf8_decode(&vc->utf8_state, &vc->utf8_codepoint, c= h)) { + case BH_UTF8_ACCEPT: + vc_put_one(vc, unicode_to_cp437(vc->utf8_codepoint)); + break; + case BH_UTF8_REJECT: + vc->utf8_state =3D BH_UTF8_ACCEPT; + break; + default: + /* Need more bytes */ + break; + } + break; + } + /* ASCII byte: abort any pending UTF-8 sequence */ + vc->utf8_state =3D BH_UTF8_ACCEPT; switch(ch) { case '\r': /* carriage return */ vt->x =3D 0; diff --git a/ui/cp437.c b/ui/cp437.c new file mode 100644 index 00000000000..8ec38b73419 --- /dev/null +++ b/ui/cp437.c @@ -0,0 +1,205 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) QEMU contributors + */ +#include "qemu/osdep.h" +#include "cp437.h" + +/* + * Unicode to CP437 page tables. + * + * Borrowed from the Linux kernel (fs/nls/nls_cp437.c, "Dual BSD/GPL"), + * generated from the Unicode Organization tables (www.unicode.org). + */ +static const unsigned char uni2cp437_page00[256] =3D { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */ +}; + +static const unsigned char uni2cp437_page01[256] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; + +static const unsigned char uni2cp437_page03[256] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; + +static const unsigned char uni2cp437_page20[256] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */ + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */ +}; + +static const unsigned char uni2cp437_page22[256] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static const unsigned char uni2cp437_page23[256] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; + +static const unsigned char uni2cp437_page25[256] =3D { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static const unsigned char *const uni2cp437_page[256] =3D { + [0x00] =3D uni2cp437_page00, [0x01] =3D uni2cp437_page01, + [0x03] =3D uni2cp437_page03, [0x20] =3D uni2cp437_page20, + [0x22] =3D uni2cp437_page22, [0x23] =3D uni2cp437_page23, + [0x25] =3D uni2cp437_page25, +}; + +/* + * Convert a Unicode code point to its CP437 equivalent for + * rendering with the VGA font. + * Returns '?' for characters that cannot be mapped. + */ +int unicode_to_cp437(uint32_t codepoint) +{ + const unsigned char *page; + unsigned char hi =3D (codepoint >> 8) & 0xff; + unsigned char lo =3D codepoint & 0xff; + + if (codepoint > 0xffff) { + return '?'; + } + + page =3D uni2cp437_page[hi]; + if (page && page[lo]) { + return page[lo]; + } + + return '?'; +} diff --git a/ui/meson.build b/ui/meson.build index ceaf110683d..d69eebfdaf1 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -18,7 +18,7 @@ system_ss.add(files( 'util.c', 'vgafont.c', )) -system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: file= s('console-vc-stubs.c')) +system_ss.add(when: pixman, if_true: files('console-vc.c', 'cp437.c'), if_= false: files('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c')) endif --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496675; cv=none; d=zohomail.com; s=zohoarc; b=FTtjFBTHZalFWPKAJzsJsvM6gxGStw0LYnYcy/QIeg3X65WM1iVH/VFmnuv+GctzGdHuHCEyL/XEkl2OZGUnLdXWR8b6/m9R3o7okvxKGZP7k2Um5BimEvp93pbpsB40r+/L3BruvRcWP8WYpVmjEBqRoMu3Swnlm5bwWjiUMuY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496675; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=hOiIw9bx+21x85nQF5knP0qQm5nnUYNoqlWGTUmBKLE=; b=EtjvX/caZ6qKrx3oaeqhMFNFyi2d1MNpm/p1VidfiGPDYk7KbVFnuwX0EBZBQbUoMXXwIFiycSnXw0G4fIF+b+k4c5VbnIrOxt1yZ2/8+U5Tnm58FHCTP/v3T8J3fWGetLjdFjzxbuNzvzONW7jNUkHTyKSn6SJMGlHbOkG+BbU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496675482891.1050150440175; Wed, 29 Apr 2026 14:04:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4h-0003kA-4h; Wed, 29 Apr 2026 17:04:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4f-0003fB-7S for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:01 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4c-0003JF-73 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:00 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-141-0Dc5derAMsOJghMapa9ybg-1; Wed, 29 Apr 2026 17:03:56 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E57BE18003FC; Wed, 29 Apr 2026 21:03:54 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 26CE630001BB; Wed, 29 Apr 2026 21:03:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496637; 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=hOiIw9bx+21x85nQF5knP0qQm5nnUYNoqlWGTUmBKLE=; b=CmyvELgGJ5xcaeDPps02lA/BU8xgAR4phTSs3gqSbDmMSRJVXdsrEAce6pURD7ht0g+c1V IACUVVb2wB1OMgiarJRaEb3b/UWtPHMbgDWFKrQPWurpOf53Nj2Bz97M0YCZQBt66PhyeF NKcHY1uqwB0+XMT39ytADKJsD5YYkj0= X-MC-Unique: 0Dc5derAMsOJghMapa9ybg-1 X-Mimecast-MFC-AGG-ID: 0Dc5derAMsOJghMapa9ybg_1777496635 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:40 +0400 Subject: [PATCH v3 07/26] ui/console-vc: move VT100 state machine and output FIFO into QemuVT100 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-7-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=32915; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=UkwYMUsoliBfPHzYTf7cEwOOoeigeZPWYjncdjZ1IL0=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILlAugwv64G1QI5k6aQ8+ZeHVVmWKQIILfP 9aAwP5Qes+JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5SHiEACn4HNkFKnftewsrGO4HvXc9rtv4WJRVZXD3yS5Ike7ZoZzvPIqnjMIcs81UeAxf1VCyS+ vyqb9MfNdypGLRcvl4qfPjXhH7Fb7RyicK2JqulJoLn6S6eJl0yu3NvM1d8+OcbBoUACYVtOdn5 73kTSzAkJ2BkM8kHEvAyJQH+jzD6rSBjSNT131yA/vNZWNwhjZc95iPFjhx7wSnH0ohI2P/ip2J dqinD138qpDWJh9tT/W1DBfxPkSVIfKxD2qQQWAo9QXrGMXCC8d79MNtsod9Bu586hvUIlKYgIq dLQ6K6QPxYe9I/4v6fhe7eVq7vLZQyvhRQlS7zuSRnAQ4GcPbLThZ255A2gx52aIonxGlHx6bpg WjurmBWtsOaX+RRSowFbiWPVZt2uLdyRzq/TNg3z9qWh//bcF8kN7XbtD1XqnsE5t7yw7GgqVe6 eJuOKBe/LMx4jgO+PmHevs+gj5xv3JnS6AXo5j0xVUKDIdxXvzpIzurVMNzWy4NKbrbZNeZiRi4 2vy/oQl4z8RCD1i/Yiri9TrJ2BNMb9WmNceboVpw86vGCSwW/rxSvIvMkLvSC7IHO7GZi983f3d 1RaYt3D+7iaeSKuibgazU4+tbGD1qi5nyupKI8lEo7Dw9DVTj6/xRw+xEno/k6MAM3lXDrxSHrJ dKHoSvfCp3XbCLw== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496676642158500 Move the terminal escape sequence parser state (TTYState, esc_params, text attributes, saved cursor position) and the output FIFO from VCChardev/QemuTextConsole into QemuVT100. Rename the corresponding functions from vc_* to vt100_* to reflect they now operate on the VT100 layer directly, removing the indirection through vc->console->vt. Add an out_flush callback to QemuVT100 so vt100_write() can flush output without knowing about QemuTextConsole, and move FIFO/VT100 initialization from qemu_text_console_init() to vc_chr_open() where the callback can be wired up. This continues the decoupling of VT100 terminal emulation from the chardev layer, making QemuVT100 a self-contained terminal emulator. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- ui/console-vc.c | 382 +++++++++++++++++++++++++++-------------------------= ---- 1 file changed, 184 insertions(+), 198 deletions(-) diff --git a/ui/console-vc.c b/ui/console-vc.c index 42d642afebb..cf1adfc3c71 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -58,6 +58,7 @@ struct QemuVT100 { pixman_image_t *image; void (*image_update)(QemuVT100 *vt, int x, int y, int width, int heigh= t); =20 + ChardevVCEncoding encoding; int width; int height; int total_height; @@ -74,6 +75,18 @@ struct QemuVT100 { int update_x1; int update_y1; =20 + enum TTYState state; + int esc_params[MAX_ESC_PARAMS]; + int nb_esc_params; + uint32_t utf8_state; /* UTF-8 DFA decoder state */ + uint32_t utf8_codepoint; /* accumulated UTF-8 code point */ + TextAttributes t_attrib; /* currently active text attributes */ + TextAttributes t_attrib_saved; + int x_saved, y_saved; + /* fifo for key pressed */ + Fifo8 out_fifo; + void (*out_flush)(QemuVT100 *vt); + QTAILQ_ENTRY(QemuVT100) list; }; =20 @@ -85,8 +98,6 @@ typedef struct QemuTextConsole { =20 QemuVT100 vt; Chardev *chr; - /* fifo for key pressed */ - Fifo8 out_fifo; } QemuTextConsole; =20 typedef QemuConsoleClass QemuTextConsoleClass; @@ -103,17 +114,9 @@ OBJECT_DEFINE_TYPE(QemuFixedTextConsole, qemu_fixed_te= xt_console, QEMU_FIXED_TEX =20 struct VCChardev { Chardev parent; - QemuTextConsole *console; =20 - enum TTYState state; - int esc_params[MAX_ESC_PARAMS]; - int nb_esc_params; - uint32_t utf8_state; /* UTF-8 DFA decoder state */ - uint32_t utf8_codepoint; /* accumulated UTF-8 code point */ - TextAttributes t_attrib; /* currently active text attributes */ - TextAttributes t_attrib_saved; - int x_saved, y_saved; ChardevVCEncoding encoding; + QemuTextConsole *console; }; typedef struct VCChardev VCChardev; =20 @@ -302,36 +305,35 @@ static void vt100_scroll(QemuVT100 *vt, int ydelta) vt100_refresh(vt); } =20 -static void qemu_text_console_flush(QemuTextConsole *s) +static void qemu_text_console_out_flush(QemuTextConsole *s) { uint32_t len, avail; =20 len =3D qemu_chr_be_can_write(s->chr); - avail =3D fifo8_num_used(&s->out_fifo); + avail =3D fifo8_num_used(&s->vt.out_fifo); while (len > 0 && avail > 0) { const uint8_t *buf; uint32_t size; =20 - buf =3D fifo8_pop_bufptr(&s->out_fifo, MIN(len, avail), &size); + buf =3D fifo8_pop_bufptr(&s->vt.out_fifo, MIN(len, avail), &size); qemu_chr_be_write(s->chr, buf, size); len =3D qemu_chr_be_can_write(s->chr); avail -=3D size; } } =20 -static void qemu_text_console_write(QemuTextConsole *s, const void *buf, s= ize_t len) +static void vt100_write(QemuVT100 *vt, const void *buf, size_t len) { uint32_t num_free; =20 - num_free =3D fifo8_num_free(&s->out_fifo); - fifo8_push_all(&s->out_fifo, buf, MIN(num_free, len)); - qemu_text_console_flush(s); + num_free =3D fifo8_num_free(&vt->out_fifo); + fifo8_push_all(&vt->out_fifo, buf, MIN(num_free, len)); + vt->out_flush(vt); } =20 /* called when an ascii key is pressed */ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) { - QemuVT100 *vt =3D &s->vt; uint8_t buf[16], *q; int c; =20 @@ -363,16 +365,16 @@ void qemu_text_console_handle_keysym(QemuTextConsole = *s, int keysym) *q++ =3D '\033'; *q++ =3D '['; *q++ =3D keysym & 0xff; - } else if (vt->echo && (keysym =3D=3D '\r' || keysym =3D=3D '\n'))= { + } else if (s->vt.echo && (keysym =3D=3D '\r' || keysym =3D=3D '\n'= )) { qemu_chr_write(s->chr, (uint8_t *)"\r", 1, true); *q++ =3D '\n'; } else { *q++ =3D keysym; } - if (vt->echo) { + if (s->vt.echo) { qemu_chr_write(s->chr, buf, q - buf, true); } - qemu_text_console_write(s, buf, q - buf); + vt100_write(&s->vt, buf, q - buf); break; } } @@ -380,30 +382,29 @@ void qemu_text_console_handle_keysym(QemuTextConsole = *s, int keysym) static void text_console_update(void *opaque, console_ch_t *chardata) { QemuTextConsole *s =3D QEMU_TEXT_CONSOLE(opaque); - QemuVT100 *vt =3D &s->vt; int i, j, src; =20 - if (vt->text_x[0] <=3D vt->text_x[1]) { - src =3D (vt->y_base + vt->text_y[0]) * vt->width; - chardata +=3D vt->text_y[0] * vt->width; - for (i =3D vt->text_y[0]; i <=3D vt->text_y[1]; i ++) - for (j =3D 0; j < vt->width; j++, src++) { + if (s->vt.text_x[0] <=3D s->vt.text_x[1]) { + src =3D (s->vt.y_base + s->vt.text_y[0]) * s->vt.width; + chardata +=3D s->vt.text_y[0] * s->vt.width; + for (i =3D s->vt.text_y[0]; i <=3D s->vt.text_y[1]; i ++) + for (j =3D 0; j < s->vt.width; j++, src++) { console_write_ch(chardata ++, - ATTR2CHTYPE(vt->cells[src].ch, - vt->cells[src].t_attrib.fgcol, - vt->cells[src].t_attrib.bgcol, - vt->cells[src].t_attrib.bold)= ); + ATTR2CHTYPE(s->vt.cells[src].ch, + s->vt.cells[src].t_attrib.fgc= ol, + s->vt.cells[src].t_attrib.bgc= ol, + s->vt.cells[src].t_attrib.bol= d)); } - dpy_text_update(QEMU_CONSOLE(s), vt->text_x[0], vt->text_y[0], - vt->text_x[1] - vt->text_x[0], i - vt->text_y[0]); - vt->text_x[0] =3D vt->width; - vt->text_y[0] =3D vt->height; - vt->text_x[1] =3D 0; - vt->text_y[1] =3D 0; + dpy_text_update(QEMU_CONSOLE(s), s->vt.text_x[0], s->vt.text_y[0], + s->vt.text_x[1] - s->vt.text_x[0], i - s->vt.text_= y[0]); + s->vt.text_x[0] =3D s->vt.width; + s->vt.text_y[0] =3D s->vt.height; + s->vt.text_x[1] =3D 0; + s->vt.text_y[1] =3D 0; } - if (vt->cursor_invalidate) { - dpy_text_cursor(QEMU_CONSOLE(s), vt->x, vt->y); - vt->cursor_invalidate =3D 0; + if (s->vt.cursor_invalidate) { + dpy_text_cursor(QEMU_CONSOLE(s), s->vt.x, s->vt.y); + s->vt.cursor_invalidate =3D 0; } } =20 @@ -492,103 +493,101 @@ static void vt100_put_lf(QemuVT100 *vt) * NOTE: I know this code is not very efficient (checking every color for = it * self) but it is more readable and better maintainable. */ -static void vc_handle_escape(VCChardev *vc) +static void vt100_handle_escape(QemuVT100 *vt) { int i; =20 - for (i =3D 0; i < vc->nb_esc_params; i++) { - switch (vc->esc_params[i]) { + for (i =3D 0; i < vt->nb_esc_params; i++) { + switch (vt->esc_params[i]) { case 0: /* reset all console attributes to default */ - vc->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + vt->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; break; case 1: - vc->t_attrib.bold =3D 1; + vt->t_attrib.bold =3D 1; break; case 4: - vc->t_attrib.uline =3D 1; + vt->t_attrib.uline =3D 1; break; case 5: - vc->t_attrib.blink =3D 1; + vt->t_attrib.blink =3D 1; break; case 7: - vc->t_attrib.invers =3D 1; + vt->t_attrib.invers =3D 1; break; case 8: - vc->t_attrib.unvisible =3D 1; + vt->t_attrib.unvisible =3D 1; break; case 22: - vc->t_attrib.bold =3D 0; + vt->t_attrib.bold =3D 0; break; case 24: - vc->t_attrib.uline =3D 0; + vt->t_attrib.uline =3D 0; break; case 25: - vc->t_attrib.blink =3D 0; + vt->t_attrib.blink =3D 0; break; case 27: - vc->t_attrib.invers =3D 0; + vt->t_attrib.invers =3D 0; break; case 28: - vc->t_attrib.unvisible =3D 0; + vt->t_attrib.unvisible =3D 0; break; /* set foreground color */ case 30: - vc->t_attrib.fgcol =3D QEMU_COLOR_BLACK; + vt->t_attrib.fgcol =3D QEMU_COLOR_BLACK; break; case 31: - vc->t_attrib.fgcol =3D QEMU_COLOR_RED; + vt->t_attrib.fgcol =3D QEMU_COLOR_RED; break; case 32: - vc->t_attrib.fgcol =3D QEMU_COLOR_GREEN; + vt->t_attrib.fgcol =3D QEMU_COLOR_GREEN; break; case 33: - vc->t_attrib.fgcol =3D QEMU_COLOR_YELLOW; + vt->t_attrib.fgcol =3D QEMU_COLOR_YELLOW; break; case 34: - vc->t_attrib.fgcol =3D QEMU_COLOR_BLUE; + vt->t_attrib.fgcol =3D QEMU_COLOR_BLUE; break; case 35: - vc->t_attrib.fgcol =3D QEMU_COLOR_MAGENTA; + vt->t_attrib.fgcol =3D QEMU_COLOR_MAGENTA; break; case 36: - vc->t_attrib.fgcol =3D QEMU_COLOR_CYAN; + vt->t_attrib.fgcol =3D QEMU_COLOR_CYAN; break; case 37: - vc->t_attrib.fgcol =3D QEMU_COLOR_WHITE; + vt->t_attrib.fgcol =3D QEMU_COLOR_WHITE; break; /* set background color */ case 40: - vc->t_attrib.bgcol =3D QEMU_COLOR_BLACK; + vt->t_attrib.bgcol =3D QEMU_COLOR_BLACK; break; case 41: - vc->t_attrib.bgcol =3D QEMU_COLOR_RED; + vt->t_attrib.bgcol =3D QEMU_COLOR_RED; break; case 42: - vc->t_attrib.bgcol =3D QEMU_COLOR_GREEN; + vt->t_attrib.bgcol =3D QEMU_COLOR_GREEN; break; case 43: - vc->t_attrib.bgcol =3D QEMU_COLOR_YELLOW; + vt->t_attrib.bgcol =3D QEMU_COLOR_YELLOW; break; case 44: - vc->t_attrib.bgcol =3D QEMU_COLOR_BLUE; + vt->t_attrib.bgcol =3D QEMU_COLOR_BLUE; break; case 45: - vc->t_attrib.bgcol =3D QEMU_COLOR_MAGENTA; + vt->t_attrib.bgcol =3D QEMU_COLOR_MAGENTA; break; case 46: - vc->t_attrib.bgcol =3D QEMU_COLOR_CYAN; + vt->t_attrib.bgcol =3D QEMU_COLOR_CYAN; break; case 47: - vc->t_attrib.bgcol =3D QEMU_COLOR_WHITE; + vt->t_attrib.bgcol =3D QEMU_COLOR_WHITE; break; } } } =20 -static void vc_update_xy(VCChardev *vc, int x, int y) +static void vt100_update_xy(QemuVT100 *vt, int x, int y) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; TextCell *c; int y1, y2; =20 @@ -609,14 +608,12 @@ static void vc_update_xy(VCChardev *vc, int x, int y) c =3D &vt->cells[y1 * vt->width + x]; vt100_putcharxy(vt, x, y2, c->ch, &(c->t_attrib)); - vt100_invalidate_xy(&s->vt, x, y2); + vt100_invalidate_xy(vt, x, y2); } } =20 -static void vc_clear_xy(VCChardev *vc, int x, int y) +static void vt100_clear_xy(QemuVT100 *vt, int x, int y) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; int y1 =3D (vt->y_base + y) % vt->total_height; if (x >=3D vt->width) { x =3D vt->width - 1; @@ -624,7 +621,7 @@ static void vc_clear_xy(VCChardev *vc, int x, int y) TextCell *c =3D &vt->cells[y1 * vt->width + x]; c->ch =3D ' '; c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - vc_update_xy(vc, x, y); + vt100_update_xy(vt, x, y); } =20 /* @@ -667,10 +664,8 @@ static uint32_t bh_utf8_decode(uint32_t *state, uint32= _t *codep, uint32_t byte) return *state; } =20 -static void vc_put_one(VCChardev *vc, int ch) +static void vt100_put_one(QemuVT100 *vt, int ch) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; TextCell *c; int y1; if (vt->x >=3D vt->width) { @@ -681,17 +676,14 @@ static void vc_put_one(VCChardev *vc, int ch) y1 =3D (vt->y_base + vt->y) % vt->total_height; c =3D &vt->cells[y1 * vt->width + vt->x]; c->ch =3D ch; - c->t_attrib =3D vc->t_attrib; - vc_update_xy(vc, vt->x, vt->y); + c->t_attrib =3D vt->t_attrib; + vt100_update_xy(vt, vt->x, vt->y); vt->x++; } =20 /* set cursor, checking bounds */ -static void vc_set_cursor(VCChardev *vc, int x, int y) +static void vt100_set_cursor(QemuVT100 *vt, int x, int y) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; - if (x < 0) { x =3D 0; } @@ -715,10 +707,8 @@ static void vc_set_cursor(VCChardev *vc, int x, int y) * characters between the cursor and right margin move to the * left. Character attributes move with the characters. */ -static void vc_csi_P(struct VCChardev *vc, unsigned int nr) +static void vt100_csi_P(QemuVT100 *vt, unsigned int nr) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; TextCell *c1, *c2; unsigned int x1, x2, y; unsigned int end, len; @@ -742,12 +732,12 @@ static void vc_csi_P(struct VCChardev *vc, unsigned i= nt nr) c2 =3D &vt->cells[y * vt->width + x2]; memmove(c1, c2, len * sizeof(*c1)); for (end =3D x1 + len; x1 < end; x1++) { - vc_update_xy(vc, x1, vt->y); + vt100_update_xy(vt, x1, vt->y); } } /* Clear the rest */ for (; x1 < vt->width; x1++) { - vc_clear_xy(vc, x1, vt->y); + vt100_clear_xy(vt, x1, vt->y); } } =20 @@ -757,10 +747,8 @@ static void vc_csi_P(struct VCChardev *vc, unsigned in= t nr) * blank characters. Text between the cursor and right margin moves to * the right. Characters scrolled past the right margin are lost. */ -static void vc_csi_at(struct VCChardev *vc, unsigned int nr) +static void vt100_csi_at(QemuVT100 *vt, unsigned int nr) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; TextCell *c1, *c2; unsigned int x1, x2, y; unsigned int end, len; @@ -784,59 +772,51 @@ static void vc_csi_at(struct VCChardev *vc, unsigned = int nr) c2 =3D &vt->cells[y * vt->width + x2]; memmove(c1, c2, len * sizeof(*c1)); for (end =3D x1 + len; x1 < end; x1++) { - vc_update_xy(vc, x1, vt->y); + vt100_update_xy(vt, x1, vt->y); } } /* Insert blanks */ for (x1 =3D vt->x; x1 < vt->x + nr; x1++) { - vc_clear_xy(vc, x1, vt->y); + vt100_clear_xy(vt, x1, vt->y); } } =20 /** - * vc_save_cursor() - saves cursor position and character attributes. + * vt100_save_cursor() - saves cursor position and character attributes. */ -static void vc_save_cursor(VCChardev *vc) +static void vt100_save_cursor(QemuVT100 *vt) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; - - vc->x_saved =3D vt->x; - vc->y_saved =3D vt->y; - vc->t_attrib_saved =3D vc->t_attrib; + vt->x_saved =3D vt->x; + vt->y_saved =3D vt->y; + vt->t_attrib_saved =3D vt->t_attrib; } =20 /** - * vc_restore_cursor() - restores cursor position and character + * vt100_restore_cursor() - restores cursor position and character * attributes from saved state. */ -static void vc_restore_cursor(VCChardev *vc) +static void vt100_restore_cursor(QemuVT100 *vt) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; - - vt->x =3D vc->x_saved; - vt->y =3D vc->y_saved; - vc->t_attrib =3D vc->t_attrib_saved; + vt->x =3D vt->x_saved; + vt->y =3D vt->y_saved; + vt->t_attrib =3D vt->t_attrib_saved; } =20 -static void vc_putchar(VCChardev *vc, int ch) +static void vt100_putchar(QemuVT100 *vt, int ch) { - QemuTextConsole *s =3D vc->console; - QemuVT100 *vt =3D &s->vt; int i; int x, y; g_autofree char *response =3D NULL; =20 - switch(vc->state) { + switch (vt->state) { case TTY_STATE_NORM: - if (ch >=3D 0x80 && vc->encoding =3D=3D CHARDEV_VC_ENCODING_UTF8) { - switch (bh_utf8_decode(&vc->utf8_state, &vc->utf8_codepoint, c= h)) { + if (ch >=3D 0x80 && vt->encoding =3D=3D CHARDEV_VC_ENCODING_UTF8) { + switch (bh_utf8_decode(&vt->utf8_state, &vt->utf8_codepoint, c= h)) { case BH_UTF8_ACCEPT: - vc_put_one(vc, unicode_to_cp437(vc->utf8_codepoint)); + vt100_put_one(vt, unicode_to_cp437(vt->utf8_codepoint)); break; case BH_UTF8_REJECT: - vc->utf8_state =3D BH_UTF8_ACCEPT; + vt->utf8_state =3D BH_UTF8_ACCEPT; break; default: /* Need more bytes */ @@ -844,14 +824,13 @@ static void vc_putchar(VCChardev *vc, int ch) } break; } - /* ASCII byte: abort any pending UTF-8 sequence */ - vc->utf8_state =3D BH_UTF8_ACCEPT; + vt->utf8_state =3D BH_UTF8_ACCEPT; switch(ch) { case '\r': /* carriage return */ vt->x =3D 0; break; case '\n': /* newline */ - vt100_put_lf(&s->vt); + vt100_put_lf(vt); break; case '\b': /* backspace */ if (vt->x > 0) @@ -875,95 +854,95 @@ static void vc_putchar(VCChardev *vc, int ch) /* SI (shift in), character set 0 (ignored) */ break; case 27: /* esc (introducing an escape sequence) */ - vc->state =3D TTY_STATE_ESC; + vt->state =3D TTY_STATE_ESC; break; default: - vc_put_one(vc, ch); + vt100_put_one(vt, ch); break; } break; case TTY_STATE_ESC: /* check if it is a terminal escape sequence */ if (ch =3D=3D '[') { for(i=3D0;iesc_params[i] =3D 0; - vc->nb_esc_params =3D 0; - vc->state =3D TTY_STATE_CSI; + vt->esc_params[i] =3D 0; + vt->nb_esc_params =3D 0; + vt->state =3D TTY_STATE_CSI; } else if (ch =3D=3D '(') { - vc->state =3D TTY_STATE_G0; + vt->state =3D TTY_STATE_G0; } else if (ch =3D=3D ')') { - vc->state =3D TTY_STATE_G1; + vt->state =3D TTY_STATE_G1; } else if (ch =3D=3D ']' || ch =3D=3D 'P' || ch =3D=3D 'X' || ch =3D=3D '^' || ch =3D=3D '_') { /* String sequences: OSC, DCS, SOS, PM, APC */ - vc->state =3D TTY_STATE_OSC; + vt->state =3D TTY_STATE_OSC; } else if (ch =3D=3D '7') { - vc_save_cursor(vc); - vc->state =3D TTY_STATE_NORM; + vt100_save_cursor(vt); + vt->state =3D TTY_STATE_NORM; } else if (ch =3D=3D '8') { - vc_restore_cursor(vc); - vc->state =3D TTY_STATE_NORM; + vt100_restore_cursor(vt); + vt->state =3D TTY_STATE_NORM; } else { - vc->state =3D TTY_STATE_NORM; + vt->state =3D TTY_STATE_NORM; } break; case TTY_STATE_CSI: /* handle escape sequence parameters */ if (ch >=3D '0' && ch <=3D '9') { - if (vc->nb_esc_params < MAX_ESC_PARAMS) { - int *param =3D &vc->esc_params[vc->nb_esc_params]; + if (vt->nb_esc_params < MAX_ESC_PARAMS) { + int *param =3D &vt->esc_params[vt->nb_esc_params]; int digit =3D (ch - '0'); =20 *param =3D (*param <=3D (INT_MAX - digit) / 10) ? *param * 10 + digit : INT_MAX; } } else { - if (vc->nb_esc_params < MAX_ESC_PARAMS) - vc->nb_esc_params++; + if (vt->nb_esc_params < MAX_ESC_PARAMS) + vt->nb_esc_params++; if (ch =3D=3D ';' || ch =3D=3D '?') { break; } - trace_console_putchar_csi(vc->esc_params[0], vc->esc_params[1], - ch, vc->nb_esc_params); - vc->state =3D TTY_STATE_NORM; + trace_console_putchar_csi(vt->esc_params[0], vt->esc_params[1], + ch, vt->nb_esc_params); + vt->state =3D TTY_STATE_NORM; switch(ch) { case 'A': /* move cursor up */ - if (vc->esc_params[0] =3D=3D 0) { - vc->esc_params[0] =3D 1; + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; } - vc_set_cursor(vc, vt->x, vt->y - vc->esc_params[0]); + vt100_set_cursor(vt, vt->x, vt->y - vt->esc_params[0]); break; case 'B': /* move cursor down */ - if (vc->esc_params[0] =3D=3D 0) { - vc->esc_params[0] =3D 1; + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; } - vc_set_cursor(vc, vt->x, vt->y + vc->esc_params[0]); + vt100_set_cursor(vt, vt->x, vt->y + vt->esc_params[0]); break; case 'C': /* move cursor right */ - if (vc->esc_params[0] =3D=3D 0) { - vc->esc_params[0] =3D 1; + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; } - vc_set_cursor(vc, vt->x + vc->esc_params[0], vt->y); + vt100_set_cursor(vt, vt->x + vt->esc_params[0], vt->y); break; case 'D': /* move cursor left */ - if (vc->esc_params[0] =3D=3D 0) { - vc->esc_params[0] =3D 1; + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; } - vc_set_cursor(vc, vt->x - vc->esc_params[0], vt->y); + vt100_set_cursor(vt, vt->x - vt->esc_params[0], vt->y); break; case 'G': /* move cursor to column */ - vc_set_cursor(vc, vc->esc_params[0] - 1, vt->y); + vt100_set_cursor(vt, vt->esc_params[0] - 1, vt->y); break; case 'f': case 'H': /* move cursor to row, column */ - vc_set_cursor(vc, vc->esc_params[1] - 1, vc->esc_params[0]= - 1); + vt100_set_cursor(vt, vt->esc_params[1] - 1, vt->esc_params= [0] - 1); break; case 'J': - switch (vc->esc_params[0]) { + switch (vt->esc_params[0]) { case 0: /* clear to end of screen */ for (y =3D vt->y; y < vt->height; y++) { @@ -971,7 +950,7 @@ static void vc_putchar(VCChardev *vc, int ch) if (y =3D=3D vt->y && x < vt->x) { continue; } - vc_clear_xy(vc, x, y); + vt100_clear_xy(vt, x, y); } } break; @@ -982,7 +961,7 @@ static void vc_putchar(VCChardev *vc, int ch) if (y =3D=3D vt->y && x > vt->x) { break; } - vc_clear_xy(vc, x, y); + vt100_clear_xy(vt, x, y); } } break; @@ -990,62 +969,62 @@ static void vc_putchar(VCChardev *vc, int ch) /* clear entire screen */ for (y =3D 0; y < vt->height; y++) { for (x =3D 0; x < vt->width; x++) { - vc_clear_xy(vc, x, y); + vt100_clear_xy(vt, x, y); } } break; } break; case 'K': - switch (vc->esc_params[0]) { + switch (vt->esc_params[0]) { case 0: /* clear to eol */ for(x =3D vt->x; x < vt->width; x++) { - vc_clear_xy(vc, x, vt->y); + vt100_clear_xy(vt, x, vt->y); } break; case 1: /* clear from beginning of line */ for (x =3D 0; x <=3D vt->x && x < vt->width; x++) { - vc_clear_xy(vc, x, vt->y); + vt100_clear_xy(vt, x, vt->y); } break; case 2: /* clear entire line */ for(x =3D 0; x < vt->width; x++) { - vc_clear_xy(vc, x, vt->y); + vt100_clear_xy(vt, x, vt->y); } break; } break; case 'P': - vc_csi_P(vc, vc->esc_params[0]); + vt100_csi_P(vt, vt->esc_params[0]); break; case 'm': - vc_handle_escape(vc); + vt100_handle_escape(vt); break; case 'n': - switch (vc->esc_params[0]) { + switch (vt->esc_params[0]) { case 5: /* report console status (always succeed)*/ - qemu_text_console_write(s, "\033[0n", 4); + vt100_write(vt, "\033[0n", 4); break; case 6: /* report cursor position */ response =3D g_strdup_printf("\033[%d;%dR", vt->y + 1, vt->x + 1); - qemu_text_console_write(s, response, strlen(response)); + vt100_write(vt, response, strlen(response)); break; } break; case 's': - vc_save_cursor(vc); + vt100_save_cursor(vt); break; case 'u': - vc_restore_cursor(vc); + vt100_restore_cursor(vt); break; case '@': - vc_csi_at(vc, vc->esc_params[0]); + vt100_csi_at(vt, vt->esc_params[0]); break; default: trace_console_putchar_unhandled(ch); @@ -1057,10 +1036,10 @@ static void vc_putchar(VCChardev *vc, int ch) case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */ if (ch =3D=3D '\a') { /* BEL terminates OSC */ - vc->state =3D TTY_STATE_NORM; + vt->state =3D TTY_STATE_NORM; } else if (ch =3D=3D 27) { /* ESC might start ST (ESC \) */ - vc->state =3D TTY_STATE_ESC; + vt->state =3D TTY_STATE_ESC; } /* All other bytes are silently consumed */ break; @@ -1071,7 +1050,7 @@ static void vc_putchar(VCChardev *vc, int ch) /* Latin-1 map */ break; } - vc->state =3D TTY_STATE_NORM; + vt->state =3D TTY_STATE_NORM; break; } } @@ -1084,22 +1063,21 @@ static int vc_chr_write(Chardev *chr, const uint8_t= *buf, int len) { VCChardev *drv =3D VC_CHARDEV(chr); QemuTextConsole *s =3D drv->console; - QemuVT100 *vt =3D &s->vt; int i; =20 - vt->update_x0 =3D vt->width * FONT_WIDTH; - vt->update_y0 =3D vt->height * FONT_HEIGHT; - vt->update_x1 =3D 0; - vt->update_y1 =3D 0; - vt100_show_cursor(vt, 0); + s->vt.update_x0 =3D s->vt.width * FONT_WIDTH; + s->vt.update_y0 =3D s->vt.height * FONT_HEIGHT; + s->vt.update_x1 =3D 0; + s->vt.update_y1 =3D 0; + vt100_show_cursor(&s->vt, 0); for(i =3D 0; i < len; i++) { - vc_putchar(drv, buf[i]); + vt100_putchar(&s->vt, buf[i]); } - vt100_show_cursor(vt, 1); - if (vt->update_x0 < vt->update_x1) { - vt100_image_update(vt, vt->update_x0, vt->update_y0, - vt->update_x1 - vt->update_x0, - vt->update_y1 - vt->update_y0); + vt100_show_cursor(&s->vt, 1); + if (s->vt.update_x0 < s->vt.update_x1) { + vt100_image_update(&s->vt, s->vt.update_x0, s->vt.update_y0, + s->vt.update_x1 - s->vt.update_x0, + s->vt.update_y1 - s->vt.update_y0); } return len; } @@ -1168,9 +1146,6 @@ qemu_text_console_init(Object *obj) { QemuTextConsole *c =3D QEMU_TEXT_CONSOLE(obj); =20 - QTAILQ_INSERT_HEAD(&vt100s, &c->vt, list); - fifo8_create(&c->out_fifo, 16); - c->vt.total_height =3D DEFAULT_BACKSCROLL; QEMU_CONSOLE(c)->hw_ops =3D &text_console_ops; QEMU_CONSOLE(c)->hw =3D c; } @@ -1194,7 +1169,7 @@ static void vc_chr_accept_input(Chardev *chr) { VCChardev *drv =3D VC_CHARDEV(chr); =20 - qemu_text_console_flush(drv->console); + qemu_text_console_out_flush(drv->console); } =20 static void vc_chr_set_echo(Chardev *chr, bool echo) @@ -1216,6 +1191,13 @@ static void text_console_image_update(QemuVT100 *vt,= int x, int y, int width, in dpy_gfx_update(QEMU_CONSOLE(console), x, y, width, height); } =20 +static void text_console_out_flush(QemuVT100 *vt) +{ + QemuTextConsole *console =3D container_of(vt, QemuTextConsole, vt); + + qemu_text_console_out_flush(console); +} + static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **err= p) { ChardevVC *vc =3D backend->u.vc.data; @@ -1245,27 +1227,31 @@ static bool vc_chr_open(Chardev *chr, ChardevBacken= d *backend, Error **errp) s =3D QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_FIXED_TEXT_CONSOLE)); } =20 + QTAILQ_INSERT_HEAD(&vt100s, &s->vt, list); + fifo8_create(&s->vt.out_fifo, 16); + s->vt.total_height =3D DEFAULT_BACKSCROLL; dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(wi= dth, height)); s->vt.image_update =3D text_console_image_update; + s->vt.out_flush =3D text_console_out_flush; =20 s->chr =3D chr; drv->console =3D s; if (vc->has_encoding) { - drv->encoding =3D vc->encoding; + drv->encoding =3D s->vt.encoding =3D vc->encoding; } =20 /* set current text attributes to default */ - drv->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + s->vt.t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; vt100_set_image(&s->vt, QEMU_CONSOLE(s)->surface->image); =20 if (chr->label) { char *msg; =20 - drv->t_attrib.bgcol =3D QEMU_COLOR_BLUE; + s->vt.t_attrib.bgcol =3D QEMU_COLOR_BLUE; msg =3D g_strdup_printf("%s console\r\n", chr->label); qemu_chr_write(chr, (uint8_t *)msg, strlen(msg), true); g_free(msg); - drv->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + s->vt.t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; } =20 qemu_chr_be_event(chr, CHR_EVENT_OPENED); --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496753; cv=none; d=zohomail.com; s=zohoarc; b=HkCso+1MA4amGETzHpCVO5TF2KcMOINmuyCWU3c5ZY5boBMf7hebejMraZmmHfmLVsDzeAyFeFVwM0C9EbppsO2gHN6x/w8PC55U9F7gyfMpJJ6X1ZZt3fWJsFZJ4doCaCq+gpvPB9pS+2u1nAmhB6xRPwQwgljbbZ/O2pHVuXc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496753; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=s0K2K5fhhdNzX4OBI1xp73vrW9s2JcoHKgf5KZfeWgY=; b=P9MJHskPGny++eBksLqCANNiQMa3Vf86Av4iXRgdQ/vbqXq8yiu3RuDfDUhNB0zsaE9IJADUnjrgC7JR6jkxq2gwoEo2sXaFM0GHW8vcGIcXdWhKfeGDin0D0QwYCr6OAnT4jWEQdzGwJc2u952HYk1bssvdzoCciGOmv3eOf9A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496753564815.9921009908772; Wed, 29 Apr 2026 14:05:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4n-0004BM-T3; Wed, 29 Apr 2026 17:04:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4m-00049c-G0 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4k-0003KQ-Rs for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:08 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-460-OxV8MbYPPzik98JKQOR5rA-1; Wed, 29 Apr 2026 17:04:01 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B7D8F18004AD; Wed, 29 Apr 2026 21:04:00 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4ED7819560AB; Wed, 29 Apr 2026 21:03:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496646; 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=s0K2K5fhhdNzX4OBI1xp73vrW9s2JcoHKgf5KZfeWgY=; b=dsJztRWWaKvjxv/kDNlIqU6Oudd8KIX6Eji2vM7QTkVq3tDEME0aTQ+DpEGjMMbX4bF9hU +PaSfOao/1h4hd7Us2T+5/CtMiHp+40Y7cGy3KUZCDF6NWjE9X/e0QaAtzqNl+oS2k91Ru EPMUz/m6rSslu2k+Ue4tn7QH55KWYqY= X-MC-Unique: OxV8MbYPPzik98JKQOR5rA-1 X-Mimecast-MFC-AGG-ID: OxV8MbYPPzik98JKQOR5rA_1777496640 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:41 +0400 Subject: [PATCH v3 08/26] ui/console-vc: extract vt100_input() from vc_chr_write() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-8-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=2581; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=OxentmOB0aHkFj9sS8PNhIY0KX1fP6rvOvIzMKx8ABo=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILU9hCjHev+l7W8XAvJ9UnIAE86/cpdvkFx Aj2B/J7oTaJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5bZ8D/9KPisxL+Ciodgx5lPxI3hvDl1zBZlCxwyWffEfmb38Do7B1hyT3U3WNN6ruDeubGMSTEV PZ/2548mfI2DL/SqXXlYRys0aEGGFt/Zn7BbzEABoqCa/pYbLTYJ5GuF+NuH5erpo+dgfqBALvP PyXHFj1BHmz5Ic50fjhcLktr+PN2q22BymRO73fGwrsu+anSzwtiOKYr/R3UHElm9W2G+xxkUNZ zVKwKnZDbzN0/WgLnPgNTyTEWS5MpUy2cTNpwB6Sb4diWGA1Vr2cbXqjRtJNkO9Ovl3tibs4Xwz UJwbX2yonbWsKI8tQDgkN5uCrYKU7VBw73A/Vu4ba4uImrl+d7H22JqZtpLbV9b4nh2lofwrlZv LgNhDVXiLsMNhydp0qob+IdiHym0N9yMC03Az9gaHXzUa8QpMBEs+tTsnpoPA5WTXrZD6mYtR+z 2jHBxnqEcxxLmIEb803dKQaBSdl/Ziz0q5liZ/DXeNnxlole6JkMg0RsqVKf/OLOp1HLa2en97a /yyOakFlpGO9hZKAZ0JCCQf2S7VIxBo+ImZrE+uQiTR8gXGg1t2z6+pWmyjRYmeVNIxCL5RbeCB hbffB0KEOgXSi42WosbbbKc0s9bukztv9nIqNOJ4UnlV8GzW/veIAThculxta26GW0TtirBtLew U3CT/fFrttN3gWg== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496782428154101 Move the VT100 input processing logic out of vc_chr_write() into a new vt100_input() function that operates on QemuVT100 directly, rather than going through the Chardev/VCChardev layers. This continues the effort to decouple the VT100 emulation from the chardev backend, making the VT100 layer self-contained and reusable. vc_chr_write() becomes a thin wrapper that extracts the QemuVT100 from the chardev and delegates to vt100_input(). Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console-vc.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/ui/console-vc.c b/ui/console-vc.c index cf1adfc3c71..024ab277e0b 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -1059,29 +1059,35 @@ static void vt100_putchar(QemuVT100 *vt, int ch) DECLARE_INSTANCE_CHECKER(VCChardev, VC_CHARDEV, TYPE_CHARDEV_VC) =20 -static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len) +static size_t vt100_input(QemuVT100 *vt, const uint8_t *buf, size_t len) { - VCChardev *drv =3D VC_CHARDEV(chr); - QemuTextConsole *s =3D drv->console; int i; =20 - s->vt.update_x0 =3D s->vt.width * FONT_WIDTH; - s->vt.update_y0 =3D s->vt.height * FONT_HEIGHT; - s->vt.update_x1 =3D 0; - s->vt.update_y1 =3D 0; - vt100_show_cursor(&s->vt, 0); + vt->update_x0 =3D vt->width * FONT_WIDTH; + vt->update_y0 =3D vt->height * FONT_HEIGHT; + vt->update_x1 =3D 0; + vt->update_y1 =3D 0; + vt100_show_cursor(vt, 0); for(i =3D 0; i < len; i++) { - vt100_putchar(&s->vt, buf[i]); + vt100_putchar(vt, buf[i]); } - vt100_show_cursor(&s->vt, 1); - if (s->vt.update_x0 < s->vt.update_x1) { - vt100_image_update(&s->vt, s->vt.update_x0, s->vt.update_y0, - s->vt.update_x1 - s->vt.update_x0, - s->vt.update_y1 - s->vt.update_y0); + vt100_show_cursor(vt, 1); + if (vt->update_x0 < vt->update_x1) { + vt100_image_update(vt, vt->update_x0, vt->update_y0, + vt->update_x1 - vt->update_x0, + vt->update_y1 - vt->update_y0); } return len; } =20 +static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len) +{ + VCChardev *drv =3D VC_CHARDEV(chr); + QemuTextConsole *s =3D drv->console; + + return vt100_input(&s->vt, buf, len); +} + void vt100_update_cursor(void) { QemuVT100 *vt; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496675; cv=none; d=zohomail.com; s=zohoarc; b=JlYO7aUo3R5OzCq0NPVYvrjKUTJlT6u8c6nNkQ4EDw00ur4klJxWYYtlqvM3KJFHtinooGdpLfFoQBUIti6FD1nfh8YaD3oeSzGw/cjZluJg8Ir7XgjhigO0865K71WQR/1verLF3GQxZmJ9FsMW86hus+1ntCZ2G3rHVV+J49g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496675; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=JmFBcPpPg70cERCREd01+2LUoYOfsSp3YOvkB7jQRG0=; b=AtTnl8fYIKNkxcdzMqgAj+7ichhH5KDDy5wCGqYdKvW8GWZnJ37/uMGupGp31mkj27LuwIJs1VwiKn38lsRITKfH830RevUY4mKkWPes0ziEj4l4PDUeGll/ohisSsxgnFRV0nitIZdfrQjhwmJcafnV+vIy92qqp4yplps9WN4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496675528660.996667765787; Wed, 29 Apr 2026 14:04:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4r-0004Qn-HV; Wed, 29 Apr 2026 17:04:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4q-0004O9-4c for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4o-0003Kq-NP for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:11 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-149-6daXo7iwMsGaUmEWulvX4g-1; Wed, 29 Apr 2026 17:04:08 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0D3B118002C5; Wed, 29 Apr 2026 21:04:07 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 122DC180045E; Wed, 29 Apr 2026 21:04:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496650; 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=JmFBcPpPg70cERCREd01+2LUoYOfsSp3YOvkB7jQRG0=; b=Tr4bowoy0XHn1L1EVNtLVnl8x28XFp0zL3HXOnXrfJ1VmOfEHtL/fEHybPW0eSYfev7VoS 0HTpU03O9p29NYAm4U/Ai8ZGZKXgoZ0BxZEO3AoWv2ERnMTCna38klaXP+3ada/lEjaef+ tYFsCd3LlLnXy2sACNxPTG6mL0vWjiI= X-MC-Unique: 6daXo7iwMsGaUmEWulvX4g-1 X-Mimecast-MFC-AGG-ID: 6daXo7iwMsGaUmEWulvX4g_1777496647 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:42 +0400 Subject: [PATCH v3 09/26] ui/console-vc: extract vt100_keysym() from qemu_text_console_handle_keysym() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-9-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=2776; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=8joCuZ7b714/pI2LClfiZ7KWft0awWMucbiOwUmsTxo=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILU+Q/oNywn9fn08iSyerRrEu/KyO0EmrpW oFflTXWRy+JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5bGED/9XYcXEvdpVU7ZnV9pUa1NjfP872/1lqReXmRV3MgVn6IsBQk8cP0oc9znqYOalcWE3uya HHFwQPH2Y9505F733R3Gi1VwKgPtINSs0spschmlX9hxa9toazXV3A4oOR/Xo9JMVVcSCYjWlko qGA9JOEjLo02e2Eud6U9zb0QWdjlPOvMlw2ZMmr+Bg90KuhZXpzOCO/xa6dLvDiJ9P9XeyFZv3a GhjWRzhjc4gmllkWQWRNootwkypj2CQovrrpziPJ4yBPN9rUi+XryZGUi2HZIC1A4OpJi54Ww/6 6ZBTsYaRTLHV0KoQ/Dq+JsShNIg0HOBm32PSs1m9Ba65deUlwNVr86VNt2lAFOtuAX38ko/HwLn BmZ5PXZINpekffxa2VgbyWRH0EkgnwvFdv89doaVR63Dt1HJHO7XQf+WvOFK5VHeX2Wxd/q9mPK CnhsFMM813/9ZiCqM9B7XlfYUwd+WRCP3OazMIomTDUoADZkHF+jRsaJfCdgfj5CWq8tALRMBz1 lAaqokIm00si2+K8g3dyfijgkp8y7kP4MmjW+PZtrCd32OZAwcpw6aoFkJgNJ4/vlfT5qNAXckT nkPQVFy7KYfCSeBQE3g+vioaKLMnP26NHRnJ/Vj/buCPE9JHKgbH6k1cocNScWV5bBMhjj6uH4M Gc1wv/osDJAUwKA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496676545158500 Move the keysym handling logic out of qemu_text_console_handle_keysym() into a new vt100_keysym() helper that operates on QemuVT100 directly, continuing the effort to decouple the VT100 layer from the console layer. The echo path is updated to call vt100_input() instead of qemu_chr_write(), since the function no longer has direct access to the chardev. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console-vc.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/ui/console-vc.c b/ui/console-vc.c index 024ab277e0b..9f5f49413d2 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -331,24 +331,25 @@ static void vt100_write(QemuVT100 *vt, const void *bu= f, size_t len) vt->out_flush(vt); } =20 -/* called when an ascii key is pressed */ -void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) +static int vt100_input(QemuVT100 *vt, const uint8_t *buf, int len); + +static void vt100_keysym(QemuVT100 *vt, int keysym) { uint8_t buf[16], *q; int c; =20 switch(keysym) { case QEMU_KEY_CTRL_UP: - vt100_scroll(&s->vt, -1); + vt100_scroll(vt, -1); break; case QEMU_KEY_CTRL_DOWN: - vt100_scroll(&s->vt, 1); + vt100_scroll(vt, 1); break; case QEMU_KEY_CTRL_PAGEUP: - vt100_scroll(&s->vt, -10); + vt100_scroll(vt, -10); break; case QEMU_KEY_CTRL_PAGEDOWN: - vt100_scroll(&s->vt, 10); + vt100_scroll(vt, 10); break; default: /* convert the QEMU keysym to VT100 key string */ @@ -365,18 +366,24 @@ void qemu_text_console_handle_keysym(QemuTextConsole = *s, int keysym) *q++ =3D '\033'; *q++ =3D '['; *q++ =3D keysym & 0xff; - } else if (s->vt.echo && (keysym =3D=3D '\r' || keysym =3D=3D '\n'= )) { - qemu_chr_write(s->chr, (uint8_t *)"\r", 1, true); + } else if (vt->echo && (keysym =3D=3D '\r' || keysym =3D=3D '\n'))= { + vt100_input(vt, (uint8_t *)"\r", 1); *q++ =3D '\n'; } else { *q++ =3D keysym; } - if (s->vt.echo) { - qemu_chr_write(s->chr, buf, q - buf, true); + if (vt->echo) { + vt100_input(vt, buf, q - buf); } - vt100_write(&s->vt, buf, q - buf); + vt100_write(vt, buf, q - buf); break; } + +} +/* called when an ascii key is pressed */ +void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) +{ + vt100_keysym(&s->vt, keysym); } =20 static void text_console_update(void *opaque, console_ch_t *chardata) --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496722; cv=none; d=zohomail.com; s=zohoarc; b=DX7LEqtF1gbHkFUnwPuM4Mth6o2JpIJL1ctGNCGJQYNp26pAsNsTdI/QKqMwmMfpidDhc41tFcHY4na9Ho9J4Gi72BQwxRfAAonkRZ89Vm4/VhCnERg0EiAhqaYKfKznWTfrDXFsrskGvw89apq5n+MhUbG9dh6THLQbUM0wmoA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496722; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=6rzLL/ck02/es3rtCEyzFAswJotjkFyi2i5qTXjS7v4=; b=V5yg+4mpbZ7bFrugmvkgmwNfd0GeTzK6W9qKTsvJjVGIcQ0lF/FB0agMPaH8IIPltrjVik9CWaFbuuQEDVawnExoCjauYHHi07hO2eoHtE/BLEwzWWWwPubCp+qhvjvfSUCKZ34T4t6Gfg52t8KidpAiF/glszyU+qUeTwSsfDs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496722785113.13740039169465; Wed, 29 Apr 2026 14:05:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC4x-00051l-H6; Wed, 29 Apr 2026 17:04:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4v-0004kp-Bn for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:17 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC4t-0003La-Ln for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:17 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-594-P11UuIqfNJqca0-HXQcJeA-1; Wed, 29 Apr 2026 17:04:13 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 560B71956080; Wed, 29 Apr 2026 21:04:12 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 53BAC19560AB; Wed, 29 Apr 2026 21:04:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496655; 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=6rzLL/ck02/es3rtCEyzFAswJotjkFyi2i5qTXjS7v4=; b=B6nGDNvRFR/pLupDUSF1SrdcwGpwhd9cyfOvdIaYFtzbN2/hrHP8cLp9NFkFHh1fbyWc43 SbFcqIRIJb3uFsJZehfxEdhttJBJNhAqYhDJt4JVuLoiS4p6WpKPntkVAjGc8v1Ubnosbp KpFFW1iNgHWIhWrL7lwhIMCidUDwGFs= X-MC-Unique: P11UuIqfNJqca0-HXQcJeA-1 X-Mimecast-MFC-AGG-ID: P11UuIqfNJqca0-HXQcJeA_1777496652 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:43 +0400 Subject: [PATCH v3 10/26] ui/console-vc: extract vt100_init() and vt100_fini() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-10-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=4232; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=lnxoLHdniGID3jNMfTck0VEAWspSpAGOyq5lUI50G/Q=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILmU/orWtNu+2WtCK8xEhL8XgWVfB94j9B+ BB1bf1ud76JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5THNEACn//+1E9J9b7nW9Len4aZpbMeiQ/CdDsqQeTl70yiAQtT3/xQPnjALcMdRYWDagCvA7pW 9GDfcmml40F/0dvyQ7f7UU5V3VqTCt76JJAzJ7eGSpwA4rupjknxOELeAGb2vnCgLqE0iYR109N AFwuvJvelfwHpdgVFDbMQgbLl+O2iyxRWWvLn7Ir28/ZIbH2knBIlN8hfkaXtjw+6BKpas5Fzrw bJ274bx1Ql07EPm20MKAnyBxoEx5msNLlOte5kqyJCkTPEmPsP5Dsf9i9cCqFOAnZVTk1He/PRF /Xqti53tQU7uPopszY2k8h0WPDFsr2/On4XSrrWzQKoCNng94EZk9l3fEVwkDbSPTONMHG3I0iq 7qx/oy+wsiDBbcIaEJ9277DqwBEmoMexPUbnMdXv8F7s/ySJmkkwBiQmgfbwwMmVZVN7SHxO6Sr NhtAIbhG+Cd13lbzJaju3MqUYjQ4fcf9WpLfrIxRvdW1O2BvDsTyuhQfSuoggG1rswgy+UfnIwO kVv3NXGGfuEC6qa/dsbUV9k8SLYED65YJt43VsT3dqKt6MYY0GGP08ieax0du1C0QLG3JZHTAix CNNB0EoIamY1BBfFmnxDsz5PGbrzRrU4NFdrYAU3UCQHX3pD9nMr7xsNkDZ1Fuw0Y7vWXukqTdU tAWydH0mNja7MBA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496724743158500 Consolidate VT100 initialization and finalization into dedicated functions, continuing the extraction of the VT100 layer from the console/chardev code. vt100_init() gathers the scattered setup (cursor timer, list insertion, FIFO creation, default attributes, and image) that was previously spread across vc_chr_open() and qemu_text_console_class_init(). vt100_fini() pairs with it by handling list removal, FIFO destruction, and cells cleanup, replacing the open-coded QTAILQ_REMOVE in qemu_text_console_finalize(). Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console-vc.c | 55 +++++++++++++++++++++++++++++++++++++----------------= -- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/ui/console-vc.c b/ui/console-vc.c index 9f5f49413d2..b58fe5de827 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -331,7 +331,7 @@ static void vt100_write(QemuVT100 *vt, const void *buf,= size_t len) vt->out_flush(vt); } =20 -static int vt100_input(QemuVT100 *vt, const uint8_t *buf, int len); +static size_t vt100_input(QemuVT100 *vt, const uint8_t *buf, size_t len); =20 static void vt100_keysym(QemuVT100 *vt, int keysym) { @@ -1129,12 +1129,19 @@ static void text_console_invalidate(void *opaque) vt100_refresh(&s->vt); } =20 +static void vt100_fini(QemuVT100 *vt) +{ + QTAILQ_REMOVE(&vt100s, vt, list); + fifo8_destroy(&vt->out_fifo); + g_free(vt->cells); +} + static void qemu_text_console_finalize(Object *obj) { QemuTextConsole *s =3D QEMU_TEXT_CONSOLE(obj); =20 - QTAILQ_REMOVE(&vt100s, &s->vt, list); + vt100_fini(&s->vt); } =20 static void @@ -1142,10 +1149,6 @@ qemu_text_console_class_init(ObjectClass *oc, const = void *data) { QemuConsoleClass *cc =3D QEMU_CONSOLE_CLASS(oc); =20 - if (!cursor_timer) { - cursor_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb= , NULL); - } - cc->get_label =3D qemu_text_console_get_label; } =20 @@ -1211,6 +1214,27 @@ static void text_console_out_flush(QemuVT100 *vt) qemu_text_console_out_flush(console); } =20 +static void vt100_init(QemuVT100 *vt, + pixman_image_t *image, + ChardevVCEncoding encoding, + void (*image_update)(QemuVT100 *vt, int x, int y, i= nt w, int h), + void (*out_flush)(QemuVT100 *vt)) +{ + if (!cursor_timer) { + cursor_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb= , NULL); + } + + vt->encoding =3D encoding; + QTAILQ_INSERT_HEAD(&vt100s, vt, list); + fifo8_create(&vt->out_fifo, 16); + vt->total_height =3D DEFAULT_BACKSCROLL; + vt->image_update =3D image_update; + vt->out_flush =3D out_flush; + /* set current text attributes to default */ + vt->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + vt100_set_image(vt, image); +} + static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **err= p) { ChardevVC *vc =3D backend->u.vc.data; @@ -1240,22 +1264,17 @@ static bool vc_chr_open(Chardev *chr, ChardevBacken= d *backend, Error **errp) s =3D QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_FIXED_TEXT_CONSOLE)); } =20 - QTAILQ_INSERT_HEAD(&vt100s, &s->vt, list); - fifo8_create(&s->vt.out_fifo, 16); - s->vt.total_height =3D DEFAULT_BACKSCROLL; dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(wi= dth, height)); - s->vt.image_update =3D text_console_image_update; - s->vt.out_flush =3D text_console_out_flush; - - s->chr =3D chr; - drv->console =3D s; if (vc->has_encoding) { - drv->encoding =3D s->vt.encoding =3D vc->encoding; + drv->encoding =3D vc->encoding; } + vt100_init(&s->vt, QEMU_CONSOLE(s)->surface->image, + drv->encoding, + text_console_image_update, + text_console_out_flush); =20 - /* set current text attributes to default */ - s->vt.t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - vt100_set_image(&s->vt, QEMU_CONSOLE(s)->surface->image); + s->chr =3D chr; + drv->console =3D s; =20 if (chr->label) { char *msg; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496677; cv=none; d=zohomail.com; s=zohoarc; b=UsQB+EofD1XPTRcLYuKSgptkFRd+t1oo3q7W56Ie9/qO/ypUkcWPadf4yQvBIMunWB72EvLoFLxqxtNTh+U6TxcpbG+Yu4NXlanU0W0e+9VKjTCTINtoKHA3aGLBxLeRdhZO3RTuRH/mB2gRyJlfD7KyLgZkT5u+WLiF7mr8ThM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496677; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IfE3kM3GXvE+FVkLELiXcNJAoP1JDi8ACboNIJNy4Bc=; b=A7OsrsX5aoziC1lX2QB9lulL6ACEjmWc7TJBsSO9mbUh7BwIbkFuPHNCV1j+lOuqZrN2PfeNGQizqIta0NrOYFhgqcCNihtuRoFbEt+NnECADPoTkp8lByp6XI2T4CIYD+/9zSLubg5mM566SU3LLmB2DExggHYXv8yMqYUWKeI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496677047695.5934843092487; Wed, 29 Apr 2026 14:04:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC56-0005ZD-2S; Wed, 29 Apr 2026 17:04:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC54-0005UJ-7U for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:26 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC52-0003N2-Au for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:25 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-313-aOrY4-u6MkuV1uGjYiXf4w-1; Wed, 29 Apr 2026 17:04:19 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1B31119560B7; Wed, 29 Apr 2026 21:04:18 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AD4F61800348; Wed, 29 Apr 2026 21:04:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496663; 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=IfE3kM3GXvE+FVkLELiXcNJAoP1JDi8ACboNIJNy4Bc=; b=Zge7OOeM+LKtzZLdIl7Gg7P6pbUjFPBc9tHW6+TGdVmE2l3+t5Y3eLGG9SFq1j5dz7BrE+ SBU9OUciz3sfee6eeNviyyxezyWlZ20BzVTESMaH35M3m/pOxq5H62SHNqcGfG2y9WHn7s uvY4wSMVhBpvap4obygE2IiMz+kio/s= X-MC-Unique: aOrY4-u6MkuV1uGjYiXf4w-1 X-Mimecast-MFC-AGG-ID: aOrY4-u6MkuV1uGjYiXf4w_1777496658 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:44 +0400 Subject: [PATCH v3 11/26] ui/console: remove console_ch_t typedef and console_write_ch() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-11-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=10560; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=e4ykukOXoAYey5FeMaNxglAMqZqFZfYwcq4HSeTlZKg=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILZRHGHkK4Uk3uUpgz3fdoCRco6QPJSl/9n hOE/xivobiJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5au4D/9ispI+a/VHGpqozmM7YqGJI9I1cC5w5V+ClKF/oSWtN9Io8TWsd+JGH3Yf+tYgbbv/BMQ czy06W2XwZAwEp8UZfZodJX1EoNF398sHM2Lxbi9PQ0xBesMijnffBtcFKyMdvF1MHAStfnMzX2 HIrYlG7zGNNT2Ptjrx63KEeMIBNh+EhBXAHvTmwr7K7yWBux8LWTOURCydJyruNN1cTJxCSMGHk T71kkxDhu9vacMowkgr80Nefvmvu/VQPiiTyBmSGQZwrfz7zpR1QUoUuwfpdbGqUthl0QhvoAmA YBic2zDY9ytFlZ2UQz89d+T0kHD+5iR9vAZSYmvs6PWI0RiGNysms80xohKdzpKVs6rgL8OGr38 qHABh7LcWv609XkpG1shdNh7H1xmr0A+9v41Bns/Pt7MQzA7EYT+0uRzBpzEaRSbizOSpp12lzW tvrvBEyj45yGGuUG9lWLa35Ij8UIiSZzxImT8JOolYpdhBsG6lxBSXH3iwTc4HIotKTaKJoueOq AwBbUBjeO3Pmu2uTrBddNV2i2HvH9MXVKJ9MJQdf9HWxwMBieR+Y77AGjFSVBp0XCliCfWsvraz 42HuvBJJfrJMB0rP7aV0mVrS+HDQ3k3dXiumwmR5IJ6IBDjHkoyKX2Ev1+msUwwzfHxIFslU4cE X1XZp0F/1mQXCyQ== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496680463154100 Since commit e2f82e924d05 ("console: purge curses bits from console.h"), console_ch_t is a plain uint32_t typedef and console_write_ch() is a trivial assignment (*dest =3D ch). These abstractions were originally needed because console_ch_t was the curses chtype when CONFIG_CURSES was enabled, and console_write_ch() handled VGA-to-curses character translation. That commit moved the curses logic into curses_update(), making the typedef and helper dead abstractions. Replace console_ch_t with uint32_t and console_write_ch() calls with direct assignments. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/ui/console.h | 9 +-------- hw/display/jazz_led.c | 10 +++++----- hw/display/vga.c | 16 ++++++++-------- hw/display/virtio-gpu-base.c | 2 +- hw/display/virtio-vga.c | 2 +- hw/display/vmware_vga.c | 2 +- ui/console-vc.c | 11 +++++------ ui/console.c | 2 +- ui/curses.c | 6 +++--- 9 files changed, 26 insertions(+), 34 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 27eacc39cc0..2bf768ed482 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -336,13 +336,6 @@ int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLCo= ntext ctx); =20 bool console_has_gl(QemuConsole *con); =20 -typedef uint32_t console_ch_t; - -static inline void console_write_ch(console_ch_t *dest, uint32_t ch) -{ - *dest =3D ch; -} - enum { GRAPHIC_FLAGS_NONE =3D 0, /* require a console/display with GL callbacks */ @@ -377,7 +370,7 @@ void graphic_console_close(QemuConsole *con); void graphic_hw_update(QemuConsole *con); 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_text_update(QemuConsole *con, uint32_t *chardata); void graphic_hw_gl_block(QemuConsole *con, bool block); =20 void qemu_console_early_init(void); diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index 7d1a020d4d9..ee9758a94b5 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -228,7 +228,7 @@ static void jazz_led_invalidate_display(void *opaque) s->state |=3D REDRAW_SEGMENTS | REDRAW_BACKGROUND; } =20 -static void jazz_led_text_update(void *opaque, console_ch_t *chardata) +static void jazz_led_text_update(void *opaque, uint32_t *chardata) { LedState *s =3D opaque; char buf[3]; @@ -238,10 +238,10 @@ static void jazz_led_text_update(void *opaque, consol= e_ch_t *chardata) =20 /* TODO: draw the segments */ snprintf(buf, 3, "%02hhx", s->segments); - console_write_ch(chardata++, ATTR2CHTYPE(buf[0], QEMU_COLOR_BLUE, - QEMU_COLOR_BLACK, 1)); - console_write_ch(chardata++, ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE, - QEMU_COLOR_BLACK, 1)); + *chardata++ =3D ATTR2CHTYPE(buf[0], QEMU_COLOR_BLUE, + QEMU_COLOR_BLACK, 1); + *chardata++ =3D ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE, + QEMU_COLOR_BLACK, 1); =20 dpy_text_update(s->con, 0, 0, 2, 1); } diff --git a/hw/display/vga.c b/hw/display/vga.c index 776aa443246..2f266f47a39 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1901,13 +1901,13 @@ static void vga_reset(void *opaque) ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1)) /* relay text rendering to the display driver * instead of doing a full vga_update_display() */ -static void vga_update_text(void *opaque, console_ch_t *chardata) +static void vga_update_text(void *opaque, uint32_t *chardata) { VGACommonState *s =3D opaque; int graphic_mode, i, cursor_offset, cursor_visible; int cw, cheight, width, height, size, c_min, c_max; uint32_t *src; - console_ch_t *dst, val; + uint32_t *dst, val; char msg_buffer[80]; int full_update =3D 0; =20 @@ -2007,14 +2007,14 @@ static void vga_update_text(void *opaque, console_c= h_t *chardata) =20 if (full_update) { for (i =3D 0; i < size; src ++, dst ++, i ++) - console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src))); + *dst =3D VMEM2CHTYPE(le32_to_cpu(*src)); =20 dpy_text_update(s->con, 0, 0, width, height); } else { c_max =3D 0; =20 for (i =3D 0; i < size; src ++, dst ++, i ++) { - console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src))); + val =3D VMEM2CHTYPE(le32_to_cpu(*src)); if (*dst !=3D val) { *dst =3D val; c_max =3D i; @@ -2023,7 +2023,7 @@ static void vga_update_text(void *opaque, console_ch_= t *chardata) } c_min =3D i; for (; i < size; src ++, dst ++, i ++) { - console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src))); + val =3D VMEM2CHTYPE(le32_to_cpu(*src)); if (*dst !=3D val) { *dst =3D val; c_max =3D i; @@ -2061,14 +2061,14 @@ static void vga_update_text(void *opaque, console_c= h_t *chardata) dpy_text_resize(s->con, s->last_width, height); =20 for (dst =3D chardata, i =3D 0; i < s->last_width * height; i ++) - console_write_ch(dst ++, ' '); + *dst++ =3D ' '; =20 size =3D strlen(msg_buffer); width =3D (s->last_width - size) / 2; dst =3D chardata + s->last_width + width; for (i =3D 0; i < size; i ++) - console_write_ch(dst ++, ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLU= E, - QEMU_COLOR_BLACK, 1)); + *dst++ =3D ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE, + QEMU_COLOR_BLACK, 1); =20 dpy_text_update(s->con, 0, 0, s->last_width, height); } diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index 94cf362d152..bdc24492850 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -88,7 +88,7 @@ static bool virtio_gpu_update_display(void *opaque) return true; } =20 -static void virtio_gpu_text_update(void *opaque, console_ch_t *chardata) +static void virtio_gpu_text_update(void *opaque, uint32_t *chardata) { } =20 diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index f4713b91a66..efd4858f3d0 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -31,7 +31,7 @@ static bool virtio_vga_base_update_display(void *opaque) } } =20 -static void virtio_vga_base_text_update(void *opaque, console_ch_t *charda= ta) +static void virtio_vga_base_text_update(void *opaque, uint32_t *chardata) { VirtIOVGABase *vvga =3D opaque; VirtIOGPUBase *g =3D vvga->vgpu; diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index c84c84a445e..11f13c98d7a 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -1184,7 +1184,7 @@ static void vmsvga_invalidate_display(void *opaque) s->invalidated =3D 1; } =20 -static void vmsvga_text_update(void *opaque, console_ch_t *chardata) +static void vmsvga_text_update(void *opaque, uint32_t *chardata) { struct vmsvga_state_s *s =3D opaque; =20 diff --git a/ui/console-vc.c b/ui/console-vc.c index b58fe5de827..b9da9ddf30d 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -386,7 +386,7 @@ void qemu_text_console_handle_keysym(QemuTextConsole *s= , int keysym) vt100_keysym(&s->vt, keysym); } =20 -static void text_console_update(void *opaque, console_ch_t *chardata) +static void text_console_update(void *opaque, uint32_t *chardata) { QemuTextConsole *s =3D QEMU_TEXT_CONSOLE(opaque); int i, j, src; @@ -396,11 +396,10 @@ static void text_console_update(void *opaque, console= _ch_t *chardata) chardata +=3D s->vt.text_y[0] * s->vt.width; for (i =3D s->vt.text_y[0]; i <=3D s->vt.text_y[1]; i ++) for (j =3D 0; j < s->vt.width; j++, src++) { - console_write_ch(chardata ++, - ATTR2CHTYPE(s->vt.cells[src].ch, - s->vt.cells[src].t_attrib.fgc= ol, - s->vt.cells[src].t_attrib.bgc= ol, - s->vt.cells[src].t_attrib.bol= d)); + *chardata++ =3D ATTR2CHTYPE(s->vt.cells[src].ch, + s->vt.cells[src].t_attrib.fgcol, + s->vt.cells[src].t_attrib.bgcol, + s->vt.cells[src].t_attrib.bold); } dpy_text_update(QEMU_CONSOLE(s), s->vt.text_x[0], s->vt.text_y[0], s->vt.text_x[1] - s->vt.text_x[0], i - s->vt.text_= y[0]); diff --git a/ui/console.c b/ui/console.c index 799d61ec1a5..1c75b1a355b 100644 --- a/ui/console.c +++ b/ui/console.c @@ -210,7 +210,7 @@ void graphic_hw_invalidate(QemuConsole *con) } } =20 -void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata) +void graphic_hw_text_update(QemuConsole *con, uint32_t *chardata) { if (con && con->hw_ops->text_update) { con->hw_ops->text_update(con->hw, chardata); diff --git a/ui/curses.c b/ui/curses.c index af4ccb4227d..96427aa6bb9 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -57,7 +57,7 @@ enum maybe_keycode { }; =20 static DisplayChangeListener *dcl; -static console_ch_t *screen; +static uint32_t *screen; static WINDOW *screenpad =3D NULL; static int width, height, gwidth, gheight, invalidate; static int px, py, sminx, sminy, smaxx, smaxy; @@ -68,7 +68,7 @@ static cchar_t *vga_to_curses; static void curses_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { - console_ch_t *line; + uint32_t *line; g_autofree cchar_t *curses_line =3D g_new(cchar_t, width); wchar_t wch[CCHARW_MAX]; attr_t attrs; @@ -796,7 +796,7 @@ static void curses_display_init(DisplayState *ds, Displ= ayOptions *opts) if (opts->u.curses.charset) { font_charset =3D opts->u.curses.charset; } - screen =3D g_new0(console_ch_t, 160 * 100); + screen =3D g_new0(uint32_t, 160 * 100); vga_to_curses =3D g_new0(cchar_t, 256); curses_setup(); curses_keyboard_setup(); --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496682; cv=none; d=zohomail.com; s=zohoarc; b=U5cPJbM5zPlPGvEYCmFDxWd1+/Ef+toZMDw9t6wloavKM4XIL6L4ta978z4xICMeRuhcUF5ae28l/tXwg0owizOTzc13luUVUSaz/Xpu/h1wp0a280JRMtn5kTp1wXmOVBxfdBRBfIDYDWFbT2lJ5gYzd2A0xITkdzxfqFDbT6E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496682; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BK3c2W6DMmyWJuLoOeRh4eKpwnPSyzyiOLd1z1qjiBM=; b=UPGCkUr3O0SbLpdk9qyqtW54P1pDtBnfaA+coHO/oDTsMPdV80WCVqkVB3IijGBVrQzMNVej489GCirptOWhyNPJNeLFEAfev0Pr53dTjnDhrBfnMz/BDozzItwGw/1Xkdw1gWiC4+c65TZv+q7v/nN+LYb2Hu17/FvcooGicvo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496682205811.468345943995; Wed, 29 Apr 2026 14:04:42 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC59-0005qE-GZ; Wed, 29 Apr 2026 17:04:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC58-0005nU-5W for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC56-0003PZ-Q0 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:29 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-643-68jPbWKXP_qLnpsjLx70mw-1; Wed, 29 Apr 2026 17:04:24 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C3B8419560B5; Wed, 29 Apr 2026 21:04:23 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B7D411800480; Wed, 29 Apr 2026 21:04:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496668; 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=BK3c2W6DMmyWJuLoOeRh4eKpwnPSyzyiOLd1z1qjiBM=; b=doIe5oH21FxAPJr+PFFcX3rz4yJ+sDx8nszOFDNiJ+aTR7dYo2sYSV2hLNu6CRq+ZSGcOu VzslVfwab9cidfnPR9z369maPsEa3ZiFgdvw4D/euFr6a0uI2uOIzEWOmsegUuGjG0sGEj kUJKRg1coBCqBuu6AK0L+URT3FnCLaA= X-MC-Unique: 68jPbWKXP_qLnpsjLx70mw-1 X-Mimecast-MFC-AGG-ID: 68jPbWKXP_qLnpsjLx70mw_1777496663 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:45 +0400 Subject: [PATCH v3 12/26] ui: move FONT_WIDTH/HEIGHT to vgafont.h MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-12-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=643; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=n2GeqMeQQVy2zQA4Nr3GV7Ks0o8e625Vkmet5L8y+uQ=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILy7Y6vusiyAX44w7elLOWnF/mbhA7Elfsx sCDKsYVus6JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5bD5EAClNgzL7i6zQ10uD66OmAO3ZoSVioHeJXdHotLVWsE5DnWtiVKMUdqnEBCNgs8jQNJTfxF 60LSqhd13mShQMcbKtEUQHOfTH0ptRyOGyxwZoLjUhcusifzj57pi0lmEGT5lhby75AGPCT9t6o bMZ80awUIx1urYC/zLRE3tHgBl9w9pZ6noNTyY/W6goJoPhO278K7MdvKP+DFNvV1+YqbW/nbJ1 RLP1cil0cgRfhaAK87C9LQG+amNw/o5r9KNe0MKfNGmj8kydKvERLMZmfvIh+CDt1mpDY1wP8+L xNJSLJBbXpKRZGyAiP5dRJiofiIE5C2SrpbktRJYeK0nEH4FZXgZp3ACFlu2zt33hdlLuQtwHY6 SYY5Wv95pRYeHckxn9qc27xDI+SP6JS3Y2u+aG2c4Dy6DUw9703pKhMIOWiqxx2jhRxIsAIuOlz vMhpoii+NHuzHGQAClWw0Gi8K7hkgSrm7DPTJfXRyeXPBRYrbtnP3Z8mrk+UCpi1CB/xSNYrDJn zgbd7gb1fsORnKWK1HGHUpTat+qkwSG8xnrCktP3tfUnopExC4CYwmp9DGjbJNbLk/DokynAvVH munkor1eiI8sIrk46sYSCsnyfu7QiAem17t6bXNJm5qtZGtgY7+iOJWCudxdXJyIygWlfxHaU7e NZRTDOrKKk1Kg3Q== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496684390154100 Since those values are related to the VGA font, it make sense to move them here. Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console-vc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/console-vc.c b/ui/console-vc.c index b9da9ddf30d..457d071c774 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -13,6 +13,7 @@ #include "ui/console.h" #include "ui/vgafont.h" #include "ui/cp437.h" +#include "ui/vgafont.h" =20 #include "pixman.h" #include "trace.h" --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496759; cv=none; d=zohomail.com; s=zohoarc; b=ZN3rDKP1luIO15lEy5jk/udXXAeb/zVZt+ivkPa6Dl9lIPxtacI14JY/uwdBTmCoSiFrYy/9upkMItLm/82OdNOqhbxcEG/l55LQFYhc8qYP5W/tErig2k842o6VEBbhdvIeaLyX9qzZWxnsuwUBZ2s9TO7UEaIvhaQgTj0lTwg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496759; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bJRqs6vvUppi6JPRfhdkq5nBLUS8sVJcdAzUCI4ynK4=; b=geAyO2+f26Tz/h6omib23b+ptoSa0lDjVefdh5mUG2biNgXQEzHGObkXmot00w1ZxId2mcLHXA1qi+ZR8GZVJpxFatt8dHVSEOPWdSDml7gNTcMY+kaw/BPDFVIzUBabgqA16q/KyeoYNqx01WZsQWi2JRHYzzjPm8cqnT0cqxY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496759150296.7833636510736; Wed, 29 Apr 2026 14:05:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6R-0006oE-Ak; Wed, 29 Apr 2026 17:05:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5G-0006Fk-Jv for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5C-0003Sm-3S for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:38 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-683-WqYQKZWyPd6aG1On25_vgQ-1; Wed, 29 Apr 2026 17:04:31 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D1F6319560A3; Wed, 29 Apr 2026 21:04:30 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 35FBF19560AB; Wed, 29 Apr 2026 21:04:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496673; 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=bJRqs6vvUppi6JPRfhdkq5nBLUS8sVJcdAzUCI4ynK4=; b=DtYo9Mik0wXMiYuH6o0TkyE/fkJt5ZY1AFFTcgx36G5CzB/cfaeVKO8VYVlGos5b2Ow3s4 AhVYVCh0bMp8Ld8+gzqpf8ESy8BT1GeUWd6LfN0twj0rlujhbTjgU+gWdcuMDpiAyIUsYA wX1Oj3B8uFvHq16ga3BawqZg3OYCy7g= X-MC-Unique: WqYQKZWyPd6aG1On25_vgQ-1 X-Mimecast-MFC-AGG-ID: WqYQKZWyPd6aG1On25_vgQ_1777496670 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:46 +0400 Subject: [PATCH v3 13/26] ui/console-vc: move VT100 emulation into separate unit MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-13-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=72240; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=uXdthhRKhJyhFmLLwzyoZN0GejQctr4lqkCfaK8l+1c=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nILpLGpI/fCw6YfUHvEszFUjrBqCZiir/ZwC DfEeVQDz8iJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyCwAKCRDa6OEJdZac 5a7wD/0byt1I4xU5DnBFZng5qtDnkg/CWGbjXGADPU6Hyq/WD1JclbAST94yXDanb6ctRrP9Loa gIMPjjr9HlvjI91Eql99toymXGnJK9US+1mhIRUihCwbM0Inmy2FHDGeW2d+2c3pE9s6xvvfE7B uHDwoxQ299tAZZm4R06mwrO+pAGx/KOKm1SX4+WTzFwvZMlN0mAXsNuLNTmDF50HSN/t+Dyax2L wum6XJvq0RjBDP1QKGBbvquh1thoxCYdAOw1XFWiQx0b/9tVBG1AmPH280tNlQReva5nCz/MpSp PwVYOIOVebkVWSExEpv3WunfE2ngUGo0Oldy/1fSVz3Pr44mObyIFKgoOV6uJvjXuhTZ6qnLrKm Eeo17OWNNONcYc061tzriqvnxCs4UJXNMOHGC2+QBXYAQk9WmGNTPnk+D6UlACr/sJOAi0pgYAu EWE0e8VZDgmgjAfWYLUgzwpJyh9gX3fX1zndY8fITw1+fTKFaP/IikaicuyzlLO85DxNk9agxRA byJINd33ItHzX7Yv3ZiLhFD+IOr6Rpda0enHJbA6TaSq/EiMevw7OTxi7Y+GLI6cnU3hj9d/MIA QOC3cVShEBNB/s6oyN3hyW21LSrvMxbwSY5OHKtmClpo7+Y1/lH+P7oYwFAXkJEA0+UrQCKaD0k DkYLyCXIaa003Ig== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496759892154100 Move the VT100 terminal emulation code into dedicated ui/vt100.c and ui/vt100.h files, completing the extraction from console-vc.c started in the previous patches. This makes the VT100 layer a self-contained module that can be reused independently of the chardev/console infrastructure. The code is moved as-is, with minor coding style fixes (adding missing braces, fixing whitespace) applied during the move. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/console-priv.h | 1 - ui/vt100.h | 95 +++++ ui/console-vc-stubs.c | 1 + ui/console-vc.c | 1034 +--------------------------------------------= ---- ui/console.c | 2 + ui/vt100.c | 984 ++++++++++++++++++++++++++++++++++++++++++++++ ui/meson.build | 4 +- 7 files changed, 1086 insertions(+), 1035 deletions(-) diff --git a/ui/console-priv.h b/ui/console-priv.h index 2299898984d..4f731b4f9ce 100644 --- a/ui/console-priv.h +++ b/ui/console-priv.h @@ -30,7 +30,6 @@ struct QemuConsole { }; =20 void qemu_text_console_update_size(QemuTextConsole *c); -void vt100_update_cursor(void); void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym); =20 #endif diff --git a/ui/vt100.h b/ui/vt100.h new file mode 100644 index 00000000000..22ce2368bff --- /dev/null +++ b/ui/vt100.h @@ -0,0 +1,95 @@ +/* + * SPDX-License-Identifier: MIT + * QEMU vt100 + */ +#ifndef VT100_H +#define VT100_H + +#include "chardev/char.h" +#include "ui/console.h" +#include "qemu/fifo8.h" +#include "qemu/queue.h" + +typedef struct TextAttributes { + uint8_t fgcol:4; + uint8_t bgcol:4; + uint8_t bold:1; + uint8_t uline:1; + uint8_t blink:1; + uint8_t invers:1; + uint8_t unvisible:1; +} TextAttributes; + +#define TEXT_ATTRIBUTES_DEFAULT ((TextAttributes) { \ + .fgcol =3D QEMU_COLOR_WHITE, \ + .bgcol =3D QEMU_COLOR_BLACK \ +}) + +typedef struct TextCell { + uint8_t ch; + TextAttributes t_attrib; +} TextCell; + +#define MAX_ESC_PARAMS 3 + +enum TTYState { + TTY_STATE_NORM, + TTY_STATE_ESC, + TTY_STATE_CSI, + TTY_STATE_G0, + TTY_STATE_G1, + TTY_STATE_OSC, +}; + +typedef struct QemuVT100 QemuVT100; + +struct QemuVT100 { + pixman_image_t *image; + void (*image_update)(QemuVT100 *vt, int x, int y, int width, int heigh= t); + + ChardevVCEncoding encoding; + int width; + int height; + int total_height; + int backscroll_height; + int x, y; + int y_displayed; + int y_base; + TextCell *cells; + int text_x[2], text_y[2], cursor_invalidate; + int echo; + + int update_x0; + int update_y0; + int update_x1; + int update_y1; + + enum TTYState state; + int esc_params[MAX_ESC_PARAMS]; + int nb_esc_params; + uint32_t utf8_state; /* UTF-8 DFA decoder state */ + uint32_t utf8_codepoint; /* accumulated UTF-8 code point */ + TextAttributes t_attrib; /* currently active text attributes */ + TextAttributes t_attrib_saved; + int x_saved, y_saved; + /* fifo for key pressed */ + Fifo8 out_fifo; + void (*out_flush)(QemuVT100 *vt); + + QTAILQ_ENTRY(QemuVT100) list; +}; + +void vt100_init(QemuVT100 *vt, + pixman_image_t *image, + ChardevVCEncoding encoding, + void (*image_update)(QemuVT100 *vt, int x, int y, int widt= h, int height), + void (*out_flush)(QemuVT100 *vt)); +void vt100_fini(QemuVT100 *vt); + +void vt100_update_cursor(void); +size_t vt100_input(QemuVT100 *vt, const uint8_t *buf, size_t len); +void vt100_keysym(QemuVT100 *vt, int keysym); +void vt100_set_image(QemuVT100 *vt, pixman_image_t *image); +void vt100_refresh(QemuVT100 *vt); + +#endif diff --git a/ui/console-vc-stubs.c b/ui/console-vc-stubs.c index d911a82f263..30e4d101197 100644 --- a/ui/console-vc-stubs.c +++ b/ui/console-vc-stubs.c @@ -9,6 +9,7 @@ #include "qemu/option.h" #include "chardev/char.h" #include "ui/console-priv.h" +#include "vt100.h" =20 void qemu_text_console_update_size(QemuTextConsole *c) { diff --git a/ui/console-vc.c b/ui/console-vc.c index 457d071c774..99ad6d079df 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -6,94 +6,17 @@ =20 #include "chardev/char.h" #include "qapi/error.h" -#include "qemu/fifo8.h" #include "qemu/option.h" #include "qemu/queue.h" #include "qom/compat-properties.h" #include "ui/console.h" #include "ui/vgafont.h" -#include "ui/cp437.h" -#include "ui/vgafont.h" +#include "ui/vt100.h" =20 #include "pixman.h" #include "trace.h" #include "console-priv.h" =20 -#define DEFAULT_BACKSCROLL 512 -#define CONSOLE_CURSOR_PERIOD 500 - -typedef struct TextAttributes { - uint8_t fgcol:4; - uint8_t bgcol:4; - uint8_t bold:1; - uint8_t uline:1; - uint8_t blink:1; - uint8_t invers:1; - uint8_t unvisible:1; -} TextAttributes; - -#define TEXT_ATTRIBUTES_DEFAULT ((TextAttributes) { \ - .fgcol =3D QEMU_COLOR_WHITE, \ - .bgcol =3D QEMU_COLOR_BLACK \ -}) - -typedef struct TextCell { - uint8_t ch; - TextAttributes t_attrib; -} TextCell; - -#define MAX_ESC_PARAMS 3 - -enum TTYState { - TTY_STATE_NORM, - TTY_STATE_ESC, - TTY_STATE_CSI, - TTY_STATE_G0, - TTY_STATE_G1, - TTY_STATE_OSC, -}; - -typedef struct QemuVT100 QemuVT100; - -struct QemuVT100 { - pixman_image_t *image; - void (*image_update)(QemuVT100 *vt, int x, int y, int width, int heigh= t); - - ChardevVCEncoding encoding; - int width; - int height; - int total_height; - int backscroll_height; - int x, y; - int y_displayed; - int y_base; - TextCell *cells; - int text_x[2], text_y[2], cursor_invalidate; - int echo; - - int update_x0; - int update_y0; - int update_x1; - int update_y1; - - enum TTYState state; - int esc_params[MAX_ESC_PARAMS]; - int nb_esc_params; - uint32_t utf8_state; /* UTF-8 DFA decoder state */ - uint32_t utf8_codepoint; /* accumulated UTF-8 code point */ - TextAttributes t_attrib; /* currently active text attributes */ - TextAttributes t_attrib_saved; - int x_saved, y_saved; - /* fifo for key pressed */ - Fifo8 out_fifo; - void (*out_flush)(QemuVT100 *vt); - - QTAILQ_ENTRY(QemuVT100) list; -}; - -static QTAILQ_HEAD(QemuVT100Head, QemuVT100) vt100s =3D - QTAILQ_HEAD_INITIALIZER(vt100s); - typedef struct QemuTextConsole { QemuConsole parent; =20 @@ -121,32 +44,6 @@ struct VCChardev { }; typedef struct VCChardev VCChardev; =20 -static const pixman_color_t color_table_rgb[2][8] =3D { - { /* dark */ - [QEMU_COLOR_BLACK] =3D QEMU_PIXMAN_COLOR_BLACK, - [QEMU_COLOR_BLUE] =3D QEMU_PIXMAN_COLOR(0x00, 0x00, 0xaa), /* = blue */ - [QEMU_COLOR_GREEN] =3D QEMU_PIXMAN_COLOR(0x00, 0xaa, 0x00), /* = green */ - [QEMU_COLOR_CYAN] =3D QEMU_PIXMAN_COLOR(0x00, 0xaa, 0xaa), /* = cyan */ - [QEMU_COLOR_RED] =3D QEMU_PIXMAN_COLOR(0xaa, 0x00, 0x00), /* = red */ - [QEMU_COLOR_MAGENTA] =3D QEMU_PIXMAN_COLOR(0xaa, 0x00, 0xaa), /* = magenta */ - [QEMU_COLOR_YELLOW] =3D QEMU_PIXMAN_COLOR(0xaa, 0xaa, 0x00), /* = yellow */ - [QEMU_COLOR_WHITE] =3D QEMU_PIXMAN_COLOR_GRAY, - }, - { /* bright */ - [QEMU_COLOR_BLACK] =3D QEMU_PIXMAN_COLOR_BLACK, - [QEMU_COLOR_BLUE] =3D QEMU_PIXMAN_COLOR(0x00, 0x00, 0xff), /* = blue */ - [QEMU_COLOR_GREEN] =3D QEMU_PIXMAN_COLOR(0x00, 0xff, 0x00), /* = green */ - [QEMU_COLOR_CYAN] =3D QEMU_PIXMAN_COLOR(0x00, 0xff, 0xff), /* = cyan */ - [QEMU_COLOR_RED] =3D QEMU_PIXMAN_COLOR(0xff, 0x00, 0x00), /* = red */ - [QEMU_COLOR_MAGENTA] =3D QEMU_PIXMAN_COLOR(0xff, 0x00, 0xff), /* = magenta */ - [QEMU_COLOR_YELLOW] =3D QEMU_PIXMAN_COLOR(0xff, 0xff, 0x00), /* = yellow */ - [QEMU_COLOR_WHITE] =3D QEMU_PIXMAN_COLOR(0xff, 0xff, 0xff), /* = white */ - } -}; - -static bool cursor_visible_phase; -static QEMUTimer *cursor_timer; - static char * qemu_text_console_get_label(const QemuConsole *c) { @@ -155,157 +52,6 @@ qemu_text_console_get_label(const QemuConsole *c) return tc->chr ? g_strdup(tc->chr->label) : NULL; } =20 -static void image_fill_rect(pixman_image_t *image, int posx, int posy, - int width, int height, pixman_color_t color) -{ - pixman_rectangle16_t rect =3D { - .x =3D posx, .y =3D posy, .width =3D width, .height =3D height - }; - - pixman_image_fill_rectangles(PIXMAN_OP_SRC, image, &color, 1, &rect); -} - -/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */ -static void image_bitblt(pixman_image_t *image, - int xs, int ys, int xd, int yd, int w, int h) -{ - pixman_image_composite(PIXMAN_OP_SRC, - image, NULL, image, - xs, ys, 0, 0, xd, yd, w, h); -} - -static void vt100_putcharxy(QemuVT100 *vt, int x, int y, int ch, - TextAttributes *t_attrib) -{ - static pixman_image_t *glyphs[256]; - pixman_color_t fgcol, bgcol; - - assert(vt->image); - if (t_attrib->invers) { - bgcol =3D color_table_rgb[t_attrib->bold][t_attrib->fgcol]; - fgcol =3D color_table_rgb[t_attrib->bold][t_attrib->bgcol]; - } else { - fgcol =3D color_table_rgb[t_attrib->bold][t_attrib->fgcol]; - bgcol =3D color_table_rgb[t_attrib->bold][t_attrib->bgcol]; - } - - if (!glyphs[ch]) { - glyphs[ch] =3D qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont= 16, ch); - } - qemu_pixman_glyph_render(glyphs[ch], vt->image, - &fgcol, &bgcol, x, y, FONT_WIDTH, FONT_HEIGHT= ); -} - -static void vt100_invalidate_xy(QemuVT100 *vt, int x, int y) -{ - if (vt->update_x0 > x * FONT_WIDTH) { - vt->update_x0 =3D x * FONT_WIDTH; - } - if (vt->update_y0 > y * FONT_HEIGHT) { - vt->update_y0 =3D y * FONT_HEIGHT; - } - if (vt->update_x1 < (x + 1) * FONT_WIDTH) { - vt->update_x1 =3D (x + 1) * FONT_WIDTH; - } - if (vt->update_y1 < (y + 1) * FONT_HEIGHT) { - vt->update_y1 =3D (y + 1) * FONT_HEIGHT; - } -} - -static void vt100_show_cursor(QemuVT100 *vt, int show) -{ - TextCell *c; - int y, y1; - int x =3D vt->x; - - vt->cursor_invalidate =3D 1; - - if (x >=3D vt->width) { - x =3D vt->width - 1; - } - y1 =3D (vt->y_base + vt->y) % vt->total_height; - y =3D y1 - vt->y_displayed; - if (y < 0) { - y +=3D vt->total_height; - } - if (y < vt->height) { - c =3D &vt->cells[y1 * vt->width + x]; - if (show && cursor_visible_phase) { - TextAttributes t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - t_attrib.invers =3D !(t_attrib.invers); /* invert fg and bg */ - vt100_putcharxy(vt, x, y, c->ch, &t_attrib); - } else { - vt100_putcharxy(vt, x, y, c->ch, &(c->t_attrib)); - } - vt100_invalidate_xy(vt, x, y); - } -} - -static void vt100_image_update(QemuVT100 *vt, int x, int y, int width, int= height) -{ - vt->image_update(vt, x, y, width, height); -} - -static void vt100_refresh(QemuVT100 *vt) -{ - TextCell *c; - int x, y, y1; - int w =3D pixman_image_get_width(vt->image); - int h =3D pixman_image_get_height(vt->image); - - vt->text_x[0] =3D 0; - vt->text_y[0] =3D 0; - vt->text_x[1] =3D vt->width - 1; - vt->text_y[1] =3D vt->height - 1; - vt->cursor_invalidate =3D 1; - - image_fill_rect(vt->image, 0, 0, w, h, - color_table_rgb[0][QEMU_COLOR_BLACK]); - y1 =3D vt->y_displayed; - for (y =3D 0; y < vt->height; y++) { - c =3D vt->cells + y1 * vt->width; - for (x =3D 0; x < vt->width; x++) { - vt100_putcharxy(vt, x, y, c->ch, - &(c->t_attrib)); - c++; - } - if (++y1 =3D=3D vt->total_height) { - y1 =3D 0; - } - } - vt100_show_cursor(vt, 1); - vt100_image_update(vt, 0, 0, w, h); -} - -static void vt100_scroll(QemuVT100 *vt, int ydelta) -{ - int i, y1; - - if (ydelta > 0) { - for(i =3D 0; i < ydelta; i++) { - if (vt->y_displayed =3D=3D vt->y_base) - break; - if (++vt->y_displayed =3D=3D vt->total_height) - vt->y_displayed =3D 0; - } - } else { - ydelta =3D -ydelta; - i =3D vt->backscroll_height; - if (i > vt->total_height - vt->height) - i =3D vt->total_height - vt->height; - y1 =3D vt->y_base - i; - if (y1 < 0) - y1 +=3D vt->total_height; - for(i =3D 0; i < ydelta; i++) { - if (vt->y_displayed =3D=3D y1) - break; - if (--vt->y_displayed < 0) - vt->y_displayed =3D vt->total_height - 1; - } - } - vt100_refresh(vt); -} - static void qemu_text_console_out_flush(QemuTextConsole *s) { uint32_t len, avail; @@ -323,64 +69,6 @@ static void qemu_text_console_out_flush(QemuTextConsole= *s) } } =20 -static void vt100_write(QemuVT100 *vt, const void *buf, size_t len) -{ - uint32_t num_free; - - num_free =3D fifo8_num_free(&vt->out_fifo); - fifo8_push_all(&vt->out_fifo, buf, MIN(num_free, len)); - vt->out_flush(vt); -} - -static size_t vt100_input(QemuVT100 *vt, const uint8_t *buf, size_t len); - -static void vt100_keysym(QemuVT100 *vt, int keysym) -{ - uint8_t buf[16], *q; - int c; - - switch(keysym) { - case QEMU_KEY_CTRL_UP: - vt100_scroll(vt, -1); - break; - case QEMU_KEY_CTRL_DOWN: - vt100_scroll(vt, 1); - break; - case QEMU_KEY_CTRL_PAGEUP: - vt100_scroll(vt, -10); - break; - case QEMU_KEY_CTRL_PAGEDOWN: - vt100_scroll(vt, 10); - break; - default: - /* convert the QEMU keysym to VT100 key string */ - q =3D buf; - if (keysym >=3D 0xe100 && keysym <=3D 0xe11f) { - *q++ =3D '\033'; - *q++ =3D '['; - c =3D keysym - 0xe100; - if (c >=3D 10) - *q++ =3D '0' + (c / 10); - *q++ =3D '0' + (c % 10); - *q++ =3D '~'; - } else if (keysym >=3D 0xe120 && keysym <=3D 0xe17f) { - *q++ =3D '\033'; - *q++ =3D '['; - *q++ =3D keysym & 0xff; - } else if (vt->echo && (keysym =3D=3D '\r' || keysym =3D=3D '\n'))= { - vt100_input(vt, (uint8_t *)"\r", 1); - *q++ =3D '\n'; - } else { - *q++ =3D keysym; - } - if (vt->echo) { - vt100_input(vt, buf, q - buf); - } - vt100_write(vt, buf, q - buf); - break; - } - -} /* called when an ascii key is pressed */ void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym) { @@ -415,678 +103,10 @@ static void text_console_update(void *opaque, uint32= _t *chardata) } } =20 -static void vt100_set_image(QemuVT100 *vt, pixman_image_t *image) -{ - TextCell *cells, *c, *c1; - int w1, x, y, last_width, w, h; - - vt->image =3D image; - w =3D pixman_image_get_width(image) / FONT_WIDTH; - h =3D pixman_image_get_height(image) / FONT_HEIGHT; - if (w =3D=3D vt->width && h =3D=3D vt->height) { - return; - } - - last_width =3D vt->width; - vt->width =3D w; - vt->height =3D h; - - w1 =3D MIN(vt->width, last_width); - - cells =3D g_new(TextCell, vt->width * vt->total_height + 1); - for (y =3D 0; y < vt->total_height; y++) { - c =3D &cells[y * vt->width]; - if (w1 > 0) { - c1 =3D &vt->cells[y * last_width]; - for (x =3D 0; x < w1; x++) { - *c++ =3D *c1++; - } - } - for (x =3D w1; x < vt->width; x++) { - c->ch =3D ' '; - c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - c++; - } - } - g_free(vt->cells); - vt->cells =3D cells; -} - -static void vt100_put_lf(QemuVT100 *vt) -{ - TextCell *c; - int x, y1; - - vt->y++; - if (vt->y >=3D vt->height) { - vt->y =3D vt->height - 1; - - if (vt->y_displayed =3D=3D vt->y_base) { - if (++vt->y_displayed =3D=3D vt->total_height) - vt->y_displayed =3D 0; - } - if (++vt->y_base =3D=3D vt->total_height) - vt->y_base =3D 0; - if (vt->backscroll_height < vt->total_height) - vt->backscroll_height++; - y1 =3D (vt->y_base + vt->height - 1) % vt->total_height; - c =3D &vt->cells[y1 * vt->width]; - for(x =3D 0; x < vt->width; x++) { - c->ch =3D ' '; - c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - c++; - } - if (vt->y_displayed =3D=3D vt->y_base) { - vt->text_x[0] =3D 0; - vt->text_y[0] =3D 0; - vt->text_x[1] =3D vt->width - 1; - vt->text_y[1] =3D vt->height - 1; - - image_bitblt(vt->image, 0, FONT_HEIGHT, 0, 0, - vt->width * FONT_WIDTH, - (vt->height - 1) * FONT_HEIGHT); - image_fill_rect(vt->image, 0, (vt->height - 1) * FONT_HEIGHT, - vt->width * FONT_WIDTH, FONT_HEIGHT, - color_table_rgb[0][TEXT_ATTRIBUTES_DEFAULT.bgc= ol]); - vt->update_x0 =3D 0; - vt->update_y0 =3D 0; - vt->update_x1 =3D vt->width * FONT_WIDTH; - vt->update_y1 =3D vt->height * FONT_HEIGHT; - } - } -} - -/* Set console attributes depending on the current escape codes. - * NOTE: I know this code is not very efficient (checking every color for = it - * self) but it is more readable and better maintainable. - */ -static void vt100_handle_escape(QemuVT100 *vt) -{ - int i; - - for (i =3D 0; i < vt->nb_esc_params; i++) { - switch (vt->esc_params[i]) { - case 0: /* reset all console attributes to default */ - vt->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - break; - case 1: - vt->t_attrib.bold =3D 1; - break; - case 4: - vt->t_attrib.uline =3D 1; - break; - case 5: - vt->t_attrib.blink =3D 1; - break; - case 7: - vt->t_attrib.invers =3D 1; - break; - case 8: - vt->t_attrib.unvisible =3D 1; - break; - case 22: - vt->t_attrib.bold =3D 0; - break; - case 24: - vt->t_attrib.uline =3D 0; - break; - case 25: - vt->t_attrib.blink =3D 0; - break; - case 27: - vt->t_attrib.invers =3D 0; - break; - case 28: - vt->t_attrib.unvisible =3D 0; - break; - /* set foreground color */ - case 30: - vt->t_attrib.fgcol =3D QEMU_COLOR_BLACK; - break; - case 31: - vt->t_attrib.fgcol =3D QEMU_COLOR_RED; - break; - case 32: - vt->t_attrib.fgcol =3D QEMU_COLOR_GREEN; - break; - case 33: - vt->t_attrib.fgcol =3D QEMU_COLOR_YELLOW; - break; - case 34: - vt->t_attrib.fgcol =3D QEMU_COLOR_BLUE; - break; - case 35: - vt->t_attrib.fgcol =3D QEMU_COLOR_MAGENTA; - break; - case 36: - vt->t_attrib.fgcol =3D QEMU_COLOR_CYAN; - break; - case 37: - vt->t_attrib.fgcol =3D QEMU_COLOR_WHITE; - break; - /* set background color */ - case 40: - vt->t_attrib.bgcol =3D QEMU_COLOR_BLACK; - break; - case 41: - vt->t_attrib.bgcol =3D QEMU_COLOR_RED; - break; - case 42: - vt->t_attrib.bgcol =3D QEMU_COLOR_GREEN; - break; - case 43: - vt->t_attrib.bgcol =3D QEMU_COLOR_YELLOW; - break; - case 44: - vt->t_attrib.bgcol =3D QEMU_COLOR_BLUE; - break; - case 45: - vt->t_attrib.bgcol =3D QEMU_COLOR_MAGENTA; - break; - case 46: - vt->t_attrib.bgcol =3D QEMU_COLOR_CYAN; - break; - case 47: - vt->t_attrib.bgcol =3D QEMU_COLOR_WHITE; - break; - } - } -} - -static void vt100_update_xy(QemuVT100 *vt, int x, int y) -{ - TextCell *c; - int y1, y2; - - vt->text_x[0] =3D MIN(vt->text_x[0], x); - vt->text_x[1] =3D MAX(vt->text_x[1], x); - vt->text_y[0] =3D MIN(vt->text_y[0], y); - vt->text_y[1] =3D MAX(vt->text_y[1], y); - - y1 =3D (vt->y_base + y) % vt->total_height; - y2 =3D y1 - vt->y_displayed; - if (y2 < 0) { - y2 +=3D vt->total_height; - } - if (y2 < vt->height) { - if (x >=3D vt->width) { - x =3D vt->width - 1; - } - c =3D &vt->cells[y1 * vt->width + x]; - vt100_putcharxy(vt, x, y2, c->ch, - &(c->t_attrib)); - vt100_invalidate_xy(vt, x, y2); - } -} - -static void vt100_clear_xy(QemuVT100 *vt, int x, int y) -{ - int y1 =3D (vt->y_base + y) % vt->total_height; - if (x >=3D vt->width) { - x =3D vt->width - 1; - } - TextCell *c =3D &vt->cells[y1 * vt->width + x]; - c->ch =3D ' '; - c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - vt100_update_xy(vt, x, y); -} - -/* - * UTF-8 DFA decoder by Bjoern Hoehrmann. - * Copyright (c) 2008-2010 Bjoern Hoehrmann - * See https://github.com/polijan/utf8_decode for details. - * - * SPDX-License-Identifier: MIT - */ -#define BH_UTF8_ACCEPT 0 -#define BH_UTF8_REJECT 12 - -static uint32_t bh_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t = byte) -{ - static const uint8_t utf8d[] =3D { - /* character class lookup */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - - /* state transition lookup */ - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,= 12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24= ,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24= ,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36= ,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12, - }; - uint32_t type =3D utf8d[byte]; - - *codep =3D (*state !=3D BH_UTF8_ACCEPT) ? - (byte & 0x3fu) | (*codep << 6) : - (0xffu >> type) & (byte); - - *state =3D utf8d[256 + *state + type]; - return *state; -} - -static void vt100_put_one(QemuVT100 *vt, int ch) -{ - TextCell *c; - int y1; - if (vt->x >=3D vt->width) { - /* line wrap */ - vt->x =3D 0; - vt100_put_lf(vt); - } - y1 =3D (vt->y_base + vt->y) % vt->total_height; - c =3D &vt->cells[y1 * vt->width + vt->x]; - c->ch =3D ch; - c->t_attrib =3D vt->t_attrib; - vt100_update_xy(vt, vt->x, vt->y); - vt->x++; -} - -/* set cursor, checking bounds */ -static void vt100_set_cursor(QemuVT100 *vt, int x, int y) -{ - if (x < 0) { - x =3D 0; - } - if (y < 0) { - y =3D 0; - } - if (y >=3D vt->height) { - y =3D vt->height - 1; - } - if (x >=3D vt->width) { - x =3D vt->width - 1; - } - - vt->x =3D x; - vt->y =3D y; -} - -/** - * vc_csi_P() - (DCH) deletes one or more characters from the cursor - * position to the right. As characters are deleted, the remaining - * characters between the cursor and right margin move to the - * left. Character attributes move with the characters. - */ -static void vt100_csi_P(QemuVT100 *vt, unsigned int nr) -{ - TextCell *c1, *c2; - unsigned int x1, x2, y; - unsigned int end, len; - - if (!nr) { - nr =3D 1; - } - if (nr > vt->width - vt->x) { - nr =3D vt->width - vt->x; - if (!nr) { - return; - } - } - - x1 =3D vt->x; - x2 =3D vt->x + nr; - len =3D vt->width - x2; - if (len) { - y =3D (vt->y_base + vt->y) % vt->total_height; - c1 =3D &vt->cells[y * vt->width + x1]; - c2 =3D &vt->cells[y * vt->width + x2]; - memmove(c1, c2, len * sizeof(*c1)); - for (end =3D x1 + len; x1 < end; x1++) { - vt100_update_xy(vt, x1, vt->y); - } - } - /* Clear the rest */ - for (; x1 < vt->width; x1++) { - vt100_clear_xy(vt, x1, vt->y); - } -} - -/** - * vc_csi_at() - (ICH) inserts `nr` blank characters with the default - * character attribute. The cursor remains at the beginning of the - * blank characters. Text between the cursor and right margin moves to - * the right. Characters scrolled past the right margin are lost. - */ -static void vt100_csi_at(QemuVT100 *vt, unsigned int nr) -{ - TextCell *c1, *c2; - unsigned int x1, x2, y; - unsigned int end, len; - - if (!nr) { - nr =3D 1; - } - if (nr > vt->width - vt->x) { - nr =3D vt->width - vt->x; - if (!nr) { - return; - } - } - - x1 =3D vt->x + nr; - x2 =3D vt->x; - len =3D vt->width - x1; - if (len) { - y =3D (vt->y_base + vt->y) % vt->total_height; - c1 =3D &vt->cells[y * vt->width + x1]; - c2 =3D &vt->cells[y * vt->width + x2]; - memmove(c1, c2, len * sizeof(*c1)); - for (end =3D x1 + len; x1 < end; x1++) { - vt100_update_xy(vt, x1, vt->y); - } - } - /* Insert blanks */ - for (x1 =3D vt->x; x1 < vt->x + nr; x1++) { - vt100_clear_xy(vt, x1, vt->y); - } -} - -/** - * vt100_save_cursor() - saves cursor position and character attributes. - */ -static void vt100_save_cursor(QemuVT100 *vt) -{ - vt->x_saved =3D vt->x; - vt->y_saved =3D vt->y; - vt->t_attrib_saved =3D vt->t_attrib; -} - -/** - * vt100_restore_cursor() - restores cursor position and character - * attributes from saved state. - */ -static void vt100_restore_cursor(QemuVT100 *vt) -{ - vt->x =3D vt->x_saved; - vt->y =3D vt->y_saved; - vt->t_attrib =3D vt->t_attrib_saved; -} - -static void vt100_putchar(QemuVT100 *vt, int ch) -{ - int i; - int x, y; - g_autofree char *response =3D NULL; - - switch (vt->state) { - case TTY_STATE_NORM: - if (ch >=3D 0x80 && vt->encoding =3D=3D CHARDEV_VC_ENCODING_UTF8) { - switch (bh_utf8_decode(&vt->utf8_state, &vt->utf8_codepoint, c= h)) { - case BH_UTF8_ACCEPT: - vt100_put_one(vt, unicode_to_cp437(vt->utf8_codepoint)); - break; - case BH_UTF8_REJECT: - vt->utf8_state =3D BH_UTF8_ACCEPT; - break; - default: - /* Need more bytes */ - break; - } - break; - } - vt->utf8_state =3D BH_UTF8_ACCEPT; - switch(ch) { - case '\r': /* carriage return */ - vt->x =3D 0; - break; - case '\n': /* newline */ - vt100_put_lf(vt); - break; - case '\b': /* backspace */ - if (vt->x > 0) - vt->x--; - break; - case '\t': /* tabspace */ - if (vt->x + (8 - (vt->x % 8)) > vt->width) { - vt->x =3D 0; - vt100_put_lf(vt); - } else { - vt->x =3D vt->x + (8 - (vt->x % 8)); - } - break; - case '\a': /* alert aka. bell */ - /* TODO: has to be implemented */ - break; - case 14: - /* SO (shift out), character set 1 (ignored) */ - break; - case 15: - /* SI (shift in), character set 0 (ignored) */ - break; - case 27: /* esc (introducing an escape sequence) */ - vt->state =3D TTY_STATE_ESC; - break; - default: - vt100_put_one(vt, ch); - break; - } - break; - case TTY_STATE_ESC: /* check if it is a terminal escape sequence */ - if (ch =3D=3D '[') { - for(i=3D0;iesc_params[i] =3D 0; - vt->nb_esc_params =3D 0; - vt->state =3D TTY_STATE_CSI; - } else if (ch =3D=3D '(') { - vt->state =3D TTY_STATE_G0; - } else if (ch =3D=3D ')') { - vt->state =3D TTY_STATE_G1; - } else if (ch =3D=3D ']' || ch =3D=3D 'P' || ch =3D=3D 'X' - || ch =3D=3D '^' || ch =3D=3D '_') { - /* String sequences: OSC, DCS, SOS, PM, APC */ - vt->state =3D TTY_STATE_OSC; - } else if (ch =3D=3D '7') { - vt100_save_cursor(vt); - vt->state =3D TTY_STATE_NORM; - } else if (ch =3D=3D '8') { - vt100_restore_cursor(vt); - vt->state =3D TTY_STATE_NORM; - } else { - vt->state =3D TTY_STATE_NORM; - } - break; - case TTY_STATE_CSI: /* handle escape sequence parameters */ - if (ch >=3D '0' && ch <=3D '9') { - if (vt->nb_esc_params < MAX_ESC_PARAMS) { - int *param =3D &vt->esc_params[vt->nb_esc_params]; - int digit =3D (ch - '0'); - - *param =3D (*param <=3D (INT_MAX - digit) / 10) ? - *param * 10 + digit : INT_MAX; - } - } else { - if (vt->nb_esc_params < MAX_ESC_PARAMS) - vt->nb_esc_params++; - if (ch =3D=3D ';' || ch =3D=3D '?') { - break; - } - trace_console_putchar_csi(vt->esc_params[0], vt->esc_params[1], - ch, vt->nb_esc_params); - vt->state =3D TTY_STATE_NORM; - switch(ch) { - case 'A': - /* move cursor up */ - if (vt->esc_params[0] =3D=3D 0) { - vt->esc_params[0] =3D 1; - } - vt100_set_cursor(vt, vt->x, vt->y - vt->esc_params[0]); - break; - case 'B': - /* move cursor down */ - if (vt->esc_params[0] =3D=3D 0) { - vt->esc_params[0] =3D 1; - } - vt100_set_cursor(vt, vt->x, vt->y + vt->esc_params[0]); - break; - case 'C': - /* move cursor right */ - if (vt->esc_params[0] =3D=3D 0) { - vt->esc_params[0] =3D 1; - } - vt100_set_cursor(vt, vt->x + vt->esc_params[0], vt->y); - break; - case 'D': - /* move cursor left */ - if (vt->esc_params[0] =3D=3D 0) { - vt->esc_params[0] =3D 1; - } - vt100_set_cursor(vt, vt->x - vt->esc_params[0], vt->y); - break; - case 'G': - /* move cursor to column */ - vt100_set_cursor(vt, vt->esc_params[0] - 1, vt->y); - break; - case 'f': - case 'H': - /* move cursor to row, column */ - vt100_set_cursor(vt, vt->esc_params[1] - 1, vt->esc_params= [0] - 1); - break; - case 'J': - switch (vt->esc_params[0]) { - case 0: - /* clear to end of screen */ - for (y =3D vt->y; y < vt->height; y++) { - for (x =3D 0; x < vt->width; x++) { - if (y =3D=3D vt->y && x < vt->x) { - continue; - } - vt100_clear_xy(vt, x, y); - } - } - break; - case 1: - /* clear from beginning of screen */ - for (y =3D 0; y <=3D vt->y; y++) { - for (x =3D 0; x < vt->width; x++) { - if (y =3D=3D vt->y && x > vt->x) { - break; - } - vt100_clear_xy(vt, x, y); - } - } - break; - case 2: - /* clear entire screen */ - for (y =3D 0; y < vt->height; y++) { - for (x =3D 0; x < vt->width; x++) { - vt100_clear_xy(vt, x, y); - } - } - break; - } - break; - case 'K': - switch (vt->esc_params[0]) { - case 0: - /* clear to eol */ - for(x =3D vt->x; x < vt->width; x++) { - vt100_clear_xy(vt, x, vt->y); - } - break; - case 1: - /* clear from beginning of line */ - for (x =3D 0; x <=3D vt->x && x < vt->width; x++) { - vt100_clear_xy(vt, x, vt->y); - } - break; - case 2: - /* clear entire line */ - for(x =3D 0; x < vt->width; x++) { - vt100_clear_xy(vt, x, vt->y); - } - break; - } - break; - case 'P': - vt100_csi_P(vt, vt->esc_params[0]); - break; - case 'm': - vt100_handle_escape(vt); - break; - case 'n': - switch (vt->esc_params[0]) { - case 5: - /* report console status (always succeed)*/ - vt100_write(vt, "\033[0n", 4); - break; - case 6: - /* report cursor position */ - response =3D g_strdup_printf("\033[%d;%dR", - vt->y + 1, vt->x + 1); - vt100_write(vt, response, strlen(response)); - break; - } - break; - case 's': - vt100_save_cursor(vt); - break; - case 'u': - vt100_restore_cursor(vt); - break; - case '@': - vt100_csi_at(vt, vt->esc_params[0]); - break; - default: - trace_console_putchar_unhandled(ch); - break; - } - break; - } - break; - case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */ - if (ch =3D=3D '\a') { - /* BEL terminates OSC */ - vt->state =3D TTY_STATE_NORM; - } else if (ch =3D=3D 27) { - /* ESC might start ST (ESC \) */ - vt->state =3D TTY_STATE_ESC; - } - /* All other bytes are silently consumed */ - break; - case TTY_STATE_G0: /* set character sets */ - case TTY_STATE_G1: /* set character sets */ - switch (ch) { - case 'B': - /* Latin-1 map */ - break; - } - vt->state =3D TTY_STATE_NORM; - break; - } -} - #define TYPE_CHARDEV_VC "chardev-vc" DECLARE_INSTANCE_CHECKER(VCChardev, VC_CHARDEV, TYPE_CHARDEV_VC) =20 -static size_t vt100_input(QemuVT100 *vt, const uint8_t *buf, size_t len) -{ - int i; - - vt->update_x0 =3D vt->width * FONT_WIDTH; - vt->update_y0 =3D vt->height * FONT_HEIGHT; - vt->update_x1 =3D 0; - vt->update_y1 =3D 0; - vt100_show_cursor(vt, 0); - for(i =3D 0; i < len; i++) { - vt100_putchar(vt, buf[i]); - } - vt100_show_cursor(vt, 1); - if (vt->update_x0 < vt->update_x1) { - vt100_image_update(vt, vt->update_x0, vt->update_y0, - vt->update_x1 - vt->update_x0, - vt->update_y1 - vt->update_y0); - } - return len; -} - static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len) { VCChardev *drv =3D VC_CHARDEV(chr); @@ -1095,30 +115,6 @@ static int vc_chr_write(Chardev *chr, const uint8_t *= buf, int len) return vt100_input(&s->vt, buf, len); } =20 -void vt100_update_cursor(void) -{ - QemuVT100 *vt; - - cursor_visible_phase =3D !cursor_visible_phase; - - if (QTAILQ_EMPTY(&vt100s)) { - return; - } - - QTAILQ_FOREACH(vt, &vt100s, list) { - vt100_refresh(vt); - } - - timer_mod(cursor_timer, - qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2= ); -} - -static void -cursor_timer_cb(void *opaque) -{ - vt100_update_cursor(); -} - static void text_console_invalidate(void *opaque) { QemuTextConsole *s =3D QEMU_TEXT_CONSOLE(opaque); @@ -1129,13 +125,6 @@ static void text_console_invalidate(void *opaque) vt100_refresh(&s->vt); } =20 -static void vt100_fini(QemuVT100 *vt) -{ - QTAILQ_REMOVE(&vt100s, vt, list); - fifo8_destroy(&vt->out_fifo); - g_free(vt->cells); -} - static void qemu_text_console_finalize(Object *obj) { @@ -1214,27 +203,6 @@ static void text_console_out_flush(QemuVT100 *vt) qemu_text_console_out_flush(console); } =20 -static void vt100_init(QemuVT100 *vt, - pixman_image_t *image, - ChardevVCEncoding encoding, - void (*image_update)(QemuVT100 *vt, int x, int y, i= nt w, int h), - void (*out_flush)(QemuVT100 *vt)) -{ - if (!cursor_timer) { - cursor_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb= , NULL); - } - - vt->encoding =3D encoding; - QTAILQ_INSERT_HEAD(&vt100s, vt, list); - fifo8_create(&vt->out_fifo, 16); - vt->total_height =3D DEFAULT_BACKSCROLL; - vt->image_update =3D image_update; - vt->out_flush =3D out_flush; - /* set current text attributes to default */ - vt->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; - vt100_set_image(vt, image); -} - static bool vc_chr_open(Chardev *chr, ChardevBackend *backend, Error **err= p) { ChardevVC *vc =3D backend->u.vc.data; diff --git a/ui/console.c b/ui/console.c index 1c75b1a355b..b837ce1c9fc 100644 --- a/ui/console.c +++ b/ui/console.c @@ -39,6 +39,8 @@ #include "system/memory.h" #include "qom/object.h" #include "qemu/memfd.h" +#include "ui/vt100.h" +#include "vgafont.h" =20 #include "console-priv.h" =20 diff --git a/ui/vt100.c b/ui/vt100.c new file mode 100644 index 00000000000..e2fba822523 --- /dev/null +++ b/ui/vt100.c @@ -0,0 +1,984 @@ +/* + * SPDX-License-Identifier: MIT + * QEMU vt100 + */ +#include "qemu/osdep.h" +#include "qemu/timer.h" +#include "cp437.h" +#include "vgafont.h" +#include "vt100.h" + +#include "trace.h" + +#define DEFAULT_BACKSCROLL 512 +#define CONSOLE_CURSOR_PERIOD 500 + +static const pixman_color_t color_table_rgb[2][8] =3D { + { /* dark */ + [QEMU_COLOR_BLACK] =3D QEMU_PIXMAN_COLOR_BLACK, + [QEMU_COLOR_BLUE] =3D QEMU_PIXMAN_COLOR(0x00, 0x00, 0xaa), /* = blue */ + [QEMU_COLOR_GREEN] =3D QEMU_PIXMAN_COLOR(0x00, 0xaa, 0x00), /* = green */ + [QEMU_COLOR_CYAN] =3D QEMU_PIXMAN_COLOR(0x00, 0xaa, 0xaa), /* = cyan */ + [QEMU_COLOR_RED] =3D QEMU_PIXMAN_COLOR(0xaa, 0x00, 0x00), /* = red */ + [QEMU_COLOR_MAGENTA] =3D QEMU_PIXMAN_COLOR(0xaa, 0x00, 0xaa), /* = magenta */ + [QEMU_COLOR_YELLOW] =3D QEMU_PIXMAN_COLOR(0xaa, 0xaa, 0x00), /* = yellow */ + [QEMU_COLOR_WHITE] =3D QEMU_PIXMAN_COLOR_GRAY, + }, + { /* bright */ + [QEMU_COLOR_BLACK] =3D QEMU_PIXMAN_COLOR_BLACK, + [QEMU_COLOR_BLUE] =3D QEMU_PIXMAN_COLOR(0x00, 0x00, 0xff), /* = blue */ + [QEMU_COLOR_GREEN] =3D QEMU_PIXMAN_COLOR(0x00, 0xff, 0x00), /* = green */ + [QEMU_COLOR_CYAN] =3D QEMU_PIXMAN_COLOR(0x00, 0xff, 0xff), /* = cyan */ + [QEMU_COLOR_RED] =3D QEMU_PIXMAN_COLOR(0xff, 0x00, 0x00), /* = red */ + [QEMU_COLOR_MAGENTA] =3D QEMU_PIXMAN_COLOR(0xff, 0x00, 0xff), /* = magenta */ + [QEMU_COLOR_YELLOW] =3D QEMU_PIXMAN_COLOR(0xff, 0xff, 0x00), /* = yellow */ + [QEMU_COLOR_WHITE] =3D QEMU_PIXMAN_COLOR(0xff, 0xff, 0xff), /* = white */ + } +}; + +static bool cursor_visible_phase; +static QEMUTimer *cursor_timer; +static QTAILQ_HEAD(QemuVT100Head, QemuVT100) vt100s =3D + QTAILQ_HEAD_INITIALIZER(vt100s); + +static void image_fill_rect(pixman_image_t *image, int posx, int posy, + int width, int height, pixman_color_t color) +{ + pixman_rectangle16_t rect =3D { + .x =3D posx, .y =3D posy, .width =3D width, .height =3D height + }; + + pixman_image_fill_rectangles(PIXMAN_OP_SRC, image, + &color, 1, &rect); +} + +/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */ +static void image_bitblt(pixman_image_t *image, + int xs, int ys, int xd, int yd, int w, int h) +{ + pixman_image_composite(PIXMAN_OP_SRC, + image, NULL, image, + xs, ys, 0, 0, xd, yd, w, h); +} + +static void vt100_putcharxy(QemuVT100 *vt, int x, int y, int ch, + TextAttributes *t_attrib) +{ + static pixman_image_t *glyphs[256]; + pixman_color_t fgcol, bgcol; + + assert(vt->image); + if (t_attrib->invers) { + bgcol =3D color_table_rgb[t_attrib->bold][t_attrib->fgcol]; + fgcol =3D color_table_rgb[t_attrib->bold][t_attrib->bgcol]; + } else { + fgcol =3D color_table_rgb[t_attrib->bold][t_attrib->fgcol]; + bgcol =3D color_table_rgb[t_attrib->bold][t_attrib->bgcol]; + } + + if (!glyphs[ch]) { + glyphs[ch] =3D qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont= 16, ch); + } + qemu_pixman_glyph_render(glyphs[ch], vt->image, + &fgcol, &bgcol, x, y, FONT_WIDTH, FONT_HEIGHT= ); +} + +static void vt100_invalidate_xy(QemuVT100 *vt, int x, int y) +{ + if (vt->update_x0 > x * FONT_WIDTH) { + vt->update_x0 =3D x * FONT_WIDTH; + } + if (vt->update_y0 > y * FONT_HEIGHT) { + vt->update_y0 =3D y * FONT_HEIGHT; + } + if (vt->update_x1 < (x + 1) * FONT_WIDTH) { + vt->update_x1 =3D (x + 1) * FONT_WIDTH; + } + if (vt->update_y1 < (y + 1) * FONT_HEIGHT) { + vt->update_y1 =3D (y + 1) * FONT_HEIGHT; + } +} + +static void vt100_show_cursor(QemuVT100 *vt, int show) +{ + TextCell *c; + int y, y1; + int x =3D vt->x; + + vt->cursor_invalidate =3D 1; + + if (x >=3D vt->width) { + x =3D vt->width - 1; + } + y1 =3D (vt->y_base + vt->y) % vt->total_height; + y =3D y1 - vt->y_displayed; + if (y < 0) { + y +=3D vt->total_height; + } + if (y < vt->height) { + c =3D &vt->cells[y1 * vt->width + x]; + if (show && cursor_visible_phase) { + TextAttributes t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + t_attrib.invers =3D !(t_attrib.invers); /* invert fg and bg */ + vt100_putcharxy(vt, x, y, c->ch, &t_attrib); + } else { + vt100_putcharxy(vt, x, y, c->ch, &(c->t_attrib)); + } + vt100_invalidate_xy(vt, x, y); + } +} + +static void vt100_image_update(QemuVT100 *vt, int x, int y, int width, int= height) +{ + vt->image_update(vt, x, y, width, height); +} + +void vt100_refresh(QemuVT100 *vt) +{ + TextCell *c; + int x, y, y1; + int w =3D pixman_image_get_width(vt->image); + int h =3D pixman_image_get_height(vt->image); + + vt->text_x[0] =3D 0; + vt->text_y[0] =3D 0; + vt->text_x[1] =3D vt->width - 1; + vt->text_y[1] =3D vt->height - 1; + vt->cursor_invalidate =3D 1; + + image_fill_rect(vt->image, 0, 0, w, h, + color_table_rgb[0][QEMU_COLOR_BLACK]); + y1 =3D vt->y_displayed; + for (y =3D 0; y < vt->height; y++) { + c =3D vt->cells + y1 * vt->width; + for (x =3D 0; x < vt->width; x++) { + vt100_putcharxy(vt, x, y, c->ch, + &(c->t_attrib)); + c++; + } + if (++y1 =3D=3D vt->total_height) { + y1 =3D 0; + } + } + vt100_show_cursor(vt, 1); + vt100_image_update(vt, 0, 0, w, h); +} + +static void vt100_scroll(QemuVT100 *vt, int ydelta) +{ + int i, y1; + + if (ydelta > 0) { + for (i =3D 0; i < ydelta; i++) { + if (vt->y_displayed =3D=3D vt->y_base) { + break; + } + if (++vt->y_displayed =3D=3D vt->total_height) { + vt->y_displayed =3D 0; + } + } + } else { + ydelta =3D -ydelta; + i =3D vt->backscroll_height; + if (i > vt->total_height - vt->height) { + i =3D vt->total_height - vt->height; + } + y1 =3D vt->y_base - i; + if (y1 < 0) { + y1 +=3D vt->total_height; + } + for (i =3D 0; i < ydelta; i++) { + if (vt->y_displayed =3D=3D y1) { + break; + } + if (--vt->y_displayed < 0) { + vt->y_displayed =3D vt->total_height - 1; + } + } + } + vt100_refresh(vt); +} + +static void vt100_write(QemuVT100 *vt, const void *buf, size_t len) +{ + uint32_t num_free; + + num_free =3D fifo8_num_free(&vt->out_fifo); + fifo8_push_all(&vt->out_fifo, buf, MIN(num_free, len)); + vt->out_flush(vt); +} + +void vt100_set_image(QemuVT100 *vt, pixman_image_t *image) +{ + TextCell *cells, *c, *c1; + int w1, x, y, last_width, w, h; + + vt->image =3D image; + w =3D pixman_image_get_width(vt->image) / FONT_WIDTH; + h =3D pixman_image_get_height(vt->image) / FONT_HEIGHT; + if (w =3D=3D vt->width && h =3D=3D vt->height) { + return; + } + + last_width =3D vt->width; + vt->width =3D w; + vt->height =3D h; + + w1 =3D MIN(vt->width, last_width); + + cells =3D g_new(TextCell, vt->width * vt->total_height + 1); + for (y =3D 0; y < vt->total_height; y++) { + c =3D &cells[y * vt->width]; + if (w1 > 0) { + c1 =3D &vt->cells[y * last_width]; + for (x =3D 0; x < w1; x++) { + *c++ =3D *c1++; + } + } + for (x =3D w1; x < vt->width; x++) { + c->ch =3D ' '; + c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + c++; + } + } + g_free(vt->cells); + vt->cells =3D cells; +} + +static void vt100_put_lf(QemuVT100 *vt) +{ + TextCell *c; + int x, y1; + + vt->y++; + if (vt->y >=3D vt->height) { + vt->y =3D vt->height - 1; + + if (vt->y_displayed =3D=3D vt->y_base) { + if (++vt->y_displayed =3D=3D vt->total_height) { + vt->y_displayed =3D 0; + } + } + if (++vt->y_base =3D=3D vt->total_height) { + vt->y_base =3D 0; + } + if (vt->backscroll_height < vt->total_height) { + vt->backscroll_height++; + } + y1 =3D (vt->y_base + vt->height - 1) % vt->total_height; + c =3D &vt->cells[y1 * vt->width]; + for (x =3D 0; x < vt->width; x++) { + c->ch =3D ' '; + c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + c++; + } + if (vt->y_displayed =3D=3D vt->y_base) { + vt->text_x[0] =3D 0; + vt->text_y[0] =3D 0; + vt->text_x[1] =3D vt->width - 1; + vt->text_y[1] =3D vt->height - 1; + + image_bitblt(vt->image, 0, FONT_HEIGHT, 0, 0, + vt->width * FONT_WIDTH, + (vt->height - 1) * FONT_HEIGHT); + image_fill_rect(vt->image, 0, (vt->height - 1) * FONT_HEIGHT, + vt->width * FONT_WIDTH, FONT_HEIGHT, + color_table_rgb[0][TEXT_ATTRIBUTES_DEFAULT.bgc= ol]); + vt->update_x0 =3D 0; + vt->update_y0 =3D 0; + vt->update_x1 =3D vt->width * FONT_WIDTH; + vt->update_y1 =3D vt->height * FONT_HEIGHT; + } + } +} + +/* + * Set console attributes depending on the current escape codes. + * NOTE: I know this code is not very efficient (checking every color for = it + * self) but it is more readable and better maintainable. + */ +static void vt100_handle_escape(QemuVT100 *vt) +{ + int i; + + for (i =3D 0; i < vt->nb_esc_params; i++) { + switch (vt->esc_params[i]) { + case 0: /* reset all console attributes to default */ + vt->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + break; + case 1: + vt->t_attrib.bold =3D 1; + break; + case 4: + vt->t_attrib.uline =3D 1; + break; + case 5: + vt->t_attrib.blink =3D 1; + break; + case 7: + vt->t_attrib.invers =3D 1; + break; + case 8: + vt->t_attrib.unvisible =3D 1; + break; + case 22: + vt->t_attrib.bold =3D 0; + break; + case 24: + vt->t_attrib.uline =3D 0; + break; + case 25: + vt->t_attrib.blink =3D 0; + break; + case 27: + vt->t_attrib.invers =3D 0; + break; + case 28: + vt->t_attrib.unvisible =3D 0; + break; + /* set foreground color */ + case 30: + vt->t_attrib.fgcol =3D QEMU_COLOR_BLACK; + break; + case 31: + vt->t_attrib.fgcol =3D QEMU_COLOR_RED; + break; + case 32: + vt->t_attrib.fgcol =3D QEMU_COLOR_GREEN; + break; + case 33: + vt->t_attrib.fgcol =3D QEMU_COLOR_YELLOW; + break; + case 34: + vt->t_attrib.fgcol =3D QEMU_COLOR_BLUE; + break; + case 35: + vt->t_attrib.fgcol =3D QEMU_COLOR_MAGENTA; + break; + case 36: + vt->t_attrib.fgcol =3D QEMU_COLOR_CYAN; + break; + case 37: + vt->t_attrib.fgcol =3D QEMU_COLOR_WHITE; + break; + /* set background color */ + case 40: + vt->t_attrib.bgcol =3D QEMU_COLOR_BLACK; + break; + case 41: + vt->t_attrib.bgcol =3D QEMU_COLOR_RED; + break; + case 42: + vt->t_attrib.bgcol =3D QEMU_COLOR_GREEN; + break; + case 43: + vt->t_attrib.bgcol =3D QEMU_COLOR_YELLOW; + break; + case 44: + vt->t_attrib.bgcol =3D QEMU_COLOR_BLUE; + break; + case 45: + vt->t_attrib.bgcol =3D QEMU_COLOR_MAGENTA; + break; + case 46: + vt->t_attrib.bgcol =3D QEMU_COLOR_CYAN; + break; + case 47: + vt->t_attrib.bgcol =3D QEMU_COLOR_WHITE; + break; + } + } +} + +static void vt100_update_xy(QemuVT100 *vt, int x, int y) +{ + TextCell *c; + int y1, y2; + + vt->text_x[0] =3D MIN(vt->text_x[0], x); + vt->text_x[1] =3D MAX(vt->text_x[1], x); + vt->text_y[0] =3D MIN(vt->text_y[0], y); + vt->text_y[1] =3D MAX(vt->text_y[1], y); + + y1 =3D (vt->y_base + y) % vt->total_height; + y2 =3D y1 - vt->y_displayed; + if (y2 < 0) { + y2 +=3D vt->total_height; + } + if (y2 < vt->height) { + if (x >=3D vt->width) { + x =3D vt->width - 1; + } + c =3D &vt->cells[y1 * vt->width + x]; + vt100_putcharxy(vt, x, y2, c->ch, + &(c->t_attrib)); + vt100_invalidate_xy(vt, x, y2); + } +} + +static void vt100_clear_xy(QemuVT100 *vt, int x, int y) +{ + int y1 =3D (vt->y_base + y) % vt->total_height; + if (x >=3D vt->width) { + x =3D vt->width - 1; + } + TextCell *c =3D &vt->cells[y1 * vt->width + x]; + c->ch =3D ' '; + c->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + vt100_update_xy(vt, x, y); +} + +/* + * UTF-8 DFA decoder by Bjoern Hoehrmann. + * Copyright (c) 2008-2010 Bjoern Hoehrmann + * See https://github.com/polijan/utf8_decode for details. + * + * SPDX-License-Identifier: MIT + */ +#define BH_UTF8_ACCEPT 0 +#define BH_UTF8_REJECT 12 + +static uint32_t bh_utf8_decode(uint32_t *state, uint32_t *codep, uint32_t = byte) +{ + static const uint8_t utf8d[] =3D { + /* character class lookup */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + /* state transition lookup */ + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,= 12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24= ,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24= ,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36= ,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, + }; + uint32_t type =3D utf8d[byte]; + + *codep =3D (*state !=3D BH_UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xffu >> type) & (byte); + + *state =3D utf8d[256 + *state + type]; + return *state; +} + +static void vt100_put_one(QemuVT100 *vt, int ch) +{ + TextCell *c; + int y1; + if (vt->x >=3D vt->width) { + /* line wrap */ + vt->x =3D 0; + vt100_put_lf(vt); + } + y1 =3D (vt->y_base + vt->y) % vt->total_height; + c =3D &vt->cells[y1 * vt->width + vt->x]; + c->ch =3D ch; + c->t_attrib =3D vt->t_attrib; + vt100_update_xy(vt, vt->x, vt->y); + vt->x++; +} + +/* set cursor, checking bounds */ +static void vt100_set_cursor(QemuVT100 *vt, int x, int y) +{ + if (x < 0) { + x =3D 0; + } + if (y < 0) { + y =3D 0; + } + if (y >=3D vt->height) { + y =3D vt->height - 1; + } + if (x >=3D vt->width) { + x =3D vt->width - 1; + } + + vt->x =3D x; + vt->y =3D y; +} + +/** + * vt100_csi_P() - (DCH) deletes one or more characters from the cursor + * position to the right. As characters are deleted, the remaining + * characters between the cursor and right margin move to the + * left. Character attributes move with the characters. + */ +static void vt100_csi_P(QemuVT100 *vt, unsigned int nr) +{ + TextCell *c1, *c2; + unsigned int x1, x2, y; + unsigned int end, len; + + if (!nr) { + nr =3D 1; + } + if (nr > vt->width - vt->x) { + nr =3D vt->width - vt->x; + if (!nr) { + return; + } + } + + x1 =3D vt->x; + x2 =3D vt->x + nr; + len =3D vt->width - x2; + if (len) { + y =3D (vt->y_base + vt->y) % vt->total_height; + c1 =3D &vt->cells[y * vt->width + x1]; + c2 =3D &vt->cells[y * vt->width + x2]; + memmove(c1, c2, len * sizeof(*c1)); + for (end =3D x1 + len; x1 < end; x1++) { + vt100_update_xy(vt, x1, vt->y); + } + } + /* Clear the rest */ + for (; x1 < vt->width; x1++) { + vt100_clear_xy(vt, x1, vt->y); + } +} + +/** + * vt100_csi_at() - (ICH) inserts `nr` blank characters with the default + * character attribute. The cursor remains at the beginning of the + * blank characters. Text between the cursor and right margin moves to + * the right. Characters scrolled past the right margin are lost. + */ +static void vt100_csi_at(QemuVT100 *vt, unsigned int nr) +{ + TextCell *c1, *c2; + unsigned int x1, x2, y; + unsigned int end, len; + + if (!nr) { + nr =3D 1; + } + if (nr > vt->width - vt->x) { + nr =3D vt->width - vt->x; + if (!nr) { + return; + } + } + + x1 =3D vt->x + nr; + x2 =3D vt->x; + len =3D vt->width - x1; + if (len) { + y =3D (vt->y_base + vt->y) % vt->total_height; + c1 =3D &vt->cells[y * vt->width + x1]; + c2 =3D &vt->cells[y * vt->width + x2]; + memmove(c1, c2, len * sizeof(*c1)); + for (end =3D x1 + len; x1 < end; x1++) { + vt100_update_xy(vt, x1, vt->y); + } + } + /* Insert blanks */ + for (x1 =3D vt->x; x1 < vt->x + nr; x1++) { + vt100_clear_xy(vt, x1, vt->y); + } +} + +/** + * vt100_save_cursor() - saves cursor position and character attributes. + */ +static void vt100_save_cursor(QemuVT100 *vt) +{ + vt->x_saved =3D vt->x; + vt->y_saved =3D vt->y; + vt->t_attrib_saved =3D vt->t_attrib; +} + +/** + * vt100_restore_cursor() - restores cursor position and character + * attributes from saved state. + */ +static void vt100_restore_cursor(QemuVT100 *vt) +{ + vt->x =3D vt->x_saved; + vt->y =3D vt->y_saved; + vt->t_attrib =3D vt->t_attrib_saved; +} + +static void vt100_putchar(QemuVT100 *vt, int ch) +{ + int i; + int x, y; + g_autofree char *response =3D NULL; + + switch (vt->state) { + case TTY_STATE_NORM: + if (ch >=3D 0x80 && vt->encoding =3D=3D CHARDEV_VC_ENCODING_UTF8) { + switch (bh_utf8_decode(&vt->utf8_state, &vt->utf8_codepoint, c= h)) { + case BH_UTF8_ACCEPT: + vt100_put_one(vt, unicode_to_cp437(vt->utf8_codepoint)); + break; + case BH_UTF8_REJECT: + vt->utf8_state =3D BH_UTF8_ACCEPT; + break; + default: + break; + } + break; + } + vt->utf8_state =3D BH_UTF8_ACCEPT; + switch (ch) { + case '\r': /* carriage return */ + vt->x =3D 0; + break; + case '\n': /* newline */ + vt100_put_lf(vt); + break; + case '\b': /* backspace */ + if (vt->x > 0) { + vt->x--; + } + break; + case '\t': /* tabspace */ + if (vt->x + (8 - (vt->x % 8)) > vt->width) { + vt->x =3D 0; + vt100_put_lf(vt); + } else { + vt->x =3D vt->x + (8 - (vt->x % 8)); + } + break; + case '\a': /* alert aka. bell */ + /* TODO: has to be implemented */ + break; + case 14: + /* SO (shift out), character set 1 (ignored) */ + break; + case 15: + /* SI (shift in), character set 0 (ignored) */ + break; + case 27: /* esc (introducing an escape sequence) */ + vt->state =3D TTY_STATE_ESC; + break; + default: + vt100_put_one(vt, ch); + break; + } + break; + case TTY_STATE_ESC: /* check if it is a terminal escape sequence */ + if (ch =3D=3D '[') { + for (i =3D 0; i < MAX_ESC_PARAMS; i++) { + vt->esc_params[i] =3D 0; + } + vt->nb_esc_params =3D 0; + vt->state =3D TTY_STATE_CSI; + } else if (ch =3D=3D '(') { + vt->state =3D TTY_STATE_G0; + } else if (ch =3D=3D ')') { + vt->state =3D TTY_STATE_G1; + } else if (ch =3D=3D ']' || ch =3D=3D 'P' || ch =3D=3D 'X' + || ch =3D=3D '^' || ch =3D=3D '_') { + /* String sequences: OSC, DCS, SOS, PM, APC */ + vt->state =3D TTY_STATE_OSC; + } else if (ch =3D=3D '7') { + vt100_save_cursor(vt); + vt->state =3D TTY_STATE_NORM; + } else if (ch =3D=3D '8') { + vt100_restore_cursor(vt); + vt->state =3D TTY_STATE_NORM; + } else { + vt->state =3D TTY_STATE_NORM; + } + break; + case TTY_STATE_CSI: /* handle escape sequence parameters */ + if (ch >=3D '0' && ch <=3D '9') { + if (vt->nb_esc_params < MAX_ESC_PARAMS) { + int *param =3D &vt->esc_params[vt->nb_esc_params]; + int digit =3D (ch - '0'); + + *param =3D (*param <=3D (INT_MAX - digit) / 10) ? + *param * 10 + digit : INT_MAX; + } + } else { + if (vt->nb_esc_params < MAX_ESC_PARAMS) { + vt->nb_esc_params++; + } + if (ch =3D=3D ';' || ch =3D=3D '?') { + break; + } + trace_console_putchar_csi(vt->esc_params[0], vt->esc_params[1], + ch, vt->nb_esc_params); + vt->state =3D TTY_STATE_NORM; + switch (ch) { + case 'A': + /* move cursor up */ + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; + } + vt100_set_cursor(vt, vt->x, vt->y - vt->esc_params[0]); + break; + case 'B': + /* move cursor down */ + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; + } + vt100_set_cursor(vt, vt->x, vt->y + vt->esc_params[0]); + break; + case 'C': + /* move cursor right */ + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; + } + vt100_set_cursor(vt, vt->x + vt->esc_params[0], vt->y); + break; + case 'D': + /* move cursor left */ + if (vt->esc_params[0] =3D=3D 0) { + vt->esc_params[0] =3D 1; + } + vt100_set_cursor(vt, vt->x - vt->esc_params[0], vt->y); + break; + case 'G': + /* move cursor to column */ + vt100_set_cursor(vt, vt->esc_params[0] - 1, vt->y); + break; + case 'f': + case 'H': + /* move cursor to row, column */ + vt100_set_cursor(vt, vt->esc_params[1] - 1, vt->esc_params= [0] - 1); + break; + case 'J': + switch (vt->esc_params[0]) { + case 0: + /* clear to end of screen */ + for (y =3D vt->y; y < vt->height; y++) { + for (x =3D 0; x < vt->width; x++) { + if (y =3D=3D vt->y && x < vt->x) { + continue; + } + vt100_clear_xy(vt, x, y); + } + } + break; + case 1: + /* clear from beginning of screen */ + for (y =3D 0; y <=3D vt->y; y++) { + for (x =3D 0; x < vt->width; x++) { + if (y =3D=3D vt->y && x > vt->x) { + break; + } + vt100_clear_xy(vt, x, y); + } + } + break; + case 2: + /* clear entire screen */ + for (y =3D 0; y < vt->height; y++) { + for (x =3D 0; x < vt->width; x++) { + vt100_clear_xy(vt, x, y); + } + } + break; + } + break; + case 'K': + switch (vt->esc_params[0]) { + case 0: + /* clear to eol */ + for (x =3D vt->x; x < vt->width; x++) { + vt100_clear_xy(vt, x, vt->y); + } + break; + case 1: + /* clear from beginning of line */ + for (x =3D 0; x <=3D vt->x && x < vt->width; x++) { + vt100_clear_xy(vt, x, vt->y); + } + break; + case 2: + /* clear entire line */ + for (x =3D 0; x < vt->width; x++) { + vt100_clear_xy(vt, x, vt->y); + } + break; + } + break; + case 'P': + vt100_csi_P(vt, vt->esc_params[0]); + break; + case 'm': + vt100_handle_escape(vt); + break; + case 'n': + switch (vt->esc_params[0]) { + case 5: + /* report console status (always succeed)*/ + vt100_write(vt, "\033[0n", 4); + break; + case 6: + /* report cursor position */ + response =3D g_strdup_printf("\033[%d;%dR", + vt->y + 1, vt->x + 1); + vt100_write(vt, response, strlen(response)); + break; + } + break; + case 's': + vt100_save_cursor(vt); + break; + case 'u': + vt100_restore_cursor(vt); + break; + case '@': + vt100_csi_at(vt, vt->esc_params[0]); + break; + default: + trace_console_putchar_unhandled(ch); + break; + } + break; + } + break; + case TTY_STATE_OSC: /* Operating System Command: ESC ] ... BEL/ST */ + if (ch =3D=3D '\a') { + /* BEL terminates OSC */ + vt->state =3D TTY_STATE_NORM; + } else if (ch =3D=3D 27) { + /* ESC might start ST (ESC \) */ + vt->state =3D TTY_STATE_ESC; + } + /* All other bytes are silently consumed */ + break; + case TTY_STATE_G0: /* set character sets */ + case TTY_STATE_G1: /* set character sets */ + switch (ch) { + case 'B': + /* Latin-1 map */ + break; + } + vt->state =3D TTY_STATE_NORM; + break; + } + +} + +size_t vt100_input(QemuVT100 *vt, const uint8_t *buf, size_t len) +{ + int i; + + vt->update_x0 =3D vt->width * FONT_WIDTH; + vt->update_y0 =3D vt->height * FONT_HEIGHT; + vt->update_x1 =3D 0; + vt->update_y1 =3D 0; + vt100_show_cursor(vt, 0); + for (i =3D 0; i < len; i++) { + vt100_putchar(vt, buf[i]); + } + vt100_show_cursor(vt, 1); + if (vt->update_x0 < vt->update_x1) { + vt100_image_update(vt, vt->update_x0, vt->update_y0, + vt->update_x1 - vt->update_x0, + vt->update_y1 - vt->update_y0); + } + return len; +} + +void vt100_keysym(QemuVT100 *vt, int keysym) +{ + uint8_t buf[16], *q; + int c; + + switch (keysym) { + case QEMU_KEY_CTRL_UP: + vt100_scroll(vt, -1); + break; + case QEMU_KEY_CTRL_DOWN: + vt100_scroll(vt, 1); + break; + case QEMU_KEY_CTRL_PAGEUP: + vt100_scroll(vt, -10); + break; + case QEMU_KEY_CTRL_PAGEDOWN: + vt100_scroll(vt, 10); + break; + default: + /* convert the QEMU keysym to VT100 key string */ + q =3D buf; + if (keysym >=3D 0xe100 && keysym <=3D 0xe11f) { + *q++ =3D '\033'; + *q++ =3D '['; + c =3D keysym - 0xe100; + if (c >=3D 10) { + *q++ =3D '0' + (c / 10); + } + *q++ =3D '0' + (c % 10); + *q++ =3D '~'; + } else if (keysym >=3D 0xe120 && keysym <=3D 0xe17f) { + *q++ =3D '\033'; + *q++ =3D '['; + *q++ =3D keysym & 0xff; + } else if (vt->echo && (keysym =3D=3D '\r' || keysym =3D=3D '\n'))= { + vt100_input(vt, (uint8_t *)"\r", 1); + *q++ =3D '\n'; + } else { + *q++ =3D keysym; + } + if (vt->echo) { + vt100_input(vt, buf, q - buf); + } + vt100_write(vt, buf, q - buf); + break; + } +} + +void vt100_update_cursor(void) +{ + QemuVT100 *vt; + + cursor_visible_phase =3D !cursor_visible_phase; + + if (QTAILQ_EMPTY(&vt100s)) { + return; + } + + QTAILQ_FOREACH(vt, &vt100s, list) { + vt100_refresh(vt); + } + + timer_mod(cursor_timer, + qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2= ); +} + +static void +cursor_timer_cb(void *opaque) +{ + vt100_update_cursor(); +} + +void vt100_init(QemuVT100 *vt, + pixman_image_t *image, + ChardevVCEncoding encoding, + void (*image_update)(QemuVT100 *vt, int x, int y, int w, i= nt h), + void (*out_flush)(QemuVT100 *vt)) +{ + if (!cursor_timer) { + cursor_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb= , NULL); + } + + vt->encoding =3D encoding; + QTAILQ_INSERT_HEAD(&vt100s, vt, list); + fifo8_create(&vt->out_fifo, 16); + vt->total_height =3D DEFAULT_BACKSCROLL; + vt->image_update =3D image_update; + vt->out_flush =3D out_flush; + /* set current text attributes to default */ + vt->t_attrib =3D TEXT_ATTRIBUTES_DEFAULT; + vt100_set_image(vt, image); +} + +void vt100_fini(QemuVT100 *vt) +{ + QTAILQ_REMOVE(&vt100s, vt, list); + fifo8_destroy(&vt->out_fifo); + g_free(vt->cells); +} diff --git a/ui/meson.build b/ui/meson.build index d69eebfdaf1..7b6e867d3af 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -3,6 +3,7 @@ system_ss.add(png) system_ss.add(files( 'clipboard.c', 'console.c', + 'cp437.c', 'cursor.c', 'display-surface.c', 'dmabuf.c', @@ -17,8 +18,9 @@ system_ss.add(files( 'ui-qmp-cmds.c', 'util.c', 'vgafont.c', + 'vt100.c', )) -system_ss.add(when: pixman, if_true: files('console-vc.c', 'cp437.c'), if_= false: files('console-vc-stubs.c')) +system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: file= s('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c')) endif --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496776; cv=none; d=zohomail.com; s=zohoarc; b=PS4+AohhbSYhLD7H0kHQej9gl2dgmisOpjIQCohItFbZKqhNQSJCshe51hdyGuo1xfkzVMjwDMoaYKMKo7BEy2tUN/6MyDJIvY10J9pznZ0hSOc0CT7U1yMro1eRBwLCiQOtqX1o1r8ntQFBAtVSxjn0ypOlmMIdYmvSzbVsVaI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496776; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=LQG0qN6rFQpchqEjkKkpkK6wYq5eQ1JvZPMXVcU8sd0=; b=k8K9ftIPbu4fW5JCKCFKTC3g5zFVsq75Tc7EgCWARW6YxXMhi7JQixD1Ir/2vZmukC5KVNdhcZK2j1KuyZYw4wGu6KOkj8mzlTIFidCjBeXFwoBjIsH1m5+ZznfBFJktC7HQnxVctRlOWWgxntqnPT4uyMpkD/wyCCS36eCawdQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496776261919.3364372793748; Wed, 29 Apr 2026 14:06:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6S-00070N-IG; Wed, 29 Apr 2026 17:05:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5K-0006Il-4j for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5H-0003TX-U2 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:41 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-183-blbw-yUNOneR9_FZY0jX-w-1; Wed, 29 Apr 2026 17:04:37 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8C9921956095 for ; Wed, 29 Apr 2026 21:04:36 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 41438300019F; Wed, 29 Apr 2026 21:04:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496679; 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=LQG0qN6rFQpchqEjkKkpkK6wYq5eQ1JvZPMXVcU8sd0=; b=JlTKN5FnD31WpRQ7kxWu9h7d6WDLZSKkqdKA7cPa3rTzPh1/WHntycHSxkYDr7hR1xcTxx wkOWOBoO88Hxbih/nMaJpmdKNtBpIfJlunrQLiK9yigr6rcNHfKGkeX5ImotgewiW8Ys9J vZqD8WKKE2OWPziPt9lgGbIHLxrL+iU= X-MC-Unique: blbw-yUNOneR9_FZY0jX-w-1 X-Mimecast-MFC-AGG-ID: blbw-yUNOneR9_FZY0jX-w_1777496676 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:47 +0400 Subject: [PATCH v3 14/26] ui/vnc: make the worker thread per-VncDisplay MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-14-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=6513; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=XCDp9S7HaL4bLvRrQfhchRC/cgPquwTPMALLwTkY/1Y=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMP0Sg7vWQoEo0cWOvJtxIFY1cyJY8gVql1 BItB7/gZb2JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5WkrD/4pyTQhgKTK/q5u2m/HYnH7/mbTqz5Dih3S4FfLbOKhRuwK7yrVPULAJpYjX8gSYoml+72 G9FsQN8hX9Ctw/brPbTmVZsfxOOSyL5xMxzyEMvmNwOo0pIS5OYnLpe88mzEDu8O4eqDzY1AVkJ CyMianmfUFhmp2vPJodB2TqrLaTc7M5C1TxlYR8X7fv2G+QCFRHcBMYLYcG/bp067NefkvrzdZI KrAHGzn+wsf2hRxcmAMZs1wvt4/yGyj0FHv4mK3kqT/IqArZ4uVEuEhXd+Z5MTF+JKEMRdKXiNl 0HAxImgN6F8XDwrYV6KFI4LPhzhu1oWgeOdiVVPBOHK1NwBgtXH3JYcw9QnLh0Uks1TLm6r7D/H rF53OUwyVoFy0MZtRnN+Rvkw1LBtsAfUFeuicu9PmapHEoO/j7gdIbrW67sdTKjuy1Qw073JziC wM5BmyYdDi5ixxKhOPz92j+0SIiGf4cXtvrxQ3dyP+WcAvorNGM5Yr5t2RyoIuPtk696swqHxvO lr/ndM13sygc6nPuGSqzDO8wdwJRAvx9sztvoWBgl32i/uWPzYRDEKLVXCZ+khUMwBnmxy/1l2e VklNKY3ou6Rpf8GrbBdFw3WkyZ1L1JJCDWwvRY5SjlZEgzD2lAVXzVkSooCfllvWgijvwNIgPb5 Ju8J/h07pXRIAtg== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496776896158500 The VNC encoding worker thread was using a single global queue shared across all VNC displays, with no way to stop it. This made it impossible to properly clean up resources when a VncDisplay is freed. Move the VncJobQueue from a file-scoped global to a per-VncDisplay member, so each display owns its worker thread and queue. Add vnc_stop_worker_thread() to perform an orderly shutdown: signal the thread to exit, join it, and destroy the queue. The thread is now created as QEMU_THREAD_JOINABLE instead of QEMU_THREAD_DETACHED. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- ui/vnc-jobs.h | 3 ++- ui/vnc.h | 2 ++ ui/vnc-jobs.c | 62 ++++++++++++++++++++++++++++++++++++++-----------------= ---- ui/vnc.c | 3 ++- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h index 59f66bcc353..e5ab55c1da6 100644 --- a/ui/vnc-jobs.h +++ b/ui/vnc-jobs.h @@ -37,7 +37,8 @@ void vnc_job_push(VncJob *job); void vnc_jobs_join(VncState *vs); =20 void vnc_jobs_consume_buffer(VncState *vs); -void vnc_start_worker_thread(void); +void vnc_start_worker_thread(VncDisplay *vd); +void vnc_stop_worker_thread(VncDisplay *vd); =20 /* Locks */ static inline int vnc_trylock_display(VncDisplay *vd) diff --git a/ui/vnc.h b/ui/vnc.h index 472a55f7b5f..780fd39469f 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -62,6 +62,7 @@ =20 typedef struct VncState VncState; typedef struct VncJob VncJob; +typedef struct VncJobQueue VncJobQueue; typedef struct VncRect VncRect; typedef struct VncRectEntry VncRectEntry; =20 @@ -158,6 +159,7 @@ struct VncDisplay int ledstate; QKbdState *kbd; QemuMutex mutex; + VncJobQueue *queue; =20 int cursor_msize; uint8_t *cursor_mask; diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 5b17ef54091..90b68bf4cb9 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -29,8 +29,6 @@ #include "qemu/osdep.h" #include "vnc.h" #include "vnc-jobs.h" -#include "qemu/sockets.h" -#include "qemu/main-loop.h" #include "trace.h" =20 /* @@ -56,17 +54,10 @@ struct VncJobQueue { QemuCond cond; QemuMutex mutex; QemuThread thread; + bool exit; QTAILQ_HEAD(, VncJob) jobs; }; =20 -typedef struct VncJobQueue VncJobQueue; - -/* - * We use a single global queue, but most of the functions are - * already reentrant, so we can easily add more than one encoding thread - */ -static VncJobQueue *queue; - static void vnc_lock_queue(VncJobQueue *queue) { qemu_mutex_lock(&queue->mutex); @@ -125,12 +116,15 @@ static void vnc_job_free(VncJob *job) */ void vnc_job_push(VncJob *job) { + VncJobQueue *queue =3D job->vs->vd->queue; + assert(!QTAILQ_IN_USE(job, next)); =20 if (QLIST_EMPTY(&job->rectangles)) { vnc_job_free(job); } else { vnc_lock_queue(queue); + assert(!queue->exit); QTAILQ_INSERT_TAIL(&queue->jobs, job, next); qemu_cond_broadcast(&queue->cond); vnc_unlock_queue(queue); @@ -139,6 +133,7 @@ void vnc_job_push(VncJob *job) =20 static bool vnc_has_job_locked(VncState *vs) { + VncJobQueue *queue =3D vs->vd->queue; VncJob *job; =20 QTAILQ_FOREACH(job, &queue->jobs, next) { @@ -151,6 +146,8 @@ static bool vnc_has_job_locked(VncState *vs) =20 void vnc_jobs_join(VncState *vs) { + VncJobQueue *queue =3D vs->vd->queue; + vnc_lock_queue(queue); while (vnc_has_job_locked(vs)) { qemu_cond_wait(&queue->cond, &queue->mutex); @@ -252,9 +249,13 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) int saved_offset; =20 vnc_lock_queue(queue); - while (QTAILQ_EMPTY(&queue->jobs)) { + while (QTAILQ_EMPTY(&queue->jobs) && !queue->exit) { qemu_cond_wait(&queue->cond, &queue->mutex); } + if (queue->exit) { + vnc_unlock_queue(queue); + return 1; + } job =3D QTAILQ_FIRST(&queue->jobs); vnc_unlock_queue(queue); =20 @@ -340,7 +341,7 @@ disconnected: return 0; } =20 -static VncJobQueue *vnc_queue_init(void) +static VncJobQueue *vnc_queue_new(void) { VncJobQueue *queue =3D g_new0(VncJobQueue, 1); =20 @@ -350,29 +351,46 @@ static VncJobQueue *vnc_queue_init(void) return queue; } =20 +static void vnc_queue_free(VncJobQueue *queue) +{ + qemu_cond_destroy(&queue->cond); + qemu_mutex_destroy(&queue->mutex); + g_free(queue); +} + static void *vnc_worker_thread(void *arg) { VncJobQueue *queue =3D arg; =20 while (!vnc_worker_thread_loop(queue)) ; - g_assert_not_reached(); + return NULL; } =20 -static bool vnc_worker_thread_running(void) +void vnc_start_worker_thread(VncDisplay *vd) { - return queue; /* Check global queue */ + assert(vd->queue =3D=3D NULL); + + vd->queue =3D vnc_queue_new(); + qemu_thread_create(&vd->queue->thread, "vnc_worker", vnc_worker_thread= , vd->queue, + QEMU_THREAD_JOINABLE); } =20 -void vnc_start_worker_thread(void) +void vnc_stop_worker_thread(VncDisplay *vd) { - VncJobQueue *q; + VncJobQueue *queue =3D vd->queue; =20 - if (vnc_worker_thread_running()) + if (!queue) { return; + } + + /* all VNC clients must have finished before we can stop the worker th= read */ + vnc_lock_queue(queue); + assert(QTAILQ_EMPTY(&queue->jobs)); + queue->exit =3D true; + qemu_cond_broadcast(&queue->cond); + vnc_unlock_queue(queue); =20 - q =3D vnc_queue_init(); - qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, - QEMU_THREAD_DETACHED); - queue =3D q; /* Set global queue */ + qemu_thread_join(&queue->thread); + g_clear_pointer(&vd->queue, vnc_queue_free); } diff --git a/ui/vnc.c b/ui/vnc.c index c87d1f61a0a..3a908670ab9 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3457,7 +3457,7 @@ void vnc_display_init(const char *id, Error **errp) vd->share_policy =3D VNC_SHARE_POLICY_ALLOW_EXCLUSIVE; vd->connections_limit =3D 32; =20 - vnc_start_worker_thread(); + vnc_start_worker_thread(vd); =20 register_displaychangelistener(&vd->dcl); vd->kbd =3D qkbd_state_init(vd->dcl.con); @@ -3513,6 +3513,7 @@ static void vnc_display_free(VncDisplay *vd) =20 assert(QTAILQ_EMPTY(&vd->clients)); =20 + vnc_stop_worker_thread(vd); vnc_display_close(vd); unregister_displaychangelistener(&vd->dcl); qkbd_state_free(vd->kbd); --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496780; cv=none; d=zohomail.com; s=zohoarc; b=TqcJWdr/b4szSSBg2Hv7Pe5Fad3x+G/guQ9bgme5TPl8uYTWeCSPoGiuzjW5oUoQxntdX9dCxlGMJLmc9u9/CpzoPusPpoJ0voNyhIGTQutuO9OcFuSpcx+PLIJHTHfM0sROqYapqKgddAGAARlyc4NkJXesH5ealOULv9muHJM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496780; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=9xsmB+cqBRqaS9skMbjA7XRg5bZVpVFUgMg50GnuroM=; b=hfgA03TNmemU0zmdiU72wost249dx0v30vciUOa8e+HAYqpugeMlhZn5JQh1oUUfAooMZtODQ3UjJk9Flyjl6Gf26QQnx+QjrSB4OjnLrzqt5RFwx8QFS1mKn5xSLW70ZAEZYBsHd/LSXNIK0mUTNh/njTJyl+90dRSigUC+op0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496780383376.4228292091724; Wed, 29 Apr 2026 14:06:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6f-0007Zo-Ak; Wed, 29 Apr 2026 17:06:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5R-0006Jo-5R for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5P-0003UQ-Gh for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:48 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-451-RWvMftFHO42LrwLjx79PZw-1; Wed, 29 Apr 2026 17:04:44 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1A1331956050; Wed, 29 Apr 2026 21:04:42 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BCB27195608E; Wed, 29 Apr 2026 21:04:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496685; 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=9xsmB+cqBRqaS9skMbjA7XRg5bZVpVFUgMg50GnuroM=; b=b8WAZlFscC06ruO5zPzyWVhWGI9JqXbWQLET9KDEFXkBM6b6ZuTW/ULXrpqAISLxITSFR+ Jq+w6gr8vEgGrVlVaiN5xjZ3KzUOmTkYEm8A3sDE9u09FmYerVXSDYdukTunbXVJyHrxCb Aoer9zAPI28tG/7TIFTmKxJCbQz6cD4= X-MC-Unique: RWvMftFHO42LrwLjx79PZw-1 X-Mimecast-MFC-AGG-ID: RWvMftFHO42LrwLjx79PZw_1777496682 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:48 +0400 Subject: [PATCH v3 15/26] ui/vnc: vnc_display_init() and vnc_display_open() return bool MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-15-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=3384; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=1BdF+ZE2ZaZ7NQ/12KK1Q24noSi6tIoILVGECxV0ikY=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMKXhnRdo6HWaNS9G8J/dKMbJdtptmf9uYN 0VTyhqYG06JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5XpdEACyKd4WFtudHsU368hBdh6Ab0Ojh6moGqf+tdEGlLib0ez3H7Z5t0WQVqSwmszgUkeQ0wu oLqUGbdkB+4oixkVw1r6PrlsNtGxdZnBrycrF2jmcB6DGpe2WtpeGLkpSe1c5L+vunpu5lTryRU hjHB4QH+iP3xJ9FpN1MxNdXVaRSB1a+6cRlpf66Gm9OhRATmru5WkxXmzGjd1/krqBFT8NoDnn0 OY7s1H52kLK2ChMcKCotM1JMg+CO0SpmsS9US1vBBfzUgxAoE+Yuo8N6AYoPSTKdAaZUFAt8PT7 VD59+9HKrYd3acB0Zrib3oZbQHZx9KOHUctWK9qFuDj5chIS0nIIcA8sl53Q8rmbivzW4iUWKAM xqwWVMJq1zopsif4YkET/LyzoC/5wOE1DNmAASSEHasYHUrbqy6gAXHFQah1n8P1smPPAhKNnF+ FYi2xyMnZYOey0CRv/WSLYonoA8Z1LpPHP34BUWaGDe6nzFZs8Ad5nHeWqN3qSTgi7fW2r+9BIL /GRPqoX7+g/Y6q94mD9ZL1oJsfxMY9xKemDvVbA+csBO0bL7mJ2XIljdb/PUKVd5IRj3CJHS/Gk hWatWV0o51PFfINn1dQVI/iD/h5rj89JdxTrvZ5FLbMEEwlu5N7rVK+Q4xeJ0rxrtojAqyZ1eCn iIxaNRoOdmyN1Gw== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496780962158500 Use the QEMU-style error pattern returning "true" on success. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Daniel P. Berrang=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/ui/console.h | 4 ++-- ui/vnc.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 2bf768ed482..7224b8142f3 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -438,8 +438,8 @@ const char *qemu_display_get_vc(DisplayOptions *opts); void qemu_display_help(void); =20 /* vnc.c */ -void vnc_display_init(const char *id, Error **errp); -void vnc_display_open(const char *id, Error **errp); +bool vnc_display_init(const char *id, Error **errp); +bool vnc_display_open(const char *id, Error **errp); void vnc_display_add_client(const char *id, int csock, bool skipauth); int vnc_display_password(const char *id, const char *password, Error **err= p); int vnc_display_pw_expire(const char *id, time_t expires); diff --git a/ui/vnc.c b/ui/vnc.c index 3a908670ab9..067f534cf08 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3425,12 +3425,12 @@ static void vmstate_change_handler(void *opaque, bo= ol running, RunState state) =20 static void vnc_display_free(VncDisplay *vd); =20 -void vnc_display_init(const char *id, Error **errp) +bool vnc_display_init(const char *id, Error **errp) { VncDisplay *vd; =20 if (vnc_display_find(id) !=3D NULL) { - return; + return true; } vd =3D g_malloc0(sizeof(*vd)); =20 @@ -3451,7 +3451,7 @@ void vnc_display_init(const char *id, Error **errp) =20 if (!vd->kbd_layout) { vnc_display_free(vd); - return; + return false; } =20 vd->share_policy =3D VNC_SHARE_POLICY_ALLOW_EXCLUSIVE; @@ -3465,6 +3465,7 @@ void vnc_display_init(const char *id, Error **errp) &vmstate_change_handler, vd); =20 QTAILQ_INSERT_TAIL(&vnc_displays, vd, next); + return true; } =20 static void vnc_display_close(VncDisplay *vd) @@ -4070,7 +4071,7 @@ bool vnc_display_update(DisplayUpdateOptionsVNC *arg,= Error **errp) return true; } =20 -void vnc_display_open(const char *id, Error **errp) +bool vnc_display_open(const char *id, Error **errp) { VncDisplay *vd =3D vnc_display_find(id); QemuOpts *opts =3D qemu_opts_find(&qemu_vnc_opts, id); @@ -4273,7 +4274,7 @@ void vnc_display_open(const char *id, Error **errp) qkbd_state_set_delay(vd->kbd, key_delay_ms); =20 if (saddr_list =3D=3D NULL) { - return; + return true; } =20 if (reverse) { @@ -4291,10 +4292,11 @@ void vnc_display_open(const char *id, Error **errp) } =20 /* Success */ - return; + return true; =20 fail: vnc_display_close(vd); + return false; } =20 void vnc_display_add_client(const char *id, int csock, bool skipauth) @@ -4350,12 +4352,10 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Err= or **errp) id =3D vnc_auto_assign_id(opts); } =20 - vnc_display_init(id, errp); - if (*errp) { + if (!vnc_display_init(id, errp)) { return -1; } - vnc_display_open(id, errp); - if (*errp) { + if (!vnc_display_open(id, errp)) { return -1; } return 0; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496837; cv=none; d=zohomail.com; s=zohoarc; b=mvfb8fEMOjuFePEjU7rKAJKS3Qtqucv3tV/gBtJej2/LcLKvcg+6MD91se5eE9JcBQZI1YeD8TT5QAOznl2MzTuRUodFKhEVd07l7Svha5socB+OOHdZu106Rq5Nl3bG5eM9L+xLAsqyZQEC2bjwQoQZD6MH9g6CzVm4ekP6syU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496837; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=cYb9CzXbF1iD7gvA2lK+zB+4NthlyQweiyV38R9QicQ=; b=Hw4iHUxJ4NZDBsrNkdcjk9W5xqR8x1gSeCPrRBB8sFwMne2VRBTwixu3krZ/VsgmD7VztPbqNWiAUCTyQxlH0SMSasJQ3bGivZQSmoS39ZQwWfYNoFcCzlWLIGSdYfVw/rTwjAsv1tWatqfScaBoCb/B9iGKejHeMsa8OsJXndw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496837610781.2943121007634; Wed, 29 Apr 2026 14:07:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6g-0007fc-M2; Wed, 29 Apr 2026 17:06:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5V-0006KU-8K for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:59 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5T-0003Ul-BC for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:04:52 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-218-t9bKILbeMEmv2oUSyE91cQ-1; Wed, 29 Apr 2026 17:04:48 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 87F93195608E for ; Wed, 29 Apr 2026 21:04:47 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7C014300019F; Wed, 29 Apr 2026 21:04:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496690; 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=cYb9CzXbF1iD7gvA2lK+zB+4NthlyQweiyV38R9QicQ=; b=GVwfRPvASlHdj6g2ufoxOvaJaExkr2sMbBwSR8oVMSQFU0/TrfmA/oXq2YDzoQO5bIRs8v BoZfzsBVq9xLnI4L0bTS7pNlKJfmPHOeDcaGz4aeM/xvT+FzvYx46fffcE0Qx1hsOKZvKR n+4jDFk8sJ88aEC37jV8P7yiSJcAXQk= X-MC-Unique: t9bKILbeMEmv2oUSyE91cQ-1 X-Mimecast-MFC-AGG-ID: t9bKILbeMEmv2oUSyE91cQ_1777496687 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:49 +0400 Subject: [PATCH v3 16/26] ui/vnc: merge vnc_display_init() and vnc_display_open() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-16-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=10282; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=O83CBYLyXPof+xTeYZA3ffs8FHHZIOfJ5nmRzw9+tcY=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMFPBUNqRKt1F/wmXGWJmdWRs8ixlCmes72 Dc7MwiGol+JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5RYtD/9dtAMaq/p1NSmtvAVUIkXwgA1aiVYOCwklEYsgeS5082YQPG6eSd7aDTOQZhQOXh9EDeu NL15U+2tQg5nSkapdJ18XSbcSUeWlRlGdorv3Mvy2j3eLkjF73ddCt4qg/Wyb+D/Hw+mFxTqQTq vymHQ4Nl9fG7eVDVS4/+AmjNhMaQwTLSKay6iUfXd27qaThfHHJ5tkDshdG+sJEeeTyjML4IC7K FvkgAdnDB10BciOMsv7g0rhX6OfRhV4vlcfI+T0h9eZRff+RqCYJ3xtEUljVRjyvPDuQ9IwVuzq WKJUqaSoZvN7VuJJlGb5Uco0O1ZQGcewnKUDemQGJNnCT9BK8KK/K60JsBYdYxfjEAoUh+SRJv5 b+x1BQ2MbdCSoOH2nMACBW+jezeNVm8Nh/fddkuQKUwsl1ivQFuN7aTX9WelXEPn4dotYgs7H6F nlw5aJiTO2u8GzgKwSEntQnv3TtLIZ/eN8waS82rgt9xd+YskuNdkKTo1A8tHYIOdHVXU//AkpI c07gyq0xTj4wntb1WDlaYHI79HE9IojM+u5xKEgbxvFvHU1En68czLHwnEZ+Z3Xp9RmEqpBkyX8 LSaWRBZyQKK8cTlLvZI0kPGdjIiiNrq/bpv2lYNHVX12Y1Job1XCl7feffSzOqGb5xHXlGXs771 Kpo1mdBwm/bEFhQ== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496839405158500 Combine the two-step vnc_display_init()/vnc_display_open() sequence into a single vnc_display_new() function that returns VncDisplay*. This simplifies the API by making vnc_display_open() an internal detail and will allow further code simplification. vnc_display_new() is moved to vnc.h, since it returns VncDisplay* now. Add vnc_display_free() for consistency, and it will be later used. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- include/ui/console.h | 2 -- ui/vnc.h | 3 ++ ui/vnc.c | 79 ++++++++++++++++++++++--------------------------= ---- 3 files changed, 36 insertions(+), 48 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 7224b8142f3..550a5e08e46 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -438,8 +438,6 @@ const char *qemu_display_get_vc(DisplayOptions *opts); void qemu_display_help(void); =20 /* vnc.c */ -bool vnc_display_init(const char *id, Error **errp); -bool vnc_display_open(const char *id, Error **errp); void vnc_display_add_client(const char *id, int csock, bool skipauth); int vnc_display_password(const char *id, const char *password, Error **err= p); int vnc_display_pw_expire(const char *id, time_t expires); diff --git a/ui/vnc.h b/ui/vnc.h index 780fd39469f..d2ebb0f7f45 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -549,6 +549,9 @@ enum VncFeatures { #define VNC_CLIPBOARD_NOTIFY (1 << 27) #define VNC_CLIPBOARD_PROVIDE (1 << 28) =20 +VncDisplay *vnc_display_new(const char *id, Error **errp); +void vnc_display_free(VncDisplay *vd); + /*************************************************************************= **** * * Internal APIs diff --git a/ui/vnc.c b/ui/vnc.c index 067f534cf08..1c649e7bccf 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3423,17 +3423,15 @@ static void vmstate_change_handler(void *opaque, bo= ol running, RunState state) update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); } =20 -static void vnc_display_free(VncDisplay *vd); +static bool vnc_display_open(VncDisplay *vd, Error **errp); =20 -bool vnc_display_init(const char *id, Error **errp) +VncDisplay *vnc_display_new(const char *id, Error **errp) { VncDisplay *vd; =20 - if (vnc_display_find(id) !=3D NULL) { - return true; - } - vd =3D g_malloc0(sizeof(*vd)); + assert(!vnc_display_find(id)); =20 + vd =3D g_new0(VncDisplay, 1); qemu_mutex_init(&vd->mutex); vd->id =3D g_strdup(id); vd->dcl.ops =3D &dcl_ops; @@ -3451,7 +3449,7 @@ bool vnc_display_init(const char *id, Error **errp) =20 if (!vd->kbd_layout) { vnc_display_free(vd); - return false; + return NULL; } =20 vd->share_policy =3D VNC_SHARE_POLICY_ALLOW_EXCLUSIVE; @@ -3464,8 +3462,13 @@ bool vnc_display_init(const char *id, Error **errp) vd->vmstate_handler_entry =3D qemu_add_vm_change_state_handler( &vmstate_change_handler, vd); =20 + if (!vnc_display_open(vd, errp)) { + vnc_display_free(vd); + return NULL; + } + QTAILQ_INSERT_TAIL(&vnc_displays, vd, next); - return true; + return vd; } =20 static void vnc_display_close(VncDisplay *vd) @@ -3506,7 +3509,7 @@ static void vnc_display_close(VncDisplay *vd) #endif } =20 -static void vnc_display_free(VncDisplay *vd) +void vnc_display_free(VncDisplay *vd) { if (!vd) { return; @@ -3528,7 +3531,6 @@ static void vnc_display_free(VncDisplay *vd) g_free(vd); } =20 - int vnc_display_password(const char *id, const char *password, Error **err= p) { VncDisplay *vd =3D vnc_display_find(id); @@ -4071,10 +4073,9 @@ bool vnc_display_update(DisplayUpdateOptionsVNC *arg= , Error **errp) return true; } =20 -bool vnc_display_open(const char *id, Error **errp) +static bool vnc_display_open(VncDisplay *vd, Error **errp) { - VncDisplay *vd =3D vnc_display_find(id); - QemuOpts *opts =3D qemu_opts_find(&qemu_vnc_opts, id); + QemuOpts *opts =3D qemu_opts_find(&qemu_vnc_opts, vd->id); g_autoptr(SocketAddressList) saddr_list =3D NULL; g_autoptr(SocketAddressList) wsaddr_list =3D NULL; const char *share, *device_id; @@ -4093,26 +4094,23 @@ bool vnc_display_open(const char *id, Error **errp) assert(vd); assert(opts); =20 - vnc_display_close(vd); - reverse =3D qemu_opt_get_bool(opts, "reverse", false); if (vnc_display_get_addresses(opts, reverse, &saddr_list, &wsaddr_list, errp) < 0) { - goto fail; + return false; } =20 - passwordSecret =3D qemu_opt_get(opts, "password-secret"); if (passwordSecret) { if (qemu_opt_get(opts, "password")) { error_setg(errp, "'password' flag is redundant with 'password-secret= '"); - goto fail; + return false; } vd->password =3D qcrypto_secret_lookup_as_utf8(passwordSecret, errp); if (!vd->password) { - goto fail; + return false; } password =3D true; } else { @@ -4123,7 +4121,7 @@ bool vnc_display_open(const char *id, Error **errp) QCRYPTO_CIPHER_ALGO_DES, QCRYPTO_CIPHER_MODE_ECB)) { error_setg(errp, "Cipher backend does not support DES algorithm"); - goto fail; + return false; } } =20 @@ -4133,7 +4131,7 @@ bool vnc_display_open(const char *id, Error **errp) #ifndef CONFIG_VNC_SASL if (sasl) { error_setg(errp, "VNC SASL auth requires cyrus-sasl support"); - goto fail; + return false; } #endif /* CONFIG_VNC_SASL */ credid =3D qemu_opt_get(opts, "tls-creds"); @@ -4144,7 +4142,7 @@ bool vnc_display_open(const char *id, Error **errp) if (!creds) { error_setg(errp, "No TLS credentials with id '%s'", credid); - goto fail; + return false; } vd->tlscreds =3D (QCryptoTLSCreds *) object_dynamic_cast(creds, @@ -4152,26 +4150,26 @@ bool vnc_display_open(const char *id, Error **errp) if (!vd->tlscreds) { error_setg(errp, "Object with id '%s' is not TLS credentials", credid); - goto fail; + return false; } object_ref(OBJECT(vd->tlscreds)); =20 if (!qcrypto_tls_creds_check_endpoint(vd->tlscreds, QCRYPTO_TLS_CREDS_ENDPOINT_S= ERVER, errp)) { - goto fail; + return false; } } tlsauthz =3D qemu_opt_get(opts, "tls-authz"); if (tlsauthz && !vd->tlscreds) { error_setg(errp, "'tls-authz' provided but TLS is not enabled"); - goto fail; + return false; } =20 saslauthz =3D qemu_opt_get(opts, "sasl-authz"); if (saslauthz && !sasl) { error_setg(errp, "'sasl-authz' provided but SASL auth is not enabl= ed"); - goto fail; + return false; } =20 share =3D qemu_opt_get(opts, "share"); @@ -4184,7 +4182,7 @@ bool vnc_display_open(const char *id, Error **errp) vd->share_policy =3D VNC_SHARE_POLICY_FORCE_SHARED; } else { error_setg(errp, "unknown vnc share=3D option"); - goto fail; + return false; } } else { vd->share_policy =3D VNC_SHARE_POLICY_ALLOW_EXCLUSIVE; @@ -4218,20 +4216,20 @@ bool vnc_display_open(const char *id, Error **errp) if (vnc_display_setup_auth(&vd->auth, &vd->subauth, vd->tlscreds, password, sasl, false, errp) < 0) { - goto fail; + return false; } trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth); =20 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth, vd->tlscreds, password, sasl, true, errp) < 0) { - goto fail; + return false; } trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth); =20 #ifdef CONFIG_VNC_SASL if (sasl && !vnc_sasl_server_init(errp)) { - goto fail; + return false; } #endif vd->lock_key_sync =3D lock_key_sync; @@ -4244,7 +4242,7 @@ bool vnc_display_open(const char *id, Error **errp) if (audiodev) { vd->audio_be =3D audio_be_by_name(audiodev, errp); if (!vd->audio_be) { - goto fail; + return false; } } else { vd->audio_be =3D audio_get_default_audio_be(NULL); @@ -4258,7 +4256,7 @@ bool vnc_display_open(const char *id, Error **errp) con =3D qemu_console_lookup_by_device_name(device_id, head, &err); if (err) { error_propagate(errp, err); - goto fail; + return false; } } else { con =3D qemu_console_lookup_default(); @@ -4279,11 +4277,11 @@ bool vnc_display_open(const char *id, Error **errp) =20 if (reverse) { if (vnc_display_connect(vd, saddr_list, wsaddr_list, errp) < 0) { - goto fail; + return false; } } else { if (vnc_display_listen(vd, saddr_list, wsaddr_list, errp) < 0) { - goto fail; + return false; } } =20 @@ -4291,12 +4289,7 @@ bool vnc_display_open(const char *id, Error **errp) vnc_display_print_local_addr(vd); } =20 - /* Success */ return true; - -fail: - vnc_display_close(vd); - return false; } =20 void vnc_display_add_client(const char *id, int csock, bool skipauth) @@ -4352,13 +4345,7 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Erro= r **errp) id =3D vnc_auto_assign_id(opts); } =20 - if (!vnc_display_init(id, errp)) { - return -1; - } - if (!vnc_display_open(id, errp)) { - return -1; - } - return 0; + return vnc_display_new(id, errp) !=3D NULL ? 0 : -1; } =20 static void vnc_register_config(void) --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496796; cv=none; d=zohomail.com; s=zohoarc; b=bYTbTRj12aXQK0qC231MyaSzF0KdLYbfkrI7593d4Syyhxz6GTBVuhYGzs5o86Ov3pGJbyXK/aSBuRFwkidVsjt/iND0LiS6VJwDs8j0NI+ajiMs1IuJHhOVllwTQJiPaUQZsuoWMKignKG1KoCkbBuXXrds9ozIy+kIoCD3C0Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496796; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=K9ejhMqDOIAnqlDB6S6XDF5JcjPS+M/QLKhH2rZsC/U=; b=HIwKiQwHSjtB/OnzWp4A+rfPXAWX/hpOp33TPUOixXDTZwusUZ2+6gTnlxfayyWohOCkja3EhN4RbAVlDImv/oTSIveLNc+CP8qZjz4JBTu/7DfLuPa0vSDfprt1UDJoKFgFjcYc0bYoLevozsKyYpQ8SrdZEh5Fh3g162WC9V8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496796073763.2280019510152; Wed, 29 Apr 2026 14:06:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6r-0007uo-3c; Wed, 29 Apr 2026 17:06:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5e-0006OV-UU for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5c-0003V5-O5 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:02 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-463-o7l964QgOf2P83nbbpg2UQ-1; Wed, 29 Apr 2026 17:04:54 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5EF6A19560B7 for ; Wed, 29 Apr 2026 21:04:53 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 007661800577; Wed, 29 Apr 2026 21:04:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496695; 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=K9ejhMqDOIAnqlDB6S6XDF5JcjPS+M/QLKhH2rZsC/U=; b=PvloAO1UvWpqe4CgtZYMrajkFzhXTGM/ztrKuSEiCSQKkeCUSV6KgoAG556hWTu869VkLB LLrZcx4GFNUMRuum5tnu9qtBIFpKUnH4COxKMjRjA9DRrokvSldyJaorQMcyVxyJbHtOgZ IWTZef6jWt8v4dUPulHOmncK9pXeTfM= X-MC-Unique: o7l964QgOf2P83nbbpg2UQ-1 X-Mimecast-MFC-AGG-ID: o7l964QgOf2P83nbbpg2UQ_1777496693 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:50 +0400 Subject: [PATCH v3 17/26] ui/vnc: clean up VNC displays on exit MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-17-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=3164; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=UofqdxEpsoMU3tHdoWYdaOMGh4untiTWKq2jjDIVs/Q=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMJ1jHyit5LpouPussdgMCirQheJLzzaMuf CCUYpcUpy6JAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5dltD/4mDqHs1l5qBtnLmqVCgXkW8sFKReO1HjMEcepO2AP+mwOcaNB7VV3gRaNLZMM5mgTs8o1 jEUrJkyFH4nXB4pIUlSX3UwF4NHLmcN8ZXPQMnzXugxl25XFGc41s/IoSn/bAGOEYjxMTChUIpb 5j0uvttmP/N8i4jbhIwGvokhYWbnYPm5DsQazcCvGAKoOHw8kYgvjXKBg20SscqVoO/8Xn7R9Ly JJk25QHu7ueag2JgFdUwREfZN8ffrVp9BcsHJ+StD9aBy8XFbz8eAm73WPjinCWzKoN7qilHJV+ DxsmyFRcdaS7Z83b9CbldlkNZliZN08PBVFNZfMnuHSlyFrAGjlrPHYp1x5Cu1yKMn4k+VKx5L4 YhuMNdFB5svr7FSGoQYt/+XwJl8MSFRCrnJqQtCycqhpeGvbbzxFpaGro5kEaOf8BxgQ4ja1Uzw cnU6/TFLUOOtrsGEml6E2Y43oy7D2P+p+W9GC7BQgLNbfdplFe4UmzK9ny+TQfHYnjQD/Wd8/l0 KxsyZ9z2CV4f/IU7budzMZBcygkqujol7YrzVKKSzilMCuCqOZGHhNF/lLcSdcgIIcry9hQFC76 JUwo6i9TiVpVIHEVB4W3JjyibDoa85keKa4ZHa8ZXMcbAz3CxKhQZzGnbT0TPE8YI4lOJbXEHGW iENqQFGK0M30qxQ== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496797081158500 Previously, VNC displays were never torn down on QEMU exit, leaking resources and leaving connected clients with unclean disconnects. Add vnc_cleanup() to free all VNC displays during qemu_cleanup(). Make vnc_display_close() initiate disconnection of active clients, and have vnc_display_free() drain the main loop until all clients have completed their teardown, instead of asserting the client list is empty. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- include/ui/console.h | 1 + system/runstate.c | 5 +++++ ui/vnc.c | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 550a5e08e46..89fb4c1942a 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -445,6 +445,7 @@ void vnc_parse(const char *str); int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp); bool vnc_display_reload_certs(const char *id, Error **errp); bool vnc_display_update(DisplayUpdateOptionsVNC *arg, Error **errp); +void vnc_cleanup(void); =20 /* input.c */ int index_from_key(const char *key, size_t key_length); diff --git a/system/runstate.c b/system/runstate.c index 770253b467b..0e1cb3b4e67 100644 --- a/system/runstate.c +++ b/system/runstate.c @@ -61,6 +61,8 @@ #include "system/confidential-guest-support.h" #include "system/system.h" #include "system/tpm.h" +#include "ui/console.h" + #include "trace.h" =20 static NotifierList exit_notifiers =3D @@ -1044,5 +1046,8 @@ void qemu_cleanup(int status) monitor_cleanup(); qemu_chr_cleanup(); user_creatable_cleanup(); +#ifdef CONFIG_VNC + vnc_cleanup(); +#endif /* TODO: unref root container, check all devices are ok */ } diff --git a/ui/vnc.c b/ui/vnc.c index 1c649e7bccf..d65153a5001 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3473,8 +3473,13 @@ VncDisplay *vnc_display_new(const char *id, Error **= errp) =20 static void vnc_display_close(VncDisplay *vd) { + VncState *vs; + assert(vd); =20 + QTAILQ_FOREACH(vs, &vd->clients, next) { + vnc_disconnect_start(vs); + } if (vd->listener) { qio_net_listener_disconnect(vd->listener); object_unref(OBJECT(vd->listener)); @@ -3515,10 +3520,12 @@ void vnc_display_free(VncDisplay *vd) return; } =20 - assert(QTAILQ_EMPTY(&vd->clients)); + vnc_display_close(vd); + while (!QTAILQ_EMPTY(&vd->clients)) { + main_loop_wait(false); + } =20 vnc_stop_worker_thread(vd); - vnc_display_close(vd); unregister_displaychangelistener(&vd->dcl); qkbd_state_free(vd->kbd); qemu_del_vm_change_state_handler(vd->vmstate_handler_entry); @@ -4348,6 +4355,15 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Erro= r **errp) return vnc_display_new(id, errp) !=3D NULL ? 0 : -1; } =20 +void vnc_cleanup(void) +{ + VncDisplay *vd, *vd_next; + + QTAILQ_FOREACH_SAFE(vd, &vnc_displays, next, vd_next) { + vnc_display_free(vd); + } +} + static void vnc_register_config(void) { qemu_add_opts(&qemu_vnc_opts); --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496809; cv=none; d=zohomail.com; s=zohoarc; b=aZyaaoXLBwOxFQiPwCnQPWmjD3l+dDByxmcp0/J2jghNp8GO3EHRNvqQ/N1Xq7iuRa7FwgDnIq6PD9d8Ad1x7vUxMkML9hQMh8HL72AJajQbAkVaIOHwFWTkf1GNEGg07UuG9hVeqn8whJY8rkp9MSvbWzMQK8bqAWI3XWeHIqM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496809; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4xEMaCQqjSebJ1+71cJFBJzEXz13GiV+gV7EIYyxol8=; b=ODbFeaOJNR7OlgwhrmLWjsVAtzZtuNKq3bglaAYWBsL3drqPfUVzSB2TR+yGLkzq1zFmmEW1808T7b67oPVyOd5Y5ByTrUVdZ3Vdk4uUBULp8Nb17V8kQzKNaB9If6RoNlQcAJeH/inhoKaqRQLTeeHpGe36oUDMU/9RYZL2sDs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496809446884.2022287096136; Wed, 29 Apr 2026 14:06:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC7J-00005V-R0; Wed, 29 Apr 2026 17:06:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5m-0006Ss-EO for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5e-0003Vd-NU for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:05 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-177-3l_ft1mkNP2D-gNrxN8AfA-1; Wed, 29 Apr 2026 17:04:59 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D2EB718004AD for ; Wed, 29 Apr 2026 21:04:58 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D3D4D1800480; Wed, 29 Apr 2026 21:04:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496701; 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=4xEMaCQqjSebJ1+71cJFBJzEXz13GiV+gV7EIYyxol8=; b=Ivkh4Pxj2G8r+di/6Vkq2giMg95zY7HAjI20SvZMRMOVsaR3uXQnnWeR4qJk8NfP1jtzqu zdzL0aGhxxsW9WU5+fCtWHVtOdggoohcxtoliA7L+zb50dD3N5U7XqwiiOJaLYzKDJ3hdS Z+QAS2rGEemiLUwYbhDj41AuL8KeWII= X-MC-Unique: 3l_ft1mkNP2D-gNrxN8AfA-1 X-Mimecast-MFC-AGG-ID: 3l_ft1mkNP2D-gNrxN8AfA_1777496698 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:51 +0400 Subject: [PATCH v3 18/26] ui/vnc: defer listener registration until the console is known MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-18-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=1763; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=RK09TmaDHI9YqNxso5kjLy2qpHqN5kF0JjAA2oakXGU=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMH3Nu8J+aiKH8UyK7dbTyZivqBc8wshoww UeEG2dABeyJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5bqED/kB2HIIs7nJrZaHcJoXvWv8vy6SdBeoGHxBvMOUmdufdiVURXjrLY4VtLurf+GKh2guuBL mI5R9jAMj8DrKMz3smJDK1Ki2xWoB9YexsW/K0NxQfJ7FQMdju/fuGYSp+4kzs/QHydrwe01MEL T/L+P/LSZwkye+GFxj52+MKM2WDK921/6npKXq0B6vZNr/lqstvX493OlOHM151THGANwocShqY 9v8ei7qHoxMR/lV/g/I71UcGfLo7yuChYMEl5kdOENywdih+qqZJ1th68cIcPq4AgUhpDoMvp9l dyS7XjaoWwAGisYLiKY+SQKQPylMHdBG25aUy4StIA6jAtzAxRVc45M91cR6EmdsW7iAz6iQB0d oPa3C2zGo10mtF2NTaC77M8iW3MAzfUJsWJIZ3g1Yf4PVygzXk/Hd9XOXD99FzZesG3t9WGNDOj SZofDW7tKlp97/pWwTdl1bRTUtBC3VfdOcq+LBw/6c9LXCzCDLKSjLxbRzEZTjS8HQthicYIXxz OVd1hcwhfv7ucyB8J/sxFBBwjvnKH3FjyCsPTGyH/OoOkOOhaTTU3lVmg5GObeLvD0O3jUjbeST AD7GLZbQI5FX46wmpwVOWXeww5bTuLwLNfS5C8x7Wy6DvhIQ72Stc4ix0zm0T9wEiDkC8iX55Jo P3NPv79F6cUXlhg== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496811163158500 Previously, the display change listener was registered early in vnc_display_new() without a console, requiring vnc_display_open() to conditionally unregister and re-register it when the actual console was resolved. Since vnc_display_new() and vnc_display_open() were merged in the previous commit, simply delay the registration and keyboard state initialization to vnc_display_open(), after the console has been looked up. This removes the conditional re-registration and simplifies the code. Reviewed-by: Daniel P. Berrang=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/vnc.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index d65153a5001..ea1579135b8 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3457,8 +3457,6 @@ VncDisplay *vnc_display_new(const char *id, Error **e= rrp) =20 vnc_start_worker_thread(vd); =20 - register_displaychangelistener(&vd->dcl); - vd->kbd =3D qkbd_state_init(vd->dcl.con); vd->vmstate_handler_entry =3D qemu_add_vm_change_state_handler( &vmstate_change_handler, vd); =20 @@ -4269,13 +4267,9 @@ static bool vnc_display_open(VncDisplay *vd, Error *= *errp) con =3D qemu_console_lookup_default(); } =20 - if (con !=3D vd->dcl.con) { - qkbd_state_free(vd->kbd); - unregister_displaychangelistener(&vd->dcl); - vd->dcl.con =3D con; - register_displaychangelistener(&vd->dcl); - vd->kbd =3D qkbd_state_init(vd->dcl.con); - } + vd->dcl.con =3D con; + register_displaychangelistener(&vd->dcl); + vd->kbd =3D qkbd_state_init(vd->dcl.con); qkbd_state_set_delay(vd->kbd, key_delay_ms); =20 if (saddr_list =3D=3D NULL) { --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496881; cv=none; d=zohomail.com; s=zohoarc; b=G+CJrP3V3NzxBuXaOwWqVX5gRsVWnmefkZWCTAAn6BRO/DHyyqXCtY/Szyc2ZaE6bhUXXrO4jSSteXrC65m2rCWLvfxWulBgKhTqokylQoSZplT3VN8Gdnh4SmDtwaxb6AS4CSA2s5TmfdLUKIPR6fvUM4lb6sjbEmcHn9ptVEQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496881; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GvceuUgF9UWGi+mkdSUd1zm6+VCfNMZH/pssttX4eis=; b=BP1phjAttym7l0b98Co/k3s2h1L4NDWiR1RyW3mSnBk0JsCXkEFUh9f+zIzKjcHWHGmptE1q//mk4zkForaBzb7mmpMw6iuRvcs3mWhwtkFEXI99VhGkNhukgsBb5eUPOUIzkjuwTjjgePjKHwH6M8C6Jsa2ckvZFnPianO0h/Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496881083258.5670616413752; Wed, 29 Apr 2026 14:08:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC7m-0001av-UU; Wed, 29 Apr 2026 17:07:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5u-0006dU-Nf for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:23 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5l-0003WE-M6 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:13 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-468-XL3B-7QIMU62J1AERxpPRg-1; Wed, 29 Apr 2026 17:05:05 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7A2311800378 for ; Wed, 29 Apr 2026 21:05:04 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 21C3E19560AB; Wed, 29 Apr 2026 21:05:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496706; 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=GvceuUgF9UWGi+mkdSUd1zm6+VCfNMZH/pssttX4eis=; b=MuwkfuafIeuw5+HmhGMpphc1Z7quDAC4mJ8kxfJu1urhsuDsuGHf/l1njI3pbQrBJeJtG6 OyQvZVhvKx/IY6H0GyK30DysbXNzDHT5Mc0GfZpkLjiqFaugfctqoFAHu+4pDKYP+8/SrU m8MyK+fuCXtNWBahDWkCya192574ClA= X-MC-Unique: XL3B-7QIMU62J1AERxpPRg-1 X-Mimecast-MFC-AGG-ID: XL3B-7QIMU62J1AERxpPRg_1777496704 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:52 +0400 Subject: [PATCH v3 19/26] ui/vnc: add vnc-system unit, to allow different implementations MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-19-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=2652; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=YzwkPRuZT+t1WALPng4UgvXGw1hhuhKzK7Bl0fT7wlw=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMOuk2e2TxtoDw8xrAjkZKxNSLglT/Onj66 +hVV1c4SEeJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5VHTD/4xqfK1+CNU92p/u2YiAs3EJOS6i7S3eeuGYamZDgUmowIo1z2r9aqJ/CD3mUyCJbKLmMY R0aX+ybX4ker7LFRwCH2DaS+G4cY1NuDvmz6peAdi9sPuhKlibDlqBbxTwK5xWl8VMPzdwM/J7c UEgZSTX4GRgNuQqZcaRJzW2nfNWIdCMtJI2yZRei93yKbrJVfH+FtX4SKBt4cWVeXOjFYloQgMD GgLFWOLiOEdwBafqWmvE9nJUayn01UMhBRMFdSfGaRJYwl7qg4xLl3SW63ff2KyGL6D+Qy2t8s+ Sl8Dr3XTujJYjAYWXSeMaJUehHeaFTl4lJB2t1BBh5j8TCTEMLtS5LypnmSg7OK8JI5ZRfTMS8B an1iJsfuI5bJNGT8L6UGSJfjm7dJlpHsBKwt1TuQLYTGntFMCC/TmNGApzmmG6KJK8ImYgJeoN7 BaDiX1b2KU8uzOyZwee5qU5NQ3ocbuXm7VqIrZa8GtEnn10JX1ZBDygQo7TC1S8cNrWwV7WBgQN jzGgbH6Kcn7T9+Qvri0lehvJqZQsq24rLUWAPe9dyYWC6W5Jh7j8oBLYUrffe/IGy+VAFO7Ppmd sgHyIf2V6KAcsL+BYyizBkaA367HC3iSE5UdsptnqCUjIG3pIuWoA13ubzCzqMSxb1v7JX+yp18 eTispZ9UwxD7EiQ== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496881476158500 The qemu-vnc server will want to signal the XVP requests, let it have its own implementation. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- ui/vnc.h | 4 ++++ ui/vnc-system.c | 19 +++++++++++++++++++ ui/vnc.c | 4 ++-- ui/meson.build | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ui/vnc.h b/ui/vnc.h index d2ebb0f7f45..0b345246c8e 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -648,4 +648,8 @@ void vnc_server_cut_text_caps(VncState *vs); void vnc_client_cut_text(VncState *vs, size_t len, uint8_t *text); void vnc_client_cut_text_ext(VncState *vs, int32_t len, uint32_t flags, ui= nt8_t *data); =20 +/* XVP events */ +void vnc_action_shutdown(VncState *vs); +void vnc_action_reset(VncState *vs); + #endif /* QEMU_VNC_H */ diff --git a/ui/vnc-system.c b/ui/vnc-system.c new file mode 100644 index 00000000000..0632885f655 --- /dev/null +++ b/ui/vnc-system.c @@ -0,0 +1,19 @@ +/* + * QEMU VNC display driver + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "qemu/osdep.h" + +#include "ui/vnc.h" +#include "system/runstate.h" + +void vnc_action_shutdown(VncState *vs) +{ + qemu_system_powerdown_request(); +} + +void vnc_action_reset(VncState *vs) +{ + qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET); +} diff --git a/ui/vnc.c b/ui/vnc.c index ea1579135b8..154b07e2e4e 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2522,13 +2522,13 @@ static int protocol_client_msg(VncState *vs, uint8_= t *data, size_t len) =20 switch (action) { case VNC_XVP_ACTION_SHUTDOWN: - qemu_system_powerdown_request(); + vnc_action_shutdown(vs); break; case VNC_XVP_ACTION_REBOOT: send_xvp_message(vs, VNC_XVP_CODE_FAIL); break; case VNC_XVP_ACTION_RESET: - qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_R= ESET); + vnc_action_reset(vs); break; default: send_xvp_message(vs, VNC_XVP_CODE_FAIL); diff --git a/ui/meson.build b/ui/meson.build index 7b6e867d3af..74151b05033 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -48,7 +48,7 @@ vnc_ss.add(files( vnc_ss.add(zlib, jpeg, png) vnc_ss.add(when: sasl, if_true: files('vnc-auth-sasl.c')) system_ss.add_all(when: [vnc, pixman], if_true: vnc_ss) -system_ss.add(when: vnc, if_false: files('vnc-stubs.c')) +system_ss.add(when: vnc, if_true: files('vnc-system.c'), if_false: files('= vnc-stubs.c')) =20 ui_modules =3D {} =20 --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496793; cv=none; d=zohomail.com; s=zohoarc; b=Vszc7TyrIinBCsGYB+cdvdnfMFM6/8d7qtsk3Y8m0pbidoaOHval+cx5qmUmYYTFXxbjfNAjmq3usUYwwqfd/f1zhdT9rEPsCX9gM6MR5FyLQGkld9n0MiIk1QPSUOzD3uaI8WiIRngkwn/mVjrOyoDL+hBxuvWqkEeli3c6Trg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496793; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Dw3WlezUpgW1Ac2LZpVgWB6GhjwurpwxGK8jST2SZXg=; b=k+xneYJ5giusofTUFyTMnVqW5Ay/itY45mwGz7Ubt2y6NAb2LuwYeTeLHh8ed0Vv2NJ1ZOZcNEqKXlkwSSzT02T7iuc6PQig7EUB7YNbcWidRpn0lybAiJ4l7QocRnwrkJTpTbvqgH2HEiYo2Um7AY7CAEFIhKfPV+/iqOSF4RE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496793344910.364953811885; Wed, 29 Apr 2026 14:06:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6Y-0007A7-4x; Wed, 29 Apr 2026 17:05:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5x-0006hn-Th for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5s-0003Wt-2F for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:21 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-629-0YUU2C5aNn-Tv3G7y5z3Zg-1; Wed, 29 Apr 2026 17:05:11 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DE08A18003FC; Wed, 29 Apr 2026 21:05:10 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E42E830001A1; Wed, 29 Apr 2026 21:05:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496713; 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=Dw3WlezUpgW1Ac2LZpVgWB6GhjwurpwxGK8jST2SZXg=; b=KVoXT9StYk6M03FM7ci+nx//zbE+Sh3tJzMZbGnxatHbz0UDET2heATolbOK8A5IbEeos3 3p4fEV5jYpf4Kp/8fiPAWDmDH+gRaQjcirja+dUBaH0axGRIkyQWXc7RNLtA28MvFf9eux KgGBqeC3hkFbRHdK5cTQ2uukI4Ztm8I= X-MC-Unique: 0YUU2C5aNn-Tv3G7y5z3Zg-1 X-Mimecast-MFC-AGG-ID: 0YUU2C5aNn-Tv3G7y5z3Zg_1777496711 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:53 +0400 Subject: [PATCH v3 20/26] ui/console: simplify registering display/console change listener MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-20-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=17792; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=bNajfHycqchmwU1i8YMXXyZVCFfcYK1+9bm/MFXideQ=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMjZNAvRxOxC6yxAwPOivKMhYd5TnOJKj+8 HDorjrmroKJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5fsVD/sFilojNecetEKlEqH/RWaHNj+19lNOnU63AGknjh7qeS20kWEbSuxwzyLKggYH8XmqZ1A FOT4sA0abGEjwfu7pIIFtxLbD0hF8shhkn33OSA86PdO9JnoJ567s0s+D9LYbTJF4hmHkitwkmz K9AUMCRuixuScbtMXBffkiFY7L+4LyS1iGClzloPQPBOIWvx+s8LY/QyL79+dM5QtJXqqxAlULe 7TroRM6/D1nATIzcNGMZkyWYPkcjgiS7u8IXYyYHEOFehq56kU12q7OVjnRbHSbpHvLHyN9ATds qi0snSentnWzI38eu+4NkzMafDo5IMxlAe+lHzunMM9b4v5y6RIArDBdMf2r0igIeTpZ31tNiuV arsYGYYwQGO2S8ND4jX1EG717/4MyaGXH4+TL5uqPVB3lhiVMjrTrsz76QixDGUNd78UHNRJ1Hc PcCqQMS9mMebQHjJxW6i1G9I94QkygULs4L9wd8fiPY4h75bKJ4mFZH9XvTKumVRgwTjuHjaGUT mnLVAEglovtthAyNQWXioA6+Kc0BNPLE8UPdeTNaj4rTN6g+jhJRrhLofsgdezcLKRqpimIOeKi otjCnYvtwPSOtAxdTGU3O4aYiUoBkfSN51/8w7h7w3ExPT80xmyJ0yDxL8Lfc3UxsFDP6TgxQ0a PGsqVocSuPFMsYw== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496795219158500 Introduce qemu_console_register_listener() which combines setting dcl->con, dcl->ops and calling register_displaychangelistener() into a single call. This removes repetitive boilerplate across all display backends and makes it harder to forget setting one of the fields. Also move the early-return check in unregister_displaychangelistener() before the trace call, so that unregistering a never-registered listener (e.g. on error paths) does not dereference a NULL ops pointer. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/ui/console.h | 6 ++++-- hw/display/qxl.c | 4 +--- ui/console.c | 11 ++++++++--- ui/curses.c | 9 +++------ ui/dbus-console.c | 6 ++---- ui/dbus-listener.c | 27 ++++++++------------------- ui/egl-headless.c | 4 +--- ui/gtk.c | 10 ++++------ ui/sdl2.c | 8 +++----- ui/spice-display.c | 8 +++----- ui/vnc.c | 11 ++++------- ui/cocoa.m | 13 ++++--------- 12 files changed, 45 insertions(+), 72 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 89fb4c1942a..69ac7b01b33 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -291,10 +291,12 @@ struct DisplayGLCtx { =20 DisplayState *init_displaystate(void); =20 -void register_displaychangelistener(DisplayChangeListener *dcl); +void qemu_console_register_listener(QemuConsole *con, + DisplayChangeListener *dcl, + const DisplayChangeListenerOps *ops); void update_displaychangelistener(DisplayChangeListener *dcl, uint64_t interval); -void unregister_displaychangelistener(DisplayChangeListener *dcl); +void qemu_console_unregister_listener(DisplayChangeListener *dcl); =20 bool dpy_ui_info_supported(const QemuConsole *con); const QemuUIInfo *dpy_get_ui_info(const QemuConsole *con); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 0a3c42c8ec2..4244ebe51d2 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2251,9 +2251,7 @@ static void qxl_realize_primary(PCIDevice *dev, Error= **errp) return; } =20 - qxl->ssd.dcl.ops =3D &display_listener_ops; - qxl->ssd.dcl.con =3D vga->con; - register_displaychangelistener(&qxl->ssd.dcl); + qemu_console_register_listener(vga->con, &qxl->ssd.dcl, &display_liste= ner_ops); } =20 static void qxl_realize_secondary(PCIDevice *dev, Error **errp) diff --git a/ui/console.c b/ui/console.c index b837ce1c9fc..4f3b4394268 100644 --- a/ui/console.c +++ b/ui/console.c @@ -572,10 +572,15 @@ dcl_set_graphic_cursor(DisplayChangeListener *dcl, Qe= muGraphicConsole *con) } } =20 -void register_displaychangelistener(DisplayChangeListener *dcl) +void qemu_console_register_listener(QemuConsole *con, + DisplayChangeListener *dcl, + const DisplayChangeListenerOps *ops) { assert(!dcl->ds); =20 + dcl->con =3D con; + dcl->ops =3D ops; + trace_displaychangelistener_register(dcl, dcl->ops->dpy_name); dcl->ds =3D get_alloc_displaystate(); QLIST_INSERT_HEAD(&dcl->ds->listeners, dcl, next); @@ -600,10 +605,10 @@ void update_displaychangelistener(DisplayChangeListen= er *dcl, } } =20 -void unregister_displaychangelistener(DisplayChangeListener *dcl) +void qemu_console_unregister_listener(DisplayChangeListener *dcl) { DisplayState *ds =3D dcl->ds; - trace_displaychangelistener_unregister(dcl, dcl->ops->dpy_name); + trace_displaychangelistener_unregister(dcl, dcl->ops ? dcl->ops->dpy_n= ame : NULL); if (!ds) { return; } diff --git a/ui/curses.c b/ui/curses.c index 96427aa6bb9..dbb5992981c 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -324,9 +324,8 @@ static void curses_refresh(DisplayChangeListener *dcl) if (con) { erase(); wnoutrefresh(stdscr); - unregister_displaychangelistener(dcl); - dcl->con =3D con; - register_displaychangelistener(dcl); + qemu_console_unregister_listener(dcl); + qemu_console_register_listener(con, dcl, dcl->= ops); =20 invalidate =3D 1; } @@ -805,9 +804,7 @@ static void curses_display_init(DisplayState *ds, Displ= ayOptions *opts) curses_winch_init(); =20 dcl =3D g_new0(DisplayChangeListener, 1); - dcl->con =3D qemu_console_lookup_default(); - dcl->ops =3D &dcl_ops; - register_displaychangelistener(dcl); + qemu_console_register_listener(qemu_console_lookup_default(), dcl, &dc= l_ops); =20 invalidate =3D 1; } diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 564f004bd86..23f547a673d 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -143,7 +143,6 @@ dbus_display_console_init(DBusDisplayConsole *object) DBusDisplayConsole *ddc =3D DBUS_DISPLAY_CONSOLE(object); =20 ddc->listeners =3D g_ptr_array_new_with_free_func(g_object_unref); - ddc->dcl.ops =3D &dbus_console_dcl_ops; } =20 static void @@ -151,7 +150,7 @@ dbus_display_console_dispose(GObject *object) { DBusDisplayConsole *ddc =3D DBUS_DISPLAY_CONSOLE(object); =20 - unregister_displaychangelistener(&ddc->dcl); + qemu_console_unregister_listener(&ddc->dcl); g_clear_object(&ddc->iface_touch); g_clear_object(&ddc->iface_mouse); g_clear_object(&ddc->iface_kbd); @@ -553,7 +552,6 @@ dbus_display_console_new(DBusDisplay *display, QemuCons= ole *con) "g-object-path", path, NULL); ddc->display =3D display; - ddc->dcl.con =3D con; /* handle errors, and skip non graphics? */ qemu_console_fill_device_address( con, device_addr, sizeof(device_addr), NULL); @@ -611,7 +609,7 @@ dbus_display_console_new(DBusDisplay *display, QemuCons= ole *con) slot->tracking_id =3D -1; } =20 - register_displaychangelistener(&ddc->dcl); + qemu_console_register_listener(con, &ddc->dcl, &dbus_console_dcl_ops); ddc->mouse_mode_notifier.notify =3D dbus_mouse_mode_change; qemu_add_mouse_mode_change_notifier(&ddc->mouse_mode_notifier); dbus_mouse_update_is_absolute(ddc); diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index e5ce92d1257..cc2c969686e 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -957,7 +957,7 @@ dbus_display_listener_dispose(GObject *object) { DBusDisplayListener *ddl =3D DBUS_DISPLAY_LISTENER(object); =20 - unregister_displaychangelistener(&ddl->dcl); + qemu_console_unregister_listener(&ddl->dcl); g_clear_object(&ddl->conn); g_clear_pointer(&ddl->bus_name, g_free); g_clear_object(&ddl->proxy); @@ -978,28 +978,12 @@ dbus_display_listener_dispose(GObject *object) G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object); } =20 -static void -dbus_display_listener_constructed(GObject *object) -{ - DBusDisplayListener *ddl =3D DBUS_DISPLAY_LISTENER(object); - - ddl->dcl.ops =3D &dbus_dcl_ops; -#ifdef CONFIG_OPENGL - if (display_opengl) { - ddl->dcl.ops =3D &dbus_gl_dcl_ops; - } -#endif - - G_OBJECT_CLASS(dbus_display_listener_parent_class)->constructed(object= ); -} - static void dbus_display_listener_class_init(DBusDisplayListenerClass *klass) { GObjectClass *object_class =3D G_OBJECT_CLASS(klass); =20 object_class->dispose =3D dbus_display_listener_dispose; - object_class->constructed =3D dbus_display_listener_constructed; } =20 static void @@ -1258,6 +1242,7 @@ dbus_display_listener_new(const char *bus_name, GDBusConnection *conn, DBusDisplayConsole *console) { + const DisplayChangeListenerOps *ops =3D &dbus_dcl_ops; DBusDisplayListener *ddl; QemuConsole *con; g_autoptr(GError) err =3D NULL; @@ -1290,8 +1275,12 @@ dbus_display_listener_new(const char *bus_name, =20 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); +#ifdef CONFIG_OPENGL + if (display_opengl) { + ops =3D &dbus_gl_dcl_ops; + } +#endif + qemu_console_register_listener(con, &ddl->dcl, ops); =20 return ddl; } diff --git a/ui/egl-headless.c b/ui/egl-headless.c index 352b30b43fb..4f046c975a9 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -229,13 +229,11 @@ static void egl_headless_init(DisplayState *ds, Displ= ayOptions *opts) } =20 edpy =3D g_new0(egl_dpy, 1); - edpy->dcl.con =3D con; - edpy->dcl.ops =3D &egl_ops; edpy->gls =3D qemu_gl_init_shader(); ctx =3D g_new0(DisplayGLCtx, 1); ctx->ops =3D &eglctx_ops; qemu_console_set_display_gl_ctx(con, ctx); - register_displaychangelistener(&edpy->dcl); + qemu_console_register_listener(con, &edpy->dcl, &egl_ops); } } =20 diff --git a/ui/gtk.c b/ui/gtk.c index ec95f0f294a..ef3707b3634 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -2251,6 +2251,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, QemuConsole *con, int idx, GSList *group, GtkWidget *view_menu) { + const DisplayChangeListenerOps *ops =3D &dcl_ops; bool zoom_to_fit =3D false; int i; =20 @@ -2275,7 +2276,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, vc->gfx.drawing_area =3D gtk_gl_area_new(); g_signal_connect(vc->gfx.drawing_area, "realize", G_CALLBACK(gl_area_realize), vc); - vc->gfx.dcl.ops =3D &dcl_gl_area_ops; + ops =3D &dcl_gl_area_ops; vc->gfx.dgc.ops =3D &gl_area_ctx_ops; } else { #ifdef CONFIG_X11 @@ -2290,7 +2291,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, #pragma GCC diagnostic ignored "-Wdeprecated-declarations" gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE); #pragma GCC diagnostic pop - vc->gfx.dcl.ops =3D &dcl_egl_ops; + ops =3D &dcl_egl_ops; vc->gfx.dgc.ops =3D &egl_ctx_ops; vc->gfx.has_dmabuf =3D qemu_egl_has_dmabuf(); #else @@ -2301,7 +2302,6 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, #endif { vc->gfx.drawing_area =3D gtk_drawing_area_new(); - vc->gfx.dcl.ops =3D &dcl_ops; } =20 =20 @@ -2325,12 +2325,10 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, V= irtualConsole *vc, vc->tab_item, gtk_label_new(vc->label)); =20 vc->gfx.kbd =3D qkbd_state_init(con); - vc->gfx.dcl.con =3D con; - if (display_opengl) { qemu_console_set_display_gl_ctx(con, &vc->gfx.dgc); } - register_displaychangelistener(&vc->gfx.dcl); + qemu_console_register_listener(con, &vc->gfx.dcl, ops); =20 gd_connect_vc_gfx_signals(vc); group =3D gd_vc_menu_init(s, vc, idx, group, view_menu); diff --git a/ui/sdl2.c b/ui/sdl2.c index 5dd612d9a6a..89516f95c41 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -934,6 +934,7 @@ static void sdl2_display_init(DisplayState *ds, Display= Options *o) sdl2_console =3D g_new0(struct sdl2_console, sdl2_num_outputs); for (i =3D 0; i < sdl2_num_outputs; i++) { QemuConsole *con =3D qemu_console_lookup_by_index(i); + const DisplayChangeListenerOps *ops =3D &dcl_2d_ops; assert(con !=3D NULL); if (!qemu_console_is_graphic(con) && qemu_console_get_index(con) !=3D 0) { @@ -943,13 +944,11 @@ static void sdl2_display_init(DisplayState *ds, Displ= ayOptions *o) sdl2_console[i].opts =3D 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; + ops =3D display_opengl ? &dcl_gl_ops : &dcl_2d_ops; #else sdl2_console[i].opengl =3D 0; - sdl2_console[i].dcl.ops =3D &dcl_2d_ops; #endif - sdl2_console[i].dcl.con =3D con; sdl2_console[i].kbd =3D qkbd_state_init(con); #ifdef CONFIG_OPENGL if (display_opengl) { @@ -957,8 +956,7 @@ static void sdl2_display_init(DisplayState *ds, Display= Options *o) sdl2_gl_console_init(&sdl2_console[i]); } #endif - register_displaychangelistener(&sdl2_console[i].dcl); - + qemu_console_register_listener(con, &sdl2_console[i].dcl, ops); #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11) if (SDL_GetWindowWMInfo(sdl2_console[i].real_window, &info)) { #if defined(SDL_VIDEO_DRIVER_WINDOWS) diff --git a/ui/spice-display.c b/ui/spice-display.c index 87cc193cdee..56d8140fad8 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -1387,13 +1387,13 @@ static void qemu_spice_display_init_one(QemuConsole= *con) SimpleSpiceDisplay *ssd =3D g_new0(SimpleSpiceDisplay, 1); Error *err =3D NULL; char device_address[256] =3D ""; + const DisplayChangeListenerOps *ops =3D &display_listener_ops; =20 qemu_spice_display_init_common(ssd); =20 - ssd->dcl.ops =3D &display_listener_ops; #ifdef HAVE_SPICE_GL if (spice_opengl) { - ssd->dcl.ops =3D &display_listener_gl_ops; + 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, @@ -1403,8 +1403,6 @@ static void qemu_spice_display_init_one(QemuConsole *= con) ssd->have_scanout =3D false; } #endif - ssd->dcl.con =3D con; - ssd->qxl.base.sif =3D &dpy_interface.base; qemu_spice_add_display_interface(&ssd->qxl, con); =20 @@ -1422,7 +1420,7 @@ static void qemu_spice_display_init_one(QemuConsole *= con) if (spice_opengl) { qemu_console_set_display_gl_ctx(con, &ssd->dgc); } - register_displaychangelistener(&ssd->dcl); + qemu_console_register_listener(con, &ssd->dcl, ops); } =20 void qemu_spice_display_init(void) diff --git a/ui/vnc.c b/ui/vnc.c index 154b07e2e4e..e8c8773a36e 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1860,10 +1860,9 @@ static void do_key_event(VncState *vs, int down, int= keycode, int sym) qkbd_state_modifier_get(vs->vd->kbd, QKBD_MOD_ALT)) { QemuConsole *con =3D qemu_console_lookup_by_index(qcode - Q_KE= Y_CODE_1); if (con) { - unregister_displaychangelistener(&vs->vd->dcl); + qemu_console_unregister_listener(&vs->vd->dcl); qkbd_state_switch_console(vs->vd->kbd, con); - vs->vd->dcl.con =3D con; - register_displaychangelistener(&vs->vd->dcl); + qemu_console_register_listener(con, &vs->vd->dcl, vs->vd->= dcl.ops); } return; } @@ -3434,7 +3433,6 @@ VncDisplay *vnc_display_new(const char *id, Error **e= rrp) vd =3D g_new0(VncDisplay, 1); qemu_mutex_init(&vd->mutex); vd->id =3D g_strdup(id); - vd->dcl.ops =3D &dcl_ops; =20 QTAILQ_INIT(&vd->clients); vd->expires =3D TIME_MAX; @@ -3524,7 +3522,7 @@ void vnc_display_free(VncDisplay *vd) } =20 vnc_stop_worker_thread(vd); - unregister_displaychangelistener(&vd->dcl); + qemu_console_unregister_listener(&vd->dcl); qkbd_state_free(vd->kbd); qemu_del_vm_change_state_handler(vd->vmstate_handler_entry); kbd_layout_free(vd->kbd_layout); @@ -4267,8 +4265,7 @@ static bool vnc_display_open(VncDisplay *vd, Error **= errp) con =3D qemu_console_lookup_default(); } =20 - vd->dcl.con =3D con; - register_displaychangelistener(&vd->dcl); + qemu_console_register_listener(con, &vd->dcl, &dcl_ops); vd->kbd =3D qkbd_state_init(vd->dcl.con); qkbd_state_set_delay(vd->kbd, key_delay_ms); =20 diff --git a/ui/cocoa.m b/ui/cocoa.m index 9093d1e408f..aaf82421589 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -93,9 +93,7 @@ static void cocoa_switch(DisplayChangeListener *dcl, .dpy_mouse_set =3D cocoa_mouse_set, .dpy_cursor_define =3D cocoa_cursor_define, }; -static DisplayChangeListener dcl =3D { - .ops =3D &dcl_ops, -}; +static DisplayChangeListener dcl; static QKbdState *kbd; static int cursor_hide =3D 1; static int left_command_key_enabled =3D 1; @@ -425,8 +423,7 @@ - (void) selectConsoleLocked:(unsigned int)index =20 unregister_displaychangelistener(&dcl); qkbd_state_switch_console(kbd, con); - dcl.con =3D con; - register_displaychangelistener(&dcl); + qemu_console_register_listener(con, &dcl, &dcl_ops); [self notifyMouseModeChange]; [self updateUIInfo]; } @@ -2145,11 +2142,9 @@ static void cocoa_display_init(DisplayState *ds, Dis= playOptions *opts) add_console_menu_entries(); addRemovableDevicesMenuItems(); =20 - dcl.con =3D qemu_console_lookup_default(); + qemu_console_register_listener(qemu_console_lookup_default(), + &dcl, &dcl_ops); kbd =3D qkbd_state_init(dcl.con); - - // register vga output callbacks - register_displaychangelistener(&dcl); qemu_add_mouse_mode_change_notifier(&mouse_mode_change_notifier); [cocoaView notifyMouseModeChange]; [cocoaView updateUIInfo]; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496815; cv=none; d=zohomail.com; s=zohoarc; b=L6jtLjMkfqtnXInJeOyNYuBzkhvQ/rrIQb87UQuY/YEKwx6/3kV49m6IiFAbRXrzctJADSbAjiI4Cvcvl9j1fCqq7e4OzFTNnsUFf2L5Sy1zaf5YTMM1bd52e6SKAiq+o+dTyQKVi4nbOXS+s334xbgdMn+OQDkihaQQgV+mO1M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496815; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=dkANc4a7F0AbJagAO11on/jJ58ayyrv4D4QifFMta6U=; b=cDLzx7xRvgdkl8n0zlvtmu7arGiiqBf7MlB6mO5ll4QDLLKlBahQUq9vthhocP80xcmUBq3iE+74friQOcvXXXaZDSeO1q0nm0NpvKq2UTIR3saMiKvhnd9Zfhux/y039cUJ6oEN1ZI0BqCXorE6/P2dBMFn+v3umvRXT5EyIoo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496815485506.5279702274671; Wed, 29 Apr 2026 14:06:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC7J-00005a-Pt; Wed, 29 Apr 2026 17:06:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5y-0006hp-PY for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:36 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC5w-0003Xn-1H for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:22 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-483-mU0yOftDNsCxlq7EAmKmGQ-1; Wed, 29 Apr 2026 17:05:17 -0400 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AA8F71800473 for ; Wed, 29 Apr 2026 21:05:16 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5EA03180045E; Wed, 29 Apr 2026 21:05:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496719; 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=dkANc4a7F0AbJagAO11on/jJ58ayyrv4D4QifFMta6U=; b=NM6dbV1klIGbCCw+lGm97uVnkhdzjfzXKFwECmWXPVgGn4y8M28vT7vNBJTvOcybr/910x LbcO+u23s9oP3CMq7fQKxh6a/lZUGlM4U0lPAa3FMCTA3UV/ZlX8YH2maqtp+CLXO2HKm9 9qxAcVR1Y1jaEqDYGmQv23Ag0ZN43mU= X-MC-Unique: mU0yOftDNsCxlq7EAmKmGQ-1 X-Mimecast-MFC-AGG-ID: mU0yOftDNsCxlq7EAmKmGQ_1777496716 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:54 +0400 Subject: [PATCH v3 21/26] ui/console: add doc comment for qemu_console_{un}register_listener() MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-21-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=1640; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=fEy64I3B0L4Z5NNPglXU9Wi7CSBCUHOGg1gEsE6KjEM=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMd06ThWKQRQf3Z3ZR3is+9cQdclY7IL2gJ wlMLS6hTlqJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5Xz0D/9Vo8vZiUKKvxxh3WfNZlJkSlGxZphNSP/QFyBUM9kXQNUvv9Mn03Ll0SybWXZeeYYHYp3 kbheX/b/xoh/6iVHK781T3vMheYJE6UaR5A40P+shUR8Xagi2+Ij4KmtmLEWJvIRA6E7QdZ9HPb fduPyH4H/P50uW63E6SOuSCbdsUZoTeL7jYDxQeT1p7aZ2+Qe0jYTgwGpkniCA1eSDRE6zpwjN5 yZt9ZtMWgZmOQPudwFBfIAKkan1sLRuNRfMoYJ0misMviTRnGBVYQk+GxjZPn02XtNDcD/MXUO8 D5puVmhdEiO7pzfc63YzT1bUqKMBKBJWypFMkV3j5cOb/3PjzAwmRizOGzq9ZYJMnqdNPU91ZU0 7CFpKYNsVmTttV4/pnM6jzIASSmKmr2hxIJqnTD/9d9N89TRIdb6t4hj46JPntPwJ82spklSnFS TXHcve2951gh1y8TXM7kgLrm+YHWI3QBFp3bgKswcoC8+L7pfrOTgyIOmMX1baYbRHaaza5HH8I cdyECnjWXIgFUTjNZ/E0rzQnLWh30A5xiXswa3+y3kgfU1xgSrp85MbJXXzDrIABBfUl6Mk6TjM U8UuLSHHUlgXNH96z0P3zJPGOkchzMPcl+6NJnZDxHFhxL9X4r9Lr95PYjL2VJRMDxIZt3wbxgD Xzt8NnPB9obh3AA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496816440154100 Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- ui/console.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ui/console.c b/ui/console.c index 4f3b4394268..22ca1c35db3 100644 --- a/ui/console.c +++ b/ui/console.c @@ -572,6 +572,17 @@ dcl_set_graphic_cursor(DisplayChangeListener *dcl, Qem= uGraphicConsole *con) } } =20 +/* + * qemu_console_register_listener: + * @con: the console to attach the listener to + * @dcl: the display change listener to register + * @ops: the listener operations (callbacks for display updates) + * + * Register a display change listener on a console. The listener + * must not already be registered (i.e. @dcl->ds must be NULL). + * This sets up the listener, adds it to the display state, triggers + * an initial display update, and setup the cursor. + */ void qemu_console_register_listener(QemuConsole *con, DisplayChangeListener *dcl, const DisplayChangeListenerOps *ops) @@ -605,6 +616,15 @@ void update_displaychangelistener(DisplayChangeListene= r *dcl, } } =20 +/* + * qemu_console_unregister_listener: + * @dcl: the display change listener to unregister + * + * Unregister a display change listener, removing it from the + * display state's listener list. If the listener is not currently + * registered (@dcl->ds is NULL), this is a no-op. After unregistering, + * the display refresh timer is recalculated. + */ void qemu_console_unregister_listener(DisplayChangeListener *dcl) { DisplayState *ds =3D dcl->ds; --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496819; cv=none; d=zohomail.com; s=zohoarc; b=UVtfX/89dstdx0rAOIjavGrOYGlFeqYOwi07tlPgq5Ku9lzOZtxoZmRvgQ/88g5oYB42RSeef67cH0iexPx1ZhQRYSlJAdKE9fwWRmc2DWXXbBcbCC6XpIn80ApWOdf5FThzA9/UEWVVDuYe8H4UN0oz/T2QxGk9YNxXz+Y21Oo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496819; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4CA7faW4kjpFUZ9K6Hu1qUZ2Eu2UZDvW9P4XCOL0kQs=; b=BbMLXxuggJah5UQrxMPVOpAikY2AAXdDwxVRVXzNB9QSZoMFrOysJ/+yEV9v2FE9k0BerlTrsfcM4BpazZFtpA340Z+s7Pw26wha3o4oIXKVygOtn1MhLqMpFiy/D+VpF1klCk3IWipeKXaJuTO9GeIYdFsDMf7DWlaSo6lxn0w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496819017839.3158059923921; Wed, 29 Apr 2026 14:06:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC7R-0000RB-M0; Wed, 29 Apr 2026 17:06:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6K-0006rG-A7 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6A-0003kI-Ns for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:41 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-221-KVMpxRbiO6ykuYucvbnS_w-1; Wed, 29 Apr 2026 17:05:25 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 80E2A1800367; Wed, 29 Apr 2026 21:05:24 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 365FE300019F; Wed, 29 Apr 2026 21:05:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496729; 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=4CA7faW4kjpFUZ9K6Hu1qUZ2Eu2UZDvW9P4XCOL0kQs=; b=RPLtp9kjsSRzHwrZ5rYR/RIu/t6iVqzjT5diZp8nA+xIoffOlupMAmtC2m3rdtCAICG+IA z3G0jRRZRuK2Tbc+2jxSUYhmyT1zqF9tGQARgMRckBo3en9C4zyeAsmONRsvHrR7ztn6mm 5hiUuHInMyl9wfHeChtBePX9ci+xyqM= X-MC-Unique: KVMpxRbiO6ykuYucvbnS_w-1 X-Mimecast-MFC-AGG-ID: KVMpxRbiO6ykuYucvbnS_w_1777496724 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:55 +0400 Subject: [PATCH v3 22/26] ui/console: rename public API to use consistent qemu_console_ prefix MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-22-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=111633; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=4O7Yqc0K57f0HMu1+fdt8Z88+jC6LR5dhu9AjWeD1I0=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMvov/cBftBPIQr0YgS6gSyY3HA3MQEs2Sv 9vLd9asHYSJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5f6OD/9c9FaBZ8LImvfMjeiPq0XO5lBLH5wMiSgRkS+XgsRlFgmCfdKvH7zWovDJIeRAPbB8ny0 x1kMxG8JxJtv9uNZGvY4YF4MU367XTTfVxFO+7HrgQOTikznvdqlotqC1B9hgHfixFtekghUa7M iN84g1lHRR82XDhtf8jB43nf3t+aG/oaj+bhScjLetVKja+pWTKoHGo+I2x+p7aULwZpFv4yJCC 8sqIdfSRruMPBCAeczvABqw+l03kDR8GrBdjdriK2foRfVx3HfP6yHyEl32yGgHOXCbjTXd4lOf YnDjY2rKgaNlpF191ScCNbs4AHKTjxHSmWtzBQhrBpC0Lg/gtlp4tCrXMDG8pwNxVfQhS2Tqmbp QLaqACzGhh9ZMd3g6R8qTWxO6m5bVTJWLgwYB2PpXNB5SyQY62+OHcUuvy6GBuztgipc8iB0GMm f/tMxmu7MxM3E8B4AmvO54iPmem97j9b0vs/rQgbWAAgZMn+dKRNBHzQwEGl0JAaqGBmztGgqw4 abk1ReoNQdvEdP9J2IvEaPTL1k5r6Pt6yKgREgwXvgfqPJ2wfHWe9gqYuX9QmREHpzpHFxYwsDm qQARq5GDpZdswOZC+i8DpF6Ng6JOeiOnUh1tyN7urV1p8NnjxF/729L8vWFSEjtCkOKSTVzhkGM 5qnpidL4EYYAmKA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496819307158500 Rename the display and graphic console public functions to follow a consistent qemu_console_ (or qemu_graphic_console_) naming convention. The previous API used a mix of prefixes: dpy_, graphic_hw_, graphic_console_, console_has_, and update_displaychangelistener(). Unify them under a common qemu_console_ namespace for better discoverability and consistency. The main renames are: - dpy_gfx_*() / dpy_text_*() / dpy_gl_*() =E2=86=92 qemu_console_*() - dpy_{get,set}_ui_info() =E2=86=92 qemu_console_{get,set}_ui_info() - graphic_hw_*() =E2=86=92 qemu_console_hw_*() - graphic_console_*() =E2=86=92 qemu_graphic_console_*() - console_has_gl() =E2=86=92 qemu_console_has_gl() - update_displaychangelistener() =E2=86=92 qemu_console_listener_set_refres= h() No functional changes. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/ui/console.h | 108 +++++++++++++++--------------- hw/arm/musicpal.c | 4 +- hw/display/artist.c | 4 +- hw/display/ati.c | 16 ++--- hw/display/bcm2835_fb.c | 5 +- hw/display/bochs-display.c | 14 ++-- hw/display/cg3.c | 6 +- hw/display/cirrus_vga.c | 8 +-- hw/display/cirrus_vga_isa.c | 2 +- hw/display/dm163.c | 6 +- hw/display/exynos4210_fimd.c | 4 +- hw/display/g364fb.c | 10 +-- hw/display/jazz_led.c | 8 +-- hw/display/macfb.c | 6 +- hw/display/next-fb.c | 4 +- hw/display/omap_lcdc.c | 4 +- hw/display/pl110.c | 4 +- hw/display/qxl-render.c | 12 ++-- hw/display/qxl.c | 14 ++-- hw/display/ramfb-standalone.c | 2 +- hw/display/ramfb.c | 4 +- hw/display/sm501.c | 6 +- hw/display/ssd0303.c | 4 +- hw/display/ssd0323.c | 5 +- hw/display/tcx.c | 16 ++--- hw/display/vga-isa.c | 2 +- hw/display/vga-mmio.c | 2 +- hw/display/vga-pci.c | 6 +- hw/display/vga.c | 40 ++++++----- hw/display/vhost-user-gpu.c | 22 +++--- hw/display/virtio-gpu-base.c | 2 +- hw/display/virtio-gpu-rutabaga.c | 10 +-- hw/display/virtio-gpu-udmabuf.c | 4 +- hw/display/virtio-gpu-virgl.c | 20 +++--- hw/display/virtio-gpu.c | 26 ++++---- hw/display/virtio-vga.c | 2 +- hw/display/vmware_vga.c | 12 ++-- hw/display/xenfb.c | 6 +- hw/display/xlnx_dp.c | 10 +-- hw/vfio/display.c | 32 ++++----- ui/console-vc.c | 12 ++-- ui/console.c | 140 +++++++++++++++++++----------------= ---- ui/curses.c | 8 +-- ui/dbus-console.c | 4 +- ui/dbus-listener.c | 10 +-- ui/egl-headless.c | 4 +- ui/gtk-egl.c | 6 +- ui/gtk-gl-area.c | 6 +- ui/gtk.c | 18 ++--- ui/sdl2-2d.c | 2 +- ui/sdl2-gl.c | 2 +- ui/sdl2.c | 6 +- ui/spice-display.c | 16 ++--- ui/vnc.c | 22 +++--- hw/display/apple-gfx.m | 16 ++--- ui/cocoa.m | 10 +-- 56 files changed, 372 insertions(+), 382 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 69ac7b01b33..cfa940d4c66 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -294,49 +294,49 @@ DisplayState *init_displaystate(void); void qemu_console_register_listener(QemuConsole *con, DisplayChangeListener *dcl, const DisplayChangeListenerOps *ops); -void update_displaychangelistener(DisplayChangeListener *dcl, - uint64_t interval); +void qemu_console_listener_set_refresh(DisplayChangeListener *dcl, + uint64_t interval); void qemu_console_unregister_listener(DisplayChangeListener *dcl); =20 -bool dpy_ui_info_supported(const QemuConsole *con); -const QemuUIInfo *dpy_get_ui_info(const QemuConsole *con); -int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info, bool delay); - -void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h); -void dpy_gfx_update_full(QemuConsole *con); -void dpy_gfx_replace_surface(QemuConsole *con, - DisplaySurface *surface); -void dpy_text_cursor(QemuConsole *con, int x, int y); -void dpy_text_update(QemuConsole *con, int x, int y, int w, int h); -void dpy_text_resize(QemuConsole *con, int w, int h); -void dpy_mouse_set(QemuConsole *con, int x, int y, bool on); -void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor); -bool dpy_gfx_check_format(QemuConsole *con, - pixman_format_code_t format); - -void dpy_gl_scanout_disable(QemuConsole *con); -void dpy_gl_scanout_texture(QemuConsole *con, - uint32_t backing_id, bool backing_y_0_top, - uint32_t backing_width, uint32_t backing_heigh= t, - uint32_t x, uint32_t y, uint32_t w, uint32_t h, - void *d3d_tex2d); -void dpy_gl_scanout_dmabuf(QemuConsole *con, - QemuDmaBuf *dmabuf); -void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, - bool have_hot, uint32_t hot_x, uint32_t hot_y); -void dpy_gl_cursor_position(QemuConsole *con, - uint32_t pos_x, uint32_t pos_y); -void dpy_gl_release_dmabuf(QemuConsole *con, - QemuDmaBuf *dmabuf); -void dpy_gl_update(QemuConsole *con, - uint32_t x, uint32_t y, uint32_t w, uint32_t h); - -QEMUGLContext dpy_gl_ctx_create(QemuConsole *con, - QEMUGLParams *params); -void dpy_gl_ctx_destroy(QemuConsole *con, QEMUGLContext ctx); -int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx); - -bool console_has_gl(QemuConsole *con); +bool qemu_console_ui_info_supported(const QemuConsole *con); +const QemuUIInfo *qemu_console_get_ui_info(const QemuConsole *con); +int qemu_console_set_ui_info(QemuConsole *con, QemuUIInfo *info, bool dela= y); + +void qemu_console_update(QemuConsole *con, int x, int y, int w, int h); +void qemu_console_update_full(QemuConsole *con); +void qemu_console_set_surface(QemuConsole *con, + DisplaySurface *surface); +void qemu_console_text_set_cursor(QemuConsole *con, int x, int y); +void qemu_console_text_update(QemuConsole *con, int x, int y, int w, int h= ); +void qemu_console_text_resize(QemuConsole *con, int w, int h); +void qemu_console_set_mouse(QemuConsole *con, int x, int y, bool on); +void qemu_console_set_cursor(QemuConsole *con, QEMUCursor *cursor); +bool qemu_console_check_format(QemuConsole *con, + pixman_format_code_t format); + +void qemu_console_gl_scanout_disable(QemuConsole *con); +void qemu_console_gl_scanout_texture(QemuConsole *con, + uint32_t backing_id, bool backing_y_0= _top, + uint32_t backing_width, uint32_t back= ing_height, + uint32_t x, uint32_t y, uint32_t w, u= int32_t h, + void *d3d_tex2d); +void qemu_console_gl_scanout_dmabuf(QemuConsole *con, + QemuDmaBuf *dmabuf); +void qemu_console_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, + bool have_hot, uint32_t hot_x, uint32_t= hot_y); +void qemu_console_gl_cursor_position(QemuConsole *con, + uint32_t pos_x, uint32_t pos_y); +void qemu_console_gl_release_dmabuf(QemuConsole *con, + QemuDmaBuf *dmabuf); +void qemu_console_gl_update(QemuConsole *con, + uint32_t x, uint32_t y, uint32_t w, uint32_t h= ); + +QEMUGLContext qemu_console_gl_ctx_create(QemuConsole *con, + QEMUGLParams *params); +void qemu_console_gl_ctx_destroy(QemuConsole *con, QEMUGLContext ctx); +int qemu_console_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx); + +bool qemu_console_has_gl(QemuConsole *con); =20 enum { GRAPHIC_FLAGS_NONE =3D 0, @@ -361,19 +361,19 @@ typedef struct GraphicHwOps { void (*gl_block)(void *opaque, bool block); } GraphicHwOps; =20 -QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, - const GraphicHwOps *ops, - void *opaque); -void graphic_console_set_hwops(QemuConsole *con, - const GraphicHwOps *hw_ops, - void *opaque); -void graphic_console_close(QemuConsole *con); - -void graphic_hw_update(QemuConsole *con); -void graphic_hw_update_done(QemuConsole *con); -void graphic_hw_invalidate(QemuConsole *con); -void graphic_hw_text_update(QemuConsole *con, uint32_t *chardata); -void graphic_hw_gl_block(QemuConsole *con, bool block); +QemuConsole *qemu_graphic_console_create(DeviceState *dev, uint32_t head, + const GraphicHwOps *ops, + void *opaque); +void qemu_graphic_console_set_hwops(QemuConsole *con, + const GraphicHwOps *hw_ops, + void *opaque); +void qemu_graphic_console_close(QemuConsole *con); + +void qemu_console_hw_update(QemuConsole *con); +void qemu_console_hw_update_done(QemuConsole *con); +void qemu_console_hw_invalidate(QemuConsole *con); +void qemu_console_hw_text_update(QemuConsole *con, uint32_t *chardata); +void qemu_console_hw_gl_block(QemuConsole *con, bool block); =20 void qemu_console_early_init(void); =20 diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index ba88ed756e2..83676eb7fea 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -170,7 +170,7 @@ static bool lcd_refresh(void *opaque) } } =20 - dpy_gfx_update(s->con, 0, 0, 128*3, 64*3); + qemu_console_update(s->con, 0, 0, 128*3, 64*3); return true; } =20 @@ -253,7 +253,7 @@ static const GraphicHwOps musicpal_gfx_ops =3D { static void musicpal_lcd_realize(DeviceState *dev, Error **errp) { musicpal_lcd_state *s =3D MUSICPAL_LCD(dev); - s->con =3D graphic_console_init(dev, 0, &musicpal_gfx_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &musicpal_gfx_ops, s); qemu_console_resize(s->con, 128 * 3, 64 * 3); } =20 diff --git a/hw/display/artist.c b/hw/display/artist.c index a07508378c7..288d466ec64 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -1324,7 +1324,7 @@ static bool artist_update_display(void *opaque) artist_draw_cursor(s); =20 if (first >=3D 0) { - dpy_gfx_update(s->con, 0, first, s->width, last - first + 1); + qemu_console_update(s->con, 0, first, s->width, last - first + 1); } =20 return true; @@ -1424,7 +1424,7 @@ static void artist_realizefn(DeviceState *dev, Error = **errp) s->misc_video |=3D 0x0A000000; s->misc_ctrl |=3D 0x00800000; =20 - s->con =3D graphic_console_init(dev, 0, &artist_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &artist_ops, s); qemu_console_resize(s->con, s->width, s->height); } =20 diff --git a/hw/display/ati.c b/hw/display/ati.c index 3a7d45a8820..d77589df67a 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -161,7 +161,7 @@ static void ati_cursor_define(ATIVGAState *s) } cursor_set_mono(s->cursor, s->regs.cur_color1, s->regs.cur_color0, (uint8_t *)&data[64], 1, (uint8_t *)&data[0]); - dpy_cursor_define(s->vga.con, s->cursor); + qemu_console_set_cursor(s->vga.con, s->cursor); } =20 /* Alternatively support guest rendered hardware cursor */ @@ -626,9 +626,9 @@ static void ati_mm_write(void *opaque, hwaddr addr, if (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) { ati_cursor_define(s); } - dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16, - s->regs.cur_hv_pos & 0xffff, - (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) !=3D = 0); + qemu_console_set_mouse(s->vga.con, s->regs.cur_hv_pos >> 1= 6, + s->regs.cur_hv_pos & 0xffff, + (s->regs.crtc_gen_cntl & CRTC2_CUR_= EN) !=3D 0); } } if ((val & (CRTC2_EXT_DISP_EN | CRTC2_EN)) !=3D @@ -780,8 +780,8 @@ static void ati_mm_write(void *opaque, hwaddr addr, } if (!s->cursor_guest_mode && (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(t & BIT(31))) { - dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16, - s->regs.cur_hv_pos & 0xffff, true); + qemu_console_set_mouse(s->vga.con, s->regs.cur_hv_pos >> 16, + s->regs.cur_hv_pos & 0xffff, true); } break; } @@ -1094,7 +1094,7 @@ static void ati_vga_realize(PCIDevice *dev, Error **e= rrp) } vga_init(vga, OBJECT(s), pci_address_space(dev), pci_address_space_io(dev), true); - vga->con =3D graphic_console_init(DEVICE(s), 0, s->vga.hw_ops, vga); + vga->con =3D qemu_graphic_console_create(DEVICE(s), 0, s->vga.hw_ops, = vga); if (s->cursor_guest_mode) { vga->cursor_invalidate =3D ati_cursor_invalidate; vga->cursor_draw_line =3D ati_cursor_draw_line; @@ -1167,7 +1167,7 @@ static void ati_vga_exit(PCIDevice *dev) ATIVGAState *s =3D ATI_VGA(dev); =20 timer_del(&s->vblank_timer); - graphic_console_close(s->vga.con); + qemu_graphic_console_close(s->vga.con); } =20 static const Property ati_vga_properties[] =3D { diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 83c4c03c7ca..bd58f625fcd 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -207,8 +207,7 @@ static bool fb_update_display(void *opaque) draw_line_src16, s, &first, &last); =20 if (first >=3D 0) { - dpy_gfx_update(s->con, 0, first, s->config.xres, - last - first + 1); + qemu_console_update(s->con, 0, first, s->config.xres, last - first= + 1); } =20 s->invalidate =3D false; @@ -427,7 +426,7 @@ static void bcm2835_fb_realize(DeviceState *dev, Error = **errp) =20 bcm2835_fb_reset(dev); =20 - s->con =3D graphic_console_init(dev, 0, &vgafb_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &vgafb_ops, s); qemu_console_resize(s->con, s->config.xres, s->config.yres); } =20 diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c index 8ef9b76cf85..64e669429c4 100644 --- a/hw/display/bochs-display.c +++ b/hw/display/bochs-display.c @@ -224,12 +224,12 @@ static bool bochs_display_update(void *opaque) mode.format, mode.stride, ptr + mode.offset); - dpy_gfx_replace_surface(s->con, ds); + qemu_console_set_surface(s->con, ds); full_update =3D true; } =20 if (full_update) { - dpy_gfx_update_full(s->con); + qemu_console_update_full(s->con); } else { snap =3D memory_region_snapshot_and_clear_dirty(&s->vram, mode.offset, mode.si= ze, @@ -243,14 +243,12 @@ static bool bochs_display_update(void *opaque) ys =3D y; } if (!dirty && ys >=3D 0) { - dpy_gfx_update(s->con, 0, ys, - mode.width, y - ys); + qemu_console_update(s->con, 0, ys, mode.width, y - ys); ys =3D -1; } } if (ys >=3D 0) { - dpy_gfx_update(s->con, 0, ys, - mode.width, y - ys); + qemu_console_update(s->con, 0, ys, mode.width, y - ys); } =20 g_free(snap); @@ -279,7 +277,7 @@ static void bochs_display_realize(PCIDevice *dev, Error= **errp) } s->vgamem =3D pow2ceil(s->vgamem); =20 - s->con =3D graphic_console_init(DEVICE(dev), 0, &bochs_display_gfx_ops= , s); + s->con =3D qemu_graphic_console_create(DEVICE(dev), 0, &bochs_display_= gfx_ops, s); =20 memory_region_init_ram(&s->vram, obj, "bochs-display-vram", s->vgamem, &error_fatal); @@ -344,7 +342,7 @@ static void bochs_display_exit(PCIDevice *dev) { BochsDisplayState *s =3D BOCHS_DISPLAY(dev); =20 - graphic_console_close(s->con); + qemu_graphic_console_close(s->con); } =20 static const Property bochs_display_properties[] =3D { diff --git a/hw/display/cg3.c b/hw/display/cg3.c index 963bb3427a6..f9dda1549dd 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -137,7 +137,7 @@ static bool cg3_update_display(void *opaque) } } else { if (y_start >=3D 0) { - dpy_gfx_update(s->con, 0, y_start, width, y - y_start); + qemu_console_update(s->con, 0, y_start, width, y - y_start= ); y_start =3D -1; } pix +=3D width; @@ -146,7 +146,7 @@ static bool cg3_update_display(void *opaque) } s->full_update =3D 0; if (y_start >=3D 0) { - dpy_gfx_update(s->con, 0, y_start, width, y - y_start); + qemu_console_update(s->con, 0, y_start, width, y - y_start); } /* vsync interrupt? */ if (s->regs[0] & CG3_CR_ENABLE_INTS) { @@ -311,7 +311,7 @@ static void cg3_realizefn(DeviceState *dev, Error **err= p) =20 sysbus_init_irq(sbd, &s->irq); =20 - s->con =3D graphic_console_init(dev, 0, &cg3_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &cg3_ops, s); qemu_console_resize(s->con, s->width, s->height); } =20 diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 48be3c8a932..0a8c74e1374 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -779,9 +779,9 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, i= nt src, int w, int h) s->cirrus_blt_width, s->cirrus_blt_height); =20 if (notify) { - dpy_gfx_update(s->vga.con, dx, dy, - s->cirrus_blt_width / depth, - s->cirrus_blt_height); + qemu_console_update(s->vga.con, dx, dy, + s->cirrus_blt_width / depth, + s->cirrus_blt_height); } =20 /* we don't have to notify the display that this portion has @@ -2964,7 +2964,7 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Er= ror **errp) } cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev= ), pci_address_space_io(dev)); - s->vga.con =3D graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, &s-= >vga); + s->vga.con =3D qemu_graphic_console_create(DEVICE(dev), 0, s->vga.hw_o= ps, &s->vga); =20 /* setup PCI */ memory_region_init(&s->pci_bar, OBJECT(dev), "cirrus-pci-bar0", 0x2000= 000); diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c index 76034a88605..b8052d1d8ed 100644 --- a/hw/display/cirrus_vga_isa.c +++ b/hw/display/cirrus_vga_isa.c @@ -62,7 +62,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Er= ror **errp) cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, isa_address_space(isadev), isa_address_space_io(isadev)); - s->con =3D graphic_console_init(dev, 0, s->hw_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, s->hw_ops, s); rom_add_vga(VGABIOS_CIRRUS_FILENAME); /* XXX ISA-LFB support */ /* FIXME not qdev yet */ diff --git a/hw/display/dm163.c b/hw/display/dm163.c index 9ea62cb4f76..afade0b98c3 100644 --- a/hw/display/dm163.c +++ b/hw/display/dm163.c @@ -277,8 +277,8 @@ static uint32_t *update_display_of_row(DM163State *s, u= int32_t *dest, } } =20 - dpy_gfx_update(s->console, 0, LED_SQUARE_SIZE * row, - RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE, LED_SQUARE_SIZE= ); + qemu_console_update(s->console, 0, LED_SQUARE_SIZE * row, + RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE, LED_SQUARE_= SIZE); s->redraw &=3D ~(1 << row); trace_dm163_redraw(s->redraw); =20 @@ -322,7 +322,7 @@ static void dm163_realize(DeviceState *dev, Error **err= p) qdev_init_gpio_in(dev, dm163_en_b_gpio_handler, 1); qdev_init_gpio_out_named(dev, &s->sout, "sout", 1); =20 - s->console =3D graphic_console_init(dev, 0, &dm163_ops, s); + s->console =3D qemu_graphic_console_create(dev, 0, &dm163_ops, s); qemu_console_resize(s->console, RGB_MATRIX_NUM_COLS * LED_SQUARE_SIZE, RGB_MATRIX_NUM_ROWS * LED_SQUARE_SIZE); } diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index a91f04aaf79..5133623ee2e 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -1340,7 +1340,7 @@ static bool exynos4210_fimd_update(void *opaque) fimd_copy_line_toqemu(global_width, s->ifb + global_width * li= ne * RGBA_SIZE, d + global_width * line * bpp); } - dpy_gfx_update_full(s->console); + qemu_console_update_full(s->console); } s->invalidate =3D false; s->vidintcon[1] |=3D FIMD_VIDINT_INTFRMPEND; @@ -1964,7 +1964,7 @@ static void exynos4210_fimd_realize(DeviceState *dev,= Error **errp) return; } =20 - s->console =3D graphic_console_init(dev, 0, &exynos4210_fimd_ops, s); + s->console =3D qemu_graphic_console_create(dev, 0, &exynos4210_fimd_op= s, s); } =20 static void exynos4210_fimd_class_init(ObjectClass *klass, const void *dat= a) diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index bd15f6f0acc..af54f1f9005 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -191,8 +191,8 @@ static void g364fb_draw_graphic8(G364State *s) } else { int dy; if (xmax || ymax) { - dpy_gfx_update(s->con, xmin, ymin, - xmax - xmin + 1, ymax - ymin + 1); + qemu_console_update(s->con, xmin, ymin, + xmax - xmin + 1, ymax - ymin + 1); xmin =3D s->width; xmax =3D 0; ymin =3D s->height; @@ -211,7 +211,7 @@ static void g364fb_draw_graphic8(G364State *s) =20 done: if (xmax || ymax) { - dpy_gfx_update(s->con, xmin, ymin, xmax - xmin + 1, ymax - ymin + = 1); + qemu_console_update(s->con, xmin, ymin, xmax - xmin + 1, ymax - ym= in + 1); } g_free(snap); } @@ -234,7 +234,7 @@ static void g364fb_draw_blank(G364State *s) d +=3D surface_stride(surface); } =20 - dpy_gfx_update_full(s->con); + qemu_console_update_full(s->con); s->blanked =3D 1; } =20 @@ -478,7 +478,7 @@ static const GraphicHwOps g364fb_ops =3D { =20 static void g364fb_init(DeviceState *dev, G364State *s) { - s->con =3D graphic_console_init(dev, 0, &g364fb_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &g364fb_ops, s); =20 memory_region_init_io(&s->mem_ctrl, OBJECT(dev), &g364fb_ctrl_ops, s, "ctrl", 0x180000); diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index ee9758a94b5..84fe1058406 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -217,7 +217,7 @@ static bool jazz_led_update_display(void *opaque) } =20 s->state =3D REDRAW_NONE; - dpy_gfx_update_full(s->con); + qemu_console_update_full(s->con); =20 return true; } @@ -233,7 +233,7 @@ static void jazz_led_text_update(void *opaque, uint32_t= *chardata) LedState *s =3D opaque; char buf[3]; =20 - dpy_text_cursor(s->con, -1, -1); + qemu_console_text_set_cursor(s->con, -1, -1); qemu_console_resize(s->con, 2, 1); =20 /* TODO: draw the segments */ @@ -243,7 +243,7 @@ static void jazz_led_text_update(void *opaque, uint32_t= *chardata) *chardata++ =3D ATTR2CHTYPE(buf[1], QEMU_COLOR_BLUE, QEMU_COLOR_BLACK, 1); =20 - dpy_text_update(s->con, 0, 0, 2, 1); + qemu_console_text_update(s->con, 0, 0, 2, 1); } =20 static int jazz_led_post_load(void *opaque, int version_id) @@ -284,7 +284,7 @@ static void jazz_led_realize(DeviceState *dev, Error **= errp) { LedState *s =3D JAZZ_LED(dev); =20 - s->con =3D graphic_console_init(dev, 0, &jazz_led_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &jazz_led_ops, s); } =20 static void jazz_led_reset(DeviceState *d) diff --git a/hw/display/macfb.c b/hw/display/macfb.c index 848c3c282bd..f40a7ed9f52 100644 --- a/hw/display/macfb.c +++ b/hw/display/macfb.c @@ -320,14 +320,14 @@ static void macfb_draw_graphic(MacfbState *s) } } else { if (ymin >=3D 0) { - dpy_gfx_update(s->con, 0, ymin, s->width, y - ymin); + qemu_console_update(s->con, 0, ymin, s->width, y - ymin); ymin =3D -1; } } } =20 if (ymin >=3D 0) { - dpy_gfx_update(s->con, 0, ymin, s->width, y - ymin); + qemu_console_update(s->con, 0, ymin, s->width, y - ymin); } =20 g_free(snap); @@ -671,7 +671,7 @@ static bool macfb_common_realize(DeviceState *dev, Macf= bState *s, Error **errp) s->regs[DAFB_MODE_CTRL1 >> 2] =3D s->mode->mode_ctrl1; s->regs[DAFB_MODE_CTRL2 >> 2] =3D s->mode->mode_ctrl2; =20 - s->con =3D graphic_console_init(dev, 0, &macfb_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &macfb_ops, s); surface =3D qemu_console_surface(s->con); =20 if (surface_bits_per_pixel(surface) !=3D 32) { diff --git a/hw/display/next-fb.c b/hw/display/next-fb.c index e758b223ef7..fa2e0d0da80 100644 --- a/hw/display/next-fb.c +++ b/hw/display/next-fb.c @@ -89,7 +89,7 @@ static bool nextfb_update(void *opaque) src_width, dest_width, 0, 1, nextfb_draw_li= ne, s, &first, &last); =20 - dpy_gfx_update(s->con, 0, 0, s->cols, s->rows); + qemu_console_update(s->con, 0, 0, s->cols, s->rows); =20 return true; } @@ -117,7 +117,7 @@ static void nextfb_realize(DeviceState *dev, Error **er= rp) s->cols =3D 1120; s->rows =3D 832; =20 - s->con =3D graphic_console_init(dev, 0, &nextfb_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &nextfb_ops, s); qemu_console_resize(s->con, s->cols, s->rows); } =20 diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c index 1e8385ebffb..2a8d5ffdd57 100644 --- a/hw/display/omap_lcdc.c +++ b/hw/display/omap_lcdc.c @@ -320,7 +320,7 @@ static bool omap_update_display(void *opaque) &first, &last); =20 if (first >=3D 0) { - dpy_gfx_update(omap_lcd->con, 0, first, width, last - first + 1); + qemu_console_update(omap_lcd->con, 0, first, width, last - first += 1); } omap_lcd->invalidate =3D 0; =20 @@ -504,7 +504,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *s= ysmem, memory_region_init_io(&s->iomem, NULL, &omap_lcdc_ops, s, "omap.lcdc",= 0x100); memory_region_add_subregion(sysmem, base, &s->iomem); =20 - s->con =3D graphic_console_init(NULL, 0, &omap_ops, s); + s->con =3D qemu_graphic_console_create(NULL, 0, &omap_ops, s); =20 return s; } diff --git a/hw/display/pl110.c b/hw/display/pl110.c index e134ac28eb6..4a93cf4cda9 100644 --- a/hw/display/pl110.c +++ b/hw/display/pl110.c @@ -303,7 +303,7 @@ static bool pl110_update_display(void *opaque) &first, &last); =20 if (first >=3D 0) { - dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1); + qemu_console_update(s->con, 0, first, s->cols, last - first + 1); } s->invalidate =3D 0; return true; @@ -557,7 +557,7 @@ static void pl110_realize(DeviceState *dev, Error **err= p) s->vblank_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, pl110_vblank_interrupt, s); qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1); - s->con =3D graphic_console_init(dev, 0, &pl110_gfx_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &pl110_gfx_ops, s); } =20 static void pl110_init(Object *obj) diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c index 5b4f8842011..7b692d5a854 100644 --- a/hw/display/qxl-render.c +++ b/hw/display/qxl-render.c @@ -135,7 +135,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevic= e *qxl) (width, height); } - dpy_gfx_replace_surface(vga->con, surface); + qemu_console_set_surface(vga->con, surface); } =20 if (!qxl->guest_primary.data) { @@ -154,16 +154,16 @@ static void qxl_render_update_area_unlocked(PCIQXLDev= ice *qxl) continue; } qxl_blit(qxl, qxl->dirty+i); - dpy_gfx_update(vga->con, - qxl->dirty[i].left, qxl->dirty[i].top, - qxl->dirty[i].right - qxl->dirty[i].left, - qxl->dirty[i].bottom - qxl->dirty[i].top); + qemu_console_update(vga->con, + qxl->dirty[i].left, qxl->dirty[i].top, + qxl->dirty[i].right - qxl->dirty[i].left, + qxl->dirty[i].bottom - qxl->dirty[i].top); } qxl->num_dirty_rects =3D 0; =20 end: if (qxl->render_update_cookie_num =3D=3D 0) { - graphic_hw_update_done(qxl->ssd.dcl.con); + qemu_console_hw_update_done(qxl->ssd.dcl.con); } } =20 diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 4244ebe51d2..74258afa582 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -1153,13 +1153,13 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d) } trace_qxl_enter_vga_mode(d->id); spice_qxl_driver_unload(&d->ssd.qxl); - graphic_console_set_hwops(d->ssd.dcl.con, d->vga.hw_ops, &d->vga); - update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_DEFAULT= ); + qemu_graphic_console_set_hwops(d->ssd.dcl.con, d->vga.hw_ops, &d->vga); + qemu_console_listener_set_refresh(&d->ssd.dcl, GUI_REFRESH_INTERVAL_DE= FAULT); qemu_spice_create_host_primary(&d->ssd); d->mode =3D QXL_MODE_VGA; qemu_spice_display_switch(&d->ssd, d->ssd.ds); vga_dirty_log_start(&d->vga); - graphic_hw_update(d->vga.con); + qemu_console_hw_update(d->vga.con); } =20 static void qxl_exit_vga_mode(PCIQXLDevice *d) @@ -1168,8 +1168,8 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d) return; } trace_qxl_exit_vga_mode(d->id); - graphic_console_set_hwops(d->ssd.dcl.con, &qxl_ops, d); - update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_IDLE); + qemu_graphic_console_set_hwops(d->ssd.dcl.con, &qxl_ops, d); + qemu_console_listener_set_refresh(&d->ssd.dcl, GUI_REFRESH_INTERVAL_ID= LE); vga_dirty_log_stop(&d->vga); qxl_destroy_primary(d, QXL_SYNC); } @@ -2237,7 +2237,7 @@ static void qxl_realize_primary(PCIDevice *dev, Error= **errp) portio_list_add(&qxl->vga_port_list, pci_address_space_io(dev), 0x3b0); qxl->have_vga =3D true; =20 - vga->con =3D graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl); + vga->con =3D qemu_graphic_console_create(DEVICE(dev), 0, &qxl_ops, qxl= ); qxl->id =3D qemu_console_get_index(vga->con); /* =3D=3D channel_id */ if (qxl->id !=3D 0) { error_setg(errp, "primary qxl-vga device must be console 0 " @@ -2262,7 +2262,7 @@ static void qxl_realize_secondary(PCIDevice *dev, Err= or **errp) memory_region_init_ram(&qxl->vga.vram, OBJECT(dev), "qxl.vgavram", qxl->vga.vram_size, &error_fatal); qxl->vga.vram_ptr =3D memory_region_get_ram_ptr(&qxl->vga.vram); - qxl->vga.con =3D graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl); + qxl->vga.con =3D qemu_graphic_console_create(DEVICE(dev), 0, &qxl_ops,= qxl); qxl->ssd.dcl.con =3D qxl->vga.con; qxl->id =3D qemu_console_get_index(qxl->vga.con); /* =3D=3D channel_id= */ =20 diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c index 27f0ba19f90..8e8ba37514a 100644 --- a/hw/display/ramfb-standalone.c +++ b/hw/display/ramfb-standalone.c @@ -41,7 +41,7 @@ static void ramfb_realizefn(DeviceState *dev, Error **err= p) { RAMFBStandaloneState *ramfb =3D RAMFB(dev); =20 - ramfb->con =3D graphic_console_init(dev, 0, &wrapper_ops, dev); + ramfb->con =3D qemu_graphic_console_create(dev, 0, &wrapper_ops, dev); ramfb->state =3D ramfb_setup(ramfb->use_legacy_x86_rom, errp); } =20 diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c index 50c25706a52..7a88f934e11 100644 --- a/hw/display/ramfb.c +++ b/hw/display/ramfb.c @@ -111,12 +111,12 @@ void ramfb_display_update(QemuConsole *con, RAMFBStat= e *s) } =20 if (s->ds) { - dpy_gfx_replace_surface(con, s->ds); + qemu_console_set_surface(con, s->ds); s->ds =3D NULL; } =20 /* simple full screen update */ - dpy_gfx_update_full(con); + qemu_console_update_full(con); } =20 static int ramfb_post_load(void *opaque, int version_id) diff --git a/hw/display/sm501.c b/hw/display/sm501.c index a3993ceba29..af870048372 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -1822,7 +1822,7 @@ static bool sm501_update_display(void *opaque) } else { if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(s->con, 0, y_start, width, y - y_start); + qemu_console_update(s->con, 0, y_start, width, y - y_start= ); y_start =3D -1; } } @@ -1831,7 +1831,7 @@ static bool sm501_update_display(void *opaque) =20 /* complete flush to display */ if (y_start >=3D 0) { - dpy_gfx_update(s->con, 0, y_start, width, y - y_start); + qemu_console_update(s->con, 0, y_start, width, y - y_start); } =20 return true; @@ -1936,7 +1936,7 @@ static void sm501_init(SM501State *s, DeviceState *de= v, &s->twoD_engine_region); =20 /* create qemu graphic console */ - s->con =3D graphic_console_init(dev, 0, &sm501_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &sm501_ops, s); } =20 static const VMStateDescription vmstate_sm501_state =3D { diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c index 229856cc427..4e3dede33f1 100644 --- a/hw/display/ssd0303.c +++ b/hw/display/ssd0303.c @@ -268,7 +268,7 @@ static bool ssd0303_update_display(void *opaque) } } s->redraw =3D 0; - dpy_gfx_update(s->con, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY); + qemu_console_update(s->con, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY); =20 return true; } @@ -309,7 +309,7 @@ static void ssd0303_realize(DeviceState *dev, Error **e= rrp) { ssd0303_state *s =3D SSD0303(dev); =20 - s->con =3D graphic_console_init(dev, 0, &ssd0303_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &ssd0303_ops, s); qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY); } =20 diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c index 67db16086c8..9309d4d10c4 100644 --- a/hw/display/ssd0323.c +++ b/hw/display/ssd0323.c @@ -270,7 +270,8 @@ static bool ssd0323_update_display(void *opaque) } } s->redraw =3D 0; - dpy_gfx_update(s->con, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY); + qemu_console_update(s->con, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY); + return true; } =20 @@ -356,7 +357,7 @@ static void ssd0323_realize(SSIPeripheral *d, Error **e= rrp) =20 s->col_end =3D 63; s->row_end =3D 79; - s->con =3D graphic_console_init(dev, 0, &ssd0323_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &ssd0323_ops, s); qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY); =20 qdev_init_gpio_in(dev, ssd0323_cd, 1); diff --git a/hw/display/tcx.c b/hw/display/tcx.c index cedbf5c7acd..2c33a9c4a32 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -243,8 +243,7 @@ static bool tcx_update_display(void *opaque) } else { if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(ts->con, 0, y_start, - ts->width, y - y_start); + qemu_console_update(ts->con, 0, y_start, ts->width, y - y_= start); y_start =3D -1; } } @@ -253,8 +252,7 @@ static bool tcx_update_display(void *opaque) } if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(ts->con, 0, y_start, - ts->width, y - y_start); + qemu_console_update(ts->con, 0, y_start, ts->width, y - y_start); } g_free(snap); return true; @@ -297,8 +295,7 @@ static bool tcx24_update_display(void *opaque) } else { if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(ts->con, 0, y_start, - ts->width, y - y_start); + qemu_console_update(ts->con, 0, y_start, ts->width, y - y_= start); y_start =3D -1; } } @@ -309,8 +306,7 @@ static bool tcx24_update_display(void *opaque) } if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(ts->con, 0, y_start, - ts->width, y - y_start); + qemu_console_update(ts->con, 0, y_start, ts->width, y - y_start); } g_free(snap); return true; @@ -864,9 +860,9 @@ static void tcx_realize(DeviceState *dev, Error **errp) sysbus_init_irq(sbd, &s->irq); =20 if (s->depth =3D=3D 8) { - s->con =3D graphic_console_init(dev, 0, &tcx_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &tcx_ops, s); } else { - s->con =3D graphic_console_init(dev, 0, &tcx24_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &tcx24_ops, s); } s->thcmisc =3D 0; =20 diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 5f55c884a1b..2cccb0ef12e 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -79,7 +79,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **e= rrp) 0x000a0000, vga_io_memory, 1); memory_region_set_coalescing(vga_io_memory); - s->con =3D graphic_console_init(dev, 0, s->hw_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, s->hw_ops, s); =20 memory_region_add_subregion(isa_address_space(isadev), VBE_DISPI_LFB_PHYSICAL_ADDRESS, diff --git a/hw/display/vga-mmio.c b/hw/display/vga-mmio.c index 1a9608d865f..3cd64951c09 100644 --- a/hw/display/vga-mmio.c +++ b/hw/display/vga-mmio.c @@ -108,7 +108,7 @@ static void vga_mmio_realizefn(DeviceState *dev, Error = **errp) } =20 sysbus_init_mmio(sbd, &s->vga.vram); - s->vga.con =3D graphic_console_init(dev, 0, s->vga.hw_ops, &s->vga); + s->vga.con =3D qemu_graphic_console_create(dev, 0, s->vga.hw_ops, &s->= vga); } =20 static const Property vga_mmio_properties[] =3D { diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 4e68dd57a17..d089847bdae 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -247,7 +247,7 @@ static void pci_std_vga_realize(PCIDevice *dev, Error *= *errp) vga_init(s, OBJECT(dev), pci_address_space(dev), pci_address_space_io(= dev), true); =20 - s->con =3D graphic_console_init(DEVICE(dev), 0, s->hw_ops, s); + s->con =3D qemu_graphic_console_create(DEVICE(dev), 0, s->hw_ops, s); =20 /* XXX: VGA_RAM_SIZE must be a power of two */ pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); @@ -282,7 +282,7 @@ static void pci_secondary_vga_realize(PCIDevice *dev, E= rror **errp) if (!vga_common_init(s, OBJECT(dev), errp)) { return; } - s->con =3D graphic_console_init(DEVICE(dev), 0, s->hw_ops, s); + s->con =3D qemu_graphic_console_create(DEVICE(dev), 0, s->hw_ops, s); =20 /* mmio bar */ memory_region_init_io(&d->mmio, OBJECT(dev), &unassigned_io_ops, NULL, @@ -306,7 +306,7 @@ static void pci_secondary_vga_exit(PCIDevice *dev) PCIVGAState *d =3D PCI_VGA(dev); VGACommonState *s =3D &d->vga; =20 - graphic_console_close(s->con); + qemu_graphic_console_close(s->con); memory_region_del_subregion(&d->mmio, &d->mrs[0]); memory_region_del_subregion(&d->mmio, &d->mrs[1]); if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) { diff --git a/hw/display/vga.c b/hw/display/vga.c index 2f266f47a39..0ac4bf37310 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1246,7 +1246,7 @@ static void vga_draw_text(VGACommonState *s, int full= _update) s->last_scr_height =3D height * cheight; qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height); surface =3D qemu_console_surface(s->con); - dpy_text_resize(s->con, width, height); + qemu_console_text_resize(s->con, width, height); s->last_depth =3D 0; s->last_width =3D width; s->last_height =3D height; @@ -1365,8 +1365,8 @@ static void vga_draw_text(VGACommonState *s, int full= _update) ch_attr_ptr++; } if (cx_max !=3D -1) { - dpy_gfx_update(s->con, cx_min * cw, cy * cheight, - (cx_max - cx_min + 1) * cw, cheight); + qemu_console_update(s->con, cx_min * cw, cy * cheight, + (cx_max - cx_min + 1) * cw, cheight); } dest +=3D linesize * cheight; line1 =3D line + cheight; @@ -1610,7 +1610,7 @@ static void vga_draw_graphic(VGACommonState *s, int f= ull_update) */ format =3D qemu_default_pixman_format(depth, !byteswap); if (format) { - allocate_surface =3D !dpy_gfx_check_format(s->con, format) + allocate_surface =3D !qemu_console_check_format(s->con, format) || s->force_shadow || force_shadow; } else { allocate_surface =3D true; @@ -1647,7 +1647,7 @@ static void vga_draw_graphic(VGACommonState *s, int f= ull_update) surface =3D qemu_create_displaysurface_from(disp_width, height, format, s->params.line_offset, s->vram_ptr + (s->params.start_addr * 4)); - dpy_gfx_replace_surface(s->con, surface); + qemu_console_set_surface(s->con, surface); } else { qemu_console_resize(s->con, disp_width, height); surface =3D qemu_console_surface(s->con); @@ -1720,8 +1720,7 @@ static void vga_draw_graphic(VGACommonState *s, int f= ull_update) } else { if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(s->con, 0, y_start, - disp_width, y - y_start); + qemu_console_update(s->con, 0, y_start, disp_width, y - y_= start); y_start =3D -1; } } @@ -1745,8 +1744,7 @@ static void vga_draw_graphic(VGACommonState *s, int f= ull_update) } if (y_start >=3D 0) { /* flush to display */ - dpy_gfx_update(s->con, 0, y_start, - disp_width, y - y_start); + qemu_console_update(s->con, 0, y_start, disp_width, y - y_start); } g_free(snap); memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table)); @@ -1767,7 +1765,7 @@ static void vga_draw_blank(VGACommonState *s, int ful= l_update) /* unshare buffer, otherwise the blanking corrupts vga vram */ surface =3D qemu_create_displaysurface(s->last_scr_width, s->last_scr_height); - dpy_gfx_replace_surface(s->con, surface); + qemu_console_set_surface(s->con, surface); } =20 w =3D s->last_scr_width * surface_bytes_per_pixel(surface); @@ -1776,7 +1774,7 @@ static void vga_draw_blank(VGACommonState *s, int ful= l_update) memset(d, 0, w); d +=3D surface_stride(surface); } - dpy_gfx_update_full(s->con); + qemu_console_update_full(s->con); } =20 #define GMODE_TEXT 0 @@ -1967,7 +1965,7 @@ static void vga_update_text(void *opaque, uint32_t *c= hardata) s->last_scr_width =3D width * cw; s->last_scr_height =3D height * cheight; qemu_console_resize(s->con, s->last_scr_width, s->last_scr_hei= ght); - dpy_text_resize(s->con, width, height); + qemu_console_text_resize(s->con, width, height); s->last_depth =3D 0; s->last_width =3D width; s->last_height =3D height; @@ -1992,11 +1990,11 @@ static void vga_update_text(void *opaque, uint32_t = *chardata) s->cr[VGA_CRTC_CURSOR_END] !=3D s->cursor_end || full_update) { cursor_visible =3D !(s->cr[VGA_CRTC_CURSOR_START] & 0x20); if (cursor_visible && cursor_offset < size && cursor_offset >= =3D 0) - dpy_text_cursor(s->con, - TEXTMODE_X(cursor_offset), - TEXTMODE_Y(cursor_offset)); + qemu_console_text_set_cursor(s->con, + TEXTMODE_X(cursor_offset), + TEXTMODE_Y(cursor_offset)); else - dpy_text_cursor(s->con, -1, -1); + qemu_console_text_set_cursor(s->con, -1, -1); s->cursor_offset =3D cursor_offset; s->cursor_start =3D s->cr[VGA_CRTC_CURSOR_START]; s->cursor_end =3D s->cr[VGA_CRTC_CURSOR_END]; @@ -2009,7 +2007,7 @@ static void vga_update_text(void *opaque, uint32_t *c= hardata) for (i =3D 0; i < size; src ++, dst ++, i ++) *dst =3D VMEM2CHTYPE(le32_to_cpu(*src)); =20 - dpy_text_update(s->con, 0, 0, width, height); + qemu_console_text_update(s->con, 0, 0, width, height); } else { c_max =3D 0; =20 @@ -2032,7 +2030,7 @@ static void vga_update_text(void *opaque, uint32_t *c= hardata) =20 if (c_min <=3D c_max) { i =3D TEXTMODE_Y(c_min); - dpy_text_update(s->con, 0, i, width, TEXTMODE_Y(c_max) - i= + 1); + qemu_console_text_update(s->con, 0, i, width, TEXTMODE_Y(c= _max) - i + 1); } } =20 @@ -2057,8 +2055,8 @@ static void vga_update_text(void *opaque, uint32_t *c= hardata) /* Display a message */ s->last_width =3D 60; s->last_height =3D height =3D 3; - dpy_text_cursor(s->con, -1, -1); - dpy_text_resize(s->con, s->last_width, height); + qemu_console_text_set_cursor(s->con, -1, -1); + qemu_console_text_resize(s->con, s->last_width, height); =20 for (dst =3D chardata, i =3D 0; i < s->last_width * height; i ++) *dst++ =3D ' '; @@ -2070,7 +2068,7 @@ static void vga_update_text(void *opaque, uint32_t *c= hardata) *dst++ =3D ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE, QEMU_COLOR_BLACK, 1); =20 - dpy_text_update(s->con, 0, 0, s->last_width, height); + qemu_console_text_update(s->con, 0, 0, s->last_width, height); } =20 static uint64_t vga_mem_read(void *opaque, hwaddr addr, diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 3f6fb7a8033..6e5e6540a46 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -142,11 +142,11 @@ vhost_user_gpu_handle_cursor(VhostUserGPU *g, VhostUs= erGpuMsg *msg) memcpy(s->current_cursor->data, up->data, 64 * 64 * sizeof(uint32_t)); =20 - dpy_cursor_define(s->con, s->current_cursor); + qemu_console_set_cursor(s->con, s->current_cursor); } =20 - dpy_mouse_set(s->con, pos->x, pos->y, - msg->request !=3D VHOST_USER_GPU_CURSOR_POS_HIDE); + qemu_console_set_mouse(s->con, pos->x, pos->y, + msg->request !=3D VHOST_USER_GPU_CURSOR_POS_HID= E); } =20 static void @@ -238,7 +238,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUse= rGpuMsg *msg) con =3D s->con; =20 if (m->width =3D=3D 0) { - dpy_gfx_replace_surface(con, NULL); + qemu_console_set_surface(con, NULL); } else { s->ds =3D qemu_create_displaysurface(m->width, m->height); /* replace surface on next update */ @@ -269,12 +269,12 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostU= serGpuMsg *msg) =20 if (dmabuf) { qemu_dmabuf_close(dmabuf); - dpy_gl_release_dmabuf(con, dmabuf); + qemu_console_gl_release_dmabuf(con, dmabuf); g_clear_pointer(&dmabuf, qemu_dmabuf_free); } =20 if (fd =3D=3D -1) { - dpy_gl_scanout_disable(con); + qemu_console_gl_scanout_disable(con); g->dmabuf[m->scanout_id] =3D NULL; break; } @@ -291,7 +291,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUse= rGpuMsg *msg) &fd, 1, false, m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP); =20 - dpy_gl_scanout_dmabuf(con, dmabuf); + qemu_console_gl_scanout_dmabuf(con, dmabuf); g->dmabuf[m->scanout_id] =3D dmabuf; break; } @@ -306,13 +306,13 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostU= serGpuMsg *msg) } =20 con =3D g->parent_obj.scanout[m->scanout_id].con; - if (!console_has_gl(con)) { + if (!qemu_console_has_gl(con)) { error_report("console doesn't support GL!"); vhost_user_gpu_unblock(g); break; } g->backend_blocked =3D true; - dpy_gl_update(con, m->x, m->y, m->width, m->height); + qemu_console_gl_update(con, m->x, m->y, m->width, m->height); break; } #ifdef CONFIG_PIXMAN @@ -337,9 +337,9 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUse= rGpuMsg *msg) =20 pixman_image_unref(image); if (qemu_console_surface(con) !=3D s->ds) { - dpy_gfx_replace_surface(con, s->ds); + qemu_console_set_surface(con, s->ds); } else { - dpy_gfx_update(con, m->x, m->y, m->width, m->height); + qemu_console_update(con, m->x, m->y, m->width, m->height); } break; } diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index bdc24492850..a68b1848295 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -253,7 +253,7 @@ virtio_gpu_base_device_realize(DeviceState *qdev, g->hw_ops =3D &virtio_gpu_ops; for (i =3D 0; i < g->conf.max_outputs; i++) { g->scanout[i].con =3D - graphic_console_init(DEVICE(g), i, &virtio_gpu_ops, g); + qemu_graphic_console_create(DEVICE(g), i, &virtio_gpu_ops, g); } =20 return true; diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutab= aga.c index ebb6c783fb0..6ff12639012 100644 --- a/hw/display/virtio-gpu-rutabaga.c +++ b/hw/display/virtio-gpu-rutabaga.c @@ -282,7 +282,7 @@ rutabaga_cmd_resource_flush(VirtIOGPU *g, struct virtio= _gpu_ctrl_command *cmd) rf.resource_id, &transfer, &transfer_iovec); CHECK(!result, cmd); - dpy_gfx_update_full(scanout->con); + qemu_console_update_full(scanout->con); } =20 static void @@ -306,8 +306,8 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct virtio_gp= u_ctrl_command *cmd) scanout =3D &vb->scanout[ss.scanout_id]; =20 if (ss.resource_id =3D=3D 0) { - dpy_gfx_replace_surface(scanout->con, NULL); - dpy_gl_scanout_disable(scanout->con); + qemu_console_set_surface(scanout->con, NULL); + qemu_console_gl_scanout_disable(scanout->con); return; } =20 @@ -331,8 +331,8 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct virtio_gp= u_ctrl_command *cmd) =20 /* realloc the surface ptr */ scanout->ds =3D qemu_create_displaysurface_pixman(res->image); - dpy_gfx_replace_surface(scanout->con, NULL); - dpy_gfx_replace_surface(scanout->con, scanout->ds); + qemu_console_set_surface(scanout->con, NULL); + qemu_console_set_surface(scanout->con, scanout->ds); res->scanout_bitmask =3D ss.scanout_id; } =20 diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabu= f.c index 74b6a7766af..d5ac1cfca0e 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -156,7 +156,7 @@ static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDM= ABuf *dmabuf) struct virtio_gpu_scanout *scanout; =20 scanout =3D &g->parent_obj.scanout[dmabuf->scanout_id]; - dpy_gl_release_dmabuf(scanout->con, dmabuf->buf); + qemu_console_gl_release_dmabuf(scanout->con, dmabuf->buf); g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next); g_free(dmabuf); @@ -232,7 +232,7 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g, height =3D qemu_dmabuf_get_height(new_primary->buf); g->dmabuf.primary[scanout_id] =3D new_primary; qemu_console_resize(scanout->con, width, height); - dpy_gl_scanout_dmabuf(scanout->con, new_primary->buf); + qemu_console_gl_scanout_dmabuf(scanout->con, new_primary->buf); =20 if (old_primary) { virtio_gpu_free_dmabuf(g, old_primary); diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c index add85bd4e61..60c78af06a4 100644 --- a/hw/display/virtio-gpu-virgl.c +++ b/hw/display/virtio-gpu-virgl.c @@ -521,7 +521,7 @@ static void virtio_gpu_rect_update(VirtIOGPU *g, int id= x, int x, int y, return; } =20 - dpy_gl_update(g->parent_obj.scanout[idx].con, x, y, width, height); + qemu_console_gl_update(g->parent_obj.scanout[idx].con, x, y, width, he= ight); } =20 static void virgl_cmd_resource_flush(VirtIOGPU *g, @@ -584,16 +584,15 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g, qemu_console_resize(g->parent_obj.scanout[ss.scanout_id].con, ss.r.width, ss.r.height); virgl_renderer_force_ctx_0(); - dpy_gl_scanout_texture( + qemu_console_gl_scanout_texture( g->parent_obj.scanout[ss.scanout_id].con, info.tex_id, 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, d3d_tex2d); } else { - dpy_gfx_replace_surface( - g->parent_obj.scanout[ss.scanout_id].con, NULL); - dpy_gl_scanout_disable(g->parent_obj.scanout[ss.scanout_id].con); + qemu_console_set_surface(g->parent_obj.scanout[ss.scanout_id].con,= NULL); + qemu_console_gl_scanout_disable(g->parent_obj.scanout[ss.scanout_i= d].con); } g->parent_obj.scanout[ss.scanout_id].resource_id =3D ss.resource_id; } @@ -1315,7 +1314,7 @@ virgl_create_context(void *opaque, int scanout_idx, qparams.major_ver =3D params->major_ver; qparams.minor_ver =3D params->minor_ver; =20 - ctx =3D dpy_gl_ctx_create(g->parent_obj.scanout[scanout_idx].con, &qpa= rams); + ctx =3D qemu_console_gl_ctx_create(g->parent_obj.scanout[scanout_idx].= con, &qparams); return (virgl_renderer_gl_context)ctx; } =20 @@ -1324,7 +1323,7 @@ static void virgl_destroy_context(void *opaque, virgl= _renderer_gl_context ctx) VirtIOGPU *g =3D opaque; QEMUGLContext qctx =3D (QEMUGLContext)ctx; =20 - dpy_gl_ctx_destroy(g->parent_obj.scanout[0].con, qctx); + qemu_console_gl_ctx_destroy(g->parent_obj.scanout[0].con, qctx); } =20 static int virgl_make_context_current(void *opaque, int scanout_idx, @@ -1333,8 +1332,7 @@ static int virgl_make_context_current(void *opaque, i= nt scanout_idx, VirtIOGPU *g =3D opaque; QEMUGLContext qctx =3D (QEMUGLContext)ctx; =20 - return dpy_gl_ctx_make_current(g->parent_obj.scanout[scanout_idx].con, - qctx); + return qemu_console_gl_ctx_make_current(g->parent_obj.scanout[scanout_= idx].con, qctx); } =20 static struct virgl_renderer_callbacks virtio_gpu_3d_cbs =3D { @@ -1399,8 +1397,8 @@ void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g) int i; =20 for (i =3D 0; i < g->parent_obj.conf.max_outputs; i++) { - dpy_gfx_replace_surface(g->parent_obj.scanout[i].con, NULL); - dpy_gl_scanout_disable(g->parent_obj.scanout[i].con); + qemu_console_set_surface(g->parent_obj.scanout[i].con, NULL); + qemu_console_gl_scanout_disable(g->parent_obj.scanout[i].con); } } =20 diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index dbb72bbb22d..88526051a99 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -103,14 +103,14 @@ static void update_cursor(VirtIOGPU *g, struct virtio= _gpu_update_cursor *cursor) if (cursor->resource_id > 0) { vgc->update_cursor_data(g, s, cursor->resource_id); } - dpy_cursor_define(s->con, s->current_cursor); + qemu_console_set_cursor(s->con, s->current_cursor); =20 s->cursor =3D *cursor; } else { s->cursor.pos.x =3D cursor->pos.x; s->cursor.pos.y =3D cursor->pos.y; } - dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y, cursor->resource_i= d); + qemu_console_set_mouse(s->con, cursor->pos.x, cursor->pos.y, cursor->r= esource_id); } =20 struct virtio_gpu_simple_resource * @@ -390,7 +390,7 @@ void virtio_gpu_disable_scanout(VirtIOGPU *g, int scano= ut_id) res->scanout_bitmask &=3D ~(1 << scanout_id); } =20 - dpy_gfx_replace_surface(scanout->con, NULL); + qemu_console_set_surface(scanout->con, NULL); scanout->resource_id =3D 0; scanout->ds =3D NULL; scanout->width =3D 0; @@ -531,8 +531,8 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g, rf.r.y + rf.r.height >=3D scanout->y) { within_bounds =3D true; =20 - if (console_has_gl(scanout->con)) { - dpy_gl_update(scanout->con, 0, 0, scanout->width, + if (qemu_console_has_gl(scanout->con)) { + qemu_console_gl_update(scanout->con, 0, 0, scanout->wi= dth, scanout->height); update_submitted =3D true; } @@ -582,8 +582,8 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g, /* work out the area we need to update for each console */ if (qemu_rect_intersect(&flush_rect, &rect, &rect)) { qemu_rect_translate(&rect, -scanout->x, -scanout->y); - dpy_gfx_update(g->parent_obj.scanout[i].con, - rect.x, rect.y, rect.width, rect.height); + qemu_console_update(g->parent_obj.scanout[i].con, + rect.x, rect.y, rect.width, rect.height); } } } @@ -649,7 +649,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, g->parent_obj.enable =3D 1; =20 if (res->blob) { - if (console_has_gl(scanout->con)) { + if (qemu_console_has_gl(scanout->con)) { if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) { virtio_gpu_update_scanout(g, scanout_id, res, fb, r); } else { @@ -665,7 +665,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, } =20 /* create a surface for this scanout */ - if ((res->blob && !console_has_gl(scanout->con)) || + if ((res->blob && !qemu_console_has_gl(scanout->con)) || !scanout->ds || surface_data(scanout->ds) !=3D data + fb->offset || scanout->width !=3D r->width || @@ -686,7 +686,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, qemu_displaysurface_set_share_handle(scanout->ds, res->share_handl= e, fb->offset); =20 pixman_image_unref(rect); - dpy_gfx_replace_surface(g->parent_obj.scanout[scanout_id].con, + qemu_console_set_surface(g->parent_obj.scanout[scanout_id].con, scanout->ds); } =20 @@ -1483,10 +1483,10 @@ static int virtio_gpu_post_load(void *opaque, int v= ersion_id) } scanout->ds =3D qemu_create_displaysurface_pixman(res->image); qemu_displaysurface_set_share_handle(scanout->ds, res->share_h= andle, 0); - dpy_gfx_replace_surface(scanout->con, scanout->ds); + qemu_console_set_surface(scanout->con, scanout->ds); } =20 - dpy_gfx_update_full(scanout->con); + qemu_console_update_full(scanout->con); if (scanout->cursor.resource_id) { update_cursor(g, &scanout->cursor); } @@ -1602,7 +1602,7 @@ static void virtio_gpu_reset_bh(void *opaque) } =20 for (i =3D 0; i < g->parent_obj.conf.max_outputs; i++) { - dpy_gfx_replace_surface(g->parent_obj.scanout[i].con, NULL); + qemu_console_set_surface(g->parent_obj.scanout[i].con, NULL); } =20 g->reset_finished =3D true; diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index efd4858f3d0..2ae649c91ae 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -172,7 +172,7 @@ static void virtio_vga_base_realize(VirtIOPCIProxy *vpc= i_dev, Error **errp) vvga->vga_mrs, true, false); =20 vga->con =3D g->scanout[0].con; - graphic_console_set_hwops(vga->con, &virtio_vga_base_ops, vvga); + qemu_graphic_console_set_hwops(vga->con, &virtio_vga_base_ops, vvga); =20 for (i =3D 0; i < g->conf.max_outputs; i++) { object_property_set_link(OBJECT(g->scanout[i].con), "device", diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 11f13c98d7a..f6f9edfd1d9 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -378,7 +378,7 @@ static inline void vmsvga_update_rect(struct vmsvga_sta= te_s *s, for (line =3D h; line > 0; line--, src +=3D bypl, dst +=3D bypl) { memcpy(dst, src, width); } - dpy_gfx_update(s->vga.con, x, y, w, h); + qemu_console_update(s->vga.con, x, y, w, h); } =20 static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s) @@ -554,7 +554,7 @@ static inline void vmsvga_cursor_define(struct vmsvga_s= tate_s *s, qc =3D cursor_builtin_left_ptr(); } =20 - dpy_cursor_define(s->vga.con, qc); + qemu_console_set_cursor(s->vga.con, qc); cursor_unref(qc); } #endif @@ -1082,7 +1082,7 @@ static void vmsvga_value_write(void *opaque, uint32_t= address, uint32_t value) s->cursor.on &=3D (value !=3D SVGA_CURSOR_ON_HIDE); #ifdef HW_MOUSE_ACCEL if (value <=3D SVGA_CURSOR_ON_SHOW) { - dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.= on); + qemu_console_set_mouse(s->vga.con, s->cursor.x, s->cursor.y, s= ->cursor.on); } #endif break; @@ -1130,7 +1130,7 @@ static inline void vmsvga_check_size(struct vmsvga_st= ate_s *s) surface =3D qemu_create_displaysurface_from(s->new_width, s->new_h= eight, format, stride, s->vga.vram_ptr); - dpy_gfx_replace_surface(s->vga.con, surface); + qemu_console_set_surface(s->vga.con, surface); s->invalidated =3D 1; } } @@ -1151,7 +1151,7 @@ static bool vmsvga_update_display(void *opaque) =20 if (s->invalidated) { s->invalidated =3D 0; - dpy_gfx_update_full(s->vga.con); + qemu_console_update_full(s->vga.con); } =20 return true; @@ -1254,7 +1254,7 @@ static void vmsvga_init(DeviceState *dev, struct vmsv= ga_state_s *s, s->scratch_size =3D SVGA_SCRATCH_SIZE; s->scratch =3D g_malloc(s->scratch_size * 4); =20 - s->vga.con =3D graphic_console_init(dev, 0, &vmsvga_ops, s); + s->vga.con =3D qemu_graphic_console_create(dev, 0, &vmsvga_ops, s); =20 s->fifo_size =3D SVGA_FIFO_SIZE; memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size, diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 2e431e27be6..8e9953bda43 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -657,7 +657,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x= , int y, int w, int h) xen_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp= ?\n", __func__, xenfb->depth, bpp); =20 - dpy_gfx_update(xenfb->con, x, y, w, h); + qemu_console_update(xenfb->con, x, y, w, h); } =20 #ifdef XENFB_TYPE_REFRESH_PERIOD @@ -743,7 +743,7 @@ static bool xenfb_update(void *opaque) surface =3D qemu_create_displaysurface(xenfb->width, xenfb->he= ight); break; } - dpy_gfx_replace_surface(xenfb->con, surface); + qemu_console_set_surface(xenfb->con, surface); xen_pv_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n", xenfb->width, xenfb->height, xenfb->depth, @@ -903,7 +903,7 @@ static int fb_initialise(struct XenLegacyDevice *xendev) if (rc !=3D 0) return rc; =20 - fb->con =3D graphic_console_init(NULL, 0, &xenfb_ops, fb); + fb->con =3D qemu_graphic_console_create(NULL, 0, &xenfb_ops, fb); =20 if (xenstore_read_fe_int(xendev, "feature-update", &fb->feature_update= ) =3D=3D -1) fb->feature_update =3D 0; diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 50e6ef10984..2486d9e5825 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -605,7 +605,7 @@ static void xlnx_dp_recreate_surface(XlnxDPState *s) =20 if ((width !=3D 0) && (height !=3D 0)) { /* - * As dpy_gfx_replace_surface calls qemu_free_displaysurface on the + * As qemu_console_replace_surface calls qemu_free_displaysurface = on the * surface we need to be careful and don't free the surface associ= ated * to the console or double free will happen. */ @@ -631,10 +631,10 @@ static void xlnx_dp_recreate_surface(XlnxDPState *s) height, s->g_plane.for= mat, 0, NULL); - dpy_gfx_replace_surface(s->console, s->bout_plane.surface); + qemu_console_set_surface(s->console, s->bout_plane.surface); } else { s->bout_plane.surface =3D NULL; - dpy_gfx_replace_surface(s->console, s->g_plane.surface); + qemu_console_set_surface(s->console, s->g_plane.surface); } =20 xlnx_dpdma_set_host_data_location(s->dpdma, DP_GRAPHIC_DMA_CHANNEL, @@ -1287,7 +1287,7 @@ static bool xlnx_dp_update_display(void *opaque) /* * XXX: We might want to update only what changed. */ - dpy_gfx_update_full(s->console); + qemu_console_update_full(s->console); =20 return true; } @@ -1387,7 +1387,7 @@ static void xlnx_dp_realize(DeviceState *dev, Error *= *errp) qdev_realize(DEVICE(s->edid), BUS(aux_get_i2c_bus(s->aux_bus)), &error_fatal); =20 - s->console =3D graphic_console_init(dev, 0, &xlnx_dp_gfx_ops, s); + s->console =3D qemu_graphic_console_create(dev, 0, &xlnx_dp_gfx_ops, s= ); surface =3D qemu_console_surface(s->console); xlnx_dpdma_set_host_data_location(s->dpdma, DP_GRAPHIC_DMA_CHANNEL, surface_data(surface)); diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 4a9a58036e3..8f91e83da88 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -264,7 +264,7 @@ static void vfio_display_free_one_dmabuf(VFIODisplay *d= py, VFIODMABuf *dmabuf) QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next); =20 qemu_dmabuf_close(dmabuf->buf); - dpy_gl_release_dmabuf(dpy->con, dmabuf->buf); + qemu_console_gl_release_dmabuf(dpy->con, dmabuf->buf); g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); g_free(dmabuf); } @@ -307,7 +307,7 @@ static bool vfio_display_dmabuf_update(void *opaque) if (dpy->dmabuf.primary !=3D primary) { dpy->dmabuf.primary =3D primary; qemu_console_resize(dpy->con, width, height); - dpy_gl_scanout_dmabuf(dpy->con, primary->buf); + qemu_console_gl_scanout_dmabuf(dpy->con, primary->buf); free_bufs =3D true; } =20 @@ -321,21 +321,21 @@ static bool vfio_display_dmabuf_update(void *opaque) if (cursor && (new_cursor || cursor->hot_updates)) { bool have_hot =3D (cursor->hot_x !=3D 0xffffffff && cursor->hot_y !=3D 0xffffffff); - dpy_gl_cursor_dmabuf(dpy->con, cursor->buf, have_hot, - cursor->hot_x, cursor->hot_y); + qemu_console_gl_cursor_dmabuf(dpy->con, cursor->buf, have_hot, + cursor->hot_x, cursor->hot_y); cursor->hot_updates =3D 0; } else if (!cursor && new_cursor) { - dpy_gl_cursor_dmabuf(dpy->con, NULL, false, 0, 0); + qemu_console_gl_cursor_dmabuf(dpy->con, NULL, false, 0, 0); } =20 if (cursor && cursor->pos_updates) { - dpy_gl_cursor_position(dpy->con, + qemu_console_gl_cursor_position(dpy->con, cursor->pos_x, cursor->pos_y); cursor->pos_updates =3D 0; } =20 - dpy_gl_update(dpy->con, 0, 0, width, height); + qemu_console_gl_update(dpy->con, 0, 0, width, height); =20 if (free_bufs) { vfio_display_free_dmabufs(vdev); @@ -363,7 +363,7 @@ static bool vfio_display_dmabuf_init(VFIOPCIDevice *vde= v, Error **errp) } =20 vdev->dpy =3D g_new0(VFIODisplay, 1); - vdev->dpy->con =3D graphic_console_init(DEVICE(vdev), 0, + vdev->dpy->con =3D qemu_graphic_console_create(DEVICE(vdev), 0, &vfio_display_dmabuf_ops, vdev); if (vdev->enable_ramfb) { @@ -396,9 +396,9 @@ void vfio_display_reset(VFIOPCIDevice *vdev) return; } =20 - dpy_gl_scanout_disable(vdev->dpy->con); + qemu_console_gl_scanout_disable(vdev->dpy->con); vfio_display_dmabuf_exit(vdev->dpy); - dpy_gfx_update_full(vdev->dpy->con); + qemu_console_update_full(vdev->dpy->con); } =20 static bool vfio_display_region_update(void *opaque) @@ -471,13 +471,13 @@ static bool vfio_display_region_update(void *opaque) dpy->region.surface =3D qemu_create_displaysurface_from (plane.width, plane.height, format, plane.stride, dpy->region.buffer.mmaps[0].mmap); - dpy_gfx_replace_surface(dpy->con, dpy->region.surface); + qemu_console_set_surface(dpy->con, dpy->region.surface); } =20 /* full screen update */ - dpy_gfx_update(dpy->con, 0, 0, - surface_width(dpy->region.surface), - surface_height(dpy->region.surface)); + qemu_console_update(dpy->con, 0, 0, + surface_width(dpy->region.surface), + surface_height(dpy->region.surface)); return true; =20 err: @@ -493,7 +493,7 @@ static const GraphicHwOps vfio_display_region_ops =3D { static bool vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp) { vdev->dpy =3D g_new0(VFIODisplay, 1); - vdev->dpy->con =3D graphic_console_init(DEVICE(vdev), 0, + vdev->dpy->con =3D qemu_graphic_console_create(DEVICE(vdev), 0, &vfio_display_region_ops, vdev); if (vdev->enable_ramfb) { @@ -553,7 +553,7 @@ void vfio_display_finalize(VFIOPCIDevice *vdev) return; } =20 - graphic_console_close(vdev->dpy->con); + qemu_graphic_console_close(vdev->dpy->con); vfio_display_dmabuf_exit(vdev->dpy); vfio_display_region_exit(vdev->dpy); vfio_display_edid_exit(vdev->dpy); diff --git a/ui/console-vc.c b/ui/console-vc.c index 99ad6d079df..828e78c41ea 100644 --- a/ui/console-vc.c +++ b/ui/console-vc.c @@ -90,15 +90,15 @@ static void text_console_update(void *opaque, uint32_t = *chardata) s->vt.cells[src].t_attrib.bgcol, s->vt.cells[src].t_attrib.bold); } - dpy_text_update(QEMU_CONSOLE(s), s->vt.text_x[0], s->vt.text_y[0], - s->vt.text_x[1] - s->vt.text_x[0], i - s->vt.text_= y[0]); + qemu_console_text_update(QEMU_CONSOLE(s), s->vt.text_x[0], s->vt.t= ext_y[0], + s->vt.text_x[1] - s->vt.text_x[0], i - s-= >vt.text_y[0]); s->vt.text_x[0] =3D s->vt.width; s->vt.text_y[0] =3D s->vt.height; s->vt.text_x[1] =3D 0; s->vt.text_y[1] =3D 0; } if (s->vt.cursor_invalidate) { - dpy_text_cursor(QEMU_CONSOLE(s), s->vt.x, s->vt.y); + qemu_console_text_set_cursor(QEMU_CONSOLE(s), s->vt.x, s->vt.y); s->vt.cursor_invalidate =3D 0; } } @@ -186,14 +186,14 @@ static void vc_chr_set_echo(Chardev *chr, bool echo) =20 void qemu_text_console_update_size(QemuTextConsole *c) { - dpy_text_resize(QEMU_CONSOLE(c), c->vt.width, c->vt.height); + qemu_console_text_resize(QEMU_CONSOLE(c), c->vt.width, c->vt.height); } =20 static void text_console_image_update(QemuVT100 *vt, int x, int y, int wid= th, int height) { QemuTextConsole *console =3D container_of(vt, QemuTextConsole, vt); =20 - dpy_gfx_update(QEMU_CONSOLE(console), x, y, width, height); + qemu_console_update(QEMU_CONSOLE(console), x, y, width, height); } =20 static void text_console_out_flush(QemuVT100 *vt) @@ -232,7 +232,7 @@ static bool vc_chr_open(Chardev *chr, ChardevBackend *b= ackend, Error **errp) s =3D QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_FIXED_TEXT_CONSOLE)); } =20 - dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(wi= dth, height)); + qemu_console_set_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(w= idth, height)); if (vc->has_encoding) { drv->encoding =3D vc->encoding; } diff --git a/ui/console.c b/ui/console.c index 22ca1c35db3..6f6330d61f1 100644 --- a/ui/console.c +++ b/ui/console.c @@ -129,26 +129,26 @@ static void gui_setup_refresh(DisplayState *ds) } } =20 -void graphic_hw_update_done(QemuConsole *con) +void qemu_console_hw_update_done(QemuConsole *con) { if (con) { qemu_co_enter_all(&con->dump_queue, NULL); } } =20 -void graphic_hw_update(QemuConsole *con) +void qemu_console_hw_update(QemuConsole *con) { if (!con) { return; } if (!con->hw_ops->gfx_update || con->hw_ops->gfx_update(con->hw)) { - graphic_hw_update_done(con); + qemu_console_hw_update_done(con); } } =20 -static void graphic_hw_update_bh(void *con) +static void console_hw_update_bh(void *con) { - graphic_hw_update(con); + qemu_console_hw_update(con); } =20 void qemu_console_co_wait_update(QemuConsole *con) @@ -156,18 +156,18 @@ void qemu_console_co_wait_update(QemuConsole *con) if (qemu_co_queue_empty(&con->dump_queue)) { /* Defer the update, it will restart the pending coroutines */ aio_bh_schedule_oneshot(qemu_get_aio_context(), - graphic_hw_update_bh, con); + console_hw_update_bh, con); } qemu_co_queue_wait(&con->dump_queue, NULL); =20 } =20 -static void graphic_hw_gl_unblock_timer(void *opaque) +static void console_hw_gl_unblock_timer(void *opaque) { warn_report("console: no gl-unblock within one second"); } =20 -void graphic_hw_gl_block(QemuConsole *con, bool block) +void qemu_console_hw_gl_block(QemuConsole *con, bool block) { uint64_t timeout; assert(con !=3D NULL); @@ -205,14 +205,14 @@ void qemu_console_set_window_id(QemuConsole *con, int= window_id) con->window_id =3D window_id; } =20 -void graphic_hw_invalidate(QemuConsole *con) +void qemu_console_hw_invalidate(QemuConsole *con) { if (con && con->hw_ops->invalidate) { con->hw_ops->invalidate(con->hw); } } =20 -void graphic_hw_text_update(QemuConsole *con, uint32_t *chardata) +void qemu_console_hw_text_update(QemuConsole *con, uint32_t *chardata) { if (con && con->hw_ops->text_update) { con->hw_ops->text_update(con->hw, chardata); @@ -502,7 +502,7 @@ qemu_graphic_console_init(Object *obj) { } =20 -bool console_has_gl(QemuConsole *con) +bool qemu_console_has_gl(QemuConsole *con) { return con->gl !=3D NULL; } @@ -527,7 +527,7 @@ static bool console_compatible_with(QemuConsole *con, =20 flags =3D con->hw_ops->get_flags ? con->hw_ops->get_flags(con->hw) : 0; =20 - if (console_has_gl(con) && + if (qemu_console_has_gl(con) && !con->gl->ops->dpy_gl_ctx_is_compatible_dcl(con->gl, dcl)) { error_setg(errp, "Display %s is incompatible with the GL context", dcl->ops->dpy_name); @@ -535,7 +535,7 @@ static bool console_compatible_with(QemuConsole *con, } =20 if (flags & GRAPHIC_FLAGS_GL && - !console_has_gl(con)) { + !qemu_console_has_gl(con)) { error_setg(errp, "The console requires a GL context."); return false; =20 @@ -605,8 +605,8 @@ void qemu_console_register_listener(QemuConsole *con, vt100_update_cursor(); } =20 -void update_displaychangelistener(DisplayChangeListener *dcl, - uint64_t interval) +void qemu_console_listener_set_refresh(DisplayChangeListener *dcl, + uint64_t interval) { DisplayState *ds =3D dcl->ds; =20 @@ -645,7 +645,7 @@ static void dpy_set_ui_info_timer(void *opaque) con->hw_ops->ui_info(con->hw, head, &con->ui_info); } =20 -bool dpy_ui_info_supported(const QemuConsole *con) +bool qemu_console_ui_info_supported(const QemuConsole *con) { if (con =3D=3D NULL) { return false; @@ -654,16 +654,16 @@ bool dpy_ui_info_supported(const QemuConsole *con) return con->hw_ops->ui_info !=3D NULL; } =20 -const QemuUIInfo *dpy_get_ui_info(const QemuConsole *con) +const QemuUIInfo *qemu_console_get_ui_info(const QemuConsole *con) { - assert(dpy_ui_info_supported(con)); + assert(qemu_console_ui_info_supported(con)); =20 return &con->ui_info; } =20 -int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info, bool delay) +int qemu_console_set_ui_info(QemuConsole *con, QemuUIInfo *info, bool dela= y) { - if (!dpy_ui_info_supported(con)) { + if (!qemu_console_ui_info_supported(con)) { return -1; } if (memcmp(&con->ui_info, info, sizeof(con->ui_info)) =3D=3D 0) { @@ -682,7 +682,7 @@ int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info,= bool delay) return 0; } =20 -void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h) +void qemu_console_update(QemuConsole *con, int x, int y, int w, int h) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -707,15 +707,15 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, i= nt w, int h) } } =20 -void dpy_gfx_update_full(QemuConsole *con) +void qemu_console_update_full(QemuConsole *con) { int w =3D qemu_console_get_width(con, 0); int h =3D qemu_console_get_height(con, 0); =20 - dpy_gfx_update(con, 0, 0, w, h); + qemu_console_update(con, 0, 0, w, h); } =20 -void dpy_gfx_replace_surface(QemuConsole *con, +void qemu_console_set_surface(QemuConsole *con, DisplaySurface *surface) { static const char placeholder_msg[] =3D "Display output is not active.= "; @@ -753,8 +753,8 @@ void dpy_gfx_replace_surface(QemuConsole *con, qemu_free_displaysurface(old_surface); } =20 -bool dpy_gfx_check_format(QemuConsole *con, - pixman_format_code_t format) +bool qemu_console_check_format(QemuConsole *con, + pixman_format_code_t format) { DisplayChangeListener *dcl; DisplayState *s =3D con->ds; @@ -789,7 +789,7 @@ static void dpy_refresh(DisplayState *s) } } =20 -void dpy_text_cursor(QemuConsole *con, int x, int y) +void qemu_console_text_set_cursor(QemuConsole *con, int x, int y) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -804,7 +804,7 @@ void dpy_text_cursor(QemuConsole *con, int x, int y) } } =20 -void dpy_text_update(QemuConsole *con, int x, int y, int w, int h) +void qemu_console_text_update(QemuConsole *con, int x, int y, int w, int h) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -819,7 +819,7 @@ void dpy_text_update(QemuConsole *con, int x, int y, in= t w, int h) } } =20 -void dpy_text_resize(QemuConsole *con, int w, int h) +void qemu_console_text_resize(QemuConsole *con, int w, int h) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -834,7 +834,7 @@ void dpy_text_resize(QemuConsole *con, int w, int h) } } =20 -void dpy_mouse_set(QemuConsole *c, int x, int y, bool on) +void qemu_console_set_mouse(QemuConsole *c, int x, int y, bool on) { QemuGraphicConsole *con =3D QEMU_GRAPHIC_CONSOLE(c); DisplayState *s =3D c->ds; @@ -853,7 +853,7 @@ void dpy_mouse_set(QemuConsole *c, int x, int y, bool o= n) } } =20 -void dpy_cursor_define(QemuConsole *c, QEMUCursor *cursor) +void qemu_console_set_cursor(QemuConsole *c, QEMUCursor *cursor) { QemuGraphicConsole *con =3D QEMU_GRAPHIC_CONSOLE(c); DisplayState *s =3D c->ds; @@ -871,26 +871,26 @@ void dpy_cursor_define(QemuConsole *c, QEMUCursor *cu= rsor) } } =20 -QEMUGLContext dpy_gl_ctx_create(QemuConsole *con, - struct QEMUGLParams *qparams) +QEMUGLContext qemu_console_gl_ctx_create(QemuConsole *con, + QEMUGLParams *qparams) { assert(con->gl); return con->gl->ops->dpy_gl_ctx_create(con->gl, qparams); } =20 -void dpy_gl_ctx_destroy(QemuConsole *con, QEMUGLContext ctx) +void qemu_console_gl_ctx_destroy(QemuConsole *con, QEMUGLContext ctx) { assert(con->gl); con->gl->ops->dpy_gl_ctx_destroy(con->gl, ctx); } =20 -int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx) +int qemu_console_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx) { assert(con->gl); return con->gl->ops->dpy_gl_ctx_make_current(con->gl, ctx); } =20 -void dpy_gl_scanout_disable(QemuConsole *con) +void qemu_console_gl_scanout_disable(QemuConsole *con) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -908,14 +908,14 @@ void dpy_gl_scanout_disable(QemuConsole *con) } } =20 -void dpy_gl_scanout_texture(QemuConsole *con, - 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, - void *d3d_tex2d) +void qemu_console_gl_scanout_texture(QemuConsole *con, + 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, + void *d3d_tex2d) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -939,8 +939,8 @@ void dpy_gl_scanout_texture(QemuConsole *con, } } =20 -void dpy_gl_scanout_dmabuf(QemuConsole *con, - QemuDmaBuf *dmabuf) +void qemu_console_gl_scanout_dmabuf(QemuConsole *con, + QemuDmaBuf *dmabuf) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -957,8 +957,8 @@ void dpy_gl_scanout_dmabuf(QemuConsole *con, } } =20 -void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, - bool have_hot, uint32_t hot_x, uint32_t hot_y) +void qemu_console_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf *dmabuf, + bool have_hot, uint32_t hot_x, uint32_t= hot_y) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -974,8 +974,8 @@ void dpy_gl_cursor_dmabuf(QemuConsole *con, QemuDmaBuf = *dmabuf, } } =20 -void dpy_gl_cursor_position(QemuConsole *con, - uint32_t pos_x, uint32_t pos_y) +void qemu_console_gl_cursor_position(QemuConsole *con, + uint32_t pos_x, uint32_t pos_y) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -990,8 +990,8 @@ void dpy_gl_cursor_position(QemuConsole *con, } } =20 -void dpy_gl_release_dmabuf(QemuConsole *con, - QemuDmaBuf *dmabuf) +void qemu_console_gl_release_dmabuf(QemuConsole *con, + QemuDmaBuf *dmabuf) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; @@ -1006,15 +1006,15 @@ void dpy_gl_release_dmabuf(QemuConsole *con, } } =20 -void dpy_gl_update(QemuConsole *con, - uint32_t x, uint32_t y, uint32_t w, uint32_t h) +void qemu_console_gl_update(QemuConsole *con, + uint32_t x, uint32_t y, uint32_t w, uint32_t h) { DisplayState *s =3D con->ds; DisplayChangeListener *dcl; =20 assert(con->gl); =20 - graphic_hw_gl_block(con, true); + qemu_console_hw_gl_block(con, true); QLIST_FOREACH(dcl, &s->listeners, next) { if (con !=3D dcl->con) { continue; @@ -1023,7 +1023,7 @@ void dpy_gl_update(QemuConsole *con, dcl->ops->dpy_gl_update(dcl, x, y, w, h); } } - graphic_hw_gl_block(con, false); + qemu_console_hw_gl_block(con, false); } =20 /***********************************************************/ @@ -1060,17 +1060,17 @@ DisplayState *init_displaystate(void) return display_state; } =20 -void graphic_console_set_hwops(QemuConsole *con, - const GraphicHwOps *hw_ops, - void *opaque) +void qemu_graphic_console_set_hwops(QemuConsole *con, + const GraphicHwOps *hw_ops, + void *opaque) { con->hw_ops =3D hw_ops; con->hw =3D opaque; } =20 -QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head, - const GraphicHwOps *hw_ops, - void *opaque) +QemuConsole *qemu_graphic_console_create(DeviceState *dev, uint32_t head, + const GraphicHwOps *hw_ops, + void *opaque) { static const char noinit[] =3D "Guest has not initialized the display (yet)."; @@ -1089,16 +1089,16 @@ QemuConsole *graphic_console_init(DeviceState *dev,= uint32_t head, s =3D (QemuConsole *)object_new(TYPE_QEMU_GRAPHIC_CONSOLE); } QEMU_GRAPHIC_CONSOLE(s)->head =3D head; - graphic_console_set_hwops(s, hw_ops, opaque); + qemu_graphic_console_set_hwops(s, hw_ops, opaque); if (dev) { object_property_set_link(OBJECT(s), "device", OBJECT(dev), &error_abort); } =20 surface =3D qemu_create_placeholder_surface(width, height, noinit); - dpy_gfx_replace_surface(s, surface); + qemu_console_set_surface(s, surface); s->gl_unblock_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, - graphic_hw_gl_unblock_timer, s); + console_hw_gl_unblock_timer, s); return s; } =20 @@ -1106,7 +1106,7 @@ static const GraphicHwOps unused_ops =3D { /* no callbacks */ }; =20 -void graphic_console_close(QemuConsole *con) +void qemu_graphic_console_close(QemuConsole *con) { static const char unplugged[] =3D "Guest display has been unplugged"; @@ -1116,13 +1116,13 @@ void graphic_console_close(QemuConsole *con) =20 trace_console_gfx_close(con->index); object_property_set_link(OBJECT(con), "device", NULL, &error_abort); - graphic_console_set_hwops(con, &unused_ops, NULL); + qemu_graphic_console_set_hwops(con, &unused_ops, NULL); =20 if (con->gl) { - dpy_gl_scanout_disable(con); + qemu_console_gl_scanout_disable(con); } surface =3D qemu_create_placeholder_surface(width, height, unplugged); - dpy_gfx_replace_surface(con, surface); + qemu_console_set_surface(con, surface); } =20 QemuConsole *qemu_console_lookup_default(void) @@ -1308,7 +1308,7 @@ void qemu_console_resize(QemuConsole *s, int width, i= nt height) } =20 surface =3D qemu_create_displaysurface(width, height); - dpy_gfx_replace_surface(s, surface); + qemu_console_set_surface(s, surface); } =20 DisplaySurface *qemu_console_surface(QemuConsole *console) diff --git a/ui/curses.c b/ui/curses.c index dbb5992981c..24d3713e57d 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -1,8 +1,8 @@ /* * QEMU curses/ncurses display driver - *=20 + * * Copyright (c) 2005 Andrzej Zaborowski - *=20 + * * 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 @@ -275,11 +275,11 @@ static void curses_refresh(DisplayChangeListener *dcl) clear(); refresh(); curses_calc_pad(); - graphic_hw_invalidate(dcl->con); + qemu_console_hw_invalidate(dcl->con); invalidate =3D 0; } =20 - graphic_hw_text_update(dcl->con, screen); + qemu_console_hw_text_update(dcl->con, screen); =20 while (1) { /* while there are any pending key strokes to process */ diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 23f547a673d..b8e5c57b148 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -200,7 +200,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc, .height =3D arg_height, }; =20 - if (!dpy_ui_info_supported(ddc->dcl.con)) { + if (!qemu_console_ui_info_supported(ddc->dcl.con)) { g_dbus_method_invocation_return_error(invocation, DBUS_DISPLAY_ERROR, DBUS_DISPLAY_ERROR_UNSUPPORT= ED, @@ -208,7 +208,7 @@ dbus_console_set_ui_info(DBusDisplayConsole *ddc, return DBUS_METHOD_INVOCATION_HANDLED; } =20 - dpy_set_ui_info(ddc->dcl.con, &info, false); + qemu_console_set_ui_info(ddc->dcl.con, &info, false); qemu_dbus_display1_console_complete_set_uiinfo(ddc->iface, invocation); return DBUS_METHOD_INVOCATION_HANDLED; } diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index cc2c969686e..2e2f6ba4183 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -241,7 +241,7 @@ static void dbus_update_gl_cb(GObject *source_object, } #endif =20 - graphic_hw_gl_block(ddl->dcl.con, false); + qemu_console_hw_gl_block(ddl->dcl.con, false); g_object_unref(ddl); } #endif @@ -257,7 +257,7 @@ static void dbus_call_update_gl(DisplayChangeListener *= dcl, =20 glFlush(); #ifdef CONFIG_GBM - graphic_hw_gl_block(ddl->dcl.con, true); + qemu_console_hw_gl_block(ddl->dcl.con, true); qemu_dbus_display1_listener_call_update_dmabuf(ddl->proxy, x, y, w, h, G_DBUS_CALL_FLAGS_NONE, @@ -276,7 +276,7 @@ static void dbus_call_update_gl(DisplayChangeListener *= dcl, Error *err =3D NULL; assert(ddl->d3d_texture); =20 - graphic_hw_gl_block(ddl->dcl.con, true); + qemu_console_hw_gl_block(ddl->dcl.con, true); if (!d3d_texture2d_release0(ddl->d3d_texture, &err)) { error_report_err(err); return; @@ -711,7 +711,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl) { DBusDisplayListener *ddl =3D container_of(dcl, DBusDisplayListener, dc= l); =20 - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); =20 if (!ddl->ds || qemu_console_is_gl_blocked(ddl->dcl.con)) { return; @@ -740,7 +740,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl) =20 static void dbus_refresh(DisplayChangeListener *dcl) { - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); } =20 #ifdef CONFIG_OPENGL diff --git a/ui/egl-headless.c b/ui/egl-headless.c index 4f046c975a9..878bfebb40c 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -23,7 +23,7 @@ typedef struct egl_dpy { =20 static void egl_refresh(DisplayChangeListener *dcl) { - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); } =20 static void egl_gfx_update(DisplayChangeListener *dcl, @@ -161,7 +161,7 @@ static void egl_scanout_flush(DisplayChangeListener *dc= l, } =20 egl_fb_read(edpy->ds, &edpy->blit_fb); - dpy_gfx_update(edpy->dcl.con, x, y, w, h); + qemu_console_update(edpy->dcl.con, x, y, w, h); } =20 static const DisplayChangeListenerOps egl_ops =3D { diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index fa8fe8970c1..7c5c9b2428c 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -108,7 +108,7 @@ void gd_egl_draw(VirtualConsole *vc) qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); return; } - graphic_hw_gl_block(vc->gfx.dcl.con, false); + qemu_console_hw_gl_block(vc->gfx.dcl.con, false); } #endif } else { @@ -176,7 +176,7 @@ void gd_egl_refresh(DisplayChangeListener *dcl) return; } =20 - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); =20 if (vc->gfx.glupdates) { vc->gfx.glupdates =3D 0; @@ -405,7 +405,7 @@ void gd_egl_flush(DisplayChangeListener *dcl, =20 if (vc->gfx.guest_fb.dmabuf && !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { - graphic_hw_gl_block(vc->gfx.dcl.con, true); + qemu_console_hw_gl_block(vc->gfx.dcl.con, true); qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true); gtk_egl_set_scanout_mode(vc, true); gtk_widget_queue_draw_area(area, x, y, w, h); diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index ce49000d3f1..23806b9d01b 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -131,7 +131,7 @@ void gd_gl_area_draw(VirtualConsole *vc) qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); return; } - graphic_hw_gl_block(vc->gfx.dcl.con, false); + qemu_console_hw_gl_block(vc->gfx.dcl.con, false); } #endif } else { @@ -195,7 +195,7 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl) } } =20 - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); =20 if (vc->gfx.glupdates) { vc->gfx.glupdates =3D 0; @@ -347,7 +347,7 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dc= l, =20 if (vc->gfx.guest_fb.dmabuf && !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { - graphic_hw_gl_block(vc->gfx.dcl.con, true); + qemu_console_hw_gl_block(vc->gfx.dcl.con, true); qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true); gtk_gl_area_set_scanout_mode(vc, true); } diff --git a/ui/gtk.c b/ui/gtk.c index ef3707b3634..2c61b601f78 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -436,7 +436,7 @@ static void gd_update(DisplayChangeListener *dcl, =20 static void gd_refresh(DisplayChangeListener *dcl) { - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); } =20 static GdkDevice *gd_get_pointer(GdkDisplay *dpy) @@ -602,7 +602,7 @@ void gd_hw_gl_flushed(void *vcon) qemu_set_fd_handler(fence_fd, NULL, NULL, NULL); close(fence_fd); qemu_dmabuf_set_fence_fd(dmabuf, -1); - graphic_hw_gl_block(vc->gfx.dcl.con, false); + qemu_console_hw_gl_block(vc->gfx.dcl.con, false); } } =20 @@ -729,27 +729,27 @@ static void gd_set_ui_refresh_rate(VirtualConsole *vc= , int refresh_rate) { QemuUIInfo info; =20 - if (!dpy_ui_info_supported(vc->gfx.dcl.con)) { + if (!qemu_console_ui_info_supported(vc->gfx.dcl.con)) { return; } =20 - info =3D *dpy_get_ui_info(vc->gfx.dcl.con); + info =3D *qemu_console_get_ui_info(vc->gfx.dcl.con); info.refresh_rate =3D refresh_rate; - dpy_set_ui_info(vc->gfx.dcl.con, &info, true); + qemu_console_set_ui_info(vc->gfx.dcl.con, &info, true); } =20 static void gd_set_ui_size(VirtualConsole *vc, gint width, gint height) { QemuUIInfo info; =20 - if (!dpy_ui_info_supported(vc->gfx.dcl.con)) { + if (!qemu_console_ui_info_supported(vc->gfx.dcl.con)) { return; } =20 - info =3D *dpy_get_ui_info(vc->gfx.dcl.con); + info =3D *qemu_console_get_ui_info(vc->gfx.dcl.con); info.width =3D width; info.height =3D height; - dpy_set_ui_info(vc->gfx.dcl.con, &info, true); + qemu_console_set_ui_info(vc->gfx.dcl.con, &info, true); } =20 #if defined(CONFIG_OPENGL) @@ -2333,7 +2333,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, Vir= tualConsole *vc, gd_connect_vc_gfx_signals(vc); group =3D gd_vc_menu_init(s, vc, idx, group, view_menu); =20 - if (dpy_ui_info_supported(vc->gfx.dcl.con)) { + if (qemu_console_ui_info_supported(vc->gfx.dcl.con)) { zoom_to_fit =3D true; } if (s->opts->u.gtk.has_zoom_to_fit) { diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c index 73052383c2e..68a3aff7151 100644 --- a/ui/sdl2-2d.c +++ b/ui/sdl2-2d.c @@ -129,7 +129,7 @@ void sdl2_2d_refresh(DisplayChangeListener *dcl) struct sdl2_console *scon =3D container_of(dcl, struct sdl2_console, d= cl); =20 assert(!scon->opengl); - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); sdl2_poll_events(scon); } =20 diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index bb066cdd885..1547ad2f6f8 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -115,7 +115,7 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl) =20 assert(scon->opengl); =20 - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); if (scon->updates && scon->real_window) { scon->updates =3D 0; sdl2_gl_render_surface(scon); diff --git a/ui/sdl2.c b/ui/sdl2.c index 89516f95c41..4fcdbd79d3c 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -604,7 +604,7 @@ static void handle_windowevent(SDL_Event *ev) .width =3D ev->window.data1, .height =3D ev->window.data2, }; - dpy_set_ui_info(scon->dcl.con, &info, true); + qemu_console_set_ui_info(scon->dcl.con, &info, true); } sdl2_redraw(scon); break; @@ -632,10 +632,10 @@ static void handle_windowevent(SDL_Event *ev) } break; case SDL_WINDOWEVENT_RESTORED: - update_displaychangelistener(&scon->dcl, GUI_REFRESH_INTERVAL_DEFA= ULT); + qemu_console_listener_set_refresh(&scon->dcl, GUI_REFRESH_INTERVAL= _DEFAULT); break; case SDL_WINDOWEVENT_MINIMIZED: - update_displaychangelistener(&scon->dcl, 500); + qemu_console_listener_set_refresh(&scon->dcl, 500); break; case SDL_WINDOWEVENT_CLOSE: if (qemu_console_is_graphic(scon->dcl.con)) { diff --git a/ui/spice-display.c b/ui/spice-display.c index 56d8140fad8..e3716127203 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -468,7 +468,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque) assert(ssd->dcl.con); cursor_ref(c); qemu_mutex_unlock(&ssd->lock); - dpy_cursor_define(ssd->dcl.con, c); + qemu_console_set_cursor(ssd->dcl.con, c); qemu_mutex_lock(&ssd->lock); cursor_unref(c); } @@ -481,7 +481,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque) ssd->mouse_x =3D -1; ssd->mouse_y =3D -1; qemu_mutex_unlock(&ssd->lock); - dpy_mouse_set(ssd->dcl.con, x, y, true); + qemu_console_set_mouse(ssd->dcl.con, x, y, true); } else { qemu_mutex_unlock(&ssd->lock); } @@ -489,7 +489,7 @@ void qemu_spice_cursor_refresh_bh(void *opaque) =20 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd) { - graphic_hw_update(ssd->dcl.con); + qemu_console_hw_update(ssd->dcl.con); =20 WITH_QEMU_LOCK_GUARD(&ssd->lock) { if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) { @@ -668,7 +668,7 @@ static int interface_client_monitors_config(QXLInstance= *sin, QemuUIInfo info; int head; =20 - if (!dpy_ui_info_supported(ssd->dcl.con)) { + if (!qemu_console_ui_info_supported(ssd->dcl.con)) { return 0; /* =3D=3D not supported by guest */ } =20 @@ -676,7 +676,7 @@ static int interface_client_monitors_config(QXLInstance= *sin, return 1; } =20 - info =3D *dpy_get_ui_info(ssd->dcl.con); + info =3D *qemu_console_get_ui_info(ssd->dcl.con); =20 head =3D qemu_console_get_index(ssd->dcl.con); if (mc->num_of_monitors > head) { @@ -690,7 +690,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, false); + qemu_console_set_ui_info(ssd->dcl.con, &info, false); return 1; } =20 @@ -817,7 +817,7 @@ static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd= , bool block) } else { timer_del(ssd->gl_unblock_timer); } - graphic_hw_gl_block(ssd->dcl.con, block); + qemu_console_hw_gl_block(ssd->dcl.con, block); } =20 static void qemu_spice_gl_unblock_bh(void *opaque) @@ -861,7 +861,7 @@ static void spice_gl_refresh(DisplayChangeListener *dcl) return; } =20 - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); if (ssd->gl_updates && ssd->have_surface) { qemu_spice_gl_block(ssd, true); glFlush(); diff --git a/ui/vnc.c b/ui/vnc.c index e8c8773a36e..d3dfabede03 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2325,8 +2325,8 @@ static void set_pixel_format(VncState *vs, int bits_p= er_pixel, =20 set_pixel_conversion(vs); =20 - graphic_hw_invalidate(vs->vd->dcl.con); - graphic_hw_update(vs->vd->dcl.con); + qemu_console_hw_invalidate(vs->vd->dcl.con); + qemu_console_hw_update(vs->vd->dcl.con); } =20 static void pixel_format_message (VncState *vs) { @@ -2384,7 +2384,7 @@ static int protocol_client_msg(VncState *vs, uint8_t = *data, size_t len) VncDisplay *vd =3D vs->vd; =20 if (data[0] > 3) { - update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); + qemu_console_listener_set_refresh(&vd->dcl, VNC_REFRESH_INTERVAL_B= ASE); } =20 switch (data[0]) { @@ -2638,9 +2638,9 @@ static int protocol_client_msg(VncState *vs, uint8_t = *data, size_t len) h =3D read_u16(data, 4); =20 trace_vnc_msg_client_set_desktop_size(vs, vs->ioc, w, h, screens); - if (dpy_ui_info_supported(vs->vd->dcl.con)) { + if (qemu_console_ui_info_supported(vs->vd->dcl.con)) { QemuUIInfo info =3D { .width =3D w, .height =3D h }; - dpy_set_ui_info(vs->vd->dcl.con, &info, false); + qemu_console_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 */); @@ -3242,14 +3242,14 @@ static void vnc_refresh(DisplayChangeListener *dcl) int has_dirty, rects =3D 0; =20 if (QTAILQ_EMPTY(&vd->clients)) { - update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX); + qemu_console_listener_set_refresh(&vd->dcl, VNC_REFRESH_INTERVAL_M= AX); return; } =20 - graphic_hw_update(vd->dcl.con); + qemu_console_hw_update(vd->dcl.con); =20 if (vnc_trylock_display(vd)) { - update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); + qemu_console_listener_set_refresh(&vd->dcl, VNC_REFRESH_INTERVAL_B= ASE); return; } =20 @@ -3323,7 +3323,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSoc= ket *sioc, sioc, websocket, vs->auth, vs->subauth); =20 VNC_DEBUG("New client on socket %p\n", vs->sioc); - update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); + qemu_console_listener_set_refresh(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); qio_channel_set_blocking(vs->ioc, false, &error_abort); g_clear_handle_id(&vs->ioc_tag, g_source_remove); if (websocket) { @@ -3363,7 +3363,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSoc= ket *sioc, vnc_update_server_surface(vd); } =20 - graphic_hw_update(vd->dcl.con); + qemu_console_hw_update(vd->dcl.con); =20 if (!vs->websocket) { vnc_start_protocol(vs); @@ -3419,7 +3419,7 @@ static void vmstate_change_handler(void *opaque, bool= running, RunState state) if (state !=3D RUN_STATE_RUNNING) { return; } - update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); + qemu_console_listener_set_refresh(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); } =20 static bool vnc_display_open(VncDisplay *vd, Error **errp); diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m index 77d80fb7cef..be0061b9db2 100644 --- a/hw/display/apple-gfx.m +++ b/hw/display/apple-gfx.m @@ -317,8 +317,8 @@ static void apple_gfx_render_frame_completed_bh(void *o= paque) copy_mtl_texture_to_surface_mem(s->texture, surface_data(s->su= rface)); if (s->gfx_update_requested) { s->gfx_update_requested =3D false; - dpy_gfx_update_full(s->con); - graphic_hw_update_done(s->con); + qemu_console_update_full(s->con); + qemu_console_hw_update_done(s->con); s->new_frame_ready =3D false; } else { s->new_frame_ready =3D true; @@ -337,7 +337,7 @@ static bool apple_gfx_fb_update_display(void *opaque) =20 assert(bql_locked()); if (s->new_frame_ready) { - dpy_gfx_update_full(s->con); + qemu_console_update_full(s->con); s->new_frame_ready =3D false; } else if (s->pending_frames > 0) { s->gfx_update_requested =3D true; @@ -380,14 +380,14 @@ static void set_mode(AppleGFXState *s, uint32_t width= , uint32_t height) (s->texture.storageMode =3D=3D MTLStorageModeManaged); } =20 - dpy_gfx_replace_surface(s->con, s->surface); + qemu_console_set_surface(s->con, s->surface); } =20 static void update_cursor(AppleGFXState *s) { assert(bql_locked()); - dpy_mouse_set(s->con, s->pgdisp.cursorPosition.x, - s->pgdisp.cursorPosition.y, qatomic_read(&s->cursor_show= )); + qemu_console_set_mouse(s->con, s->pgdisp.cursorPosition.x, + s->pgdisp.cursorPosition.y, qatomic_read(&s->cu= rsor_show)); } =20 static void update_cursor_bh(void *opaque) @@ -443,7 +443,7 @@ static void set_cursor_glyph(void *opaque) } px_data +=3D padding_bytes_per_row; } - dpy_cursor_define(s->con, s->cursor); + qemu_console_set_cursor(s->con, s->cursor); update_cursor(s); } [glyph release]; @@ -792,7 +792,7 @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceS= tate *dev, apple_gfx_create_display_mode_array(display_modes, num_display_mod= es); [mode_array release]; =20 - s->con =3D graphic_console_init(dev, 0, &apple_gfx_fb_ops, s); + s->con =3D qemu_graphic_console_create(dev, 0, &apple_gfx_fb_ops, s); return true; } =20 diff --git a/ui/cocoa.m b/ui/cocoa.m index aaf82421589..98394cdc507 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -421,7 +421,7 @@ - (void) selectConsoleLocked:(unsigned int)index return; } =20 - unregister_displaychangelistener(&dcl); + qemu_console_unregister_listener(&dcl); qkbd_state_switch_console(kbd, con); qemu_console_register_listener(con, &dcl, &dcl_ops); [self notifyMouseModeChange]; @@ -669,8 +669,8 @@ - (void) updateUIInfoLocked CVTime period =3D CVDisplayLinkGetNominalOutputVideoRefreshPer= iod(displayLink); CVDisplayLinkRelease(displayLink); if (!(period.flags & kCVTimeIsIndefinite)) { - update_displaychangelistener(&dcl, - 1000 * period.timeValue / per= iod.timeScale); + qemu_console_listener_set_refresh(&dcl, + 1000 * period.timeValue = / period.timeScale); info.refresh_rate =3D (int64_t)1000 * period.timeScale / p= eriod.timeValue; } } @@ -688,7 +688,7 @@ - (void) updateUIInfoLocked info.width =3D frameSize.width * [[self window] backingScaleFactor]; info.height =3D frameSize.height * [[self window] backingScaleFactor]; =20 - dpy_set_ui_info(dcl.con, &info, TRUE); + qemu_console_set_ui_info(dcl.con, &info, TRUE); } =20 #pragma clang diagnostic pop @@ -2056,7 +2056,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl) NSAutoreleasePool * pool =3D [[NSAutoreleasePool alloc] init]; =20 COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n"); - graphic_hw_update(dcl->con); + qemu_console_hw_update(dcl->con); =20 if (cbchangecount !=3D [[NSPasteboard generalPasteboard] changeCount])= { qemu_clipboard_info_unref(cbinfo); --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496793; cv=none; d=zohomail.com; s=zohoarc; b=mSA7c9Ch4qSjEcy7gUq2V4923KGeLWz9q7T1I0smtxXKQElhXEiDPt5a9DPhuxagS1UeAavYBbCma35NZPIPAEAecZ/QJAMY+8YFCtA/G/Bx5qPIOonvIpkndqvojx5ipbswkKc7AFaWBOxmNkRAWADfwUn8cBAkCfCO4T6JH94= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496793; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/WSuOvXfhRMR7yGWenNLNnW4GMzW27uioJUsplyvKkE=; b=bK8bslemSXP1Pl8aDCTgKMSzffUIa5Hnpf2rXgdZhEfCeJafibIQFfrj1NszqOlzZcJSr36bdfVRdrkIlTZEzpBNjn3M+UB4e2+e5CZAvA0Q82MnCuaav4hDw1qaaZJSMBm6CRJa3bgvBzDlQwN9Pl3IbSZjdgP7W9pEtgknayg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496793271590.6780294374231; Wed, 29 Apr 2026 14:06:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC6Y-0007Kl-HE; Wed, 29 Apr 2026 17:05:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6K-0006rH-BH for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6F-0003kY-Vq for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:43 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-48-U4g3bEDVOXmPxg9BW8tShQ-1; Wed, 29 Apr 2026 17:05:31 -0400 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 885C61800352 for ; Wed, 29 Apr 2026 21:05:30 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CD60819560AB; Wed, 29 Apr 2026 21:05:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496733; 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=/WSuOvXfhRMR7yGWenNLNnW4GMzW27uioJUsplyvKkE=; b=DUw37TK5nijA+WsCRTGNzwJImnrEQQANyK2ZdWwUTp3dcX7CwqThjnM3ySEc6w1Uciocvc g/lQTZUa4Ox4ucV9pSBA5f+yErdO/rEYS7Yqf/HempfoWu8BzkCpFR1S2taf2iQ2uvywzs U8Pa6G39ita844lJHIgRozQwhOqU13I= X-MC-Unique: U4g3bEDVOXmPxg9BW8tShQ-1 X-Mimecast-MFC-AGG-ID: U4g3bEDVOXmPxg9BW8tShQ_1777496730 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:56 +0400 Subject: [PATCH v3 23/26] ui/vnc: replace VNC_DEBUG with trace-events MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-23-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=22270; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=CWW/s7uLrXm6szAKgSaWp7eUxMnvX23qQxNfl3DfoWE=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMQ2AbUwelTXJlVl5jYl/9I4hpr3r8qO8X1 8SRyLOAajiJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5UdbEACQWcfJPRVmvCnRBnosh1kqi4bwmXxf+d6lB7uyW+p8lRhOaGfMSCmp1wgZCdBDOZ+tlE8 P24SLVSVmEUmj7bwbUV7l2ZxClRmwaTWayfCYA6goLBBLBpR6z21iobta+gwacH1YaQAl+Vag01 u9UZsFvkaoyCZ5K7uAsXd0XnG3p02qRgoGuEul0A7lWI3cJxjnAb4Jz8EdLwwMtDH0OqdGoY65R 2skB/Pi4dTVe70Ytmjch15MVzTJ8JPNR6PHXW1oE2quf+1NWh4MK6znJtHrAtfmG3A/tyLgpdAy cYQIY7KAGSrMHGj1uXU9FCBs0HYAFC/sBdD5oP4um0DWmZ4AWBa0AQIiqK/t41044aFhyOWXMV1 iEjY2F8wz9N3VIajacN5QbKmPuTwKheL0iAnuSEjP4heq3hrB5yRR3pkqwwyu+145MrJlQYOxXh 5Yg8MK87QunsuQvlIHM93i68BLpLb3fiEz2OgZjO6F1j3hm7qd/dKOX/Haud/S7B6ak1wf+2Ij1 IT4RiuDYKuH+rsMIgjfC8v8QqbGNyQv9LW0vjQYeZ14tUL1G/kAIBcZ7WtWmu8RPZqVddgAn5DG /CkW3LFFcBgrkqm717l/LnK3zw5J1LLMK9BeGNfqSH8pqnop765PZGrzSiHIT/2vqQTGbi0fAy6 xBiDS6YUpcQ2XJA== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496795385158500 Replace #ifdef printf() with run-time trace events. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- ui/vnc.h | 8 ------ ui/vnc-auth-sasl.c | 13 ++++----- ui/vnc-enc-tight.c | 4 +-- ui/vnc-enc-zlib.c | 4 +-- ui/vnc-ws.c | 10 +++---- ui/vnc.c | 83 ++++++++++++++++++++------------------------------= ---- ui/trace-events | 29 ++++++++++++++++++- 7 files changed, 73 insertions(+), 78 deletions(-) diff --git a/ui/vnc.h b/ui/vnc.h index 0b345246c8e..0750bf5f72f 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -46,14 +46,6 @@ #include "vnc-enc-zrle.h" #include "ui/kbd-state.h" =20 -// #define _VNC_DEBUG 1 - -#ifdef _VNC_DEBUG -#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } w= hile (0) -#else -#define VNC_DEBUG(fmt, ...) do { } while (0) -#endif - /*************************************************************************= **** * * Core data structures diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c index 3f4cfc471d5..9964b969ac2 100644 --- a/ui/vnc-auth-sasl.c +++ b/ui/vnc-auth-sasl.c @@ -73,10 +73,10 @@ size_t vnc_client_write_sasl(VncState *vs) { size_t ret; =20 - VNC_DEBUG("Write SASL: Pending output %p size %zd offset %zd " - "Encoded: %p size %d offset %d\n", - vs->output.buffer, vs->output.capacity, vs->output.offset, - vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOf= fset); + trace_vnc_sasl_write_pending(vs, vs->output.buffer, vs->output.capacit= y, + vs->output.offset, vs->sasl.encoded, + vs->sasl.encodedLength, + vs->sasl.encodedOffset); =20 if (!vs->sasl.encoded) { int err; @@ -157,8 +157,7 @@ size_t vnc_client_read_sasl(VncState *vs) =20 if (err !=3D SASL_OK) return vnc_client_io_error(vs, -1, NULL); - VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n", - encoded, ret, decoded, decodedLen); + trace_vnc_sasl_read_decoded(vs, encoded, ret, decoded, decodedLen); buffer_reserve(&vs->input, decodedLen); buffer_append(&vs->input, decoded, decodedLen); return decodedLen; @@ -717,5 +716,3 @@ void start_auth_sasl(VncState *vs) error_free(local_err); vnc_client_error(vs); } - - diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 9dfe6ae5a24..ca671427018 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -46,6 +46,7 @@ #include "vnc.h" #include "vnc-enc-tight.h" #include "vnc-palette.h" +#include "trace.h" =20 /* Compression level stuff. The following array contains various encoder parameters for each of 10 compression levels (0..9). @@ -795,8 +796,7 @@ static int tight_init_stream(VncState *vs, VncTight *ti= ght, int stream_id, if (zstream->opaque =3D=3D NULL) { int err; =20 - VNC_DEBUG("VNC: TIGHT: initializing zlib stream %d\n", stream_id); - VNC_DEBUG("VNC: TIGHT: opaque =3D %p | vs =3D %p\n", zstream->opaq= ue, vs); + trace_vnc_tight_zlib_init(vs, stream_id, zstream->opaque); zstream->zalloc =3D vnc_zlib_zalloc; zstream->zfree =3D vnc_zlib_zfree; =20 diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c index a6d287118aa..657b47ceb2b 100644 --- a/ui/vnc-enc-zlib.c +++ b/ui/vnc-enc-zlib.c @@ -26,6 +26,7 @@ =20 #include "qemu/osdep.h" #include "vnc.h" +#include "trace.h" =20 #define ZALLOC_ALIGNMENT 16 =20 @@ -71,8 +72,7 @@ static int vnc_zlib_stop(VncState *vs, VncWorker *worker) if (zstream->opaque !=3D vs) { int err; =20 - VNC_DEBUG("VNC: initializing zlib stream\n"); - VNC_DEBUG("VNC: opaque =3D %p | vs =3D %p\n", zstream->opaque, vs); + trace_vnc_zlib_init(vs, zstream->opaque); zstream->zalloc =3D vnc_zlib_zalloc; zstream->zfree =3D vnc_zlib_zfree; =20 diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 9e3503d93d8..b7d4de41431 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -32,11 +32,11 @@ static void vncws_tls_handshake_done(QIOTask *task, Error *err =3D NULL; =20 if (qio_task_propagate_error(task, &err)) { - VNC_DEBUG("Handshake failed %s\n", error_get_pretty(err)); + trace_vnc_ws_tls_handshake_fail(vs, error_get_pretty(err)); vnc_client_error(vs); error_free(err); } else { - VNC_DEBUG("TLS handshake complete, starting websocket handshake\n"= ); + trace_vnc_ws_tls_handshake_complete(vs); if (vs->ioc_tag) { g_source_remove(vs->ioc_tag); } @@ -71,7 +71,7 @@ gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UN= USED, vs->vd->tlsauthzid, &err); if (!tls) { - VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err)); + trace_vnc_ws_tls_setup_fail(vs, error_get_pretty(err)); error_free(err); vnc_client_error(vs); return TRUE; @@ -101,11 +101,11 @@ static void vncws_handshake_done(QIOTask *task, Error *err =3D NULL; =20 if (qio_task_propagate_error(task, &err)) { - VNC_DEBUG("Websock handshake failed %s\n", error_get_pretty(err)); + trace_vnc_ws_handshake_fail(vs, error_get_pretty(err)); vnc_client_error(vs); error_free(err); } else { - VNC_DEBUG("Websock handshake complete, starting VNC protocol\n"); + trace_vnc_ws_handshake_complete(vs); vnc_start_protocol(vs); if (vs->ioc_tag) { g_source_remove(vs->ioc_tag); diff --git a/ui/vnc.c b/ui/vnc.c index d3dfabede03..56dd43d53ff 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -75,17 +75,7 @@ static void vnc_disconnect_finish(VncState *vs); =20 static void vnc_set_share_mode(VncState *vs, VncShareMode mode) { -#ifdef _VNC_DEBUG - static const char *mn[] =3D { - [0] =3D "undefined", - [VNC_SHARE_MODE_CONNECTING] =3D "connecting", - [VNC_SHARE_MODE_SHARED] =3D "shared", - [VNC_SHARE_MODE_EXCLUSIVE] =3D "exclusive", - [VNC_SHARE_MODE_DISCONNECTED] =3D "disconnected", - }; - fprintf(stderr, "%s/%p: %s -> %s\n", __func__, - vs->ioc, mn[vs->share_mode], mn[mode]); -#endif + trace_vnc_set_share_mode(vs, vs->ioc, vs->share_mode, mode); =20 switch (vs->share_mode) { case VNC_SHARE_MODE_CONNECTING: @@ -185,8 +175,9 @@ static void vnc_init_basic_info_from_remote_addr(QIOCha= nnelSocket *ioc, qapi_free_SocketAddress(addr); } =20 -static const char *vnc_auth_name(VncDisplay *vd) { - switch (vd->auth) { +static const char *vnc_auth_name(int auth, int subauth) +{ + switch (auth) { case VNC_AUTH_INVALID: return "invalid"; case VNC_AUTH_NONE: @@ -204,7 +195,7 @@ static const char *vnc_auth_name(VncDisplay *vd) { case VNC_AUTH_TLS: return "tls"; case VNC_AUTH_VENCRYPT: - switch (vd->subauth) { + switch (subauth) { case VNC_AUTH_VENCRYPT_PLAIN: return "vencrypt+plain"; case VNC_AUTH_VENCRYPT_TLSNONE: @@ -244,7 +235,7 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *v= d) info =3D g_malloc0(sizeof(*info)); vnc_init_basic_info_from_server_addr(qio_net_listener_sioc(vd->listene= r, 0), qapi_VncServerInfo_base(info), &e= rr); - info->auth =3D g_strdup(vnc_auth_name(vd)); + info->auth =3D g_strdup(vnc_auth_name(vd->auth, vd->subauth)); if (err) { qapi_free_VncServerInfo(info); info =3D NULL; @@ -421,7 +412,7 @@ VncInfo *qmp_query_vnc(Error **errp) =20 info->has_family =3D true; =20 - info->auth =3D g_strdup(vnc_auth_name(vd)); + info->auth =3D g_strdup(vnc_auth_name(vd->auth, vd->subauth)); } =20 qapi_free_SocketAddress(addr); @@ -1383,7 +1374,7 @@ size_t vnc_client_io_error(VncState *vs, ssize_t ret,= Error *err) =20 void vnc_client_error(VncState *vs) { - VNC_DEBUG("Closing down client sock: protocol error\n"); + trace_vnc_client_protocol_error(vs); vnc_disconnect_start(vs); } =20 @@ -1408,7 +1399,7 @@ size_t vnc_client_write_buf(VncState *vs, const uint8= _t *data, size_t datalen) Error *err =3D NULL; ssize_t ret; ret =3D qio_channel_write(vs->ioc, (const char *)data, datalen, &err); - VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret); + trace_vnc_client_write_wire(vs, data, datalen, ret); return vnc_client_io_error(vs, ret, err); } =20 @@ -1429,9 +1420,9 @@ static size_t vnc_client_write_plain(VncState *vs) size_t ret; =20 #ifdef CONFIG_VNC_SASL - VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SS= F %d\n", - vs->output.buffer, vs->output.capacity, vs->output.offset, - vs->sasl.waitWriteSSF); + trace_vnc_client_write_plain(vs, vs->output.buffer, + vs->output.capacity, vs->output.offset, + vs->sasl.waitWriteSSF); =20 if (vs->sasl.conn && vs->sasl.runSSF && @@ -1532,7 +1523,7 @@ size_t vnc_client_read_buf(VncState *vs, uint8_t *dat= a, size_t datalen) ssize_t ret; Error *err =3D NULL; ret =3D qio_channel_read(vs->ioc, (char *)data, datalen, &err); - VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret); + trace_vnc_client_read_wire(vs, data, datalen, ret); return vnc_client_io_error(vs, ret, err); } =20 @@ -1549,8 +1540,8 @@ size_t vnc_client_read_buf(VncState *vs, uint8_t *dat= a, size_t datalen) static size_t vnc_client_read_plain(VncState *vs) { size_t ret; - VNC_DEBUG("Read plain %p size %zd offset %zd\n", - vs->input.buffer, vs->input.capacity, vs->input.offset); + trace_vnc_client_read_plain(vs, vs->input.buffer, + vs->input.capacity, vs->input.offset); buffer_reserve(&vs->input, 4096); ret =3D vnc_client_read_buf(vs, buffer_end(&vs->input), 4096); if (!ret) @@ -2213,7 +2204,7 @@ static void set_encodings(VncState *vs, int32_t *enco= dings, size_t n_encodings) } break; default: - VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc); + trace_vnc_client_unknown_encoding(vs, i, enc); break; } } @@ -2581,14 +2572,13 @@ static int protocol_client_msg(VncState *vs, uint8_= t *data, size_t len) case 4: vs->as.fmt =3D AUDIO_FORMAT_U32; break; case 5: vs->as.fmt =3D AUDIO_FORMAT_S32; break; default: - VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4= )); + trace_vnc_client_invalid_audio_format(vs, read_u8(data= , 4)); vnc_client_error(vs); break; } vs->as.nchannels =3D read_u8(data, 5); if (vs->as.nchannels !=3D 1 && vs->as.nchannels !=3D 2) { - VNC_DEBUG("Invalid audio channel count %d\n", - read_u8(data, 5)); + trace_vnc_client_invalid_audio_channels(vs, read_u8(da= ta, 5)); vnc_client_error(vs); break; } @@ -2598,7 +2588,7 @@ static int protocol_client_msg(VncState *vs, uint8_t = *data, size_t len) * protects calculations involving 'vs->as.freq' later. */ if (freq > 48000) { - VNC_DEBUG("Invalid audio frequency %u > 48000", freq); + trace_vnc_client_invalid_audio_freq(vs, freq); vnc_client_error(vs); break; } @@ -2607,14 +2597,14 @@ static int protocol_client_msg(VncState *vs, uint8_= t *data, size_t len) vs, vs->ioc, vs->as.fmt, vs->as.nchannels, vs->as.freq= ); break; default: - VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 2)); + trace_vnc_client_invalid_audio_msg(vs, read_u8(data, 2)); vnc_client_error(vs); break; } break; =20 default: - VNC_DEBUG("Msg: %d\n", read_u16(data, 0)); + trace_vnc_client_unknown_qemu_msg(vs, read_u16(data, 0)); vnc_client_error(vs); break; } @@ -2649,7 +2639,7 @@ static int protocol_client_msg(VncState *vs, uint8_t = *data, size_t len) break; } default: - VNC_DEBUG("Msg: %d\n", data[0]); + trace_vnc_client_unknown_msg(vs, data[0]); vnc_client_error(vs); break; } @@ -2929,18 +2919,18 @@ static int protocol_version(VncState *vs, uint8_t *= version, size_t len) local[12] =3D 0; =20 if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) !=3D 2) { - VNC_DEBUG("Malformed protocol version %s\n", local); + trace_vnc_client_protocol_version_malformed(vs, local); vnc_client_error(vs); return 0; } - VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->mi= nor); + trace_vnc_client_protocol_version(vs, vs->major, vs->minor); if (vs->major !=3D 3 || (vs->minor !=3D 3 && vs->minor !=3D 4 && vs->minor !=3D 5 && vs->minor !=3D 7 && vs->minor !=3D 8)) { - VNC_DEBUG("Unsupported client version\n"); + trace_vnc_client_protocol_version_unsupported(vs); vnc_write_u32(vs, VNC_AUTH_INVALID); vnc_flush(vs); vnc_client_error(vs); @@ -2960,7 +2950,7 @@ static int protocol_version(VncState *vs, uint8_t *ve= rsion, size_t len) trace_vnc_auth_pass(vs, vs->auth); start_client_init(vs); } else if (vs->auth =3D=3D VNC_AUTH_VNC) { - VNC_DEBUG("Tell client VNC auth\n"); + trace_vnc_client_auth_method(vs, vs->auth); vnc_write_u32(vs, vs->auth); vnc_flush(vs); start_auth_vnc(vs); @@ -3319,10 +3309,7 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSo= cket *sioc, vs->subauth =3D vd->subauth; } } - VNC_DEBUG("Client sioc=3D%p ws=3D%d auth=3D%d subauth=3D%d\n", - sioc, websocket, vs->auth, vs->subauth); - - VNC_DEBUG("New client on socket %p\n", vs->sioc); + trace_vnc_client_setup(vs, sioc, websocket, vs->auth, vs->subauth); qemu_console_listener_set_refresh(&vd->dcl, VNC_REFRESH_INTERVAL_BASE); qio_channel_set_blocking(vs->ioc, false, &error_abort); g_clear_handle_id(&vs->ioc_tag, g_source_remove); @@ -3727,13 +3714,10 @@ vnc_display_setup_auth(int *auth, */ if (websocket || !tlscreds) { if (password) { - VNC_DEBUG("Initializing VNC server with password auth\n"); *auth =3D VNC_AUTH_VNC; } else if (sasl) { - VNC_DEBUG("Initializing VNC server with SASL auth\n"); *auth =3D VNC_AUTH_SASL; } else { - VNC_DEBUG("Initializing VNC server with no auth\n"); *auth =3D VNC_AUTH_NONE; } *subauth =3D VNC_AUTH_INVALID; @@ -3752,27 +3736,20 @@ vnc_display_setup_auth(int *auth, *auth =3D VNC_AUTH_VENCRYPT; if (password) { if (is_x509) { - VNC_DEBUG("Initializing VNC server with x509 password auth= \n"); *subauth =3D VNC_AUTH_VENCRYPT_X509VNC; } else { - VNC_DEBUG("Initializing VNC server with TLS password auth\= n"); *subauth =3D VNC_AUTH_VENCRYPT_TLSVNC; } - } else if (sasl) { if (is_x509) { - VNC_DEBUG("Initializing VNC server with x509 SASL auth\n"); *subauth =3D VNC_AUTH_VENCRYPT_X509SASL; } else { - VNC_DEBUG("Initializing VNC server with TLS SASL auth\n"); *subauth =3D VNC_AUTH_VENCRYPT_TLSSASL; } } else { if (is_x509) { - VNC_DEBUG("Initializing VNC server with x509 no auth\n"); *subauth =3D VNC_AUTH_VENCRYPT_X509NONE; } else { - VNC_DEBUG("Initializing VNC server with TLS no auth\n"); *subauth =3D VNC_AUTH_VENCRYPT_TLSNONE; } } @@ -4221,14 +4198,16 @@ static bool vnc_display_open(VncDisplay *vd, Error = **errp) sasl, false, errp) < 0) { return false; } - trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth); + trace_vnc_auth_init(vd, 0, vd->auth, vd->subauth, + vnc_auth_name(vd->auth, vd->subauth)); =20 if (vnc_display_setup_auth(&vd->ws_auth, &vd->ws_subauth, vd->tlscreds, password, sasl, true, errp) < 0) { return false; } - trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth); + trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth, + vnc_auth_name(vd->ws_auth, vd->ws_subauth)); =20 #ifdef CONFIG_VNC_SASL if (sasl && !vnc_sasl_server_init(errp)) { diff --git a/ui/trace-events b/ui/trace-events index 3eba9ca3a82..c1ea56874ee 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -83,7 +83,7 @@ vnc_job_discard_rect(void *state, void *job, int x, int y= , int w, int h) "VNC jo vnc_job_clamp_rect(void *state, void *job, int x, int y, int w, int h) "VN= C job clamp rect state=3D%p job=3D%p offset=3D%d,%d size=3D%dx%d" vnc_job_clamped_rect(void *state, void *job, int x, int y, int w, int h) "= VNC job clamp rect state=3D%p job=3D%p offset=3D%d,%d size=3D%dx%d" vnc_job_nrects(void *state, void *job, int nrects) "VNC job state=3D%p job= =3D%p nrects=3D%d" -vnc_auth_init(void *display, int websock, int auth, int subauth) "VNC auth= init state=3D%p websock=3D%d auth=3D%d subauth=3D%d" +vnc_auth_init(void *display, int websock, int auth, int subauth, const cha= r *name) "VNC auth init state=3D%p websock=3D%d auth=3D%d subauth=3D%d name= =3D%s" vnc_auth_start(void *state, int method) "VNC client auth start state=3D%p = method=3D%d" vnc_auth_pass(void *state, int method) "VNC client auth passed state=3D%p = method=3D%d" vnc_auth_fail(void *state, int method, const char *message, const char *re= ason) "VNC client auth failed state=3D%p method=3D%d message=3D%s reason=3D= %s" @@ -97,6 +97,33 @@ vnc_auth_sasl_step(void *state, const void *clientdata, = size_t clientlen, const vnc_auth_sasl_ssf(void *state, int ssf) "VNC client auth SASL SSF state=3D= %p size=3D%d" vnc_auth_sasl_username(void *state, const char *name) "VNC client auth SAS= L user state=3D%p name=3D%s" vnc_auth_sasl_acl(void *state, int allow) "VNC client auth SASL ACL state= =3D%p allow=3D%d" +vnc_set_share_mode(void *state, void *ioc, int old_mode, int new_mode) "VN= C set share mode state=3D%p ioc=3D%p old=3D%d new=3D%d" +vnc_client_protocol_error(void *state) "VNC client protocol error state=3D= %p" +vnc_client_write_wire(void *state, const void *data, size_t datalen, ssize= _t ret) "VNC client write wire state=3D%p data=3D%p len=3D%zu ret=3D%zd" +vnc_client_write_plain(void *state, const void *buffer, size_t capacity, s= ize_t offset, int wait_ssf) "VNC client write plain state=3D%p buffer=3D%p = capacity=3D%zu offset=3D%zu wait_ssf=3D%d" +vnc_client_read_wire(void *state, const void *data, size_t datalen, ssize_= t ret) "VNC client read wire state=3D%p data=3D%p len=3D%zu ret=3D%zd" +vnc_client_read_plain(void *state, const void *buffer, size_t capacity, si= ze_t offset) "VNC client read plain state=3D%p buffer=3D%p capacity=3D%zu o= ffset=3D%zu" +vnc_client_unknown_encoding(void *state, int index, int encoding) "VNC cli= ent unknown encoding state=3D%p index=3D%d encoding=3D0x%x" +vnc_client_invalid_audio_format(void *state, int fmt) "VNC client invalid = audio format state=3D%p fmt=3D%d" +vnc_client_invalid_audio_channels(void *state, int channels) "VNC client i= nvalid audio channel count state=3D%p channels=3D%d" +vnc_client_invalid_audio_freq(void *state, unsigned int freq) "VNC client = invalid audio frequency state=3D%p freq=3D%u" +vnc_client_invalid_audio_msg(void *state, int msg) "VNC client invalid aud= io message state=3D%p msg=3D%d" +vnc_client_unknown_qemu_msg(void *state, int msg) "VNC client unknown QEMU= msg state=3D%p msg=3D%d" +vnc_client_unknown_msg(void *state, int msg) "VNC client unknown msg state= =3D%p msg=3D%d" +vnc_client_protocol_version(void *state, int major, int minor) "VNC client= protocol version state=3D%p version=3D%d.%d" +vnc_client_protocol_version_malformed(void *state, const char *version) "V= NC client malformed protocol version state=3D%p version=3D%s" +vnc_client_protocol_version_unsupported(void *state) "VNC client unsupport= ed protocol version state=3D%p" +vnc_client_auth_method(void *state, int auth) "VNC client auth method stat= e=3D%p auth=3D%d" +vnc_client_setup(void *state, void *ioc, int websocket, int auth, int suba= uth) "VNC client setup state=3D%p ioc=3D%p websocket=3D%d auth=3D%d subauth= =3D%d" +vnc_ws_tls_handshake_fail(void *state, const char *msg) "VNC WS TLS handsh= ake failed state=3D%p msg=3D%s" +vnc_ws_tls_handshake_complete(void *state) "VNC WS TLS handshake complete = state=3D%p" +vnc_ws_tls_setup_fail(void *state, const char *msg) "VNC WS TLS setup fail= ed state=3D%p msg=3D%s" +vnc_ws_handshake_fail(void *state, const char *msg) "VNC WS handshake fail= ed state=3D%p msg=3D%s" +vnc_ws_handshake_complete(void *state) "VNC WS handshake complete state=3D= %p" +vnc_sasl_write_pending(void *state, const void *buffer, size_t capacity, s= ize_t offset, const void *encoded, int encoded_len, int encoded_offset) "VN= C SASL write pending state=3D%p buffer=3D%p capacity=3D%zu offset=3D%zu enc= oded=3D%p encoded_len=3D%d encoded_offset=3D%d" +vnc_sasl_read_decoded(void *state, const void *encoded, size_t encoded_len= , const void *decoded, unsigned int decoded_len) "VNC SASL read decoded sta= te=3D%p encoded=3D%p encoded_len=3D%zu decoded=3D%p decoded_len=3D%u" +vnc_zlib_init(void *state, const void *opaque) "VNC zlib init state=3D%p o= paque=3D%p" +vnc_tight_zlib_init(void *state, int stream_id, const void *opaque) "VNC t= ight zlib init state=3D%p stream=3D%d opaque=3D%p" =20 =20 # input.c --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496830; cv=none; d=zohomail.com; s=zohoarc; b=hHih+Dplzs1KHD9auvMJDTPZTEmxMw5wkHT1VnQyi//tzunrLq0lgzr+hmFiHjS4xnfQn/65hU+1nJor4qczlb3pWrQzjYRrsKuBjLm5MvQfvmlJFVfxdnjgNUBtXtsQoZYWm8W1cnySYoYYgnKwr6wWJICSlb2ejOtMnp/Lbr4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496830; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=rATqHGgV7J0uCAxeGwhnayw8CEra+4LpOlbkbjvPAAk=; b=YCuuqd5d9Zc9fUvS8cwBROMndyHKEjkPcQq1uYQZpEgGXO+3q5If5jcBpH00hPF5q3jIN8UVmXkAaV1WoGdsXkUccHfa1fyOf7brQRFHmjyma+CUcENv6iOI4rz51c0eLvDX6DWocJgPf8iJMPAVZ/8nYxrDjTGQdPIb/PDJfcs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496830503699.74914643584; Wed, 29 Apr 2026 14:07:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC7Q-0000Pz-0q; Wed, 29 Apr 2026 17:06:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6M-0006ri-AD for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:49 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6H-0003lL-9N for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:45 -0400 Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-628-fCEZFIVFMhOe3w0bZShOJQ-1; Wed, 29 Apr 2026 17:05:37 -0400 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2F4FF19560AD; Wed, 29 Apr 2026 21:05:36 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 059EC1800348; Wed, 29 Apr 2026 21:05:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496740; 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=rATqHGgV7J0uCAxeGwhnayw8CEra+4LpOlbkbjvPAAk=; b=X8R6/Hm1jhT0x6giQdKHO/vkxM2kZaACwL3ygXS2UbZo3bYQTMyedatX3DcQp5tBA3XCWS lZDQAqJMbtrdCHBaxu8BYP76eDv+P+HcLLsbP+IITtynkm1hTIvge9Ve3evUa790sOgop0 vRZs42FI9/JHC4oxQKyx8UT1t1HjG54= X-MC-Unique: fCEZFIVFMhOe3w0bZShOJQ-1 X-Mimecast-MFC-AGG-ID: fCEZFIVFMhOe3w0bZShOJQ_1777496736 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:57 +0400 Subject: [PATCH v3 24/26] ui: extract common sources into a static library MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-24-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= X-Developer-Signature: v=1; a=openpgp-sha256; l=4428; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=3mdkDik1/6BvAhfSRONuuZ0VcbtAx/YtCiUuV9Md1dc=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMS0GC0IUiJBQjUd1tzihJdm6oN8s8kDSNe dt2Q9DtMzGJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5eWTEACDykXx6TmEu0Qc5ubu1J/OsWCKxIssByKh+AiM/CNB9EE5HmWRB3GW33A4ydiYK+eXffv gwxSyMmrqNyfV/r60LWACavTw3I3aQPIbpzdcfGFRRJijF6OPW4ppwQgsacha7b8r5Sx3DLvz+a s3xeZnjsCGldjYqnYbYvcYN6MT8P+QbSyIl30kfR1ZYz/KJ1tkvpL2bWLHE70KN6ZZLa5DFDh46 DoDpkGQxEexMMsnTsi37EmN6zZndhQ5Qa68LYRNRPOHqERWnBTqL0xVFrHHqT0kb7z9C1GdvY2Y vy1+ZGZUb/mAl6A/XDptqmTsgRDruuNYBfuW/vcbD5op+n8RziVKw60qLhQqM+CFjBcgHSM6RWm ksNweZuyZ89SH24zir2SD2WMcvzU6bMVN6DtGixPVaDYZLD4ARx01saXSgU6jnvj530SwzU10KS zA/koZ0GhGuTPHpCpGrMHecZhhRsks9DNUtRD6cdL0IAEQz9KmfXquteOfmin+B1fdHSUo6/W+B PciKzGcQlKEPlUUPBDdbdE9RAUQifRdOVb+h10T/rJcKU5gaTzMKoJ/FmBiuJXVt6aDhsz2pSyE NrC9bU1S47DoCXJf81DR9kv8aijlZiSflBzbxK1ROnVUlKO7BLLFDguG/6iyfI38WaxatgWVOAC y9nUdEZL43c01sg== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 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=lists1p.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: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496832739154100 Move clipboard, cursor, display-surface, input-keymap, kbd-state, keymaps, vt100, and qemu-pixman into a separate static library 'qemuui'. This allows these common UI sources to be linked by targets outside of the system emulator build, such as standalone VNC or D-Bus display binaries. keymaps generation has to be moved earlier, so that header dependency are resolved first. The library objects are re-exported via a dependency so existing system_ss consumers are unaffected. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Marc-Andr=C3=A9 Lureau --- ui/meson.build | 103 ++++++++++++++++++++++++++++++-----------------------= ---- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/ui/meson.build b/ui/meson.build index 74151b05033..1b8f71796e4 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -1,25 +1,67 @@ -system_ss.add(pixman) +keymaps =3D [ + ['atset1', 'qcode'], + ['linux', 'qcode'], + ['qcode', 'atset1'], + ['qcode', 'atset2'], + ['qcode', 'atset3'], + ['qcode', 'linux'], + ['qcode', 'qnum'], + ['qcode', 'sun'], + ['qnum', 'qcode'], + ['usb', 'qcode'], + ['win32', 'qcode'], + ['x11', 'qcode'], + ['xorgevdev', 'qcode'], + ['xorgkbd', 'qcode'], + ['xorgxquartz', 'qcode'], + ['xorgxwin', 'qcode'], + ['osx', 'qcode'], +] + +if have_system or xkbcommon.found() + keycodemapdb_proj =3D subproject('keycodemapdb', required: true) + foreach e : keymaps + output =3D 'input-keymap-@0@-to-@1@.c.inc'.format(e[0], e[1]) + genh +=3D custom_target(output, + output: output, + capture: true, + input: keycodemapdb_proj.get_variable('keymaps_csv'), + command: [python, keycodemapdb_proj.get_variable('keymap= _gen').full_path(), + 'code-map', '--lang', 'glib2', + '--varname', 'qemu_input_map_@0@_to_@1@'.forma= t(e[0], e[1]), + '@INPUT0@', e[0], e[1]]) + endforeach +endif + +libui_sources =3D files( + 'clipboard.c', + 'console.c', + 'cursor.c', + 'dmabuf.c', + 'display-surface.c', + 'input-keymap.c', + 'kbd-state.c', + 'keymaps.c', + 'qemu-pixman.c', + 'vgafont.c', + ) +if pixman.found() + libui_sources +=3D files('cp437.c', 'vt100.c') +endif +libui =3D static_library('qemuui', libui_sources + genh, + dependencies: [pixman], + build_by_default: false) +ui =3D declare_dependency(objects: libui.extract_all_objects(recursive: fa= lse), dependencies: [pixman]) system_ss.add(png) system_ss.add(files( - 'clipboard.c', - 'console.c', - 'cp437.c', - 'cursor.c', - 'display-surface.c', - 'dmabuf.c', - 'input-keymap.c', 'input-legacy.c', 'input-barrier.c', 'input.c', - 'kbd-state.c', - 'keymaps.c', - 'qemu-pixman.c', 'ui-hmp-cmds.c', 'ui-qmp-cmds.c', 'util.c', - 'vgafont.c', - 'vt100.c', )) +system_ss.add(ui) system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: file= s('console-vc-stubs.c')) if dbus_display system_ss.add(files('dbus-module.c')) @@ -149,41 +191,6 @@ if spice.found() endif endif =20 -keymaps =3D [ - ['atset1', 'qcode'], - ['linux', 'qcode'], - ['qcode', 'atset1'], - ['qcode', 'atset2'], - ['qcode', 'atset3'], - ['qcode', 'linux'], - ['qcode', 'qnum'], - ['qcode', 'sun'], - ['qnum', 'qcode'], - ['usb', 'qcode'], - ['win32', 'qcode'], - ['x11', 'qcode'], - ['xorgevdev', 'qcode'], - ['xorgkbd', 'qcode'], - ['xorgxquartz', 'qcode'], - ['xorgxwin', 'qcode'], - ['osx', 'qcode'], -] - -if have_system or xkbcommon.found() - keycodemapdb_proj =3D subproject('keycodemapdb', required: true) - foreach e : keymaps - output =3D 'input-keymap-@0@-to-@1@.c.inc'.format(e[0], e[1]) - genh +=3D custom_target(output, - output: output, - capture: true, - input: keycodemapdb_proj.get_variable('keymaps_csv'), - command: [python, keycodemapdb_proj.get_variable('keymap= _gen').full_path(), - 'code-map', '--lang', 'glib2', - '--varname', 'qemu_input_map_@0@_to_@1@'.forma= t(e[0], e[1]), - '@INPUT0@', e[0], e[1]]) - endforeach -endif - subdir('shader') =20 if have_system --=20 2.54.0 From nobody Sat May 30 19:23:14 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1777496877; cv=none; d=zohomail.com; s=zohoarc; b=PBnLef9m5s/F+0h8P8bMYfZphdFfrtDgzuObFuchcBm2kO5p3yotbv0dBHJPfDdItETmDQhNba6dr9CHq7anvU0LsV4IPIyHTTFlJxtROr/+ERFNazQvilFG/ooskvbRuiAWIUCTo2BSfG2fmQlgrI2BQBTzSzRBo4VaD1ouh20= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777496877; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5M69FqQz8i1tkdKMn9kq/IgsfDbfg7yNoRa3QNEz72o=; b=JDAy0v5ybmb+IoZSF8DawfRTRDhwZlMP50J0zKjpOLmQBycEq9/6b5Z/lTF7CuXCxZSVQwxDo71Id/fDJGUdf4Wlk6F6kK5rT9B2Pau10GHCJsKlXy0fCj0tUzKDbtUgNPzTlTXF6JhRGX8jP8ONKUCjNEuxqEo/4vWPzAjTagc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1777496877182315.60005562156516; Wed, 29 Apr 2026 14:07:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wIC7U-0000pG-Rk; Wed, 29 Apr 2026 17:06:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6O-0006vu-R1 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:51 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wIC6L-0003mB-V4 for qemu-devel@nongnu.org; Wed, 29 Apr 2026 17:05:48 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-222--PGbzyVtPLCzXsfEYoscmg-1; Wed, 29 Apr 2026 17:05:42 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B19A31800350 for ; Wed, 29 Apr 2026 21:05:41 +0000 (UTC) Received: from localhost (unknown [10.44.22.2]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 59A04195608E; Wed, 29 Apr 2026 21:05:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777496744; 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=5M69FqQz8i1tkdKMn9kq/IgsfDbfg7yNoRa3QNEz72o=; b=g4IceB2DF5+AqXw1iAZE6nHO10gCJs+DuHAuxja8hF0hYjU6esz/yG2Bd0tncAGGSu/26C rwkp/62rm+buZrJwqlBswuzs63yZ2Xl3JbvsotKeLmvowqCZxw7RBgLYEKSUq70JpUQlkO J5anIQqfiUgO22CAGtDW8txSIDZdyLI= X-MC-Unique: -PGbzyVtPLCzXsfEYoscmg-1 X-Mimecast-MFC-AGG-ID: -PGbzyVtPLCzXsfEYoscmg_1777496741 From: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Date: Thu, 30 Apr 2026 01:02:58 +0400 Subject: [PATCH v3 25/26] tests/qtest: drop DBUS_VMSTATE_TEST_TMPDIR MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260430-qemu-vnc-v3-25-be96757428d0@redhat.com> References: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> In-Reply-To: <20260430-qemu-vnc-v3-0-be96757428d0@redhat.com> To: qemu-devel@nongnu.org Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Developer-Signature: v=1; a=openpgp-sha256; l=1313; i=marcandre.lureau@redhat.com; h=from:subject:message-id; bh=AF4tw00UydsKNYnU8BNeLalb8J4vuxmLglgznwUcFSY=; b=owEBbQKS/ZANAwAKAdro4Ql1lpzlAcsmYgBp8nIMW/qvxfnqn4y0Ah7ob4fHqmBH753+YO1CH 10RF9NJsyWJAjMEAAEKAB0WIQSHqb2TP4fGBtJ29i3a6OEJdZac5QUCafJyDAAKCRDa6OEJdZac 5X17D/9xtTUbuAsYJ+WO+iW06Ro+n/RbB6sO9aVs3v/LmNIB55X1lVqeqH41ZwMbfQSx4QiwOYS k181RdDWRjUOSkzwpUA/yYy7dKkDycZGhPHLeN8GIxIK8r2B30ECoEZByp7ayEMGTiyAMZ994Bu LcmAzswlA2K7E9d9il4nzTfj5+tN0J02N9AFNq1t45MVrCij/WAwp368HyymiUyKQl8QIVatApO eqbzr3PECfX3gGR/7OOzwV4nuQL1OQUqqOXTVH6XP3uu0jq08idSeOo79bS69mOnGAZlGpsv24x VUYCSxKIqL834relHbqhGkvzBOExuHbLZSi9o1BKieHdjcz1J1CdN022fx6wTsIii4VA0tcv+3u i6Zh697SUFEpbIIWzYokXnbquULG/+UEXQ1V28E7ne+fYZkZg7KfLN3o8fbXSbofS9je7aqw7m2 fiU6uPMyoYf0K82MXLMgvUoLHvRGeODtOBjuOTWP22XZMZHA5eFXR3sM/b5CWYmDZv1dGPOwIMZ OuNc4RoRyu+QpKOXbYyzE4jPRjXe4dg5vUE6eypBjf06Ott0YEaF5mZwslTTWnY5RXe8w5/fg0n GoGVKZ5fud1MiXCzxBI+GptiAuDL+OxTLZFBxsDiOv8BPxo0q0OBD8VEDJeO9xfjv0xxOYeQgEy AOulCeCFjTgIGPg== X-Developer-Key: i=marcandre.lureau@redhat.com; a=openpgp; fpr=87A9BD933F87C606D276F62DDAE8E10975969CE5 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 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=lists1p.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: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1777496877465158500 It can rely on the location of the temporary configuration instead, so we don't have to set that environment variable on every test. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- tests/qtest/dbus-vmstate-test.c | 2 -- tests/dbus-daemon.sh | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/qtest/dbus-vmstate-test.c b/tests/qtest/dbus-vmstate-tes= t.c index 0a82cc9f935..ee034afa7ba 100644 --- a/tests/qtest/dbus-vmstate-test.c +++ b/tests/qtest/dbus-vmstate-test.c @@ -360,8 +360,6 @@ main(int argc, char **argv) exit(1); } =20 - g_setenv("DBUS_VMSTATE_TEST_TMPDIR", workdir, true); - qtest_add_func("/dbus-vmstate/without-list", test_dbus_vmstate_without_list); qtest_add_func("/dbus-vmstate/with-list", diff --git a/tests/dbus-daemon.sh b/tests/dbus-daemon.sh index 474e2501548..c4a50c73774 100755 --- a/tests/dbus-daemon.sh +++ b/tests/dbus-daemon.sh @@ -26,7 +26,7 @@ write_config() cat > "$CONF" < session - unix:tmpdir=3D$DBUS_VMSTATE_TEST_TMPDIR + unix:tmpdir=3D$(dirname "$CONF") =20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/qemu-vnc/trace-events b/tools/qemu-vnc/trace-events new file mode 100644 index 00000000000..e3b550de10e --- /dev/null +++ b/tools/qemu-vnc/trace-events @@ -0,0 +1,21 @@ +qemu_vnc_audio_out_fini(uint64_t id) "id=3D%" PRIu64 +qemu_vnc_audio_out_init(uint64_t id, uint32_t freq, uint8_t channels, uint= 8_t bits) "id=3D%" PRIu64 " freq=3D%u ch=3D%u bits=3D%u" +qemu_vnc_audio_out_set_enabled(uint64_t id, bool enabled) "id=3D%" PRIu64 = " enabled=3D%d" +qemu_vnc_audio_out_write(uint64_t id, size_t size) "id=3D%" PRIu64 " size= =3D%zu" +qemu_vnc_chardev_connected(const char *name) "name=3D%s" +qemu_vnc_clipboard_grab(int selection, uint32_t serial) "selection=3D%d se= rial=3D%u" +qemu_vnc_clipboard_release(int selection) "selection=3D%d" +qemu_vnc_clipboard_request(int selection) "selection=3D%d" +qemu_vnc_client_not_found(const char *host, const char *service) "host=3D%= s service=3D%s" +qemu_vnc_console_io_error(const char *name) "name=3D%s" +qemu_vnc_cursor_define(int width, int height, int hot_x, int hot_y) "w=3D%= d h=3D%d hot=3D%d,%d" +qemu_vnc_input_abs(uint32_t x, uint32_t y) "x=3D%u y=3D%u" +qemu_vnc_input_btn(int button, bool press) "button=3D%d press=3D%d" +qemu_vnc_input_rel(int dx, int dy) "dx=3D%d dy=3D%d" +qemu_vnc_key_event(int qcode, bool down) "qcode=3D%d down=3D%d" +qemu_vnc_owner_appeared(const char *name) "peer=3D%s" +qemu_vnc_owner_vanished(const char *name) "peer=3D%s" +qemu_vnc_scanout(uint32_t width, uint32_t height, uint32_t stride, uint32_= t format) "w=3D%u h=3D%u stride=3D%u fmt=3D0x%x" +qemu_vnc_scanout_map(uint32_t width, uint32_t height, uint32_t stride, uin= t32_t format, uint32_t offset) "w=3D%u h=3D%u stride=3D%u fmt=3D0x%x offset= =3D%u" +qemu_vnc_update(int x, int y, int w, int h, uint32_t stride, uint32_t form= at) "x=3D%d y=3D%d w=3D%d h=3D%d stride=3D%u fmt=3D0x%x" +qemu_vnc_update_map(uint32_t x, uint32_t y, uint32_t w, uint32_t h) "x=3D%= u y=3D%u w=3D%u h=3D%u" --=20 2.54.0