diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2021-05-19 07:39:38 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2021-05-21 09:42:44 +0200 |
commit | 0bf41cab93e5c72dcda717abd625698b59d9ba3e (patch) | |
tree | 9f240856fecebcdf5c11adf1a3879fa318820b6c /ui/vnc.c | |
parent | f0349f4d8947ad32d0fa4678cbf5dbb356fcbda1 (diff) |
ui/vnc: clipboard support
This patch adds support for cut+paste to the qemu vnc server, which
allows the vnc client exchange clipbaord data with qemu and other peers
like the qemu vdagent implementation.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20210519053940.1888907-1-kraxel@redhat.com
Message-Id: <20210519053940.1888907-8-kraxel@redhat.com>
Diffstat (limited to 'ui/vnc.c')
-rw-r--r-- | ui/vnc.c | 21 |
1 files changed, 15 insertions, 6 deletions
@@ -25,6 +25,7 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" #include "vnc.h" #include "vnc-jobs.h" #include "trace.h" @@ -1352,6 +1353,9 @@ void vnc_disconnect_finish(VncState *vs) /* last client gone */ vnc_update_server_surface(vs->vd); } + if (vs->cbpeer.update.notify) { + qemu_clipboard_peer_unregister(&vs->cbpeer); + } vnc_unlock_output(vs); @@ -1777,10 +1781,6 @@ uint32_t read_u32(uint8_t *data, size_t offset) (data[offset + 2] << 8) | data[offset + 3]); } -static void client_cut_text(VncState *vs, size_t len, uint8_t *text) -{ -} - static void check_pointer_type_change(Notifier *notifier, void *data) { VncState *vs = container_of(notifier, VncState, mouse_mode_notifier); @@ -2222,6 +2222,10 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) send_xvp_message(vs, VNC_XVP_CODE_INIT); } break; + case VNC_ENCODING_CLIPBOARD_EXT: + vs->features |= VNC_FEATURE_CLIPBOARD_EXT_MASK; + vnc_server_cut_text_caps(vs); + break; case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9: vs->tight->compression = (enc & 0x0F); break; @@ -2438,7 +2442,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) return 8; } if (len == 8) { - uint32_t dlen = read_u32(data, 4); + uint32_t dlen = abs(read_s32(data, 4)); if (dlen > (1 << 20)) { error_report("vnc: client_cut_text msg payload has %u bytes" " which exceeds our limit of 1MB.", dlen); @@ -2450,7 +2454,12 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) } } - client_cut_text(vs, read_u32(data, 4), data + 8); + if (read_s32(data, 4) < 0) { + vnc_client_cut_text_ext(vs, abs(read_s32(data, 4)), + read_u32(data, 8), data + 12); + break; + } + vnc_client_cut_text(vs, read_u32(data, 4), data + 8); break; case VNC_MSG_CLIENT_XVP: if (!(vs->features & VNC_FEATURE_XVP)) { |