* [PATCH 1/4] input: mt: Break out slots handling
2010-11-29 7:13 [PATCH 0/4] input: mt: Driver interface simplifications Henrik Rydberg
@ 2010-11-29 7:13 ` Henrik Rydberg
2010-11-29 7:13 ` [PATCH 2/4] input: mt: Collect slots initialization code Henrik Rydberg
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Henrik Rydberg @ 2010-11-29 7:13 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input, linux-kernel, Henrik Rydberg
In preparation for common code to handle a larger set of MT slots
devices, move the slots handling over to a separate file.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
---
drivers/hid/hid-3m-pct.c | 1 +
drivers/input/Makefile | 2 +-
drivers/input/input-mt.c | 58 +++++++++++++++++++++++++++++++
drivers/input/input.c | 48 +-------------------------
drivers/input/misc/uinput.c | 1 +
drivers/input/tablet/wacom_wac.c | 1 +
drivers/input/touchscreen/wacom_w8001.c | 2 +-
include/linux/input-mt.h | 44 +++++++++++++++++++++++
include/linux/input.h | 16 --------
9 files changed, 108 insertions(+), 65 deletions(-)
create mode 100644 drivers/input/input-mt.c
create mode 100644 include/linux/input-mt.h
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index 02d8cd3..cb507f4 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
+#include <linux/input-mt.h>
MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
MODULE_DESCRIPTION("3M PCT multitouch panels");
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 7ad212d..569938b 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -5,7 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT) += input-core.o
-input-core-objs := input.o input-compat.o ff-core.o
+input-core-objs := input.o input-compat.o ff-core.o input-mt.o
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
new file mode 100644
index 0000000..ee24d28
--- /dev/null
+++ b/drivers/input/input-mt.c
@@ -0,0 +1,58 @@
+/*
+ * Input Multitouch Library
+ *
+ * Copyright (c) 2008-2010 Henrik Rydberg
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input-mt.h>
+#include <linux/slab.h>
+
+/**
+ * input_mt_create_slots() - create MT input slots
+ * @dev: input device supporting MT events and finger tracking
+ * @num_slots: number of slots used by the device
+ *
+ * This function allocates all necessary memory for MT slot handling in the
+ * input device, and adds ABS_MT_SLOT to the device capabilities. All slots
+ * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.
+ */
+int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
+{
+ int i;
+
+ if (!num_slots)
+ return 0;
+
+ dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
+ if (!dev->mt)
+ return -ENOMEM;
+
+ dev->mtsize = num_slots;
+ input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
+
+ /* Mark slots as 'unused' */
+ for (i = 0; i < num_slots; i++)
+ input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1);
+
+ return 0;
+}
+EXPORT_SYMBOL(input_mt_create_slots);
+
+/**
+ * input_mt_destroy_slots() - frees the MT slots of the input device
+ * @dev: input device with allocated MT slots
+ *
+ * This function is only needed in error path as the input core will
+ * automatically free the MT slots when the device is destroyed.
+ */
+void input_mt_destroy_slots(struct input_dev *dev)
+{
+ kfree(dev->mt);
+ dev->mt = NULL;
+ dev->mtsize = 0;
+}
+EXPORT_SYMBOL(input_mt_destroy_slots);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index db409d6..504cf63 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/input.h>
+#include <linux/input-mt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/random.h>
@@ -1725,52 +1725,6 @@ void input_free_device(struct input_dev *dev)
EXPORT_SYMBOL(input_free_device);
/**
- * input_mt_create_slots() - create MT input slots
- * @dev: input device supporting MT events and finger tracking
- * @num_slots: number of slots used by the device
- *
- * This function allocates all necessary memory for MT slot handling in the
- * input device, and adds ABS_MT_SLOT to the device capabilities. All slots
- * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.
- */
-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
-{
- int i;
-
- if (!num_slots)
- return 0;
-
- dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
- if (!dev->mt)
- return -ENOMEM;
-
- dev->mtsize = num_slots;
- input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
-
- /* Mark slots as 'unused' */
- for (i = 0; i < num_slots; i++)
- dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1;
-
- return 0;
-}
-EXPORT_SYMBOL(input_mt_create_slots);
-
-/**
- * input_mt_destroy_slots() - frees the MT slots of the input device
- * @dev: input device with allocated MT slots
- *
- * This function is only needed in error path as the input core will
- * automatically free the MT slots when the device is destroyed.
- */
-void input_mt_destroy_slots(struct input_dev *dev)
-{
- kfree(dev->mt);
- dev->mt = NULL;
- dev->mtsize = 0;
-}
-EXPORT_SYMBOL(input_mt_destroy_slots);
-
-/**
* input_set_capability - mark device as capable of a certain event
* @dev: device that is capable of emitting or accepting event
* @type: type of the event (EV_KEY, EV_REL, etc...)
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index b941078..e8962b1 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,6 +37,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uinput.h>
+#include <linux/input-mt.h>
#include "../input-compat.h"
static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index b3252ef..107ee3a 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -14,6 +14,7 @@
#include "wacom_wac.h"
#include "wacom.h"
+#include <linux/input-mt.h>
static int wacom_penpartner_irq(struct wacom_wac *wacom)
{
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 9ae4c7b..1fb0cbc 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/input.h>
+#include <linux/input-mt.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/ctype.h>
diff --git a/include/linux/input-mt.h b/include/linux/input-mt.h
new file mode 100644
index 0000000..4f5e9d0
--- /dev/null
+++ b/include/linux/input-mt.h
@@ -0,0 +1,44 @@
+#ifndef _INPUT_MT_H
+#define _INPUT_MT_H
+
+/*
+ * Input Multitouch Library
+ *
+ * Copyright (c) 2010 Henrik Rydberg
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+
+/**
+ * struct input_mt_slot - represents the state of an input MT slot
+ * @abs: holds current values of ABS_MT axes for this slot
+ */
+struct input_mt_slot {
+ int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
+};
+
+static inline void input_mt_set_value(struct input_mt_slot *slot,
+ unsigned code, int value)
+{
+ slot->abs[code - ABS_MT_FIRST] = value;
+}
+
+static inline int input_mt_get_value(const struct input_mt_slot *slot,
+ unsigned code)
+{
+ return slot->abs[code - ABS_MT_FIRST];
+}
+
+int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);
+void input_mt_destroy_slots(struct input_dev *dev);
+
+static inline void input_mt_slot(struct input_dev *dev, int slot)
+{
+ input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
+}
+
+#endif
diff --git a/include/linux/input.h b/include/linux/input.h
index 6ef4446..dd7c0fc 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1083,14 +1083,6 @@ struct ff_effect {
#include <linux/mod_devicetable.h>
/**
- * struct input_mt_slot - represents the state of an input MT slot
- * @abs: holds current values of ABS_MT axes for this slot
- */
-struct input_mt_slot {
- int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
-};
-
-/**
* struct input_dev - represents an input device
* @name: name of the device
* @phys: physical path to the device in the system hierarchy
@@ -1463,11 +1455,6 @@ static inline void input_mt_sync(struct input_dev *dev)
input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
}
-static inline void input_mt_slot(struct input_dev *dev, int slot)
-{
- input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
-}
-
void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);
/**
@@ -1580,8 +1567,5 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
int input_ff_create_memless(struct input_dev *dev, void *data,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);
-void input_mt_destroy_slots(struct input_dev *dev);
-
#endif
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/4] input: mt: Collect slots initialization code
2010-11-29 7:13 [PATCH 0/4] input: mt: Driver interface simplifications Henrik Rydberg
2010-11-29 7:13 ` [PATCH 1/4] input: mt: Break out slots handling Henrik Rydberg
@ 2010-11-29 7:13 ` Henrik Rydberg
2010-11-29 7:13 ` [PATCH 3/4] input: mt: Move tracking and pointer emulation to input-mt Henrik Rydberg
2010-11-29 7:13 ` [PATCH 4/4] input: mt: Add pressure to pointer emulation code Henrik Rydberg
3 siblings, 0 replies; 9+ messages in thread
From: Henrik Rydberg @ 2010-11-29 7:13 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input, linux-kernel, Henrik Rydberg
The MT slots devices all follow the same initialization pattern
of creating slots and hinting about buffer size. Let drivers call
an initialization function instead, and make sure it can be called
repeatedly without side effects.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
---
drivers/hid/hid-3m-pct.c | 5 +----
drivers/input/input-mt.c | 19 +++++++++++++------
drivers/input/misc/uinput.c | 3 +--
drivers/input/tablet/wacom_wac.c | 2 +-
drivers/input/touchscreen/wacom_w8001.c | 2 +-
include/linux/input-mt.h | 2 +-
6 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index cb507f4..e3711c5 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -29,7 +29,6 @@ MODULE_LICENSE("GPL");
#define MAX_SLOTS 60
#define MAX_TRKID USHRT_MAX
-#define MAX_EVENTS 360
/* estimated signal-to-noise ratios */
#define SN_MOVE 2048
@@ -123,9 +122,7 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
EV_ABS, ABS_MT_TRACKING_ID);
input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
0, MAX_TRKID, 0, 0);
- if (!hi->input->mt)
- input_mt_create_slots(hi->input, MAX_SLOTS);
- input_set_events_per_packet(hi->input, MAX_EVENTS);
+ input_mt_init_slots(hi->input, MAX_SLOTS);
return 1;
}
/* let hid-input decide for the others */
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index ee24d28..c4a9784 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -12,20 +12,25 @@
#include <linux/slab.h>
/**
- * input_mt_create_slots() - create MT input slots
+ * input_mt_init_slots() - initialize MT input slots
* @dev: input device supporting MT events and finger tracking
* @num_slots: number of slots used by the device
*
- * This function allocates all necessary memory for MT slot handling in the
- * input device, and adds ABS_MT_SLOT to the device capabilities. All slots
- * are initially marked as unused by setting ABS_MT_TRACKING_ID to -1.
+ * This function allocates all necessary memory for MT slot handling
+ * in the input device, adds ABS_MT_SLOT to the device capabilities
+ * and sets up appropriate event buffers. All slots are initially
+ * marked as unused by setting ABS_MT_TRACKING_ID to -1. May be called
+ * repeatedly. Returns -EINVAL if attempting to reinitialize with a
+ * different number of slots.
*/
-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
+int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
{
int i;
if (!num_slots)
return 0;
+ if (dev->mt)
+ return dev->mtsize != num_slots ? -EINVAL : 0;
dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
if (!dev->mt)
@@ -33,6 +38,7 @@ int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
dev->mtsize = num_slots;
input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
+ input_set_events_per_packet(dev, 6 * num_slots);
/* Mark slots as 'unused' */
for (i = 0; i < num_slots; i++)
@@ -40,7 +46,7 @@ int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
return 0;
}
-EXPORT_SYMBOL(input_mt_create_slots);
+EXPORT_SYMBOL(input_mt_init_slots);
/**
* input_mt_destroy_slots() - frees the MT slots of the input device
@@ -54,5 +60,6 @@ void input_mt_destroy_slots(struct input_dev *dev)
kfree(dev->mt);
dev->mt = NULL;
dev->mtsize = 0;
+ dev->slot = 0;
}
EXPORT_SYMBOL(input_mt_destroy_slots);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index e8962b1..67aa7ba 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -407,8 +407,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
goto exit;
if (test_bit(ABS_MT_SLOT, dev->absbit)) {
int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
- input_mt_create_slots(dev, nslot);
- input_set_events_per_packet(dev, 6 * nslot);
+ input_mt_init_slots(dev, nslot);
} else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
input_set_events_per_packet(dev, 60);
}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 107ee3a..3f9e280 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1273,7 +1273,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
- input_mt_create_slots(input_dev, 2);
+ input_mt_init_slots(input_dev, 2);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
0, features->x_max,
features->x_fuzz, 0);
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 1fb0cbc..b706cd5 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -318,7 +318,7 @@ static int w8001_setup(struct w8001 *w8001)
case 5:
w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
- input_mt_create_slots(dev, 2);
+ input_mt_init_slots(dev, 2);
input_set_abs_params(dev, ABS_MT_TRACKING_ID,
0, MAX_TRACKING_ID, 0, 0);
input_set_abs_params(dev, ABS_MT_POSITION_X,
diff --git a/include/linux/input-mt.h b/include/linux/input-mt.h
index 4f5e9d0..d7f6518 100644
--- a/include/linux/input-mt.h
+++ b/include/linux/input-mt.h
@@ -33,7 +33,7 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot,
return slot->abs[code - ABS_MT_FIRST];
}
-int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);
+int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
void input_mt_destroy_slots(struct input_dev *dev);
static inline void input_mt_slot(struct input_dev *dev, int slot)
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/4] input: mt: Move tracking and pointer emulation to input-mt
2010-11-29 7:13 [PATCH 0/4] input: mt: Driver interface simplifications Henrik Rydberg
2010-11-29 7:13 ` [PATCH 1/4] input: mt: Break out slots handling Henrik Rydberg
2010-11-29 7:13 ` [PATCH 2/4] input: mt: Collect slots initialization code Henrik Rydberg
@ 2010-11-29 7:13 ` Henrik Rydberg
2010-11-30 21:50 ` Henrik Rydberg
2010-11-29 7:13 ` [PATCH 4/4] input: mt: Add pressure to pointer emulation code Henrik Rydberg
3 siblings, 1 reply; 9+ messages in thread
From: Henrik Rydberg @ 2010-11-29 7:13 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input, linux-kernel, Henrik Rydberg
The drivers using the type B protocol all report tracking information
the same way. The contact id is semantically equivalent to
ABS_MT_SLOT, and the handling of ABS_MT_TRACKING_ID only complicates
the driver. The situation can be improved upon by providing a common
pointer emulation code, thereby removing the need for the tracking id
in the driver. This patch moves all tracking event handling over to
the input core, simplifying both the existing drivers and the ones
currently in preparation.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
---
drivers/hid/hid-3m-pct.c | 30 +-----------
drivers/input/input-mt.c | 77 +++++++++++++++++++++++++++++--
drivers/input/tablet/wacom_wac.c | 8 +--
drivers/input/tablet/wacom_wac.h | 4 --
drivers/input/touchscreen/wacom_w8001.c | 13 +----
include/linux/input-mt.h | 11 ++++
include/linux/input.h | 1 +
7 files changed, 90 insertions(+), 54 deletions(-)
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c
index e3711c5..a9fc2c1 100644
--- a/drivers/hid/hid-3m-pct.c
+++ b/drivers/hid/hid-3m-pct.c
@@ -28,7 +28,6 @@ MODULE_LICENSE("GPL");
#include "hid-ids.h"
#define MAX_SLOTS 60
-#define MAX_TRKID USHRT_MAX
/* estimated signal-to-noise ratios */
#define SN_MOVE 2048
@@ -36,14 +35,11 @@ MODULE_LICENSE("GPL");
struct mmm_finger {
__s32 x, y, w, h;
- __u16 id;
- bool prev_touch;
bool touch, valid;
};
struct mmm_data {
struct mmm_finger f[MAX_SLOTS];
- __u16 id;
__u8 curid;
__u8 nexp, nreal;
bool touch, valid;
@@ -117,11 +113,6 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
0, 1, 0, 0);
return 1;
case HID_DG_CONTACTID:
- field->logical_maximum = MAX_TRKID;
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_TRACKING_ID);
- input_set_abs_params(hi->input, ABS_MT_TRACKING_ID,
- 0, MAX_TRKID, 0, 0);
input_mt_init_slots(hi->input, MAX_SLOTS);
return 1;
}
@@ -152,7 +143,6 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi,
*/
static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
{
- struct mmm_finger *oldest = 0;
int i;
for (i = 0; i < MAX_SLOTS; ++i) {
struct mmm_finger *f = &md->f[i];
@@ -161,6 +151,7 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
continue;
}
input_mt_slot(input, i);
+ input_mt_report_slot_state(input, f->touch);
if (f->touch) {
/* this finger is on the screen */
int wide = (f->w > f->h);
@@ -168,33 +159,16 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
int major = max(f->w, f->h) >> 1;
int minor = min(f->w, f->h) >> 1;
- if (!f->prev_touch)
- f->id = md->id++;
- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id);
input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
- /* touchscreen emulation: pick the oldest contact */
- if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1)))
- oldest = f;
- } else {
- /* this finger took off the screen */
- input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1);
}
- f->prev_touch = f->touch;
f->valid = 0;
}
- /* touchscreen emulation */
- if (oldest) {
- input_event(input, EV_KEY, BTN_TOUCH, 1);
- input_event(input, EV_ABS, ABS_X, oldest->x);
- input_event(input, EV_ABS, ABS_Y, oldest->y);
- } else {
- input_event(input, EV_KEY, BTN_TOUCH, 0);
- }
+ input_mt_report_pointer_emulation(input);
input_sync(input);
}
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index c4a9784..08aa682 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -11,17 +11,18 @@
#include <linux/input-mt.h>
#include <linux/slab.h>
+#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
+
/**
* input_mt_init_slots() - initialize MT input slots
* @dev: input device supporting MT events and finger tracking
* @num_slots: number of slots used by the device
*
* This function allocates all necessary memory for MT slot handling
- * in the input device, adds ABS_MT_SLOT to the device capabilities
- * and sets up appropriate event buffers. All slots are initially
- * marked as unused by setting ABS_MT_TRACKING_ID to -1. May be called
- * repeatedly. Returns -EINVAL if attempting to reinitialize with a
- * different number of slots.
+ * in the input device, prepares the ABS_MT_SLOT and
+ * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
+ * May be called repeatedly. Returns -EINVAL if attempting to
+ * reinitialize with a different number of slots.
*/
int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
{
@@ -38,6 +39,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
dev->mtsize = num_slots;
input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
+ input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
input_set_events_per_packet(dev, 6 * num_slots);
/* Mark slots as 'unused' */
@@ -61,5 +63,70 @@ void input_mt_destroy_slots(struct input_dev *dev)
dev->mt = NULL;
dev->mtsize = 0;
dev->slot = 0;
+ dev->trkid = 0;
}
EXPORT_SYMBOL(input_mt_destroy_slots);
+
+/**
+ * input_mt_report_state() - report contact state
+ * @dev: input device with allocated MT slots
+ * @active: true if contact is active, false otherwise
+ *
+ * Reports an active touch via ABS_MT_TRACKING_ID. If active is
+ * true and the slot is currently inactive, a new tracking id is
+ * assigned to the slot.
+ */
+void input_mt_report_slot_state(struct input_dev *dev, bool active)
+{
+ struct input_mt_slot *mt = dev->mt;
+ int id;
+
+ if (!mt || !active) {
+ input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
+ return;
+ }
+
+ id = input_mt_get_value(&mt[dev->slot], ABS_MT_TRACKING_ID);
+ if (id < 0)
+ id = input_mt_new_trkid(dev);
+ input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
+}
+EXPORT_SYMBOL(input_mt_report_slot_state);
+
+/**
+ * input_mt_report_pointer_emulation() - common pointer emulation
+ * @dev: input device with allocated MT slots
+ *
+ * Performs legacy pointer emulation via BTN_TOUCH, ABS_X and ABS_Y.
+ */
+void input_mt_report_pointer_emulation(struct input_dev *dev)
+{
+ struct input_mt_slot *oldest = 0;
+ int oldid = dev->trkid;
+ int count = 0;
+ int i;
+
+ for (i = 0; i < dev->mtsize; ++i) {
+ struct input_mt_slot *ps = &dev->mt[i];
+ int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
+
+ if (id < 0)
+ continue;
+ if ((id - oldid) & TRKID_SGN) {
+ oldest = ps;
+ oldid = id;
+ }
+ count++;
+ }
+
+ input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
+
+ if (oldest) {
+ int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
+ int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
+
+ input_event(dev, EV_ABS, ABS_X, x);
+ input_event(dev, EV_ABS, ABS_Y, y);
+ }
+}
+EXPORT_SYMBOL(input_mt_report_pointer_emulation);
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 3f9e280..e160f48 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -885,14 +885,12 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
input_report_abs(input, ABS_MT_PRESSURE, p);
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
- if (wacom->id[i] < 0)
- wacom->id[i] = wacom->trk_id++ & MAX_TRACKING_ID;
+ input_mt_report_slot_state(input, true);
if (!count++)
sp = p, sx = x, sy = y;
} else {
- wacom->id[i] = -1;
+ input_mt_report_slot_state(input, false);
}
- input_report_abs(input, ABS_MT_TRACKING_ID, wacom->id[i]);
}
input_report_key(input, BTN_TOUCH, count > 0);
@@ -1283,8 +1281,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, features->pressure_max,
features->pressure_fuzz, 0);
- input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
- MAX_TRACKING_ID, 0, 0);
} else if (features->device_type == BTN_TOOL_PEN) {
__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 00ca015..b1310ec 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -42,9 +42,6 @@
#define WACOM_QUIRK_MULTI_INPUT 0x0001
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
-/* largest reported tracking id */
-#define MAX_TRACKING_ID 0xfff
-
enum {
PENPARTNER = 0,
GRAPHIRE,
@@ -100,7 +97,6 @@ struct wacom_wac {
int id[3];
__u32 serial[2];
int last_finger;
- int trk_id;
struct wacom_features features;
struct wacom_shared *shared;
struct input_dev *input;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index b706cd5..03bbc4a 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -48,8 +48,6 @@ MODULE_LICENSE("GPL");
#define W8001_PKTLEN_TPCCTL 11 /* control packet */
#define W8001_PKTLEN_TOUCH2FG 13
-#define MAX_TRACKING_ID 0xFF /* arbitrarily chosen */
-
struct w8001_coord {
u8 rdy;
u8 tsw;
@@ -87,7 +85,6 @@ struct w8001 {
char phys[32];
int type;
unsigned int pktlen;
- int trkid[2];
};
static void parse_data(u8 *data, struct w8001_coord *coord)
@@ -116,7 +113,6 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
static void parse_touch(struct w8001 *w8001)
{
- static int trkid;
struct input_dev *dev = w8001->dev;
unsigned char *data = w8001->data;
int i;
@@ -132,12 +128,10 @@ static void parse_touch(struct w8001 *w8001)
input_report_abs(dev, ABS_MT_POSITION_X, x);
input_report_abs(dev, ABS_MT_POSITION_Y, y);
input_report_abs(dev, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
- if (w8001->trkid[i] < 0)
- w8001->trkid[i] = trkid++ & MAX_TRACKING_ID;
+ input_report_slot_state(dev, true);
} else {
- w8001->trkid[i] = -1;
+ input_report_slot_state(dev, false);
}
- input_report_abs(dev, ABS_MT_TRACKING_ID, w8001->trkid[i]);
}
input_sync(dev);
@@ -319,8 +313,6 @@ static int w8001_setup(struct w8001 *w8001)
w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
input_mt_init_slots(dev, 2);
- input_set_abs_params(dev, ABS_MT_TRACKING_ID,
- 0, MAX_TRACKING_ID, 0, 0);
input_set_abs_params(dev, ABS_MT_POSITION_X,
0, touch.x, 0, 0);
input_set_abs_params(dev, ABS_MT_POSITION_Y,
@@ -372,7 +364,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
w8001->serio = serio;
w8001->id = serio->id.id;
w8001->dev = input_dev;
- w8001->trkid[0] = w8001->trkid[1] = -1;
init_completion(&w8001->cmd_done);
snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
diff --git a/include/linux/input-mt.h b/include/linux/input-mt.h
index d7f6518..1a44567 100644
--- a/include/linux/input-mt.h
+++ b/include/linux/input-mt.h
@@ -13,6 +13,8 @@
#include <linux/input.h>
+#define TRKID_MAX 0xffff
+
/**
* struct input_mt_slot - represents the state of an input MT slot
* @abs: holds current values of ABS_MT axes for this slot
@@ -36,9 +38,18 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot,
int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
void input_mt_destroy_slots(struct input_dev *dev);
+static inline int input_mt_new_trkid(struct input_dev *dev)
+{
+ return dev->trkid++ & TRKID_MAX;
+}
+
static inline void input_mt_slot(struct input_dev *dev, int slot)
{
input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
}
+void input_mt_report_slot_state(struct input_dev *dev, bool active);
+
+void input_mt_report_pointer_emulation(struct input_dev *dev);
+
#endif
diff --git a/include/linux/input.h b/include/linux/input.h
index dd7c0fc..3b856d6 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1206,6 +1206,7 @@ struct input_dev {
struct input_mt_slot *mt;
int mtsize;
int slot;
+ int trkid;
struct input_absinfo *absinfo;
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread