lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 13 Nov 2012 18:29:12 +0100
From:	Benjamin Tissoires <benjamin.tissoires@...il.com>
To:	Henrik Rydberg <rydberg@...omail.se>
Cc:	Dmitry Torokhov <dmitry.torokhov@...il.com>,
	Jiri Kosina <jkosina@...e.cz>,
	Stephane Chatty <chatty@...c.fr>, linux-input@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 11/13] HID: hid-multitouch: support for hovering devices

Hi Henrik,

thanks for the review of the patchset. I'll do my best for the next version :)

On Tue, Nov 13, 2012 at 5:42 PM, Henrik Rydberg <rydberg@...omail.se> wrote:
> On Wed, Nov 07, 2012 at 05:37:34PM +0100, Benjamin Tissoires wrote:
>> Win8 devices supporting hovering must provides InRange HID field.
>
> provide the
>
>> The information that the finger is here but is not touching the surface
>> is sent to the user space through ABS_MT_DISTANCE as required by the
>> multitouch protocol.
>
> In the absence of more detailed information, use ABS_MT_DISTANCE with
> a [0,1] interval to distinguish between presence (1) and touch (0).
>
>>
>> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@...il.com>
>> ---
>>  drivers/hid/hid-multitouch.c | 24 ++++++++++++++++++++----
>>  1 file changed, 20 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
>> index b393c6c..1f3d1e0 100644
>> --- a/drivers/hid/hid-multitouch.c
>> +++ b/drivers/hid/hid-multitouch.c
>> @@ -59,6 +59,7 @@ struct mt_slot {
>>       __s32 x, y, cx, cy, p, w, h;
>>       __s32 contactid;        /* the device ContactID assigned to this slot */
>>       bool touch_state;       /* is the touch valid? */
>> +     bool inrange_state;     /* is the finger in proximity of the sensor? */
>>  };
>>
>>  struct mt_class {
>> @@ -397,6 +398,12 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
>>       case HID_UP_DIGITIZER:
>>               switch (usage->hid) {
>>               case HID_DG_INRANGE:
>> +                     if (cls->quirks & MT_QUIRK_WIN_8_CERTIFIED) {
>> +                             hid_map_usage(hi, usage, bit, max,
>> +                                     EV_ABS, ABS_MT_DISTANCE);
>> +                             input_set_abs_params(hi->input,
>> +                                     ABS_MT_DISTANCE, -1, 1, 0, 0);
>
> Why [-1,1] here?

At first, I only used [0,1]. However, it's still the same problem with
the information being kept between the touches:
if you start an application after having touched your device, you
normally have to ask for the different per-touche states to get x, y,
distance, pressure, etc...
However, this is not much mandatory because the protocol in its
current form ensures that you will get the new states of the axes when
a new touch occurs.

ABS_MT_DISTANCE is a little bit different here because the protocol
guarantees that once you get the "not in range" state through
tracking_id == -1, distance should be 1.
When the new touch of the very same slot occurs, you also have the
guarantee that distance is at 1 too.

So basically, if you don't ask for the slot states, you will never get
that very first distance.

I know that it's a user-space problem, but honestly, I don't want to
fix several user-space problems when we could fix it through the
protocol.

I can see 2 solutions:
- set the range to: [0,1] and still sending -1 (or 2) for the invalid
distance value (if it's not clamped)
- set the range to: [0,2] and having: 0 for touch, 1 for hovering, and
2 for not in range

Does that make sense?

>
>> +                     }
>>                       mt_store_field(usage, td, hi);
>>                       td->last_field_index = field->index;
>>                       return 1;
>> @@ -516,6 +523,10 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
>>               if (slotnum < 0 || slotnum >= td->maxcontacts)
>>                       return;
>>
>> +             if (!test_bit(ABS_MT_DISTANCE, input->absbit))
>> +                     /* If InRange is not present, rely on TipSwitch */
>> +                     s->inrange_state = s->touch_state;
>> +
>
> This could be skipped, see below.
>
>>               if (td->mtclass.quirks & MT_QUIRK_IGNORE_DUPLICATES &&
>>                   input_mt_is_active(&input->mt->slots[slotnum]) &&
>>                   input_mt_is_used(input->mt, &input->mt->slots[slotnum]))
>> @@ -523,9 +534,9 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
>>
>>               input_mt_slot(input, slotnum);
>>               input_mt_report_slot_state(input, MT_TOOL_FINGER,
>> -                     s->touch_state);
>> -             if (s->touch_state) {
>> -                     /* this finger is on the screen */
>> +                     s->inrange_state);
>> +             if (s->inrange_state) {
>> +                     /* this finger is in proximity of the sensor */
>
> Using (s->touch_state || s->inrange_state) here seems simpler.

agree.

>
>>                       int wide = (s->w > s->h);
>>                       /* divided by two to match visual scale of touch */
>>                       int major = max(s->w, s->h) >> 1;
>> @@ -535,11 +546,14 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
>>                       input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
>>                       input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx);
>>                       input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
>> +                     input_event(input, EV_ABS, ABS_MT_DISTANCE,
>> +                             !s->touch_state);
>>                       input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
>>                       input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
>>                       input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
>>                       input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
>> -             }
>> +             } else
>> +                     input_event(input, EV_ABS, ABS_MT_DISTANCE, -1);
>
> Just skip this, please.

see above.

Cheers,
Benjamin

>
>>       }
>>
>>       td->num_received++;
>> @@ -567,6 +581,8 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
>>               case HID_DG_INRANGE:
>>                       if (quirks & MT_QUIRK_VALID_IS_INRANGE)
>>                               td->curvalid = value;
>> +                     if (quirks & MT_QUIRK_WIN_8_CERTIFIED)
>> +                             td->curdata.inrange_state = value;
>>                       break;
>>               case HID_DG_TIPSWITCH:
>>                       if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
>> --
>> 1.7.11.7
>>
>
> Thanks,
> Henrik
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ