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

Reply via email to