aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/input-mt.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-12-15 07:50:34 -0500
committerHenrik Rydberg <rydberg@euromail.se>2010-12-16 04:41:38 -0500
commitc5f4dec1ceb6ab773bbbefbe64a7c990c7d6b17f (patch)
treefdc8b67537b73474bd34b65d0d1c5bc7a9de3c7a /drivers/input/input-mt.c
parent8cde81001626c4c60b26ef2eb5fc522885ed9fd0 (diff)
input: mt: Move tracking and pointer emulation to input-mt
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. Acked-by: Ping Cheng <pingc@wacom.com> Acked-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'drivers/input/input-mt.c')
-rw-r--r--drivers/input/input-mt.c115
1 files changed, 110 insertions, 5 deletions
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index f400e47092c..c48c81f0308 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -11,17 +11,18 @@
11#include <linux/input/mt.h> 11#include <linux/input/mt.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13 13
14#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
15
14/** 16/**
15 * input_mt_init_slots() - initialize MT input slots 17 * input_mt_init_slots() - initialize MT input slots
16 * @dev: input device supporting MT events and finger tracking 18 * @dev: input device supporting MT events and finger tracking
17 * @num_slots: number of slots used by the device 19 * @num_slots: number of slots used by the device
18 * 20 *
19 * This function allocates all necessary memory for MT slot handling 21 * This function allocates all necessary memory for MT slot handling
20 * in the input device, adds ABS_MT_SLOT to the device capabilities 22 * in the input device, prepares the ABS_MT_SLOT and
21 * and sets up appropriate event buffers. All slots are initially 23 * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
22 * marked as unused by setting ABS_MT_TRACKING_ID to -1. May be called 24 * May be called repeatedly. Returns -EINVAL if attempting to
23 * repeatedly. Returns -EINVAL if attempting to reinitialize with a 25 * reinitialize with a different number of slots.
24 * different number of slots.
25 */ 26 */
26int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) 27int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
27{ 28{
@@ -38,6 +39,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
38 39
39 dev->mtsize = num_slots; 40 dev->mtsize = num_slots;
40 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); 41 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
42 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
41 input_set_events_per_packet(dev, 6 * num_slots); 43 input_set_events_per_packet(dev, 6 * num_slots);
42 44
43 /* Mark slots as 'unused' */ 45 /* Mark slots as 'unused' */
@@ -61,5 +63,108 @@ void input_mt_destroy_slots(struct input_dev *dev)
61 dev->mt = NULL; 63 dev->mt = NULL;
62 dev->mtsize = 0; 64 dev->mtsize = 0;
63 dev->slot = 0; 65 dev->slot = 0;
66 dev->trkid = 0;
64} 67}
65EXPORT_SYMBOL(input_mt_destroy_slots); 68EXPORT_SYMBOL(input_mt_destroy_slots);
69
70/**
71 * input_mt_report_slot_state() - report contact state
72 * @dev: input device with allocated MT slots
73 * @tool_type: the tool type to use in this slot
74 * @active: true if contact is active, false otherwise
75 *
76 * Reports a contact via ABS_MT_TRACKING_ID, and optionally
77 * ABS_MT_TOOL_TYPE. If active is true and the slot is currently
78 * inactive, or if the tool type is changed, a new tracking id is
79 * assigned to the slot. The tool type is only reported if the
80 * corresponding absbit field is set.
81 */
82void input_mt_report_slot_state(struct input_dev *dev,
83 unsigned int tool_type, bool active)
84{
85 struct input_mt_slot *mt;
86 int id;
87
88 if (!dev->mt || !active) {
89 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
90 return;
91 }
92
93 mt = &dev->mt[dev->slot];
94 id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
95 if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
96 id = input_mt_new_trkid(dev);
97
98 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
99 input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
100}
101EXPORT_SYMBOL(input_mt_report_slot_state);
102
103/**
104 * input_mt_report_finger_count() - report contact count
105 * @dev: input device with allocated MT slots
106 * @count: the number of contacts
107 *
108 * Reports the contact count via BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP,
109 * BTN_TOOL_TRIPLETAP and BTN_TOOL_QUADTAP.
110 *
111 * The input core ensures only the KEY events already setup for
112 * this device will produce output.
113 */
114void input_mt_report_finger_count(struct input_dev *dev, int count)
115{
116 input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);
117 input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
118 input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
119 input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
120}
121EXPORT_SYMBOL(input_mt_report_finger_count);
122
123/**
124 * input_mt_report_pointer_emulation() - common pointer emulation
125 * @dev: input device with allocated MT slots
126 * @use_count: report number of active contacts as finger count
127 *
128 * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
129 * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
130 *
131 * The input core ensures only the KEY and ABS axes already setup for
132 * this device will produce output.
133 */
134void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
135{
136 struct input_mt_slot *oldest = 0;
137 int oldid = dev->trkid;
138 int count = 0;
139 int i;
140
141 for (i = 0; i < dev->mtsize; ++i) {
142 struct input_mt_slot *ps = &dev->mt[i];
143 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
144
145 if (id < 0)
146 continue;
147 if ((id - oldid) & TRKID_SGN) {
148 oldest = ps;
149 oldid = id;
150 }
151 count++;
152 }
153
154 input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
155 if (use_count)
156 input_mt_report_finger_count(dev, count);
157
158 if (oldest) {
159 int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
160 int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
161 int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);
162
163 input_event(dev, EV_ABS, ABS_X, x);
164 input_event(dev, EV_ABS, ABS_Y, y);
165 input_event(dev, EV_ABS, ABS_PRESSURE, p);
166 } else {
167 input_event(dev, EV_ABS, ABS_PRESSURE, 0);
168 }
169}
170EXPORT_SYMBOL(input_mt_report_pointer_emulation);