All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Soumyajyotii Ssarkar <soumyajyotisarkar23@gmail.com>
Cc: qemu-devel@nongnu.org,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Soumyajyotii Ssarkar" <sarkarsoumyajyoti23@gmail.com>,
	"Michael Tokarev" <mjt@tls.msk.ru>,
	"Thomas Lambertz" <patch@thomaslambertz.de>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Alex Golovko" <alex@browserling.com>,
	"ShengYi Hung" <aokblast@FreeBSD.org>
Subject: Re: [RFC PATCH 5/5] input/hid: apply multiplier scaling with residual accumulation
Date: Mon, 28 Sep 2026 15:00:45 +0100	[thread overview]
Message-ID: <87se2ta31u.fsf@draig.linaro.org> (raw)
In-Reply-To: <20260331170823.72511-6-soumyajyotisarkar23@gmail.com> (Soumyajyotii Ssarkar's message of "Tue, 31 Mar 2026 22:38:23 +0530")

Soumyajyotii Ssarkar <soumyajyotisarkar23@gmail.com> writes:

> Implement multiplier-based scaling with residual accumulation for
> fine-grained mouse wheel and pan sensitivity control in report mode.
>
> Applies divisor based scaling (1, 4, 8, 16) based on negotiated
> multiplier values.
> Then uses residual based approach to prevent precision loss:
>
>   residual += delta
>   output = residual / divisor
>   residual -= output * divisor
>
> Residual state preserved across VM migrations via VMState.
>
> Signed-off-by: Soumyajyotii Ssarkar <soumyajyotisarkar23@gmail.com>
> ---
>  hw/input/hid.c         | 60 ++++++++++++++++++++++++++++++++++++++++++
>  include/hw/input/hid.h |  2 ++
>  2 files changed, 62 insertions(+)
>
> diff --git a/hw/input/hid.c b/hw/input/hid.c
> index d0b7af7c13..9b800faeb0 100644
> --- a/hw/input/hid.c
> +++ b/hw/input/hid.c
> @@ -365,6 +365,7 @@ void hid_pointer_activate(HIDState *hs)
>  int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
>  {
>      int dx, dy, dz, pan, l;
> +    int wheel_divisor, pan_divisor;
>      int index;
>      HIDPointerEvent *e;
>
> @@ -392,6 +393,54 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
>      e->pan -= pan;
>
>
> +    if (hs->kind == HID_MOUSE && hs->protocol != 0) {
> +        switch (hs->ptr.wheel_multiplier & 0x03) {
> +        case 0:
> +            wheel_divisor = 1;
> +            break;
> +        case 1:
> +            wheel_divisor = 4;
> +            break;
> +        case 2:
> +            wheel_divisor = 8;
> +            break;
> +        default:
> +            wheel_divisor = 16;
> +            break;
> +        }
> +
> +        switch (hs->ptr.pan_multiplier & 0x03) {
> +        case 0:
> +            pan_divisor = 1;
> +            break;
> +        case 1:
> +            pan_divisor = 4;
> +            break;
> +        case 2:
> +            pan_divisor = 8;
> +            break;
> +        default:
> +            pan_divisor = 16;
> +            break;
> +        }
> +
> +        if (wheel_divisor > 1) {
> +            hs->ptr.wheel_residual += dz;
> +            dz = hs->ptr.wheel_residual / wheel_divisor;
> +            hs->ptr.wheel_residual -= dz * wheel_divisor;
> +        } else {
> +            hs->ptr.wheel_residual = 0;
> +        }
> +
> +        if (pan_divisor > 1) {
> +            hs->ptr.pan_residual += pan;
> +            pan = hs->ptr.pan_residual / pan_divisor;
> +            hs->ptr.pan_residual -= pan * pan_divisor;
> +        } else {
> +            hs->ptr.pan_residual = 0;
> +        }
> +    }
> +
>      if (hs->n &&
>          !e->dz &&
>          !e->pan &&
> @@ -405,6 +454,7 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
>      dz = 0 - dz;
>      pan = 0 - pan;
>      l = 0;
> +
>      switch (hs->kind) {
>      case HID_MOUSE:
>          if (hs->protocol == 0) {
> @@ -528,6 +578,11 @@ void hid_reset(HIDState *hs)
>      case HID_MOUSE:
>      case HID_TABLET:
>          memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
> +        hs->ptr.mouse_grabbed = 0;
> +        hs->ptr.wheel_multiplier = 0;
> +        hs->ptr.pan_multiplier = 0;
> +        hs->ptr.wheel_residual = 0;
> +        hs->ptr.pan_residual = 0;
>          break;
>      }
>      hs->head = 0;
> @@ -619,6 +674,7 @@ static const VMStateDescription vmstate_hid_ptr_queue = {
>          VMSTATE_INT32(xdx, HIDPointerEvent),
>          VMSTATE_INT32(ydy, HIDPointerEvent),
>          VMSTATE_INT32(dz, HIDPointerEvent),
> +        VMSTATE_INT32(pan, HIDPointerEvent),
>          VMSTATE_INT32(buttons_state, HIDPointerEvent),
>          VMSTATE_END_OF_LIST()
>      }
> @@ -636,6 +692,10 @@ const VMStateDescription vmstate_hid_ptr_device = {
>          VMSTATE_UINT32(n, HIDState),
>          VMSTATE_INT32(protocol, HIDState),
>          VMSTATE_UINT8(idle, HIDState),
> +        VMSTATE_UINT8(ptr.wheel_multiplier, HIDState),
> +        VMSTATE_UINT8(ptr.pan_multiplier, HIDState),
> +        VMSTATE_INT32(ptr.wheel_residual, HIDState),
> +        VMSTATE_INT32(ptr.pan_residual, HIDState),
>          VMSTATE_END_OF_LIST(),

If you update migration state you also need to ensure that older systems
can be migrated to newer ones. There are some docs in docs/devel that
give some guidance on handling these cases. 

>      }
>  };
> diff --git a/include/hw/input/hid.h b/include/hw/input/hid.h
> index 1a1941d371..db902fa023 100644
> --- a/include/hw/input/hid.h
> +++ b/include/hw/input/hid.h
> @@ -25,6 +25,8 @@ typedef struct HIDMouseState {
>      int mouse_grabbed;
>      uint8_t wheel_multiplier;
>      uint8_t pan_multiplier;
> +    int32_t wheel_residual;
> +    int32_t pan_residual;
>  } HIDMouseState;
>
>  typedef struct HIDKeyboardState {

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro


      parent reply	other threads:[~2026-09-28 14:01 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31 17:08 [RFC PATCH 0/5] Add high-resolution 2D mouse wheel support to USB HID Soumyajyotii Ssarkar
2026-03-31 17:08 ` [RFC PATCH 1/5] input/hid: add horizontal pan to pointer event path Soumyajyotii Ssarkar
2026-09-27 17:06   ` Helge Deller
2026-03-31 17:08 ` [RFC PATCH 2/5] usb/hid: add enhanced wheel mouse report descriptor and packet size Soumyajyotii Ssarkar
2026-09-27 17:11   ` Helge Deller
2026-09-28  8:31   ` Alex Bennée
2026-10-08 15:30     ` Soumyajyotii Ssarkar
2026-03-31 17:08 ` [RFC PATCH 3/5] input/hid: emit protocol aware mouse reports with pan support Soumyajyotii Ssarkar
2026-09-27 17:14   ` Helge Deller
2026-03-31 17:08 ` [RFC PATCH 4/5] usb/hid: handle mouse feature report for wheel/pan multipliers Soumyajyotii Ssarkar
2026-09-27 19:58   ` Helge Deller
2026-03-31 17:08 ` [RFC PATCH 5/5] input/hid: apply multiplier scaling with residual accumulation Soumyajyotii Ssarkar
2026-09-27 20:21   ` Helge Deller
2026-09-28 14:00   ` Alex Bennée [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87se2ta31u.fsf@draig.linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=alex@browserling.com \
    --cc=aokblast@FreeBSD.org \
    --cc=mjt@tls.msk.ru \
    --cc=patch@thomaslambertz.de \
    --cc=pbonzini@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=sarkarsoumyajyoti23@gmail.com \
    --cc=soumyajyotisarkar23@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.