Commit a69c5f8b authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina

HID: multitouch: breaks out touch handling in specific functions

This will allow easier integration of hybrid pen and touch devices.
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 4f22decf
...@@ -114,6 +114,9 @@ struct mt_device { ...@@ -114,6 +114,9 @@ struct mt_device {
unsigned mt_flags; /* flags to pass to input-mt */ unsigned mt_flags; /* flags to pass to input-mt */
}; };
static void mt_post_parse_default_settings(struct mt_device *td);
static void mt_post_parse(struct mt_device *td);
/* classes of device behavior */ /* classes of device behavior */
#define MT_CLS_DEFAULT 0x0001 #define MT_CLS_DEFAULT 0x0001
...@@ -364,7 +367,7 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td, ...@@ -364,7 +367,7 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
f->usages[f->length++] = usage->hid; f->usages[f->length++] = usage->hid;
} }
static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage, struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max) unsigned long **bit, int *max)
{ {
...@@ -373,13 +376,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -373,13 +376,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
int code; int code;
struct hid_usage *prev_usage = NULL; struct hid_usage *prev_usage = NULL;
/* Only map fields from TouchScreen or TouchPad collections.
* We need to ignore fields that belong to other collections
* such as Mouse that might have the same GenericDesktop usages. */
if (field->application == HID_DG_TOUCHSCREEN) if (field->application == HID_DG_TOUCHSCREEN)
td->mt_flags |= INPUT_MT_DIRECT; td->mt_flags |= INPUT_MT_DIRECT;
else if (field->application != HID_DG_TOUCHPAD)
return 0;
/* /*
* Model touchscreens providing buttons as touchpads. * Model touchscreens providing buttons as touchpads.
...@@ -388,12 +386,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -388,12 +386,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
(usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
td->mt_flags |= INPUT_MT_POINTER; td->mt_flags |= INPUT_MT_POINTER;
/* eGalax devices provide a Digitizer.Stylus input which overrides
* the correct Digitizers.Finger X/Y ranges.
* Let's just ignore this input. */
if (field->physical == HID_DG_STYLUS)
return -1;
if (usage->usage_index) if (usage->usage_index)
prev_usage = &field->usage[usage->usage_index - 1]; prev_usage = &field->usage[usage->usage_index - 1];
...@@ -514,7 +506,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -514,7 +506,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
return 0; return 0;
} }
static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage, struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max) unsigned long **bit, int *max)
{ {
...@@ -605,7 +597,7 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) ...@@ -605,7 +597,7 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
td->num_received = 0; td->num_received = 0;
} }
static int mt_event(struct hid_device *hid, struct hid_field *field, static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value) struct hid_usage *usage, __s32 value)
{ {
/* we will handle the hidinput part later, now remains hiddev */ /* we will handle the hidinput part later, now remains hiddev */
...@@ -681,19 +673,13 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, ...@@ -681,19 +673,13 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
} }
} }
static void mt_report(struct hid_device *hid, struct hid_report *report) static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
{ {
struct mt_device *td = hid_get_drvdata(hid); struct mt_device *td = hid_get_drvdata(hid);
struct hid_field *field; struct hid_field *field;
unsigned count; unsigned count;
int r, n; int r, n;
if (report->id != td->mt_report_id)
return;
if (!(hid->claimed & HID_CLAIMED_INPUT))
return;
/* /*
* Includes multi-packet support where subsequent * Includes multi-packet support where subsequent
* packets are sent with zero contactcount. * packets are sent with zero contactcount.
...@@ -721,6 +707,81 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) ...@@ -721,6 +707,81 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
mt_sync_frame(td, report->field[0]->hidinput->input); mt_sync_frame(td, report->field[0]->hidinput->input);
} }
static void mt_touch_input_configured(struct hid_device *hdev,
struct hid_input *hi)
{
struct mt_device *td = hid_get_drvdata(hdev);
struct mt_class *cls = &td->mtclass;
struct input_dev *input = hi->input;
if (!td->maxcontacts)
td->maxcontacts = MT_DEFAULT_MAXCONTACT;
mt_post_parse(td);
if (td->serial_maybe)
mt_post_parse_default_settings(td);
if (cls->is_indirect)
td->mt_flags |= INPUT_MT_POINTER;
if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
td->mt_flags |= INPUT_MT_DROP_UNUSED;
input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
td->mt_flags = 0;
}
static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
/* Only map fields from TouchScreen or TouchPad collections.
* We need to ignore fields that belong to other collections
* such as Mouse that might have the same GenericDesktop usages. */
if (field->application != HID_DG_TOUCHSCREEN &&
field->application != HID_DG_TOUCHPAD)
return 0;
/* eGalax devices provide a Digitizer.Stylus input which overrides
* the correct Digitizers.Finger X/Y ranges.
* Let's just ignore this input. */
if (field->physical == HID_DG_STYLUS)
return -1;
return mt_touch_input_mapping(hdev, hi, field, usage, bit, max);
}
static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
}
static int mt_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
struct mt_device *td = hid_get_drvdata(hid);
if (field->report->id == td->mt_report_id)
return mt_touch_event(hid, field, usage, value);
/* ignore other reports */
return 1;
}
static void mt_report(struct hid_device *hid, struct hid_report *report)
{
struct mt_device *td = hid_get_drvdata(hid);
if (!(hid->claimed & HID_CLAIMED_INPUT))
return;
if (report->id == td->mt_report_id)
mt_touch_report(hid, report);
}
static void mt_set_input_mode(struct hid_device *hdev) static void mt_set_input_mode(struct hid_device *hdev)
{ {
struct mt_device *td = hid_get_drvdata(hdev); struct mt_device *td = hid_get_drvdata(hdev);
...@@ -795,32 +856,14 @@ static void mt_post_parse(struct mt_device *td) ...@@ -795,32 +856,14 @@ static void mt_post_parse(struct mt_device *td)
} }
static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
{ {
struct mt_device *td = hid_get_drvdata(hdev);
struct mt_class *cls = &td->mtclass;
struct input_dev *input = hi->input; struct input_dev *input = hi->input;
/* Only initialize slots for MT input devices */ /* Only initialize slots for MT input devices */
if (!test_bit(ABS_MT_POSITION_X, input->absbit)) if (!test_bit(ABS_MT_POSITION_X, input->absbit))
return; return;
if (!td->maxcontacts) mt_touch_input_configured(hdev, hi);
td->maxcontacts = MT_DEFAULT_MAXCONTACT;
mt_post_parse(td);
if (td->serial_maybe)
mt_post_parse_default_settings(td);
if (cls->is_indirect)
td->mt_flags |= INPUT_MT_POINTER;
if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
td->mt_flags |= INPUT_MT_DROP_UNUSED;
input_mt_init_slots(input, td->maxcontacts, td->mt_flags);
td->mt_flags = 0;
} }
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment