#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 /* * 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 */ }; enum qemu_pvmouse_axis_type { /* absolute */ QEMU_PVMOUSE_AXIS_POS_X = 1, QEMU_PVMOUSE_AXIS_POS_Y, QEMU_PVMOUSE_AXIS_PRESSURE, /* 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__ */