Page MenuHomeFreeBSD

D60431.1793475105.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D60431.1793475105.diff

diff --git a/usr.sbin/bhyve/usb_mouse.c b/usr.sbin/bhyve/usb_mouse.c
--- a/usr.sbin/bhyve/usb_mouse.c
+++ b/usr.sbin/bhyve/usb_mouse.c
@@ -51,6 +51,9 @@
/* USB endpoint context (1-15) for reporting mouse data events*/
#define UMOUSE_INTR_ENDPT 1
+/* reports not yet taken by the guest */
+#define UMOUSE_QLEN 64
+
#define UMOUSE_REPORT_DESC_TYPE 0x22
#define UMOUSE_GET_REPORT 0x01
@@ -239,8 +242,10 @@
struct umouse_softc {
struct usb_hci *hci;
- struct umouse_report um_report;
- int newdata;
+ struct umouse_report um_report; /* the latest state */
+ int newdata; /* a report is queued */
+ struct umouse_report q[UMOUSE_QLEN]; /* oldest first */
+ int qhead, qlen;
struct {
uint8_t idle;
uint8_t protocol;
@@ -253,6 +258,29 @@
struct timeval prev_evt;
};
+/*
+ * Queue a report for the guest (sc->mtx held). A report with the buttons
+ * of the newest queued one and no wheel movement in either is a move: it
+ * replaces that one. Anything else gets a report of its own, so the guest
+ * sees every press, release and wheel step, however quickly they came.
+ */
+static void
+umouse_queue(struct umouse_softc *sc, const struct umouse_report *r)
+{
+ struct umouse_report *last;
+
+ last = sc->qlen > 0 ?
+ &sc->q[(sc->qhead + sc->qlen - 1) % UMOUSE_QLEN] : NULL;
+ if (last != NULL && last->buttons == r->buttons && last->z == 0 &&
+ r->z == 0)
+ *last = *r;
+ else if (sc->qlen < UMOUSE_QLEN) {
+ sc->q[(sc->qhead + sc->qlen) % UMOUSE_QLEN] = *r;
+ sc->qlen++;
+ } else
+ *last = *r; /* full: the latest state still arrives */
+}
+
static void
umouse_event(uint8_t button, int x, int y, void *arg)
{
@@ -286,6 +314,7 @@
/* scale coords to mouse resolution */
sc->um_report.x = MOUSE_MAX_X * x / gc->width;
sc->um_report.y = MOUSE_MAX_Y * y / gc->height;
+ umouse_queue(sc, &sc->um_report);
sc->newdata = 1;
pthread_mutex_unlock(&sc->mtx);
@@ -754,11 +783,18 @@
sc->polling = 1;
if (len > 0) {
- sc->newdata = 0;
+ struct umouse_report *r = &sc->um_report;
+
+ if (sc->qlen > 0) {
+ r = &sc->q[sc->qhead];
+ sc->qhead = (sc->qhead + 1) % UMOUSE_QLEN;
+ sc->qlen--;
+ }
+ sc->newdata = sc->qlen > 0;
data->processed = 1;
data->bdone += 6;
- memcpy(udata, &sc->um_report, 6);
+ memcpy(udata, r, 6);
data->blen = len - 6;
if (data->blen > 0)
err = USB_ERR_SHORT_XFER;
@@ -783,6 +819,7 @@
sc = scarg;
sc->newdata = 0;
+ sc->qhead = sc->qlen = 0;
return (0);
}
@@ -810,6 +847,9 @@
SNAPSHOT_VAR_OR_LEAVE(sc->um_report, meta, ret, done);
SNAPSHOT_VAR_OR_LEAVE(sc->newdata, meta, ret, done);
+ /* The queue is not saved: a restored tablet sends the latest state. */
+ if (meta->op == VM_SNAPSHOT_RESTORE)
+ sc->qhead = sc->qlen = 0;
SNAPSHOT_VAR_OR_LEAVE(sc->hid.idle, meta, ret, done);
SNAPSHOT_VAR_OR_LEAVE(sc->hid.protocol, meta, ret, done);
SNAPSHOT_VAR_OR_LEAVE(sc->hid.feature, meta, ret, done);

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 31, 7:31 PM (11 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40407331
Default Alt Text
D60431.1793475105.diff (2 KB)

Event Timeline