diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2020-12-08 12:57:34 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2020-12-11 08:06:40 +0100 |
commit | 074a86d0b3e8a9352dcca32b46917e1b3ab23ea4 (patch) | |
tree | 22480fee922b49de7dc8a31056c8857636bfcf24 /ui | |
parent | a7d83e43597964047e1d2f326c249082e7d9b99f (diff) |
vnc: add alpha cursor support
There is a new vnc extension for cursors with an alpha channel. Use
it if supported by the vnc client, prefer it over the "rich cursor"
extension which supports only a bitmask for transparency.
This is a visible improvement especially on modern desktops which
actually use the alpha channel when defining cursors.
https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#cursor-with-alpha-pseudo-encoding
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Tested-by: Daniel P. Berrangé <berrange@redhat.com>
Message-id: 20201208115737.18581-7-kraxel@redhat.com
Diffstat (limited to 'ui')
-rw-r--r-- | ui/vnc.c | 21 | ||||
-rw-r--r-- | ui/vnc.h | 2 |
2 files changed, 20 insertions, 3 deletions
@@ -937,6 +937,18 @@ static int vnc_cursor_define(VncState *vs) QEMUCursor *c = vs->vd->cursor; int isize; + if (vnc_has_feature(vs, VNC_FEATURE_ALPHA_CURSOR)) { + vnc_lock_output(vs); + vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); + vnc_write_u8(vs, 0); /* padding */ + vnc_write_u16(vs, 1); /* # of rects */ + vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height, + VNC_ENCODING_ALPHA_CURSOR); + vnc_write_s32(vs, VNC_ENCODING_RAW); + vnc_write(vs, c->data, c->width * c->height * 4); + vnc_unlock_output(vs); + return 0; + } if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) { vnc_lock_output(vs); vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); @@ -2102,9 +2114,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) break; case VNC_ENCODING_RICH_CURSOR: vs->features |= VNC_FEATURE_RICH_CURSOR_MASK; - if (vs->vd->cursor) { - vnc_cursor_define(vs); - } + break; + case VNC_ENCODING_ALPHA_CURSOR: + vs->features |= VNC_FEATURE_ALPHA_CURSOR_MASK; break; case VNC_ENCODING_EXT_KEY_EVENT: send_ext_key_event_ack(vs); @@ -2134,6 +2146,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vnc_desktop_resize(vs); check_pointer_type_change(&vs->mouse_mode_notifier, NULL); vnc_led_state_change(vs); + if (vs->vd->cursor) { + vnc_cursor_define(vs); + } } static void set_pixel_conversion(VncState *vs) @@ -448,6 +448,7 @@ enum VncFeatures { VNC_FEATURE_TIGHT, VNC_FEATURE_ZLIB, VNC_FEATURE_RICH_CURSOR, + VNC_FEATURE_ALPHA_CURSOR, VNC_FEATURE_TIGHT_PNG, VNC_FEATURE_ZRLE, VNC_FEATURE_ZYWRLE, @@ -461,6 +462,7 @@ enum VncFeatures { #define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT) #define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB) #define VNC_FEATURE_RICH_CURSOR_MASK (1 << VNC_FEATURE_RICH_CURSOR) +#define VNC_FEATURE_ALPHA_CURSOR_MASK (1 << VNC_FEATURE_ALPHA_CURSOR) #define VNC_FEATURE_TIGHT_PNG_MASK (1 << VNC_FEATURE_TIGHT_PNG) #define VNC_FEATURE_ZRLE_MASK (1 << VNC_FEATURE_ZRLE) #define VNC_FEATURE_ZYWRLE_MASK (1 << VNC_FEATURE_ZYWRLE) |