Hi On Thu, Dec 3, 2020 at 3:11 PM Gerd Hoffmann <kra...@redhat.com> wrote:
> 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 <kra...@redhat.com> > --- > ui/vnc.h | 2 ++ > ui/vnc.c | 21 ++++++++++++++++++--- > 2 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/ui/vnc.h b/ui/vnc.h > index 6f5006da3593..c8d3ad9ec496 100644 > --- a/ui/vnc.h > +++ b/ui/vnc.h > @@ -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) > diff --git a/ui/vnc.c b/ui/vnc.c > index 8c2771c1ce3b..247e80d8f5c8 100644 > --- a/ui/vnc.c > +++ b/ui/vnc.c > @@ -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); > + } > Looks good. Minor nit, I would suggest to do the "if (!vs->vd->cursor) return" in vnc_cursor_define(). Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com> } > > static void set_pixel_conversion(VncState *vs) > -- > 2.27.0 > > > -- Marc-André Lureau