Well, I was wrong -- it is sending a duplicate mouse packets when the mouse wheel is rotated. The packets correctly represent the mouse buttons state. I just now discovered that one of my Logitech mice sends continuous mouse events when the wheel is rotated half a notch and held there. Another Logitech mouse doesn't do that but does send multiple (6-10) events per notch. A Microsoft mouse sends 2 events per notch.
I don't know where these should be suppressed. Mouse wheel rotation of a host mouse shouldn't send anything to the emulated Sun mouse. I suspect that the unwanted host events are propagating down to escc via calls to sunmouse_sync. So is sunmouse_sync where they should be filtered out? Probably, because the calling code is not specific to sunmouse and for other mice those calls are needed. -- Carl On Mon, Sep 2, 2024 at 4:16 PM Carl Hauser <chau...@pullman.com> wrote: > This still, but less frequently, shows the behavior of having the cursor > leap downwards occasionally. I may not be able to work on debugging it > until next week, but I'll try to see if I can figure it out sooner. The > hypothesis with the old code was that it was sending floods of mouse > messages and the Sun driver was dropping a byte at some point. So that's > the first thing I'll look into with this new code, but it could be > something different. This is definitely better than the old code -- just > not sending anything in response to mouse wheel movement helps a lot. > > On Mon, Sep 2, 2024 at 2:38 PM Mark Cave-Ayland < > mark.cave-ayl...@ilande.co.uk> wrote: > >> Update the Sun mouse implementation to use QemuInputHandler instead of the >> legacy qemu_add_mouse_event_handler() function. >> >> Note that this conversion adds extra sunmouse_* members to >> ESCCChannelState >> but they are not added to the migration stream (similar to the Sun >> keyboard >> members). If this were desired in future, the Sun devices should be split >> into separate devices and added to the migration stream there instead. >> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> >> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2518 >> --- >> hw/char/escc.c | 79 ++++++++++++++++++++++++++++++------------ >> include/hw/char/escc.h | 3 ++ >> roms/seabios | 2 +- >> 3 files changed, 60 insertions(+), 24 deletions(-) >> >> diff --git a/hw/char/escc.c b/hw/char/escc.c >> index d450d70eda..6d4e3e3350 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_dx = s->sunmouse_dy = s->sunmouse_buttons = 0; >> clear_queue(s); >> } >> >> @@ -952,53 +953,85 @@ static void handle_kbd_command(ESCCChannelState *s, >> int val) >> } >> } >> >> -static void sunmouse_event(void *opaque, >> - int dx, int dy, int dz, int buttons_state) >> +static void sunmouse_handle_event(DeviceState *dev, QemuConsole *src, >> + InputEvent *evt) >> { >> - ESCCChannelState *s = opaque; >> - int ch; >> + ESCCChannelState *s = (ESCCChannelState *)dev; >> + InputMoveEvent *move; >> + InputBtnEvent *btn; >> + static const int bmap[INPUT_BUTTON__MAX] = { >> + [INPUT_BUTTON_LEFT] = 0x4, >> + [INPUT_BUTTON_MIDDLE] = 0x2, >> + [INPUT_BUTTON_RIGHT] = 0x1, >> + [INPUT_BUTTON_SIDE] = 0x0, >> + [INPUT_BUTTON_EXTRA] = 0x0, >> + }; >> + >> + switch (evt->type) { >> + case INPUT_EVENT_KIND_REL: >> + move = evt->u.rel.data; >> + if (move->axis == INPUT_AXIS_X) { >> + s->sunmouse_dx += move->value; >> + } else if (move->axis == INPUT_AXIS_Y) { >> + s->sunmouse_dy -= move->value; >> + } >> + break; >> >> - trace_escc_sunmouse_event(dx, dy, buttons_state); >> - ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */ >> + case INPUT_EVENT_KIND_BTN: >> + btn = evt->u.btn.data; >> + if (btn->down) { >> + s->sunmouse_buttons |= bmap[btn->button]; >> + } else { >> + s->sunmouse_buttons &= ~bmap[btn->button]; >> + } >> + break; >> >> - if (buttons_state & MOUSE_EVENT_LBUTTON) { >> - ch ^= 0x4; >> - } >> - if (buttons_state & MOUSE_EVENT_MBUTTON) { >> - ch ^= 0x2; >> - } >> - if (buttons_state & MOUSE_EVENT_RBUTTON) { >> - ch ^= 0x1; >> + default: >> + /* keep gcc happy */ >> + break; >> } >> +} >> >> - put_queue(s, ch); >> +static void sunmouse_sync(DeviceState *dev) >> +{ >> + ESCCChannelState *s = (ESCCChannelState *)dev; >> + int ch; >> >> - ch = dx; >> + trace_escc_sunmouse_event(s->sunmouse_dx, s->sunmouse_dy, 0); >> + ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */ >> + ch ^= s->sunmouse_buttons; >> + put_queue(s, ch); >> >> + ch = s->sunmouse_dx; >> if (ch > 127) { >> ch = 127; >> } else if (ch < -127) { >> ch = -127; >> } >> - >> put_queue(s, ch & 0xff); >> + s->sunmouse_dx = 0; >> >> - ch = -dy; >> - >> + ch = s->sunmouse_dy; >> if (ch > 127) { >> ch = 127; >> } else if (ch < -127) { >> ch = -127; >> } >> - >> put_queue(s, ch & 0xff); >> + s->sunmouse_dy = 0; >> >> /* MSC protocol specifies two extra motion bytes */ >> - >> put_queue(s, 0); >> put_queue(s, 0); >> } >> >> +static const QemuInputHandler sunmouse_handler = { >> + .name = "QEMU Sun Mouse", >> + .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, >> + .event = sunmouse_handle_event, >> + .sync = sunmouse_sync, >> +}; >> + >> static void escc_init1(Object *obj) >> { >> ESCCState *s = ESCC(obj); >> @@ -1036,8 +1069,8 @@ static void escc_realize(DeviceState *dev, Error >> **errp) >> } >> >> if (s->chn[0].type == escc_mouse) { >> - qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, >> - "QEMU Sun Mouse"); >> + s->chn[0].hs = qemu_input_handler_register((DeviceState >> *)(&s->chn[0]), >> + &sunmouse_handler); >> } >> if (s->chn[1].type == escc_kbd) { >> s->chn[1].hs = qemu_input_handler_register((DeviceState >> *)(&s->chn[1]), >> diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h >> index 5669a5b811..8c4c6a7730 100644 >> --- a/include/hw/char/escc.h >> +++ b/include/hw/char/escc.h >> @@ -46,6 +46,9 @@ typedef struct ESCCChannelState { >> uint8_t rx, tx; >> QemuInputHandlerState *hs; >> char *sunkbd_layout; >> + int sunmouse_dx; >> + int sunmouse_dy; >> + int sunmouse_buttons; >> } ESCCChannelState; >> >> struct ESCCState { >> diff --git a/roms/seabios b/roms/seabios >> index a6ed6b701f..7d0c606870 160000 >> --- a/roms/seabios >> +++ b/roms/seabios >> @@ -1 +1 @@ >> -Subproject commit a6ed6b701f0a57db0569ab98b0661c12a6ec3ff8 >> +Subproject commit 7d0c6068703eae9f2498be0c900ab95b25b4f07a >> -- >> 2.39.2 >> >> >>