summary refs log tree commit diff stats
path: root/ui/clipboard.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2025-05-25 09:50:54 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2025-05-25 09:50:54 -0400
commit6f388a37e6dc2df4457692afe6adb5448b7db31d (patch)
treec7e8dbc79b70b26d3da2ce03f4092dcd93c0e838 /ui/clipboard.c
parent668df86ee8076152320345d8e36be7c95ec0a09a (diff)
parentf05e1a93f48729b568fdf86a12d56ee142cee5e1 (diff)
downloadfocaccia-qemu-6f388a37e6dc2df4457692afe6adb5448b7db31d.tar.gz
focaccia-qemu-6f388a37e6dc2df4457692afe6adb5448b7db31d.zip
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging
UI-related

- vdagent migration support
- gtk: improve scale handling

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCgA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmgyAywcHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5TbTD/4/3da55xtH0yVSol+G
# T6S7F1GKUbSCi0y/t+PiG2usiE17euZ+m1mKBAOT2kObehS3gWybIreNBZ3IAPZg
# Hm8RoIU6yStui2RZ/rKx2d1P2nq3mMmaB7uToHwPl6KsO2hYm75zmXCGH6oBI+ah
# muNkxzsIky9qnOaKeZRODPkPiG1LXfte0IYV6wkpBcXUqE595rQfD9WDuOJ7WKJe
# T1GiwxdClZGBM6SahDhfwdoFx1yTk8rTtTdYM0K3W7xMQGvCKLGQHDmS7JeQ1lm3
# 42H3kh760UwNqSyk4L0TWZiGrsEWCsbU7heiRLeVL/FBA8N2TWL6xKB/xSO4duJ3
# v63652/rNh18AFnSRu0CaIBwf/hXfLpU/cKv/Sqmm2X8FjD7dLMyaAHCz1BC0acU
# +VA8JKRu7F5GbsisaYyG4lY6u8IBw9sq/FhyNBflBy3MQl0v4PV5x1eqDbGT1560
# k2bQbIChumn8U4TmEA1IHDFX45cdxZmlgnt7yq+SUn5/CmRJrXAlacPRje4A4omL
# YS3Y1Qn4X7sXyIdoHvxofng2NU0nfZX9az27aXsGkRNtzjibZzjl8rJKcaCx0LGQ
# uFJwA+ArCJjTJ3EB09373iGixW0Vuv4dM4IkNp+QGoCOVH0jeER6bs9cNROG6WmS
# e1nWuW0hZgmdusw1S0ncxFc+YA==
# =SjRP
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 24 May 2025 13:34:36 EDT
# gpg:                using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg:                issuer "marcandre.lureau@redhat.com"
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full]
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full]
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276  F62D DAE8 E109 7596 9CE5

* tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu:
  ui/gtk-egl: Render guest content with padding in fixed-scale mode
  ui/gtk-gl-area: Render guest content with padding in fixed-scale mode
  ui/gtk: Consider scaling when propagating ui info
  ui/gtk: Don't update scale in fixed scale mode in gtk-egl.c
  ui/sdl: Consider scaling in mouse event handling
  ui/gtk: Update scales in fixed-scale mode when rendering GL area
  gtk/ui: Introduce helper gd_update_scale
  ui/gtk: Use consistent naming for variables in different coordinates
  ui/gtk: Document scale and coordinate handling
  ui/vdagent: remove migration blocker
  ui/vdagent: add migration support
  ui/vdagent: factor out clipboard peer registration
  ui/vdagent: keep "connected" state
  ui/vdagent: replace Buffer with GByteArray
  ui/clipboard: delay clipboard update when not running
  ui/clipboard: add vmstate_cbinfo
  ui/clipboard: split out QemuClipboardContent
  ui/clipboard: use int for selection field
  ui/gtk: warn if setting the clipboard failed

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'ui/clipboard.c')
-rw-r--r--ui/clipboard.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/ui/clipboard.c b/ui/clipboard.c
index 132086eb13..ec00a0b8ec 100644
--- a/ui/clipboard.c
+++ b/ui/clipboard.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "system/runstate.h"
 #include "ui/clipboard.h"
 #include "trace.h"
 
@@ -7,8 +8,62 @@ static NotifierList clipboard_notifiers =
 
 static QemuClipboardInfo *cbinfo[QEMU_CLIPBOARD_SELECTION__COUNT];
 
+static VMChangeStateEntry *cb_change_state_entry = NULL;
+
+static bool cb_reset_serial_on_resume = false;
+
+static const VMStateDescription vmstate_cbcontent = {
+    .name = "clipboard/content",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .fields = (const VMStateField[]) {
+        VMSTATE_BOOL(available, QemuClipboardContent),
+        VMSTATE_BOOL(requested, QemuClipboardContent),
+        VMSTATE_UINT32(size, QemuClipboardContent),
+        VMSTATE_VBUFFER_ALLOC_UINT32(data, QemuClipboardContent, 0, 0, size),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+const VMStateDescription vmstate_cbinfo = {
+    .name = "clipboard",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .fields = (const VMStateField[]) {
+        VMSTATE_INT32(selection, QemuClipboardInfo),
+        VMSTATE_BOOL(has_serial, QemuClipboardInfo),
+        VMSTATE_UINT32(serial, QemuClipboardInfo),
+        VMSTATE_STRUCT_ARRAY(types, QemuClipboardInfo, QEMU_CLIPBOARD_TYPE__COUNT, 0, vmstate_cbcontent, QemuClipboardContent),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void qemu_clipboard_change_state(void *opaque, bool running, RunState state)
+{
+    int i;
+
+    if (!running) {
+        return;
+    }
+
+    if (cb_reset_serial_on_resume) {
+        qemu_clipboard_reset_serial();
+    }
+
+    for (i = 0; i < QEMU_CLIPBOARD_SELECTION__COUNT; i++) {
+        if (cbinfo[i]) {
+            qemu_clipboard_update(cbinfo[i]);
+        }
+    }
+
+}
+
 void qemu_clipboard_peer_register(QemuClipboardPeer *peer)
 {
+    if (cb_change_state_entry == NULL) {
+        cb_change_state_entry = qemu_add_vm_change_state_handler(qemu_clipboard_change_state, NULL);
+    }
+
     notifier_list_add(&clipboard_notifiers, &peer->notifier);
 }
 
@@ -83,7 +138,9 @@ void qemu_clipboard_update(QemuClipboardInfo *info)
         }
     }
 
-    notifier_list_notify(&clipboard_notifiers, &notify);
+    if (runstate_is_running() || runstate_check(RUN_STATE_SUSPENDED)) {
+        notifier_list_notify(&clipboard_notifiers, &notify);
+    }
 
     if (cbinfo[info->selection] != info) {
         qemu_clipboard_info_unref(cbinfo[info->selection]);
@@ -163,7 +220,12 @@ void qemu_clipboard_reset_serial(void)
             info->serial = 0;
         }
     }
-    notifier_list_notify(&clipboard_notifiers, &notify);
+
+    if (runstate_is_running() || runstate_check(RUN_STATE_SUSPENDED)) {
+        notifier_list_notify(&clipboard_notifiers, &notify);
+    } else {
+        cb_reset_serial_on_resume = true;
+    }
 }
 
 void qemu_clipboard_set_data(QemuClipboardPeer *peer,