Hi

On Wed, Jun 10, 2026 at 2:58 PM Marc-André Lureau
<[email protected]> wrote:
>
> Replace the legacy QEMUPutMouseEvent callbacks with a proper
> QemuInputHandler registration. The device now receives typed
> input events (BTN/ABS/REL) directly.
>
> Signed-off-by: Marc-André Lureau <[email protected]>

One of the 2 patches missing ack/review in this series,

thanks


> ---
>  hw/usb/dev-wacom.c | 155 
> ++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 94 insertions(+), 61 deletions(-)
>
> diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c
> index 14d07e81281..c69e247f7b7 100644
> --- a/hw/usb/dev-wacom.c
> +++ b/hw/usb/dev-wacom.c
> @@ -42,10 +42,10 @@
>  struct USBWacomState {
>      USBDevice dev;
>      USBEndpoint *intr;
> -    QEMUPutMouseEntry *eh_entry;
> -    int dx, dy, dz, buttons_state;
> -    int x, y;
> -    int mouse_grabbed;
> +    QemuInputHandlerState *hs;
> +    int axis[INPUT_AXIS__MAX];
> +    int dz;
> +    bool btns[INPUT_BUTTON__MAX];
>      enum {
>          WACOM_MODE_HID = 1,
>          WACOM_MODE_WACOM = 2,
> @@ -188,29 +188,37 @@ static const USBDesc desc_wacom = {
>      .str  = desc_strings,
>  };
>
> -static void usb_mouse_event(void *opaque,
> -                            int dx1, int dy1, int dz1, int buttons_state)
> +static void usb_wacom_input_event(DeviceState *dev, QemuConsole *src,
> +                                  QemuInputEvent *evt)
>  {
> -    USBWacomState *s = opaque;
> +    USBWacomState *s = USB_WACOM(dev);
>
> -    s->dx += dx1;
> -    s->dy += dy1;
> -    s->dz += dz1;
> -    s->buttons_state = buttons_state;
> -    s->changed = 1;
> -    usb_wakeup(s->intr, 0);
> +    switch (evt->type) {
> +    case INPUT_EVENT_KIND_BTN:
> +        if (evt->btn.down) {
> +            if (evt->btn.button == INPUT_BUTTON_WHEEL_UP) {
> +                s->dz--;
> +            } else if (evt->btn.button == INPUT_BUTTON_WHEEL_DOWN) {
> +                s->dz++;
> +            }
> +        }
> +        s->btns[evt->btn.button] = evt->btn.down;
> +        break;
> +    case INPUT_EVENT_KIND_ABS:
> +        s->axis[evt->abs.axis] = evt->abs.value;
> +        break;
> +    case INPUT_EVENT_KIND_REL:
> +        s->axis[evt->rel.axis] += evt->rel.value;
> +        break;
> +    default:
> +        break;
> +    }
>  }
>
> -static void usb_wacom_event(void *opaque,
> -                            int x, int y, int dz, int buttons_state)
> +static void usb_wacom_input_sync(DeviceState *dev)
>  {
> -    USBWacomState *s = opaque;
> +    USBWacomState *s = USB_WACOM(dev);
>
> -    /* scale to Penpartner resolution */
> -    s->x = (x * 5040 / 0x7FFF);
> -    s->y = (y * 3780 / 0x7FFF);
> -    s->dz += dz;
> -    s->buttons_state = buttons_state;
>      s->changed = 1;
>      usb_wakeup(s->intr, 0);
>  }
> @@ -225,32 +233,57 @@ static inline int int_clamp(int val, int vmin, int vmax)
>          return val;
>  }
>
> +static void usb_wacom_register_input_handler(USBWacomState *s, bool absolute)
> +{
> +    static const QemuInputHandler usb_wacom_abs_handler = {
> +        .name  = "QEMU PenPartner tablet",
> +        .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
> +        .event = usb_wacom_input_event,
> +        .sync  = usb_wacom_input_sync,
> +    };
> +
> +    static const QemuInputHandler usb_wacom_rel_handler = {
> +        .name  = "QEMU PenPartner tablet",
> +        .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
> +        .event = usb_wacom_input_event,
> +        .sync  = usb_wacom_input_sync,
> +    };
> +
> +    const QemuInputHandler *h = absolute ?
> +        &usb_wacom_abs_handler : &usb_wacom_rel_handler;
> +
> +    g_clear_pointer(&s->hs, qemu_input_handler_unregister);
> +
> +    s->hs = qemu_input_handler_register(DEVICE(s), h);
> +    qemu_input_handler_activate(s->hs);
> +}
> +
>  static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
>  {
>      int dx, dy, dz, b, l;
>
> -    if (!s->mouse_grabbed) {
> -        s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, 0,
> -                        "QEMU PenPartner tablet");
> -        qemu_activate_mouse_event_handler(s->eh_entry);
> -        s->mouse_grabbed = 1;
> +    if (!s->hs) {
> +        usb_wacom_register_input_handler(s, false);
>      }
>
> -    dx = int_clamp(s->dx, -128, 127);
> -    dy = int_clamp(s->dy, -128, 127);
> +    dx = int_clamp(s->axis[INPUT_AXIS_X], -128, 127);
> +    dy = int_clamp(s->axis[INPUT_AXIS_Y], -128, 127);
>      dz = int_clamp(s->dz, -128, 127);
>
> -    s->dx -= dx;
> -    s->dy -= dy;
> +    s->axis[INPUT_AXIS_X] -= dx;
> +    s->axis[INPUT_AXIS_Y] -= dy;
>      s->dz -= dz;
>
>      b = 0;
> -    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
> +    if (s->btns[INPUT_BUTTON_LEFT]) {
>          b |= 0x01;
> -    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
> +    }
> +    if (s->btns[INPUT_BUTTON_RIGHT]) {
>          b |= 0x02;
> -    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
> +    }
> +    if (s->btns[INPUT_BUTTON_MIDDLE]) {
>          b |= 0x04;
> +    }
>
>      buf[0] = b;
>      buf[1] = dx;
> @@ -265,32 +298,40 @@ static int usb_mouse_poll(USBWacomState *s, uint8_t 
> *buf, int len)
>
>  static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
>  {
> -    int b;
> +    int b, x, y;
>
> -    if (!s->mouse_grabbed) {
> -        s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, 1,
> -                        "QEMU PenPartner tablet");
> -        qemu_activate_mouse_event_handler(s->eh_entry);
> -        s->mouse_grabbed = 1;
> +    if (!s->hs) {
> +        usb_wacom_register_input_handler(s, true);
>      }
>
>      b = 0;
> -    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
> +    if (s->btns[INPUT_BUTTON_LEFT]) {
>          b |= 0x01;
> -    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
> +    }
> +    if (s->btns[INPUT_BUTTON_RIGHT]) {
>          b |= 0x40;
> -    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
> +    }
> +    if (s->btns[INPUT_BUTTON_MIDDLE]) {
>          b |= 0x20; /* eraser */
> +    }
>
> -    if (len < 7)
> +    if (len < 7) {
>          return 0;
> +    }
> +
> +    x = qemu_input_scale_axis(s->axis[INPUT_AXIS_X],
> +                              INPUT_EVENT_ABS_MIN, INPUT_EVENT_ABS_MAX,
> +                              0, 5040);
> +    y = qemu_input_scale_axis(s->axis[INPUT_AXIS_Y],
> +                              INPUT_EVENT_ABS_MIN, INPUT_EVENT_ABS_MAX,
> +                              0, 3780);
>
>      buf[0] = s->mode;
>      buf[5] = 0x00 | (b & 0xf0);
> -    buf[1] = s->x & 0xff;
> -    buf[2] = s->x >> 8;
> -    buf[3] = s->y & 0xff;
> -    buf[4] = s->y >> 8;
> +    buf[1] = x & 0xff;
> +    buf[2] = x >> 8;
> +    buf[3] = y & 0xff;
> +    buf[4] = y >> 8;
>      if (b & 0x3f) {
>          buf[6] = 0;
>      } else {
> @@ -302,15 +343,13 @@ static int usb_wacom_poll(USBWacomState *s, uint8_t 
> *buf, int len)
>
>  static void usb_wacom_handle_reset(USBDevice *dev)
>  {
> -    USBWacomState *s = (USBWacomState *) dev;
> +    USBWacomState *s = USB_WACOM(dev);
>
> -    s->dx = 0;
> -    s->dy = 0;
> +    memset(s->axis, 0, sizeof(s->axis));
> +    memset(s->btns, 0, sizeof(s->btns));
>      s->dz = 0;
> -    s->x = 0;
> -    s->y = 0;
> -    s->buttons_state = 0;
>      s->mode = WACOM_MODE_HID;
> +    g_clear_pointer(&s->hs, qemu_input_handler_unregister);
>  }
>
>  static void usb_wacom_handle_control(USBDevice *dev, USBPacket *p,
> @@ -337,10 +376,7 @@ static void usb_wacom_handle_control(USBDevice *dev, 
> USBPacket *p,
>          }
>          break;
>      case WACOM_SET_REPORT:
> -        if (s->mouse_grabbed) {
> -            qemu_remove_mouse_event_handler(s->eh_entry);
> -            s->mouse_grabbed = 0;
> -        }
> +        g_clear_pointer(&s->hs, qemu_input_handler_unregister);
>          s->mode = data[0];
>          break;
>      case WACOM_GET_REPORT:
> @@ -400,10 +436,7 @@ static void usb_wacom_unrealize(USBDevice *dev)
>  {
>      USBWacomState *s = (USBWacomState *) dev;
>
> -    if (s->mouse_grabbed) {
> -        qemu_remove_mouse_event_handler(s->eh_entry);
> -        s->mouse_grabbed = 0;
> -    }
> +    g_clear_pointer(&s->hs, qemu_input_handler_unregister);
>  }
>
>  static void usb_wacom_realize(USBDevice *dev, Error **errp)
>
> --
> 2.54.0
>
>

Reply via email to