diff options
author | Benjamin Tissoires <benjamin.tissoires@gmail.com> | 2012-11-14 10:59:19 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-11-15 04:09:12 -0500 |
commit | 349fd6705b13946c04794bf27d67282940aa46b8 (patch) | |
tree | 45a7012eb24f99b589418c9cf4e4a1c581c4549e /drivers/hid | |
parent | afbcb04c181f36634f4af207bb0c9cc46b7405e4 (diff) |
HID: multitouch: support T and C for win8 devices
Win8 input specification clarifies the X and Y sent by devices.
It distincts the position where the user wants to Touch (T) from
the center of the ellipsoide (C). This patch enable supports for this
distinction in hid-multitouch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 9c7415ff4aaf..a2963b238fde 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); | |||
54 | #define MT_QUIRK_NO_AREA (1 << 9) | 54 | #define MT_QUIRK_NO_AREA (1 << 9) |
55 | 55 | ||
56 | struct mt_slot { | 56 | struct mt_slot { |
57 | __s32 x, y, p, w, h; | 57 | __s32 x, y, cx, cy, p, w, h; |
58 | __s32 contactid; /* the device ContactID assigned to this slot */ | 58 | __s32 contactid; /* the device ContactID assigned to this slot */ |
59 | bool touch_state; /* is the touch valid? */ | 59 | bool touch_state; /* is the touch valid? */ |
60 | }; | 60 | }; |
@@ -322,6 +322,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
322 | struct mt_device *td = hid_get_drvdata(hdev); | 322 | struct mt_device *td = hid_get_drvdata(hdev); |
323 | struct mt_class *cls = &td->mtclass; | 323 | struct mt_class *cls = &td->mtclass; |
324 | int code; | 324 | int code; |
325 | struct hid_usage *prev_usage = NULL; | ||
325 | 326 | ||
326 | /* Only map fields from TouchScreen or TouchPad collections. | 327 | /* Only map fields from TouchScreen or TouchPad collections. |
327 | * We need to ignore fields that belong to other collections | 328 | * We need to ignore fields that belong to other collections |
@@ -344,23 +345,42 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
344 | if (field->physical == HID_DG_STYLUS) | 345 | if (field->physical == HID_DG_STYLUS) |
345 | return -1; | 346 | return -1; |
346 | 347 | ||
348 | if (usage->usage_index) | ||
349 | prev_usage = &field->usage[usage->usage_index - 1]; | ||
350 | |||
347 | switch (usage->hid & HID_USAGE_PAGE) { | 351 | switch (usage->hid & HID_USAGE_PAGE) { |
348 | 352 | ||
349 | case HID_UP_GENDESK: | 353 | case HID_UP_GENDESK: |
350 | switch (usage->hid) { | 354 | switch (usage->hid) { |
351 | case HID_GD_X: | 355 | case HID_GD_X: |
352 | hid_map_usage(hi, usage, bit, max, | 356 | if (prev_usage && (prev_usage->hid == usage->hid)) { |
357 | hid_map_usage(hi, usage, bit, max, | ||
358 | EV_ABS, ABS_MT_TOOL_X); | ||
359 | set_abs(hi->input, ABS_MT_TOOL_X, field, | ||
360 | cls->sn_move); | ||
361 | } else { | ||
362 | hid_map_usage(hi, usage, bit, max, | ||
353 | EV_ABS, ABS_MT_POSITION_X); | 363 | EV_ABS, ABS_MT_POSITION_X); |
354 | set_abs(hi->input, ABS_MT_POSITION_X, field, | 364 | set_abs(hi->input, ABS_MT_POSITION_X, field, |
355 | cls->sn_move); | 365 | cls->sn_move); |
366 | } | ||
367 | |||
356 | mt_store_field(usage, td, hi); | 368 | mt_store_field(usage, td, hi); |
357 | td->last_field_index = field->index; | 369 | td->last_field_index = field->index; |
358 | return 1; | 370 | return 1; |
359 | case HID_GD_Y: | 371 | case HID_GD_Y: |
360 | hid_map_usage(hi, usage, bit, max, | 372 | if (prev_usage && (prev_usage->hid == usage->hid)) { |
373 | hid_map_usage(hi, usage, bit, max, | ||
374 | EV_ABS, ABS_MT_TOOL_Y); | ||
375 | set_abs(hi->input, ABS_MT_TOOL_Y, field, | ||
376 | cls->sn_move); | ||
377 | } else { | ||
378 | hid_map_usage(hi, usage, bit, max, | ||
361 | EV_ABS, ABS_MT_POSITION_Y); | 379 | EV_ABS, ABS_MT_POSITION_Y); |
362 | set_abs(hi->input, ABS_MT_POSITION_Y, field, | 380 | set_abs(hi->input, ABS_MT_POSITION_Y, field, |
363 | cls->sn_move); | 381 | cls->sn_move); |
382 | } | ||
383 | |||
364 | mt_store_field(usage, td, hi); | 384 | mt_store_field(usage, td, hi); |
365 | td->last_field_index = field->index; | 385 | td->last_field_index = field->index; |
366 | return 1; | 386 | return 1; |
@@ -501,6 +521,8 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) | |||
501 | 521 | ||
502 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); | 522 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); |
503 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); | 523 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); |
524 | input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx); | ||
525 | input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy); | ||
504 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | 526 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); |
505 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); | 527 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); |
506 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | 528 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
@@ -552,10 +574,16 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
552 | td->curdata.p = value; | 574 | td->curdata.p = value; |
553 | break; | 575 | break; |
554 | case HID_GD_X: | 576 | case HID_GD_X: |
555 | td->curdata.x = value; | 577 | if (usage->code == ABS_MT_TOOL_X) |
578 | td->curdata.cx = value; | ||
579 | else | ||
580 | td->curdata.x = value; | ||
556 | break; | 581 | break; |
557 | case HID_GD_Y: | 582 | case HID_GD_Y: |
558 | td->curdata.y = value; | 583 | if (usage->code == ABS_MT_TOOL_Y) |
584 | td->curdata.cy = value; | ||
585 | else | ||
586 | td->curdata.y = value; | ||
559 | break; | 587 | break; |
560 | case HID_DG_WIDTH: | 588 | case HID_DG_WIDTH: |
561 | td->curdata.w = value; | 589 | td->curdata.w = value; |