From: Anthony Liguori <anthony@codemonkey.ws>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [RfC PATCH] vnc: rich cursor support.
Date: Mon, 03 May 2010 07:20:25 -0500 [thread overview]
Message-ID: <4BDEBF89.9020702@codemonkey.ws> (raw)
In-Reply-To: <1272887953-28305-1-git-send-email-kraxel@redhat.com>
On 05/03/2010 06:59 AM, Gerd Hoffmann wrote:
> Hi,
>
> Simple patch. Difficuilt matter. Not really sure where to go from
> here ...
>
It'll be a complicated patch :-) I looked at this a while ago and there
are a few gotchas.
> The whole thing is about local cursor support, i.e. just let the UI
> (sdl, vnc viewer, spice client, ...) draw the mouse pointer directly,
> without round trip to the guest for mouse pointer rendering.
>
> Current state in upstream qemu: vmware svga supports it. sdl supports
> it. When running vmware vga on sdl you should get it. In theory. In
> practice it doesn't work correctly.
>
Cirrus technically supports it do but almost nothing uses the hardware
cursor support in Cirrus (only win2k configured in a certain way).
> SDL can only handle 1bit (black/white) mouse cursors (with mask)
>
I personally don't think we should even bother with anything other than
ARGB cursors. Not enough things render 1bit cursors via hardware in my
experience.
> I've seen vmware vga send only 1bit cursors (with mask, winxp guest),
> althougth it seems to be designed to support colored pointers too.
>
VMware VGA sends full ARGB cursors. That's what you get by default when
you use vmware-vga and X.
> vnc has two extentions for it: xcursor (1bit too, using a mask, but also
> allows to specify foreground/backgrund color) and rich cursor (uses
> pixelformat of the display, i.e. allows color).
>
The key problem with VNC is that it has no notion of disabling cursor
offload. This means that when the guest tries to disable it (like via a
reset cycle), we have to make sure to send a NULL cursor to avoid the
cursor being rendered.
This effectively disables any attempt by the client to draw a double
cursor though.
> spice supports a whole bunch of formats, although I've seen only two of
> them used in practice: 1bit (with mask) and 32bit (rgb + alpha).
>
>
> The current hooks supporting local pointer (mouse_set, cursor_define)
> are in DisplayState, although I think they belong into
> DisplayChangeListener.
>
>
> Ok, how to sort this mess?
>
>
> I think we should put everything into a QEMUCursor struct, so we don't
> have to pass tons of parameters to the ->cursor_define() callback.
>
Agreed.
> Does it make sense to reuse "struct PixelFormat" for the cursor? I tend
> to think not. I expect we'll see three different cases be used in
> practice:
>
> (1) 1-bit image (and mask).
> (2) Same pixelformat as DisplayState (and mask).
> (3) 32bit RGB + alpha.
>
I think always making a cursor 32bit ARGB would be reasonable. Let the
backend sort things out. Since we have the PixelFormat structures, it's
easy enough to add a routine to convert between formats.
> Current PixelFormat can cover only (2) and even in that case it is
> redundant with DisplayState->pf.
>
> I think we also better allow only certain sizes. Minimum requirement
> should be that the width is a multiple of 8. Handling bitmasks just
> become too ugly without that. I'd tend to go further even and allow
> only 32x32 and 64x64 mouse pointers. Maybe 48x48 too.
>
I'm not sure it's necessary to be so restrictive. If you assume ARGB,
then masking isn't an issue.
Regards,
Anthony Liguori
> Comments?
>
>
> cheers,
> Gerd
>
> ---
> vnc.c | 35 +++++++++++++++++++++++++++++++++++
> vnc.h | 2 +
> 2 files changed, 37 insertions(+), 0 deletions(-)
>
> diff --git a/vnc.c b/vnc.c
> index 9ba603c..5d9b9cb 100644
> --- a/vnc.c
> +++ b/vnc.c
> @@ -925,6 +925,36 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
> }
> }
>
> +static void vnc_mouse_set(int x, int y, int visible)
> +{
> + /* can we do that ??? */
> +}
> +
> +static void vnc_cursor_define(int width, int height, int bpp,
> + int hot_x, int hot_y,
> + uint8_t *image, uint8_t *mask)
> +{
> + VncDisplay *vd = vnc_display;
> + int pixels, isize, msize;
> + VncState *vs;
> +
> + pixels = width * height;
> + isize = pixels * bpp / 8;
> + msize = pixels / 8;
> +
> + QTAILQ_FOREACH(vs,&vd->clients, next) {
> + if (!vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR))
> + continue;
> + 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, hot_x, hot_y, width, height,
> + VNC_ENCODING_RICH_CURSOR);
> + vnc_write(vs, image, isize);
> + vnc_write(vs, mask, msize);
> + }
> +}
> +
> static int find_and_clear_dirty_height(struct VncState *vs,
> int y, int last_x, int x)
> {
> @@ -1800,6 +1830,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
> case VNC_ENCODING_POINTER_TYPE_CHANGE:
> vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
> break;
> + case VNC_ENCODING_RICH_CURSOR:
> + vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
> + break;
> case VNC_ENCODING_EXT_KEY_EVENT:
> send_ext_key_event_ack(vs);
> break;
> @@ -2487,6 +2520,8 @@ void vnc_display_init(DisplayState *ds)
> dcl->dpy_resize = vnc_dpy_resize;
> dcl->dpy_setdata = vnc_dpy_setdata;
> register_displaychangelistener(ds, dcl);
> + ds->mouse_set = vnc_mouse_set;
> + ds->cursor_define = vnc_cursor_define;
> }
>
>
> diff --git a/vnc.h b/vnc.h
> index b593608..ede9040 100644
> --- a/vnc.h
> +++ b/vnc.h
> @@ -266,6 +266,7 @@ enum {
> #define VNC_FEATURE_TIGHT 4
> #define VNC_FEATURE_ZLIB 5
> #define VNC_FEATURE_COPYRECT 6
> +#define VNC_FEATURE_RICH_CURSOR 7
>
> #define VNC_FEATURE_RESIZE_MASK (1<< VNC_FEATURE_RESIZE)
> #define VNC_FEATURE_HEXTILE_MASK (1<< VNC_FEATURE_HEXTILE)
> @@ -274,6 +275,7 @@ enum {
> #define VNC_FEATURE_TIGHT_MASK (1<< VNC_FEATURE_TIGHT)
> #define VNC_FEATURE_ZLIB_MASK (1<< VNC_FEATURE_ZLIB)
> #define VNC_FEATURE_COPYRECT_MASK (1<< VNC_FEATURE_COPYRECT)
> +#define VNC_FEATURE_RICH_CURSOR_MASK (1<< VNC_FEATURE_RICH_CURSOR)
>
>
> /* Client -> Server message IDs */
>
next prev parent reply other threads:[~2010-05-03 12:20 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-03 11:59 [Qemu-devel] [RfC PATCH] vnc: rich cursor support Gerd Hoffmann
2010-05-03 12:20 ` Anthony Liguori [this message]
2010-05-03 12:46 ` Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4BDEBF89.9020702@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=kraxel@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).