From f155cbd57b37fa600c580ed30d593f47383ecd38 Mon Sep 17 00:00:00 2001
From: Carl Hauser <chau...@pullman.com>
Date: Fri, 16 Aug 2024 09:20:36 -0700
Subject: [PATCH] hw/char: suppress sunmouse events with no changes

Sun optical mice circa 1993 were based on the Mouse Systems
Corp. optical mice. The technical manual for those mice
states that mice only send events when there is motion or the
button state changes. The Solaris 2.5.6 mouse driver seems
to be confused by updates that don't follow this specification.

This patch adds a field to the ESCCChannelState to contain
the button state sent in the last event and uses that in
sunmouse_event to avoid sending unnecessary updates.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2518
Signed-off-by: Carl Hauser <chau...@pullman.com>
---
 hw/char/escc.c         | 10 ++++++++++
 include/hw/char/escc.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/char/escc.c b/hw/char/escc.c
index d450d70eda..7732141cf5 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -287,6 +287,7 @@ static void escc_reset_chn(ESCCChannelState *s)
     s->rxint = s->txint = 0;
     s->rxint_under_svc = s->txint_under_svc = 0;
     s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
+    s->sunmouse_prev_state = 0;
     clear_queue(s);
 }

@@ -959,6 +960,15 @@ static void sunmouse_event(void *opaque,
     int ch;

     trace_escc_sunmouse_event(dx, dy, buttons_state);
+
+    /* Don't send duplicate events without motion */
+    if (dx == 0 &&
+        dy == 0 &&
+        (s->sunmouse_prev_state ^ buttons_state) == 0) {
+        return;
+    }
+    s->sunmouse_prev_state = buttons_state;
+
     ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */

     if (buttons_state & MOUSE_EVENT_LBUTTON) {
diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h
index 5669a5b811..bc5ba4f564 100644
--- a/include/hw/char/escc.h
+++ b/include/hw/char/escc.h
@@ -46,6 +46,7 @@ typedef struct ESCCChannelState {
     uint8_t rx, tx;
     QemuInputHandlerState *hs;
     char *sunkbd_layout;
+    int sunmouse_prev_state;
 } ESCCChannelState;

 struct ESCCState {
--
2.34.1

Reply via email to