Re: [PATCH 4/4] ui/vnc: notify client of clipboard peer status
Lucas Kornicki <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Hi Marc-Andre I quickly became aware of the shortcomings of my v1 series and I've already drafted a v2 where the cover is a bit more detailed and the commits were fixed to remove the Change-IDs. On 8/18/26 15:33, Marc-André Lureau wrote: > !-------------------------------------------------------------------| > CAUTION: External Email > > |-------------------------------------------------------------------! > > Hi Lukasz > > On Tue, Aug 18, 2026 at 4:15 PM Lukasz Kornicki > <[email protected]> wrote: >> Introduce a new vnc message (VNC_MSG_SERVER_QEMU_CLIPBOARD_STATUS) and >> the corresponding feature/encoding. >> >> When a client requests this feature, the server will inform the client >> whether a guest clipboard peer is present. The server will repeat the >> notification each time availability of a guest clipboard peer changes. >> >> This change enables the VNC client to determine if a guest side >> clipboard peer is available for clipboard exchange and react to >> changes of its availability. >> >> Until now the VNC clipboard peer was only registered when >> VNC_FEATURE_CLIPBOARD_EXT was enabled. With this change the VNC peer >> can be registered just for the purpose of receiving peer status >> updates. This requires introducing a VNC_FEATURE_CLIPBOARD_EXT guard >> before the QEMU_CLIPBOARD_UPDATE_INFO handler which previously only ran >> if VNC_FEATURE_CLIPBOARD_EXT was enabled. >> > The series looks good, but this extension is not documented afaict. > Can you make a PR for it? Sure. I've found this repo before but was not aware that it functions in any official capacity. >> Change-Id: Id0897a24fae103288c399f73e808ed6c07018359 > What is this? Is it a gerrit thing? Yes, I forgot to remove the commit-msg hook and they got regenerated right after I removed them :) >> Signed-off-by: Lukasz Kornicki <[email protected]> >> --- >> ui/trace-events | 1 + >> ui/vnc-clipboard.c | 31 ++++++++++++++++++++++++++++++- >> ui/vnc.c | 6 ++++++ >> ui/vnc.h | 8 ++++++++ >> 4 files changed, 45 insertions(+), 1 deletion(-) >> >> diff --git a/ui/trace-events b/ui/trace-events >> index 917d116d90..d2fe153b7d 100644 >> --- a/ui/trace-events >> +++ b/ui/trace-events >> @@ -48,6 +48,7 @@ vnc_msg_server_ext_desktop_resize(void *state, void *ioc, int width, int height, >> vnc_msg_client_audio_enable(void *state, void *ioc) "VNC client msg audio enable state=%p ioc=%p" >> vnc_msg_client_audio_disable(void *state, void *ioc) "VNC client msg audio disable state=%p ioc=%p" >> vnc_msg_client_audio_format(void *state, void *ioc, int fmt, int channels, int freq) "VNC client msg audio format state=%p ioc=%p fmt=%d channels=%d freq=%d" >> +vnc_clipboard_peer_status_send(void *state, bool present) "VNC server clipboard peer status state=%p present=%d" >> vnc_msg_client_cut_text(void *state, void *ioc, int len) "VNC client msg cut text state=%p ioc=%p len=%u" >> vnc_msg_client_cut_text_ext(void *state, void *ioc, int len, int flags) "VNC client msg cut text state=%p ioc=%p len=%u flags=%u" >> vnc_msg_client_ext_key_event(void *state, void *ioc, int down, int sym, int keycode) "VNC client msg ext key event state=%p ioc=%p down=%u sym=%u keycode=%u" >> diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c >> index 67f710f6ed..4ecc4489e4 100644 >> --- a/ui/vnc-clipboard.c >> +++ b/ui/vnc-clipboard.c >> @@ -26,6 +26,7 @@ >> #include "qemu/error-report.h" >> #include "vnc.h" >> #include "vnc-jobs.h" >> +#include "trace.h" >> >> static uint8_t *inflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size) >> { >> @@ -224,6 +225,23 @@ static void vnc_clipboard_update_info(VncState *vs, QemuClipboardInfo *info) >> } >> } >> >> +void vnc_clipboard_peer_status_send(VncState *vs, bool present) >> +{ >> + if (!vnc_has_feature(vs, VNC_FEATURE_CLIPBOARD_STATUS)) { >> + return; >> + } >> + >> + trace_vnc_clipboard_peer_status_send(vs, present); >> + >> + vnc_lock_output(vs); >> + vnc_write_u8(vs, VNC_MSG_SERVER_QEMU); >> + vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_CLIPBOARD_STATUS); >> + vnc_write_u16(vs, present ? VNC_CLIPBOARD_PEER_PRESENT >> + : VNC_CLIPBOARD_PEER_ABSENT); >> + vnc_unlock_output(vs); >> + vnc_flush(vs); >> +} >> + >> static void vnc_clipboard_notify(Notifier *notifier, void *data) >> { >> VncState *vs = container_of(notifier, VncState, cbpeer.notifier); >> @@ -231,13 +249,24 @@ static void vnc_clipboard_notify(Notifier *notifier, void *data) >> >> switch (notify->type) { >> case QEMU_CLIPBOARD_UPDATE_INFO: >> + /* ignore the update if client does not want ext messages */ >> + if (!vnc_has_feature(vs, VNC_FEATURE_CLIPBOARD_EXT)) { >> + return; >> + } >> + >> vnc_clipboard_update_info(vs, notify->info); >> return; >> case QEMU_CLIPBOARD_RESET_SERIAL: >> /* ignore */ >> return; >> case QEMU_CLIPBOARD_PEER_UPDATE: >> - /* ignore */ >> + /* only guest side peers affect the status we relay to the client */ >> + if (!notify->peer_update.peer->guest) { >> + return; >> + } >> + >> + vnc_clipboard_peer_status_send(vs, >> + qemu_clipboard_guest_peer_present()); >> return; >> } >> } >> diff --git a/ui/vnc.c b/ui/vnc.c >> index 656768f9c9..9e44a20311 100644 >> --- a/ui/vnc.c >> +++ b/ui/vnc.c >> @@ -2191,6 +2191,12 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) >> vnc_set_feature(vs, VNC_FEATURE_CLIPBOARD_EXT); >> vnc_server_cut_text_caps(vs); >> break; >> + case VNC_ENCODING_CLIPBOARD_STATUS: >> + vnc_set_feature(vs, VNC_FEATURE_CLIPBOARD_STATUS); >> + vnc_clipboard_peer_register(vs); >> + vnc_clipboard_peer_status_send(vs, >> + qemu_clipboard_guest_peer_present()); >> + break; >> case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9: >> vc->worker.tight.compression = (enc & 0x0F); >> break; >> diff --git a/ui/vnc.h b/ui/vnc.h >> index d8b0070396..6e8fa66e9c 100644 >> --- a/ui/vnc.h >> +++ b/ui/vnc.h >> @@ -422,6 +422,7 @@ enum { >> #define VNC_ENCODING_DESKTOP_RESIZE_EXT 0XFFFFFECC /* -308 */ >> #define VNC_ENCODING_XVP 0XFFFFFECB /* -309 */ >> #define VNC_ENCODING_ALPHA_CURSOR 0XFFFFFEC6 /* -314 */ >> +#define VNC_ENCODING_CLIPBOARD_STATUS 0XFFFFFEC5 /* -315 */ >> #define VNC_ENCODING_WMVi 0x574D5669 >> #define VNC_ENCODING_CLIPBOARD_EXT 0xc0a1e5ce >> >> @@ -466,6 +467,7 @@ enum VncFeatures { >> VNC_FEATURE_LED_STATE, >> VNC_FEATURE_XVP, >> VNC_FEATURE_CLIPBOARD_EXT, >> + VNC_FEATURE_CLIPBOARD_STATUS, >> VNC_FEATURE_AUDIO, >> }; >> >> @@ -507,6 +509,7 @@ enum VncFeatures { >> >> /* QEMU server -> client message IDs */ >> #define VNC_MSG_SERVER_QEMU_AUDIO 1 >> +#define VNC_MSG_SERVER_QEMU_CLIPBOARD_STATUS 2 >> >> >> >> @@ -541,6 +544,10 @@ enum VncFeatures { >> #define VNC_CLIPBOARD_NOTIFY (1 << 27) >> #define VNC_CLIPBOARD_PROVIDE (1 << 28) >> >> +/* guest side clipboard peer status */ >> +#define VNC_CLIPBOARD_PEER_ABSENT 0 >> +#define VNC_CLIPBOARD_PEER_PRESENT 1 >> + >> VncDisplay *vnc_display_new(const char *id, Error **errp); >> void vnc_display_free(VncDisplay *vd); >> >> @@ -637,6 +644,7 @@ void vnc_zrle_clear(VncWorker *worker); >> >> /* vnc-clipboard.c */ >> void vnc_clipboard_peer_register(VncState *vs); >> +void vnc_clipboard_peer_status_send(VncState *vs, bool present); >> 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, uint8_t *data); >> -- >> 2.43.0 >> >>