* [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. @ 2010-07-05 14:50 Michael Poole 2010-07-05 16:28 ` Chase Douglas 2010-07-05 19:54 ` Ping Cheng 0 siblings, 2 replies; 14+ messages in thread From: Michael Poole @ 2010-07-05 14:50 UTC (permalink / raw) To: Jiri Kosina, Chase Douglas; +Cc: linux-input The X and Y values have two more significant bits in the same byte that contains click status. Include these in the reported value. Thanks to Iain Hibbert of NetBSD for pointing this out. Signed-off-by: Michael Poole <mdpoole@troilus.org> --- drivers/hid/hid-magicmouse.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 0b89c1c..7cdda23 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, * to have the current touch information before * generating a click event. */ - x = (signed char)data[1]; - y = (signed char)data[2]; + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; clicks = data[3]; break; case 0x20: /* Theoretically battery status (0-100), but I have -- 1.7.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 14:50 [PATCH] hid-magicmouse: Correct parsing of large X and Y motions Michael Poole @ 2010-07-05 16:28 ` Chase Douglas 2010-07-11 21:07 ` Jiri Kosina 2010-07-05 19:54 ` Ping Cheng 1 sibling, 1 reply; 14+ messages in thread From: Chase Douglas @ 2010-07-05 16:28 UTC (permalink / raw) To: Michael Poole; +Cc: Jiri Kosina, linux-input On Mon, 2010-07-05 at 10:50 -0400, Michael Poole wrote: > The X and Y values have two more significant bits in the same byte > that contains click status. Include these in the reported value. > Thanks to Iain Hibbert of NetBSD for pointing this out. > > Signed-off-by: Michael Poole <mdpoole@troilus.org> > --- > drivers/hid/hid-magicmouse.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > index 0b89c1c..7cdda23 100644 > --- a/drivers/hid/hid-magicmouse.c > +++ b/drivers/hid/hid-magicmouse.c > @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, > * to have the current touch information before > * generating a click event. > */ > - x = (signed char)data[1]; > - y = (signed char)data[2]; > + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; > + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; > clicks = data[3]; > break; > case 0x20: /* Theoretically battery status (0-100), but I have Looks right to me. Acked-by: Chase Douglas <chase.douglas@canonical.com> -- Chase ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 16:28 ` Chase Douglas @ 2010-07-11 21:07 ` Jiri Kosina 0 siblings, 0 replies; 14+ messages in thread From: Jiri Kosina @ 2010-07-11 21:07 UTC (permalink / raw) To: Chase Douglas; +Cc: Michael Poole, linux-input On Mon, 5 Jul 2010, Chase Douglas wrote: > On Mon, 2010-07-05 at 10:50 -0400, Michael Poole wrote: > > The X and Y values have two more significant bits in the same byte > > that contains click status. Include these in the reported value. > > Thanks to Iain Hibbert of NetBSD for pointing this out. > > > > Signed-off-by: Michael Poole <mdpoole@troilus.org> > > --- > > drivers/hid/hid-magicmouse.c | 4 ++-- > > 1 files changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > > index 0b89c1c..7cdda23 100644 > > --- a/drivers/hid/hid-magicmouse.c > > +++ b/drivers/hid/hid-magicmouse.c > > @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > * to have the current touch information before > > * generating a click event. > > */ > > - x = (signed char)data[1]; > > - y = (signed char)data[2]; > > + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; > > + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; > > clicks = data[3]; > > break; > > case 0x20: /* Theoretically battery status (0-100), but I have > > Looks right to me. > > Acked-by: Chase Douglas <chase.douglas@canonical.com> Thanks. Applied to magicmouse branch now. -- Jiri Kosina SUSE Labs, Novell Inc. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 14:50 [PATCH] hid-magicmouse: Correct parsing of large X and Y motions Michael Poole 2010-07-05 16:28 ` Chase Douglas @ 2010-07-05 19:54 ` Ping Cheng 2010-07-05 20:02 ` Chase Douglas 2010-07-05 22:51 ` Dmitry Torokhov 1 sibling, 2 replies; 14+ messages in thread From: Ping Cheng @ 2010-07-05 19:54 UTC (permalink / raw) To: Michael Poole; +Cc: Jiri Kosina, Chase Douglas, linux-input On Mon, Jul 5, 2010 at 10:50 PM, Michael Poole <mdpoole@troilus.org> wrote: > The X and Y values have two more significant bits in the same byte > that contains click status. Include these in the reported value. > Thanks to Iain Hibbert of NetBSD for pointing this out. > > Signed-off-by: Michael Poole <mdpoole@troilus.org> > --- > drivers/hid/hid-magicmouse.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > index 0b89c1c..7cdda23 100644 > --- a/drivers/hid/hid-magicmouse.c > +++ b/drivers/hid/hid-magicmouse.c > @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, > * to have the current touch information before > * generating a click event. > */ > - x = (signed char)data[1]; > - y = (signed char)data[2]; > + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; > + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; Will the following give us the same result? + x = (int)(((data[3] & 0x0c) << 6) | data[1]); + y = (int)(((data[3] & 0x30) << 4) | data[2]); Ping > clicks = data[3]; > break; > case 0x20: /* Theoretically battery status (0-100), but I have > -- > 1.7.1 > -- > To unsubscribe from this list: send the line "unsubscribe linux-input" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 19:54 ` Ping Cheng @ 2010-07-05 20:02 ` Chase Douglas 2010-07-05 20:33 ` Michael Poole 2010-07-05 22:51 ` Dmitry Torokhov 1 sibling, 1 reply; 14+ messages in thread From: Chase Douglas @ 2010-07-05 20:02 UTC (permalink / raw) To: Ping Cheng; +Cc: Michael Poole, Jiri Kosina, linux-input On Tue, 2010-07-06 at 03:54 +0800, Ping Cheng wrote: > On Mon, Jul 5, 2010 at 10:50 PM, Michael Poole <mdpoole@troilus.org> wrote: > > The X and Y values have two more significant bits in the same byte > > that contains click status. Include these in the reported value. > > Thanks to Iain Hibbert of NetBSD for pointing this out. > > > > Signed-off-by: Michael Poole <mdpoole@troilus.org> > > --- > > drivers/hid/hid-magicmouse.c | 4 ++-- > > 1 files changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c > > index 0b89c1c..7cdda23 100644 > > --- a/drivers/hid/hid-magicmouse.c > > +++ b/drivers/hid/hid-magicmouse.c > > @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, > > * to have the current touch information before > > * generating a click event. > > */ > > - x = (signed char)data[1]; > > - y = (signed char)data[2]; > > + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; > > + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; > > Will the following give us the same result? > > + x = (int)(((data[3] & 0x0c) << 6) | data[1]); > + y = (int)(((data[3] & 0x30) << 4) | data[2]); I thought about this too, but there's a sign extension issue. If the X coordinate is -1 (these are relative coordinates), then you will end up with (int)(1023), which is no longer -1. When you shift to the right, the bits are sign-extended. Thus, shifting everything to the most significant bit of an integer, and then shifting everything back to the least significant will properly sign extend. (I actually wrote a test program just to verify this) That's just a reason for the shifts. There very well could be a more elegant solution. -- Chase ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 20:02 ` Chase Douglas @ 2010-07-05 20:33 ` Michael Poole 2010-07-05 20:51 ` Chase Douglas 0 siblings, 1 reply; 14+ messages in thread From: Michael Poole @ 2010-07-05 20:33 UTC (permalink / raw) To: Chase Douglas; +Cc: Ping Cheng, Jiri Kosina, linux-input Chase Douglas writes: > On Tue, 2010-07-06 at 03:54 +0800, Ping Cheng wrote: >> On Mon, Jul 5, 2010 at 10:50 PM, Michael Poole <mdpoole@troilus.org> wrote: >> > The X and Y values have two more significant bits in the same byte >> > that contains click status. Include these in the reported value. >> > Thanks to Iain Hibbert of NetBSD for pointing this out. >> > >> > Signed-off-by: Michael Poole <mdpoole@troilus.org> >> > --- >> > drivers/hid/hid-magicmouse.c | 4 ++-- >> > 1 files changed, 2 insertions(+), 2 deletions(-) >> > >> > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c >> > index 0b89c1c..7cdda23 100644 >> > --- a/drivers/hid/hid-magicmouse.c >> > +++ b/drivers/hid/hid-magicmouse.c >> > @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, >> > * to have the current touch information before >> > * generating a click event. >> > */ >> > - x = (signed char)data[1]; >> > - y = (signed char)data[2]; >> > + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; >> > + y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; >> >> Will the following give us the same result? >> >> + x = (int)(((data[3] & 0x0c) << 6) | data[1]); >> + y = (int)(((data[3] & 0x30) << 4) | data[2]); > > I thought about this too, but there's a sign extension issue. If the X > coordinate is -1 (these are relative coordinates), then you will end up > with (int)(1023), which is no longer -1. > > When you shift to the right, the bits are sign-extended. Thus, shifting > everything to the most significant bit of an integer, and then shifting > everything back to the least significant will properly sign extend. > > (I actually wrote a test program just to verify this) > > That's just a reason for the shifts. There very well could be a more > elegant solution. C99 says that the result of right-shifting a negative value is compiler-defined. gcc documents that it ensures sign extension. Other parts of hid-magicmouse.c use this idiom already. The corresponding idiom in hid-core.c (see the snto32() function) would look something like this: x = ((data[3] & 0x0c) << 6) | data[1]; x |= (x & (1 << 9)) ? (-1 << 10) : 0; Which do people find more readable? Is the more portable behavior of this idiom preferred over requiring sign extension by the compiler? Michael Poole ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 20:33 ` Michael Poole @ 2010-07-05 20:51 ` Chase Douglas 2010-07-05 22:08 ` Michael Poole 0 siblings, 1 reply; 14+ messages in thread From: Chase Douglas @ 2010-07-05 20:51 UTC (permalink / raw) To: Michael Poole; +Cc: Ping Cheng, Jiri Kosina, linux-input On Mon, 2010-07-05 at 16:33 -0400, Michael Poole wrote: > C99 says that the result of right-shifting a negative value is > compiler-defined. gcc documents that it ensures sign extension. Other > parts of hid-magicmouse.c use this idiom already. The corresponding > idiom in hid-core.c (see the snto32() function) would look something > like this: > > x = ((data[3] & 0x0c) << 6) | data[1]; > x |= (x & (1 << 9)) ? (-1 << 10) : 0; snto32() seems like something we should be using in hid-magicmouse.c? On further thought, it actually seems like something that should be a macro in linux/kernel.h. I would think there could be utility for it in many places of the kernel. -- Chase ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 20:51 ` Chase Douglas @ 2010-07-05 22:08 ` Michael Poole 2010-07-05 22:25 ` Chase Douglas 2010-07-06 11:23 ` ext-phil.2.carmody 0 siblings, 2 replies; 14+ messages in thread From: Michael Poole @ 2010-07-05 22:08 UTC (permalink / raw) To: Chase Douglas; +Cc: Ping Cheng, Jiri Kosina, linux-input Chase Douglas writes: > On Mon, 2010-07-05 at 16:33 -0400, Michael Poole wrote: >> C99 says that the result of right-shifting a negative value is >> compiler-defined. gcc documents that it ensures sign extension. Other >> parts of hid-magicmouse.c use this idiom already. The corresponding >> idiom in hid-core.c (see the snto32() function) would look something >> like this: >> >> x = ((data[3] & 0x0c) << 6) | data[1]; >> x |= (x & (1 << 9)) ? (-1 << 10) : 0; > > snto32() seems like something we should be using in hid-magicmouse.c? On > further thought, it actually seems like something that should be a macro > in linux/kernel.h. I would think there could be utility for it in many > places of the kernel. Probably so. The patch below is a proof of concept, which probably is not worth including until we decide the right place to put snto32(), but I think does show that using snto32() is more readable than the current code. Note the bitwise-and for the ABS_MT_POSITION_X value: I missed that the first time I tried this, to rather undesirable effect. I am not sure whether snto32() should automatically do that kind of masking: It is only needed in one out of the four sites here, but it is a fairly easy mistake to make. Michael Poole --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -163,14 +163,26 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) msc->scroll_accel = SCROLL_ACCEL_DEFAULT; } +/* Function shamelessly borrowed from hid-core.c. */ + +static s32 snto32(__u32 value, unsigned n) +{ + switch (n) { + case 8: return ((__s8)value); + case 16: return ((__s16)value); + case 32: return ((__s32)value); + } + return value & (1 << (n - 1)) ? value | (-1 << n) : value; +} + static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) { struct input_dev *input = msc->input; __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; int misc = tdata[5] | tdata[6] << 8; int id = (misc >> 6) & 15; - int x = x_y << 12 >> 20; - int y = -(x_y >> 20); + int x = snto32((x_y >> 8) & 4095, 12); + int y = snto32(x_y >> 20, 12); int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; /* Store tracking ID and other fields. */ @@ -285,8 +297,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, * to have the current touch information before * generating a click event. */ - x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; - y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; + x = snto32(((data[3] & 0x0c) << 6) | data[1], 10); + y = snto32(((data[3] & 0x30) << 4) | data[2], 10); clicks = data[3]; break; case 0x20: /* Theoretically battery status (0-100), but I have ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 22:08 ` Michael Poole @ 2010-07-05 22:25 ` Chase Douglas 2010-07-06 11:23 ` ext-phil.2.carmody 1 sibling, 0 replies; 14+ messages in thread From: Chase Douglas @ 2010-07-05 22:25 UTC (permalink / raw) To: Michael Poole; +Cc: Ping Cheng, Jiri Kosina, linux-input On Mon, 2010-07-05 at 18:08 -0400, Michael Poole wrote: > Chase Douglas writes: > > snto32() seems like something we should be using in hid-magicmouse.c? On > > further thought, it actually seems like something that should be a macro > > in linux/kernel.h. I would think there could be utility for it in many > > places of the kernel. > > Probably so. The patch below is a proof of concept, which probably is > not worth including until we decide the right place to put snto32(), but > I think does show that using snto32() is more readable than the current > code. > > Note the bitwise-and for the ABS_MT_POSITION_X value: I missed that the > first time I tried this, to rather undesirable effect. I am not sure > whether snto32() should automatically do that kind of masking: It is > only needed in one out of the four sites here, but it is a fairly easy > mistake to make. > > Michael Poole > > --- a/drivers/hid/hid-magicmouse.c > +++ b/drivers/hid/hid-magicmouse.c > @@ -163,14 +163,26 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) > msc->scroll_accel = SCROLL_ACCEL_DEFAULT; > } > > +/* Function shamelessly borrowed from hid-core.c. */ > + > +static s32 snto32(__u32 value, unsigned n) > +{ > + switch (n) { > + case 8: return ((__s8)value); > + case 16: return ((__s16)value); > + case 32: return ((__s32)value); > + } > + return value & (1 << (n - 1)) ? value | (-1 << n) : value; > +} > + > static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) > { > struct input_dev *input = msc->input; > __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; > int misc = tdata[5] | tdata[6] << 8; > int id = (misc >> 6) & 15; > - int x = x_y << 12 >> 20; > - int y = -(x_y >> 20); > + int x = snto32((x_y >> 8) & 4095, 12); > + int y = snto32(x_y >> 20, 12); > int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; > > /* Store tracking ID and other fields. */ Instead of having this intermediate x_y that's shifted 8 bits to the left, why not do: int x = snto32((tdata[1] << 8 | tdata[0]) & 0xFFF, 12); int y = snto32(tdata[2] << 4 | tdata[1] >> 4, 12); P.S.: I much prefer hex when doing masks because it's easier to count the bits. -- Chase ^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 22:08 ` Michael Poole 2010-07-05 22:25 ` Chase Douglas @ 2010-07-06 11:23 ` ext-phil.2.carmody 2010-07-06 11:38 ` Datta, Shubhrajyoti 2010-07-06 11:55 ` Michael Poole 1 sibling, 2 replies; 14+ messages in thread From: ext-phil.2.carmody @ 2010-07-06 11:23 UTC (permalink / raw) To: mdpoole, chase.douglas; +Cc: pinglinux, jkosina, linux-input Arsebiscuits, forced to use webmail, sloppily prefixing every line with '>' manually ... ________________________________________ From: linux-input-owner@vger.kernel.org [linux-input-owner@vger.kernel.org] On Behalf Of ext Michael Poole [mdpoole@troilus.org] Sent: Tuesday, July 06, 2010 12:08 AM To: Chase Douglas Cc: Ping Cheng; Jiri Kosina; linux-input@vger.kernel.org Subject: Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. >Chase Douglas writes: > >> On Mon, 2010-07-05 at 16:33 -0400, Michael Poole wrote: >>> C99 says that the result of right-shifting a negative value is >>> compiler-defined. gcc documents that it ensures sign extension. Other >>> parts of hid-magicmouse.c use this idiom already. The corresponding >>> idiom in hid-core.c (see the snto32() function) would look something >>> like this: >>> >>> x = ((data[3] & 0x0c) << 6) | data[1]; >>> x |= (x & (1 << 9)) ? (-1 << 10) : 0; >> >> snto32() seems like something we should be using in hid-magicmouse.c? On >> further thought, it actually seems like something that should be a macro >> in linux/kernel.h. I would think there could be utility for it in many >> places of the kernel. > >Probably so. The patch below is a proof of concept, which probably is >not worth including until we decide the right place to put snto32(), but >I think does show that using snto32() is more readable than the current >code. > >Note the bitwise-and for the ABS_MT_POSITION_X value: I missed that the >first time I tried this, to rather undesirable effect. I am not sure >whether snto32() should automatically do that kind of masking: It is >only needed in one out of the four sites here, but it is a fairly easy >mistake to make. > >Michael Poole > >--- a/drivers/hid/hid-magicmouse.c >+++ b/drivers/hid/hid-magicmouse.c >@@ -163,14 +163,26 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) > msc->scroll_accel = SCROLL_ACCEL_DEFAULT; > } > >+/* Function shamelessly borrowed from hid-core.c. */ >+ >+static s32 snto32(__u32 value, unsigned n) >+{ >+ switch (n) { >+ case 8: return ((__s8)value); >+ case 16: return ((__s16)value); >+ case 32: return ((__s32)value); Beware - this relies on sane behaviour from the current and future compilers, as the C standard doesn't mandate what should happen when shortening out of range signed values. [n869.txt: 6.3.1.1.#3] >+ } >+ return value & (1 << (n - 1)) ? value | (-1 << n) : value; That signed left shift, however, is good old fashioned undefined behaviour. [n869.txt 6.5.7.#4] >+} >+ > static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) > { > struct input_dev *input = msc->input; > __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; > int misc = tdata[5] | tdata[6] << 8; > int id = (misc >> 6) & 15; >- int x = x_y << 12 >> 20; >- int y = -(x_y >> 20); >+ int x = snto32((x_y >> 8) & 4095, 12); >+ int y = snto32(x_y >> 20, 12); > int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; > > /* Store tracking ID and other fields. */ >@@ -285,8 +297,8 @@ static int magicmouse_raw_event(struct hid_device *hdev, > * to have the current touch information before > * generating a click event. > */ >- x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; >- y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; >+ x = snto32(((data[3] & 0x0c) << 6) | data[1], 10); >+ y = snto32(((data[3] & 0x30) << 4) | data[2], 10); > clicks = data[3]; > break; > case 0x20: /* Theoretically battery status (0-100), but I have ^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-06 11:23 ` ext-phil.2.carmody @ 2010-07-06 11:38 ` Datta, Shubhrajyoti 2010-07-06 11:55 ` Michael Poole 1 sibling, 0 replies; 14+ messages in thread From: Datta, Shubhrajyoti @ 2010-07-06 11:38 UTC (permalink / raw) To: ext-phil.2.carmody@nokia.com, mdpoole@troilus.org, chase.douglas@canonical.com Cc: pinglinux@gmail.com, jkosina@suse.cz, linux-input@vger.kernel.org > -----Original Message----- > From: linux-input-owner@vger.kernel.org [mailto:linux-input- > owner@vger.kernel.org] On Behalf Of ext-phil.2.carmody@nokia.com > Sent: Tuesday, July 06, 2010 4:53 PM > To: mdpoole@troilus.org; chase.douglas@canonical.com > Cc: pinglinux@gmail.com; jkosina@suse.cz; linux-input@vger.kernel.org > Subject: RE: [PATCH] hid-magicmouse: Correct parsing of large X and Y > motions. > > Arsebiscuits, forced to use webmail, sloppily prefixing every line with > '>' manually ... > > ________________________________________ > From: linux-input-owner@vger.kernel.org [linux-input- > owner@vger.kernel.org] On Behalf Of ext Michael Poole > [mdpoole@troilus.org] > Sent: Tuesday, July 06, 2010 12:08 AM > To: Chase Douglas > Cc: Ping Cheng; Jiri Kosina; linux-input@vger.kernel.org > Subject: Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y > motions. > > >Chase Douglas writes: > > > >> On Mon, 2010-07-05 at 16:33 -0400, Michael Poole wrote: > >>> C99 says that the result of right-shifting a negative value is > >>> compiler-defined. gcc documents that it ensures sign extension. > Other > >>> parts of hid-magicmouse.c use this idiom already. The corresponding > >>> idiom in hid-core.c (see the snto32() function) would look something > >>> like this: > >>> > >>> x = ((data[3] & 0x0c) << 6) | data[1]; > >>> x |= (x & (1 << 9)) ? (-1 << 10) : 0; > >> > >> snto32() seems like something we should be using in hid-magicmouse.c? > On > >> further thought, it actually seems like something that should be a > macro > >> in linux/kernel.h. I would think there could be utility for it in many > >> places of the kernel. > > > >Probably so. The patch below is a proof of concept, which probably is > >not worth including until we decide the right place to put snto32(), but > >I think does show that using snto32() is more readable than the current > >code. > > > >Note the bitwise-and for the ABS_MT_POSITION_X value: I missed that the > >first time I tried this, to rather undesirable effect. I am not sure > >whether snto32() should automatically do that kind of masking: It is > >only needed in one out of the four sites here, but it is a fairly easy > >mistake to make. > > > >Michael Poole > > > >--- a/drivers/hid/hid-magicmouse.c > >+++ b/drivers/hid/hid-magicmouse.c > >@@ -163,14 +163,26 @@ static void magicmouse_emit_buttons(struct > magicmouse_sc *msc, int state) > > msc->scroll_accel = SCROLL_ACCEL_DEFAULT; > > } > > > >+/* Function shamelessly borrowed from hid-core.c. */ > >+ > >+static s32 snto32(__u32 value, unsigned n) > >+{ > >+ switch (n) { > >+ case 8: return ((__s8)value); > >+ case 16: return ((__s16)value); > >+ case 32: return ((__s32)value); > > Beware - this relies on sane behaviour from the current and future > compilers, as the C standard doesn't mandate what should happen when > shortening out of range signed values. [n869.txt: 6.3.1.1.#3] Any reason of choosing __s32/ s32 ? > > >+ } > >+ return value & (1 << (n - 1)) ? value | (-1 << n) : value; > > That signed left shift, however, is good old fashioned undefined > behaviour. [n869.txt 6.5.7.#4] > > >+} > >+ > > static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, > u8 *tdata) > > { > > struct input_dev *input = msc->input; > > __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; > > int misc = tdata[5] | tdata[6] << 8; > > int id = (misc >> 6) & 15; > >- int x = x_y << 12 >> 20; > >- int y = -(x_y >> 20); > >+ int x = snto32((x_y >> 8) & 4095, 12); > >+ int y = snto32(x_y >> 20, 12); > > int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; > > > > /* Store tracking ID and other fields. */ > >@@ -285,8 +297,8 @@ static int magicmouse_raw_event(struct hid_device > *hdev, > > * to have the current touch information before > > * generating a click event. > > */ > >- x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> > 22; > >- y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> > 22; > >+ x = snto32(((data[3] & 0x0c) << 6) | data[1], 10); > >+ y = snto32(((data[3] & 0x30) << 4) | data[2], 10); > > clicks = data[3]; > > break; > > case 0x20: /* Theoretically battery status (0-100), but I have > -- > To unsubscribe from this list: send the line "unsubscribe linux-input" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-06 11:23 ` ext-phil.2.carmody 2010-07-06 11:38 ` Datta, Shubhrajyoti @ 2010-07-06 11:55 ` Michael Poole 2010-07-06 13:05 ` ext-phil.2.carmody 1 sibling, 1 reply; 14+ messages in thread From: Michael Poole @ 2010-07-06 11:55 UTC (permalink / raw) To: ext-phil.2.carmody; +Cc: chase.douglas, pinglinux, jkosina, linux-input ext-phil.2.carmody@nokia.com writes: [snip] >>+/* Function shamelessly borrowed from hid-core.c. */ >>+ >>+static s32 snto32(__u32 value, unsigned n) >>+{ >>+ switch (n) { >>+ case 8: return ((__s8)value); >>+ case 16: return ((__s16)value); >>+ case 32: return ((__s32)value); > > Beware - this relies on sane behaviour from the current and future compilers, as the C standard doesn't mandate what should happen when shortening out of range signed values. [n869.txt: 6.3.1.1.#3] That's good to know. There's probably some much more complicated, but portable, way to write the operation -- I suspect we'll continue to rely on the compiler to be sane. >>+ } >>+ return value & (1 << (n - 1)) ? value | (-1 << n) : value; > > That signed left shift, however, is good old fashioned undefined behaviour. [n869.txt 6.5.7.#4] Which version is that from? The copy of C99 I have says the resulting value is -1 * (2 ** n) if that value can be represented. (A 6 May 2005 committee draft of TC2 says the same thing.) Until n > 31, the behavior should be standard-defined. Michael ^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-06 11:55 ` Michael Poole @ 2010-07-06 13:05 ` ext-phil.2.carmody 0 siblings, 0 replies; 14+ messages in thread From: ext-phil.2.carmody @ 2010-07-06 13:05 UTC (permalink / raw) To: mdpoole; +Cc: chase.douglas, pinglinux, jkosina, linux-input From: ext Michael Poole [mdpoole@troilus.org] >ext-phil.2.carmody@nokia.com writes: > >[snip] >>>+/* Function shamelessly borrowed from hid-core.c. */ >>>+ >>>+static s32 snto32(__u32 value, unsigned n) >>>+{ >>>+ switch (n) { >>>+ case 8: return ((__s8)value); >>>+ case 16: return ((__s16)value); >>>+ case 32: return ((__s32)value); >> >> Beware - this relies on sane behaviour from the current and future compilers, as the C standard doesn't mandate what should happen when shortening out of range signed values. [n869.txt: 6.3.1.1.#3] > >That's good to know. There's probably some much more complicated, but >portable, way to write the operation -- I suspect we'll continue to rely >on the compiler to be sane. > >>>+ } >>>+ return value & (1 << (n - 1)) ? value | (-1 << n) : value; >> >> That signed left shift, however, is good old fashioned undefined behaviour. [n869.txt 6.5.7.#4] > >Which version is that from? A text version of n869, which looks like it suffered a little in conversion to not-quite-ASCII. > The copy of C99 I have says the resulting >value is -1 * (2 ** n) if that value can be represented. (A 6 May 2005 >committee draft of TC2 says the same thing.) Until n > 31, the behavior >should be standard-defined. Looking at the pdfs, agreed, My mistake. I shall have to 'fix' the non-ASCII in my text version, as I much prefer greppable text to pdfs. Phil ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] hid-magicmouse: Correct parsing of large X and Y motions. 2010-07-05 19:54 ` Ping Cheng 2010-07-05 20:02 ` Chase Douglas @ 2010-07-05 22:51 ` Dmitry Torokhov 1 sibling, 0 replies; 14+ messages in thread From: Dmitry Torokhov @ 2010-07-05 22:51 UTC (permalink / raw) To: Ping Cheng Cc: Michael Poole, Jiri Kosina, Chase Douglas, linux-input@vger.kernel.org On Jul 5, 2010, at 12:54 PM, Ping Cheng <pinglinux@gmail.com> wrote: > On Mon, Jul 5, 2010 at 10:50 PM, Michael Poole <mdpoole@troilus.org> > wrote: >> The X and Y values have two more significant bits in the same byte >> that contains click status. Include these in the reported value. >> Thanks to Iain Hibbert of NetBSD for pointing this out. >> >> Signed-off-by: Michael Poole <mdpoole@troilus.org> >> --- >> drivers/hid/hid-magicmouse.c | 4 ++-- >> 1 files changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid- >> magicmouse.c >> index 0b89c1c..7cdda23 100644 >> --- a/drivers/hid/hid-magicmouse.c >> +++ b/drivers/hid/hid-magicmouse.c >> @@ -267,8 +267,8 @@ static int magicmouse_raw_event(struct >> hid_device *hdev, >> * to have the current touch information before >> * generating a click event. >> */ >> - x = (signed char)data[1]; >> - y = (signed char)data[2]; >> + x = (int)(((data[3] & 0x0c) << 28) | (data[1] << >> 22)) >> 22; >> + y = (int)(((data[3] & 0x30) << 26) | (data[2] << >> 22)) >> 22; > > Will the following give us the same result? > > + x = (int)(((data[3] & 0x0c) << 6) | data[1]); > + y = (int)(((data[3] & 0x30) << 4) | data[2]); I'd think you'd run into endianness issues. -- Dmitry ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2010-07-11 21:07 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-07-05 14:50 [PATCH] hid-magicmouse: Correct parsing of large X and Y motions Michael Poole 2010-07-05 16:28 ` Chase Douglas 2010-07-11 21:07 ` Jiri Kosina 2010-07-05 19:54 ` Ping Cheng 2010-07-05 20:02 ` Chase Douglas 2010-07-05 20:33 ` Michael Poole 2010-07-05 20:51 ` Chase Douglas 2010-07-05 22:08 ` Michael Poole 2010-07-05 22:25 ` Chase Douglas 2010-07-06 11:23 ` ext-phil.2.carmody 2010-07-06 11:38 ` Datta, Shubhrajyoti 2010-07-06 11:55 ` Michael Poole 2010-07-06 13:05 ` ext-phil.2.carmody 2010-07-05 22:51 ` Dmitry Torokhov
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).