[PATCH 4/4] ui/vnc: notify client of clipboard peer status
Lukasz Kornicki <[email protected]>
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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. Change-Id: Id0897a24fae103288c399f73e808ed6c07018359 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