diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2012-09-15 09:15:58 -0400 |
---|---|---|
committer | Henrik Rydberg <rydberg@euromail.se> | 2012-09-19 13:50:17 -0400 |
commit | 8d18fba282120a4a8e4416d1202522ffae8cad58 (patch) | |
tree | 22e3ddabba314c9ad544b9fefe004194205c2940 | |
parent | 4cbe5a555fa58a79b6ecbb6c531b8bab0650778d (diff) |
Input: Break out MT data
Move all MT-related things to a separate place. This saves some
bytes for non-mt input devices, and prepares for new MT features.
Reviewed-and-tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
Tested-by: Ping Cheng <pingc@wacom.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r-- | drivers/input/evdev.c | 10 | ||||
-rw-r--r-- | drivers/input/input-mt.c | 48 | ||||
-rw-r--r-- | drivers/input/input.c | 20 | ||||
-rw-r--r-- | include/linux/input.h | 11 | ||||
-rw-r--r-- | include/linux/input/mt.h | 18 |
5 files changed, 61 insertions, 46 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6c58bfff01a3..a0692c551be5 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -653,20 +653,22 @@ static int evdev_handle_mt_request(struct input_dev *dev, | |||
653 | unsigned int size, | 653 | unsigned int size, |
654 | int __user *ip) | 654 | int __user *ip) |
655 | { | 655 | { |
656 | const struct input_mt_slot *mt = dev->mt; | 656 | const struct input_mt *mt = dev->mt; |
657 | unsigned int code; | 657 | unsigned int code; |
658 | int max_slots; | 658 | int max_slots; |
659 | int i; | 659 | int i; |
660 | 660 | ||
661 | if (get_user(code, &ip[0])) | 661 | if (get_user(code, &ip[0])) |
662 | return -EFAULT; | 662 | return -EFAULT; |
663 | if (!input_is_mt_value(code)) | 663 | if (!mt || !input_is_mt_value(code)) |
664 | return -EINVAL; | 664 | return -EINVAL; |
665 | 665 | ||
666 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); | 666 | max_slots = (size - sizeof(__u32)) / sizeof(__s32); |
667 | for (i = 0; i < dev->mtsize && i < max_slots; i++) | 667 | for (i = 0; i < mt->num_slots && i < max_slots; i++) { |
668 | if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i])) | 668 | int value = input_mt_get_value(&mt->slots[i], code); |
669 | if (put_user(value, &ip[1 + i])) | ||
669 | return -EFAULT; | 670 | return -EFAULT; |
671 | } | ||
670 | 672 | ||
671 | return 0; | 673 | return 0; |
672 | } | 674 | } |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 70a16c7da8cc..37ee1f925d23 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
@@ -27,26 +27,28 @@ | |||
27 | */ | 27 | */ |
28 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) | 28 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots) |
29 | { | 29 | { |
30 | struct input_mt *mt = dev->mt; | ||
30 | int i; | 31 | int i; |
31 | 32 | ||
32 | if (!num_slots) | 33 | if (!num_slots) |
33 | return 0; | 34 | return 0; |
34 | if (dev->mt) | 35 | if (mt) |
35 | return dev->mtsize != num_slots ? -EINVAL : 0; | 36 | return mt->num_slots != num_slots ? -EINVAL : 0; |
36 | 37 | ||
37 | dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL); | 38 | mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL); |
38 | if (!dev->mt) | 39 | if (!mt) |
39 | return -ENOMEM; | 40 | return -ENOMEM; |
40 | 41 | ||
41 | dev->mtsize = num_slots; | 42 | mt->num_slots = num_slots; |
42 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | 43 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); |
43 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); | 44 | input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0); |
44 | input_set_events_per_packet(dev, 6 * num_slots); | 45 | input_set_events_per_packet(dev, 6 * num_slots); |
45 | 46 | ||
46 | /* Mark slots as 'unused' */ | 47 | /* Mark slots as 'unused' */ |
47 | for (i = 0; i < num_slots; i++) | 48 | for (i = 0; i < num_slots; i++) |
48 | input_mt_set_value(&dev->mt[i], ABS_MT_TRACKING_ID, -1); | 49 | input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); |
49 | 50 | ||
51 | dev->mt = mt; | ||
50 | return 0; | 52 | return 0; |
51 | } | 53 | } |
52 | EXPORT_SYMBOL(input_mt_init_slots); | 54 | EXPORT_SYMBOL(input_mt_init_slots); |
@@ -62,9 +64,6 @@ void input_mt_destroy_slots(struct input_dev *dev) | |||
62 | { | 64 | { |
63 | kfree(dev->mt); | 65 | kfree(dev->mt); |
64 | dev->mt = NULL; | 66 | dev->mt = NULL; |
65 | dev->mtsize = 0; | ||
66 | dev->slot = 0; | ||
67 | dev->trkid = 0; | ||
68 | } | 67 | } |
69 | EXPORT_SYMBOL(input_mt_destroy_slots); | 68 | EXPORT_SYMBOL(input_mt_destroy_slots); |
70 | 69 | ||
@@ -83,18 +82,19 @@ EXPORT_SYMBOL(input_mt_destroy_slots); | |||
83 | void input_mt_report_slot_state(struct input_dev *dev, | 82 | void input_mt_report_slot_state(struct input_dev *dev, |
84 | unsigned int tool_type, bool active) | 83 | unsigned int tool_type, bool active) |
85 | { | 84 | { |
86 | struct input_mt_slot *mt; | 85 | struct input_mt *mt = dev->mt; |
86 | struct input_mt_slot *slot; | ||
87 | int id; | 87 | int id; |
88 | 88 | ||
89 | if (!dev->mt || !active) { | 89 | if (!mt || !active) { |
90 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | 90 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); |
91 | return; | 91 | return; |
92 | } | 92 | } |
93 | 93 | ||
94 | mt = &dev->mt[dev->slot]; | 94 | slot = &mt->slots[mt->slot]; |
95 | id = input_mt_get_value(mt, ABS_MT_TRACKING_ID); | 95 | id = input_mt_get_value(slot, ABS_MT_TRACKING_ID); |
96 | if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type) | 96 | if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type) |
97 | id = input_mt_new_trkid(dev); | 97 | id = input_mt_new_trkid(mt); |
98 | 98 | ||
99 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); | 99 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); |
100 | input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); | 100 | input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); |
@@ -135,13 +135,19 @@ EXPORT_SYMBOL(input_mt_report_finger_count); | |||
135 | */ | 135 | */ |
136 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | 136 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) |
137 | { | 137 | { |
138 | struct input_mt_slot *oldest = NULL; | 138 | struct input_mt *mt = dev->mt; |
139 | int oldid = dev->trkid; | 139 | struct input_mt_slot *oldest; |
140 | int count = 0; | 140 | int oldid, count, i; |
141 | int i; | 141 | |
142 | if (!mt) | ||
143 | return; | ||
144 | |||
145 | oldest = 0; | ||
146 | oldid = mt->trkid; | ||
147 | count = 0; | ||
142 | 148 | ||
143 | for (i = 0; i < dev->mtsize; ++i) { | 149 | for (i = 0; i < mt->num_slots; ++i) { |
144 | struct input_mt_slot *ps = &dev->mt[i]; | 150 | struct input_mt_slot *ps = &mt->slots[i]; |
145 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); | 151 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); |
146 | 152 | ||
147 | if (id < 0) | 153 | if (id < 0) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 8921c6180c51..79a4a2ad74de 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -166,6 +166,7 @@ static void input_stop_autorepeat(struct input_dev *dev) | |||
166 | static int input_handle_abs_event(struct input_dev *dev, | 166 | static int input_handle_abs_event(struct input_dev *dev, |
167 | unsigned int code, int *pval) | 167 | unsigned int code, int *pval) |
168 | { | 168 | { |
169 | struct input_mt *mt = dev->mt; | ||
169 | bool is_mt_event; | 170 | bool is_mt_event; |
170 | int *pold; | 171 | int *pold; |
171 | 172 | ||
@@ -174,8 +175,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
174 | * "Stage" the event; we'll flush it later, when we | 175 | * "Stage" the event; we'll flush it later, when we |
175 | * get actual touch data. | 176 | * get actual touch data. |
176 | */ | 177 | */ |
177 | if (*pval >= 0 && *pval < dev->mtsize) | 178 | if (mt && *pval >= 0 && *pval < mt->num_slots) |
178 | dev->slot = *pval; | 179 | mt->slot = *pval; |
179 | 180 | ||
180 | return INPUT_IGNORE_EVENT; | 181 | return INPUT_IGNORE_EVENT; |
181 | } | 182 | } |
@@ -184,9 +185,8 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
184 | 185 | ||
185 | if (!is_mt_event) { | 186 | if (!is_mt_event) { |
186 | pold = &dev->absinfo[code].value; | 187 | pold = &dev->absinfo[code].value; |
187 | } else if (dev->mt) { | 188 | } else if (mt) { |
188 | struct input_mt_slot *mtslot = &dev->mt[dev->slot]; | 189 | pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST]; |
189 | pold = &mtslot->abs[code - ABS_MT_FIRST]; | ||
190 | } else { | 190 | } else { |
191 | /* | 191 | /* |
192 | * Bypass filtering for multi-touch events when | 192 | * Bypass filtering for multi-touch events when |
@@ -205,9 +205,9 @@ static int input_handle_abs_event(struct input_dev *dev, | |||
205 | } | 205 | } |
206 | 206 | ||
207 | /* Flush pending "slot" event */ | 207 | /* Flush pending "slot" event */ |
208 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { | 208 | if (is_mt_event && mt && mt->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { |
209 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); | 209 | input_abs_set_val(dev, ABS_MT_SLOT, mt->slot); |
210 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | 210 | input_pass_event(dev, EV_ABS, ABS_MT_SLOT, mt->slot); |
211 | } | 211 | } |
212 | 212 | ||
213 | return INPUT_PASS_TO_HANDLERS; | 213 | return INPUT_PASS_TO_HANDLERS; |
@@ -1751,8 +1751,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
1751 | int i; | 1751 | int i; |
1752 | unsigned int events; | 1752 | unsigned int events; |
1753 | 1753 | ||
1754 | if (dev->mtsize) { | 1754 | if (dev->mt) { |
1755 | mt_slots = dev->mtsize; | 1755 | mt_slots = dev->mt->num_slots; |
1756 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { | 1756 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { |
1757 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - | 1757 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - |
1758 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, | 1758 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, |
diff --git a/include/linux/input.h b/include/linux/input.h index 725dcd0f63a4..9da4f5796fd6 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -1203,11 +1203,7 @@ struct ff_effect { | |||
1203 | * software autorepeat | 1203 | * software autorepeat |
1204 | * @timer: timer for software autorepeat | 1204 | * @timer: timer for software autorepeat |
1205 | * @rep: current values for autorepeat parameters (delay, rate) | 1205 | * @rep: current values for autorepeat parameters (delay, rate) |
1206 | * @mt: pointer to array of struct input_mt_slot holding current values | 1206 | * @mt: pointer to multitouch state |
1207 | * of tracked contacts | ||
1208 | * @mtsize: number of MT slots the device uses | ||
1209 | * @slot: MT slot currently being transmitted | ||
1210 | * @trkid: stores MT tracking ID for the current contact | ||
1211 | * @absinfo: array of &struct input_absinfo elements holding information | 1207 | * @absinfo: array of &struct input_absinfo elements holding information |
1212 | * about absolute axes (current value, min, max, flat, fuzz, | 1208 | * about absolute axes (current value, min, max, flat, fuzz, |
1213 | * resolution) | 1209 | * resolution) |
@@ -1287,10 +1283,7 @@ struct input_dev { | |||
1287 | 1283 | ||
1288 | int rep[REP_CNT]; | 1284 | int rep[REP_CNT]; |
1289 | 1285 | ||
1290 | struct input_mt_slot *mt; | 1286 | struct input_mt *mt; |
1291 | int mtsize; | ||
1292 | int slot; | ||
1293 | int trkid; | ||
1294 | 1287 | ||
1295 | struct input_absinfo *absinfo; | 1288 | struct input_absinfo *absinfo; |
1296 | 1289 | ||
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index f86737586e19..63458bced77d 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h | |||
@@ -23,6 +23,20 @@ struct input_mt_slot { | |||
23 | int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; | 23 | int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | /** | ||
27 | * struct input_mt - state of tracked contacts | ||
28 | * @trkid: stores MT tracking ID for the next contact | ||
29 | * @num_slots: number of MT slots the device uses | ||
30 | * @slot: MT slot currently being transmitted | ||
31 | * @slots: array of slots holding current values of tracked contacts | ||
32 | */ | ||
33 | struct input_mt { | ||
34 | int trkid; | ||
35 | int num_slots; | ||
36 | int slot; | ||
37 | struct input_mt_slot slots[]; | ||
38 | }; | ||
39 | |||
26 | static inline void input_mt_set_value(struct input_mt_slot *slot, | 40 | static inline void input_mt_set_value(struct input_mt_slot *slot, |
27 | unsigned code, int value) | 41 | unsigned code, int value) |
28 | { | 42 | { |
@@ -38,9 +52,9 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot, | |||
38 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); | 52 | int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); |
39 | void input_mt_destroy_slots(struct input_dev *dev); | 53 | void input_mt_destroy_slots(struct input_dev *dev); |
40 | 54 | ||
41 | static inline int input_mt_new_trkid(struct input_dev *dev) | 55 | static inline int input_mt_new_trkid(struct input_mt *mt) |
42 | { | 56 | { |
43 | return dev->trkid++ & TRKID_MAX; | 57 | return mt->trkid++ & TRKID_MAX; |
44 | } | 58 | } |
45 | 59 | ||
46 | static inline void input_mt_slot(struct input_dev *dev, int slot) | 60 | static inline void input_mt_slot(struct input_dev *dev, int slot) |