Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F176842037
D60431.1793475105.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None
D60431.1793475105.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D60431: bhyve: usb_mouse: do not lose a button or wheel event
Attached
Detach File
Event Timeline