* [PATCH 0/3] HID: magicmouse: More scroll improvements
@ 2010-06-21 1:32 Chase Douglas
2010-06-21 1:32 ` [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state Chase Douglas
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Chase Douglas @ 2010-06-21 1:32 UTC (permalink / raw)
To: Jiri Kosina, Michael Poole; +Cc: linux-input
The following three patches improve scrolling for Apple Magicmouse
devices. The first two were sent as a set of four patches. Two were
applied while two were reviewed later. They are now ready for
application. The last patch is new, but is rather simple.
I have been running with these patches for a few weeks and have been
very happy with the results :).
HID: magicmouse: properly account for scroll movement in state
HID: magicmouse: add param for scroll speed
HID: magicmouse: enable horizontal scrolling
--
drivers/hid/hid-magicmouse.c | 63 ++++++++++++++++++++++++++++++------------
1 files changed, 45 insertions(+), 18 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state
2010-06-21 1:32 [PATCH 0/3] HID: magicmouse: More scroll improvements Chase Douglas
@ 2010-06-21 1:32 ` Chase Douglas
2010-06-24 8:48 ` Jiri Kosina
2010-06-21 1:32 ` [PATCH 2/3] HID: magicmouse: add param for scroll speed Chase Douglas
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Chase Douglas @ 2010-06-21 1:32 UTC (permalink / raw)
To: Jiri Kosina, Michael Poole; +Cc: linux-input
Before this change, sequential scroll events would take a variable
amount of movement due to incorrect accounting. This change ensures all
scroll movements require a deterministic touch movement for an action to
occur.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Acked-by: Michael Poole <mdpoole@troilus.org>
---
drivers/hid/hid-magicmouse.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 4c4a79c..f44aaf2 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -189,7 +189,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
case TOUCH_STATE_DRAG:
step = step / accel_profile[msc->scroll_accel];
if (step != 0) {
- msc->touches[id].scroll_y = y;
+ msc->touches[id].scroll_y -=
+ step * accel_profile[msc->scroll_accel];
msc->scroll_jiffies = now;
input_report_rel(input, REL_WHEEL, step);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] HID: magicmouse: add param for scroll speed
2010-06-21 1:32 [PATCH 0/3] HID: magicmouse: More scroll improvements Chase Douglas
2010-06-21 1:32 ` [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state Chase Douglas
@ 2010-06-21 1:32 ` Chase Douglas
2010-06-21 1:32 ` [PATCH 3/3] HID: magicmouse: enable horizontal scrolling Chase Douglas
2010-06-24 8:50 ` [PATCH 0/3] HID: magicmouse: More scroll improvements Jiri Kosina
3 siblings, 0 replies; 9+ messages in thread
From: Chase Douglas @ 2010-06-21 1:32 UTC (permalink / raw)
To: Jiri Kosina, Michael Poole; +Cc: linux-input
The new scroll_speed param takes an integer value from 0 to 63, where 0
is slowest and 63 is fastest. The default of 32 remains the same. This
parameter also affects scroll acceleration linearly.
A second part of this change is a tightly coupled modification to the
scroll acceleration. Previously, scroll acceleration could be reset
without lifting the scroll finger. This is rather unintuitive and hard
to control in the case where a user wants faster scrolling, but wants to
hold the scroll touch for longer than a moment.
Note that scroll acceleration levels are now 1-7, where 7 is slowest. In
the previous implementation, there were 8 levels defined, but it was
impossible to start at the slowest level. In order to keep the default
scroll speed unchanged, only 7 levels are used now.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Acked-by: Michael Poole <mdpoole@troilus.org>
---
drivers/hid/hid-magicmouse.c | 43 +++++++++++++++++++++++++++--------------
1 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index f44aaf2..fe0c760 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -30,6 +30,17 @@ static bool emulate_scroll_wheel = true;
module_param(emulate_scroll_wheel, bool, 0644);
MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
+static unsigned int scroll_speed = 32;
+static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
+ unsigned long speed;
+ if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
+ return -EINVAL;
+ scroll_speed = speed;
+ return 0;
+}
+module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644);
+MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)");
+
static bool scroll_acceleration = false;
module_param(scroll_acceleration, bool, 0644);
MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
@@ -54,6 +65,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define TOUCH_STATE_START 0x30
#define TOUCH_STATE_DRAG 0x40
+#define SCROLL_ACCEL_DEFAULT 7
+
/**
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
* @input: Input device through which we report events.
@@ -145,7 +158,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
input_report_key(msc->input, BTN_RIGHT, state & 2);
if (state != last_state)
- msc->scroll_accel = 0;
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
}
static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
@@ -167,30 +180,28 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
* vertical touch motions.
*/
if (emulate_scroll_wheel) {
- static const int accel_profile[] = {
- 256, 228, 192, 160, 128, 96, 64, 32,
- };
unsigned long now = jiffies;
int step = msc->touches[id].scroll_y - y;
- /* Reset acceleration after half a second. */
- if (time_after(now, msc->scroll_jiffies + HZ / 2))
- msc->scroll_accel = 0;
-
/* Calculate and apply the scroll motion. */
switch (tdata[7] & TOUCH_STATE_MASK) {
case TOUCH_STATE_START:
msc->touches[id].scroll_y = y;
- if (scroll_acceleration)
- msc->scroll_accel = min_t(int,
- msc->scroll_accel + 1,
- ARRAY_SIZE(accel_profile) - 1);
+
+ /* Reset acceleration after half a second. */
+ if (scroll_acceleration && time_before(now,
+ msc->scroll_jiffies + HZ / 2))
+ msc->scroll_accel = max_t(int,
+ msc->scroll_accel - 1, 1);
+ else
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
+
break;
case TOUCH_STATE_DRAG:
- step = step / accel_profile[msc->scroll_accel];
+ step /= (64 - (int)scroll_speed) * msc->scroll_accel;
if (step != 0) {
- msc->touches[id].scroll_y -=
- step * accel_profile[msc->scroll_accel];
+ msc->touches[id].scroll_y -= step *
+ (64 - scroll_speed) * msc->scroll_accel;
msc->scroll_jiffies = now;
input_report_rel(input, REL_WHEEL, step);
}
@@ -351,6 +362,8 @@ static int magicmouse_probe(struct hid_device *hdev,
return -ENOMEM;
}
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
+
msc->quirks = id->driver_data;
hid_set_drvdata(hdev, msc);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] HID: magicmouse: enable horizontal scrolling
2010-06-21 1:32 [PATCH 0/3] HID: magicmouse: More scroll improvements Chase Douglas
2010-06-21 1:32 ` [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state Chase Douglas
2010-06-21 1:32 ` [PATCH 2/3] HID: magicmouse: add param for scroll speed Chase Douglas
@ 2010-06-21 1:32 ` Chase Douglas
2010-06-22 1:29 ` Michael Poole
2010-06-24 8:50 ` [PATCH 0/3] HID: magicmouse: More scroll improvements Jiri Kosina
3 siblings, 1 reply; 9+ messages in thread
From: Chase Douglas @ 2010-06-21 1:32 UTC (permalink / raw)
To: Jiri Kosina, Michael Poole; +Cc: linux-input
Mimicks OS X behavior.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
---
drivers/hid/hid-magicmouse.c | 25 +++++++++++++++++++------
1 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index fe0c760..0b89c1c 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -95,6 +95,7 @@ struct magicmouse_sc {
struct {
short x;
short y;
+ short scroll_x;
short scroll_y;
u8 size;
} touches[16];
@@ -181,11 +182,13 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
*/
if (emulate_scroll_wheel) {
unsigned long now = jiffies;
- int step = msc->touches[id].scroll_y - y;
+ int step_x = msc->touches[id].scroll_x - x;
+ int step_y = msc->touches[id].scroll_y - y;
/* Calculate and apply the scroll motion. */
switch (tdata[7] & TOUCH_STATE_MASK) {
case TOUCH_STATE_START:
+ msc->touches[id].scroll_x = x;
msc->touches[id].scroll_y = y;
/* Reset acceleration after half a second. */
@@ -198,12 +201,20 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
break;
case TOUCH_STATE_DRAG:
- step /= (64 - (int)scroll_speed) * msc->scroll_accel;
- if (step != 0) {
- msc->touches[id].scroll_y -= step *
+ step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
+ if (step_x != 0) {
+ msc->touches[id].scroll_x -= step_x *
(64 - scroll_speed) * msc->scroll_accel;
msc->scroll_jiffies = now;
- input_report_rel(input, REL_WHEEL, step);
+ input_report_rel(input, REL_HWHEEL, -step_x);
+ }
+
+ step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
+ if (step_y != 0) {
+ msc->touches[id].scroll_y -= step_y *
+ (64 - scroll_speed) * msc->scroll_accel;
+ msc->scroll_jiffies = now;
+ input_report_rel(input, REL_WHEEL, step_y);
}
break;
}
@@ -318,8 +329,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
__set_bit(EV_REL, input->evbit);
__set_bit(REL_X, input->relbit);
__set_bit(REL_Y, input->relbit);
- if (emulate_scroll_wheel)
+ if (emulate_scroll_wheel) {
__set_bit(REL_WHEEL, input->relbit);
+ __set_bit(REL_HWHEEL, input->relbit);
+ }
if (report_touches) {
__set_bit(EV_ABS, input->evbit);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] HID: magicmouse: enable horizontal scrolling
2010-06-21 1:32 ` [PATCH 3/3] HID: magicmouse: enable horizontal scrolling Chase Douglas
@ 2010-06-22 1:29 ` Michael Poole
2010-06-22 3:08 ` Chase Douglas
0 siblings, 1 reply; 9+ messages in thread
From: Michael Poole @ 2010-06-22 1:29 UTC (permalink / raw)
To: Chase Douglas; +Cc: Jiri Kosina, linux-input
Chase Douglas writes:
> Mimicks OS X behavior.
>
> Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
> ---
> drivers/hid/hid-magicmouse.c | 25 +++++++++++++++++++------
> 1 files changed, 19 insertions(+), 6 deletions(-)
I like this general idea, but Dmitry Torokhov didn't like my previous
patch to achieve a similar effect:
https://patchwork.kernel.org/patch/84201/
The only behavioral question I would have is whether a single
touch/swipe should be locked in one direction or if it should be able to
generate both horizontal and vertical scroll events. That seems like a
user preference thing to me.
(My real wish is for X and the various widget libraries to get decent
multitouch support soon, so that the kernel doesn't have to address
those policy questions.)
Michael
> diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
> index fe0c760..0b89c1c 100644
> --- a/drivers/hid/hid-magicmouse.c
> +++ b/drivers/hid/hid-magicmouse.c
> @@ -95,6 +95,7 @@ struct magicmouse_sc {
> struct {
> short x;
> short y;
> + short scroll_x;
> short scroll_y;
> u8 size;
> } touches[16];
> @@ -181,11 +182,13 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> */
> if (emulate_scroll_wheel) {
> unsigned long now = jiffies;
> - int step = msc->touches[id].scroll_y - y;
> + int step_x = msc->touches[id].scroll_x - x;
> + int step_y = msc->touches[id].scroll_y - y;
>
> /* Calculate and apply the scroll motion. */
> switch (tdata[7] & TOUCH_STATE_MASK) {
> case TOUCH_STATE_START:
> + msc->touches[id].scroll_x = x;
> msc->touches[id].scroll_y = y;
>
> /* Reset acceleration after half a second. */
> @@ -198,12 +201,20 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
>
> break;
> case TOUCH_STATE_DRAG:
> - step /= (64 - (int)scroll_speed) * msc->scroll_accel;
> - if (step != 0) {
> - msc->touches[id].scroll_y -= step *
> + step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
> + if (step_x != 0) {
> + msc->touches[id].scroll_x -= step_x *
> (64 - scroll_speed) * msc->scroll_accel;
> msc->scroll_jiffies = now;
> - input_report_rel(input, REL_WHEEL, step);
> + input_report_rel(input, REL_HWHEEL, -step_x);
> + }
> +
> + step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
> + if (step_y != 0) {
> + msc->touches[id].scroll_y -= step_y *
> + (64 - scroll_speed) * msc->scroll_accel;
> + msc->scroll_jiffies = now;
> + input_report_rel(input, REL_WHEEL, step_y);
> }
> break;
> }
> @@ -318,8 +329,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
> __set_bit(EV_REL, input->evbit);
> __set_bit(REL_X, input->relbit);
> __set_bit(REL_Y, input->relbit);
> - if (emulate_scroll_wheel)
> + if (emulate_scroll_wheel) {
> __set_bit(REL_WHEEL, input->relbit);
> + __set_bit(REL_HWHEEL, input->relbit);
> + }
>
> if (report_touches) {
> __set_bit(EV_ABS, input->evbit);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] HID: magicmouse: enable horizontal scrolling
2010-06-22 1:29 ` Michael Poole
@ 2010-06-22 3:08 ` Chase Douglas
2010-06-22 9:10 ` Jiri Kosina
0 siblings, 1 reply; 9+ messages in thread
From: Chase Douglas @ 2010-06-22 3:08 UTC (permalink / raw)
To: Michael Poole; +Cc: Jiri Kosina, linux-input
On Mon, 2010-06-21 at 21:29 -0400, Michael Poole wrote:
> Chase Douglas writes:
>
> > Mimicks OS X behavior.
> >
> > Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
> > ---
> > drivers/hid/hid-magicmouse.c | 25 +++++++++++++++++++------
> > 1 files changed, 19 insertions(+), 6 deletions(-)
>
> I like this general idea, but Dmitry Torokhov didn't like my previous
> patch to achieve a similar effect:
> https://patchwork.kernel.org/patch/84201/
To be fair, that patch had a lot more in it. I'm not sure that appending
horizontal scroll to what's already in the driver is too much to ask.
> The only behavioral question I would have is whether a single
> touch/swipe should be locked in one direction or if it should be able to
> generate both horizontal and vertical scroll events. That seems like a
> user preference thing to me.
Not that we should necessarily mimick OS X, but they scroll in both axes
simultaneously. I have no problem with it, and I've not heard of anyone
else gripe either.
Locking it in to one direction may not seem logical to an end user, and
would add more complexity to the code.
> (My real wish is for X and the various widget libraries to get decent
> multitouch support soon, so that the kernel doesn't have to address
> those policy questions.)
I'm trying to help out with that, and I realize it's the real end-game
here. However, like you said, there's no support quite yet. So while end
users twiddle their thumbs waiting for support above the kernel, we
should throw them a bone.
-- Chase
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] HID: magicmouse: enable horizontal scrolling
2010-06-22 3:08 ` Chase Douglas
@ 2010-06-22 9:10 ` Jiri Kosina
0 siblings, 0 replies; 9+ messages in thread
From: Jiri Kosina @ 2010-06-22 9:10 UTC (permalink / raw)
To: Chase Douglas; +Cc: Michael Poole, linux-input
On Mon, 21 Jun 2010, Chase Douglas wrote:
> > > Mimicks OS X behavior.
> > >
> > > Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
> > > ---
> > > drivers/hid/hid-magicmouse.c | 25 +++++++++++++++++++------
> > > 1 files changed, 19 insertions(+), 6 deletions(-)
> >
> > I like this general idea, but Dmitry Torokhov didn't like my previous
> > patch to achieve a similar effect:
> > https://patchwork.kernel.org/patch/84201/
>
> To be fair, that patch had a lot more in it. I'm not sure that appending
> horizontal scroll to what's already in the driver is too much to ask.
I agree here. Horizontal scrolling support itself is fine.
I have the patches in my to-review queue, will process them shortly.
Thanks,
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state
2010-06-21 1:32 ` [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state Chase Douglas
@ 2010-06-24 8:48 ` Jiri Kosina
0 siblings, 0 replies; 9+ messages in thread
From: Jiri Kosina @ 2010-06-24 8:48 UTC (permalink / raw)
To: Chase Douglas; +Cc: Michael Poole, linux-input
On Sun, 20 Jun 2010, Chase Douglas wrote:
> Before this change, sequential scroll events would take a variable
> amount of movement due to incorrect accounting. This change ensures all
> scroll movements require a deterministic touch movement for an action to
> occur.
>
> Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
> Acked-by: Michael Poole <mdpoole@troilus.org>
> ---
> drivers/hid/hid-magicmouse.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
> index 4c4a79c..f44aaf2 100644
> --- a/drivers/hid/hid-magicmouse.c
> +++ b/drivers/hid/hid-magicmouse.c
> @@ -189,7 +189,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> case TOUCH_STATE_DRAG:
> step = step / accel_profile[msc->scroll_accel];
> if (step != 0) {
> - msc->touches[id].scroll_y = y;
> + msc->touches[id].scroll_y -=
> + step * accel_profile[msc->scroll_accel];
> msc->scroll_jiffies = now;
> input_report_rel(input, REL_WHEEL, step);
> }
Applied, thanks.
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] HID: magicmouse: More scroll improvements
2010-06-21 1:32 [PATCH 0/3] HID: magicmouse: More scroll improvements Chase Douglas
` (2 preceding siblings ...)
2010-06-21 1:32 ` [PATCH 3/3] HID: magicmouse: enable horizontal scrolling Chase Douglas
@ 2010-06-24 8:50 ` Jiri Kosina
3 siblings, 0 replies; 9+ messages in thread
From: Jiri Kosina @ 2010-06-24 8:50 UTC (permalink / raw)
To: Chase Douglas; +Cc: Michael Poole, linux-input
On Sun, 20 Jun 2010, Chase Douglas wrote:
> The following three patches improve scrolling for Apple Magicmouse
> devices. The first two were sent as a set of four patches. Two were
> applied while two were reviewed later. They are now ready for
> application. The last patch is new, but is rather simple.
>
> I have been running with these patches for a few weeks and have been
> very happy with the results :).
>
> HID: magicmouse: properly account for scroll movement in state
> HID: magicmouse: add param for scroll speed
> HID: magicmouse: enable horizontal scrolling
> --
> drivers/hid/hid-magicmouse.c | 63 ++++++++++++++++++++++++++++++------------
> 1 files changed, 45 insertions(+), 18 deletions(-)
I have applied all three patches into my 'magicmouse' branch. Thanks,
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-06-24 8:50 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-21 1:32 [PATCH 0/3] HID: magicmouse: More scroll improvements Chase Douglas
2010-06-21 1:32 ` [PATCH 1/3] HID: magicmouse: properly account for scroll movement in state Chase Douglas
2010-06-24 8:48 ` Jiri Kosina
2010-06-21 1:32 ` [PATCH 2/3] HID: magicmouse: add param for scroll speed Chase Douglas
2010-06-21 1:32 ` [PATCH 3/3] HID: magicmouse: enable horizontal scrolling Chase Douglas
2010-06-22 1:29 ` Michael Poole
2010-06-22 3:08 ` Chase Douglas
2010-06-22 9:10 ` Jiri Kosina
2010-06-24 8:50 ` [PATCH 0/3] HID: magicmouse: More scroll improvements Jiri Kosina
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).