[Spice-devel] paravirtual mouse/tablet, v5

Alon Levy alevy at redhat.com
Thu Jan 27 07:12:12 PST 2011


On Thu, Jan 27, 2011 at 02:11:35PM +0100, Gerd Hoffmann wrote:
>   Hi,
> 
> Next revision the pvmouse protocol.  It is quite different now, I've
> decided to move to a model with one message per updated value,
> simliar to the linux input layer.  There isn't a "mouse move"
> message any more.  A mouse move event will be three messages now:
> one to update X, one to update Y and a third sync message to mark
> the end of the message block.  That should be *alot* easier to
> extend in the future.
> 
> Header file is attached.  Comments are welcome.
> 
Comments inline (one at the very end).

> thanks,
>   Gerd

> #ifndef __QEMU_PVMOUSE__
> #define __QEMU_PVMOUSE__ 1
> 
> /*
>  * qemu patavirtual mouse/tablet interface
>  *
>  * quick overview
>  * ==============
>  *
>  * device initialization
>  * ---------------------
>  *
>  *  (1) host sends INIT with supported feature bits
>  *  (2) guests sends ACK to ack the features it is
>  *      able to handle (and willing to use).
>  *  (3) host sends a INFO message for each button and
>  *      each axis supported.  More INFO messages might
>  *      follow for features added to the protocol later
>  *      on if enabled by the INIT+ACK handshake.
>  *      A SYNC message marks the end of the device
>  *      information messages.
>  *
>  * input event reporting
>  * ---------------------
>  *
>  *  host sends one or more BTN_DOWN, BTN_UP and AXIS messages,
>  *  followed by a SYNC.  A button press would be just BTN_DOWN+SYNC.
>  *  A mouse move would be two AXIS messages (one for x, one for y)
>  *  followed by SYNC.
>  *
>  * multitouch events
>  * -----------------
>  *
>  *  Each reported touch point starts with a POINT message, followed by
>  *  multiple AXIS messages (at least x+y, most likely also pressure).
>  *  The whole group is followed by SYNC.  A report for two fingers
>  *  would look like this:
>  *
>  *   POINT
>  *     AXIS x=23
>  *     AXIS y=42
>  *     AXIS pressure=3
>  *   POINT
>  *     AXIS x=78
>  *     AXIS y=56
>  *     AXIS pressure=4
>  *   SYNC
>  *
>  *  In case the device supports ID tracking the POINT message will
>  *  carry the ID.  Updates need only be sent for points which did
>  *  change.  IDs are added by using them the first time.  IDs are
>  *  invalidated when the finger is lifted (aka pressure=0).
>  *
>  *  In case the device doesn't support ID tracking each report must
>  *  include all current touch points (in unspecified order).
>  *
>  */
> 
> #include <inttypes.h>
> 
> /*
>  * our virtio-serial channel name(s)
>  */
> #define QEMU_PVMOUSE_FORMAT "org.qemu.pvmouse.%d"
> 
> enum qemu_pvmouse_msg_type {
>     /* feature flag negotiation */
>     QEMU_PVMOUSE_MSG_INIT,
>     QEMU_PVMOUSE_MSG_ACK,
>     /* device information */
>     QEMU_PVMOUSE_MSG_AXIS_INFO,
>     QEMU_PVMOUSE_MSG_BUTTON_INFO,
>     /* device events */
>     QEMU_PVMOUSE_MSG_BTN_DOWN,
>     QEMU_PVMOUSE_MSG_BTN_UP,
>     QEMU_PVMOUSE_MSG_AXIS,
>     /* message grouping */
>     QEMU_PVMOUSE_MSG_POINT,
>     QEMU_PVMOUSE_MSG_SYNC,
> };
> 
> typedef enum qemu_pvmouse_features {
>     QEMU_PVMOUSE_FEATURE_MULTITOUCH,
> };
> 
> /*
>  * QEMU_PVMOUSE_MSG_INIT, host -> guest
>  * First message.  Sent before any other event.
>  */
> typedef struct qemu_pvmouse_init {
>     uint32_t features;        /* qemu_pvmouse_features */
> } qemu_pvmouse_init;
> 
> /*
>  * QEMU_PVMOUSE_MSG_ACK, guest -> host
>  * Sent after pvmouse_init.  Host will not send
>  * additional messages until this is received.
>  */
> typedef struct qemu_pvmouse_ack {
>     uint32_t features; /* qemu_pvtable_features */

Why does this comment say "qemu_pvtable_features" and the one above
says "qemu_pvmouse_features"?

> };
> 
> 
> enum qemu_pvmouse_axis_type {
>     /* absolute */
>     QEMU_PVMOUSE_AXIS_POS_X = 1,
>     QEMU_PVMOUSE_AXIS_POS_Y,
>     QEMU_PVMOUSE_AXIS_PRESSURE,
> 

So is the concensus to not treat 3d mice as core protocol?
just a AXIS_POS_Z and AXIS_REL_Z I think would be simple to
add. Running cad apps in a vm seems possible.

>     /* relative */
>     QEMU_PVMOUSE_AXIS_REL_X = 257,
>     QEMU_PVMOUSE_AXIS_REL_Y,
>     QEMU_PVMOUSE_AXIS_WHEEL_VERT,
>     QEMU_PVMOUSE_AXIS_WHEEL_HORIZ,
> };
> 
> enum qemu_pvmouse_axis_flags {
>     QEMU_PVMOUSE_AXIS_PEN,
>     QEMU_PVMOUSE_AXIS_TOUCH,
>     QEMU_PVMOUSE_AXIS_MULTITOUCH,
>     QEMU_PVMOUSE_AXIS_POINT_ID,
> };
> #define QEMU_PVMOUSE_AXIS_MASK_PEN         (1 << QEMU_PVMOUSE_AXIS_PEN)
> #define QEMU_PVMOUSE_AXIS_MASK_TOUCH       (1 << QEMU_PVMOUSE_AXIS_TOUCH)
> #define QEMU_PVMOUSE_AXIS_MASK_MULTITOUCH  (1 << QEMU_PVMOUSE_AXIS_MULTITOUCH)
> #define QEMU_PVMOUSE_AXIS_MASK_POINT_ID    (1 << QEMU_PVMOUSE_AXIS_ID)
> 
> /*
>  * QEMU_PVMOUSE_MSG_AXIS_INFO, host -> guest
>  * Send axis informations.
>  */
> typedef struct qemu_pvmouse_axis_info {
>     uint32_t axis_id;
>     uint32_t type;
>     uint32_t flags;
>     int32_t  min;
>     int32_t  max;
>     char     label[];
> };
> 
> /*
>  * QEMU_PVMOUSE_MSG_AXIS, host -> guest
>  * Send mouse/pen/finger/wheel move events.
>  */
> typedef struct qemu_pvmouse_axis_event {
>     uint32_t axis_id;
>     int32_t  value;
> };
> 
> /*
>  * QEMU_PVMOUSE_MSG_BUTTON_INFO, host -> guest
>  * Send button informations.
>  */
> typedef struct qemu_pvmouse_button_info {
>     uint32_t button_id;
>     char     label[];
> };
> 
> /*
>  * QEMU_PVMOUSE_MSG_BTN_{DOWN,UP}, host -> guest
>  * Send button press+release events.
>  */
> typedef struct qemu_pvmouse_btn_event {
>     uint32_t button_id;
> };
> 
> /*
>  * QEMU_PVMOUSE_MSG_POINT, host -> guest
>  * marks the start of a point group for multitouch devices.
>  */
> typedef struct qemu_pvmouse_point {
>     uint32_t id;
> };
> 
> /*
>  * QEMU_PVMOUSE_MSG_SYNC, host -> guest
>  * Marks the end of a message group which belongs together
>  * and carries the time stamp for all those events.
>  *
>  * The timestamp is specified in nanoseconds.  Timebase is undefined.
>  * This is supposed to be used to figure how much time passed between
>  * two events, to decide whenever two mouse clicks should be
>  * interpreted as double click or not and simliar stuff.
>  */
> typedef struct qemu_pvmouse_sync {
>     uint64_t timestamp;
> };
> 
> 
> typedef struct qemu_pvmouse_header {
>     uint32_t size;            /* whole message size */
>     uint32_t type;            /* qemu_pvmouse_type */
> } qemu_pvmouse_header;
> 
> typedef union qemu_pvmouse_payload {
>     qemu_pvmouse_init     init;
>     qemu_pvmouse_ack      ack;
>     /* ... */
> };
> 
> typedef struct qemu_pvmouse_message {
>     qemu_pvmouse_header  hdr;
>     qemu_pvmouse_payload data;
> } qemu_pvmouse_message;
> 
> #endif /* __QEMU_PVMOUSE__ */

What's the outcome of the discussion with Peter? wasn't there
a suggestion to send information from the host to the guest about
monitor configuration, so guest can do inverse to send correct
coordinates to host?


> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel



More information about the Spice-devel mailing list