Skip to content

Commit 8d18fba

Browse files
committed
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>
1 parent 4cbe5a5 commit 8d18fba

5 files changed

Lines changed: 61 additions & 46 deletions

File tree

drivers/input/evdev.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,20 +653,22 @@ static int evdev_handle_mt_request(struct input_dev *dev,
653653
unsigned int size,
654654
int __user *ip)
655655
{
656-
const struct input_mt_slot *mt = dev->mt;
656+
const struct input_mt *mt = dev->mt;
657657
unsigned int code;
658658
int max_slots;
659659
int i;
660660

661661
if (get_user(code, &ip[0]))
662662
return -EFAULT;
663-
if (!input_is_mt_value(code))
663+
if (!mt || !input_is_mt_value(code))
664664
return -EINVAL;
665665

666666
max_slots = (size - sizeof(__u32)) / sizeof(__s32);
667-
for (i = 0; i < dev->mtsize && i < max_slots; i++)
668-
if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i]))
667+
for (i = 0; i < mt->num_slots && i < max_slots; i++) {
668+
int value = input_mt_get_value(&mt->slots[i], code);
669+
if (put_user(value, &ip[1 + i]))
669670
return -EFAULT;
671+
}
670672

671673
return 0;
672674
}

drivers/input/input-mt.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,28 @@
2727
*/
2828
int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots)
2929
{
30+
struct input_mt *mt = dev->mt;
3031
int i;
3132

3233
if (!num_slots)
3334
return 0;
34-
if (dev->mt)
35-
return dev->mtsize != num_slots ? -EINVAL : 0;
35+
if (mt)
36+
return mt->num_slots != num_slots ? -EINVAL : 0;
3637

37-
dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
38-
if (!dev->mt)
38+
mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL);
39+
if (!mt)
3940
return -ENOMEM;
4041

41-
dev->mtsize = num_slots;
42+
mt->num_slots = num_slots;
4243
input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
4344
input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
4445
input_set_events_per_packet(dev, 6 * num_slots);
4546

4647
/* Mark slots as 'unused' */
4748
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);
4950

51+
dev->mt = mt;
5052
return 0;
5153
}
5254
EXPORT_SYMBOL(input_mt_init_slots);
@@ -62,9 +64,6 @@ void input_mt_destroy_slots(struct input_dev *dev)
6264
{
6365
kfree(dev->mt);
6466
dev->mt = NULL;
65-
dev->mtsize = 0;
66-
dev->slot = 0;
67-
dev->trkid = 0;
6867
}
6968
EXPORT_SYMBOL(input_mt_destroy_slots);
7069

@@ -83,18 +82,19 @@ EXPORT_SYMBOL(input_mt_destroy_slots);
8382
void input_mt_report_slot_state(struct input_dev *dev,
8483
unsigned int tool_type, bool active)
8584
{
86-
struct input_mt_slot *mt;
85+
struct input_mt *mt = dev->mt;
86+
struct input_mt_slot *slot;
8787
int id;
8888

89-
if (!dev->mt || !active) {
89+
if (!mt || !active) {
9090
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
9191
return;
9292
}
9393

94-
mt = &dev->mt[dev->slot];
95-
id = input_mt_get_value(mt, ABS_MT_TRACKING_ID);
96-
if (id < 0 || input_mt_get_value(mt, ABS_MT_TOOL_TYPE) != tool_type)
97-
id = input_mt_new_trkid(dev);
94+
slot = &mt->slots[mt->slot];
95+
id = input_mt_get_value(slot, ABS_MT_TRACKING_ID);
96+
if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type)
97+
id = input_mt_new_trkid(mt);
9898

9999
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
100100
input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
@@ -135,13 +135,19 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
135135
*/
136136
void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
137137
{
138-
struct input_mt_slot *oldest = NULL;
139-
int oldid = dev->trkid;
140-
int count = 0;
141-
int i;
138+
struct input_mt *mt = dev->mt;
139+
struct input_mt_slot *oldest;
140+
int oldid, count, i;
141+
142+
if (!mt)
143+
return;
144+
145+
oldest = 0;
146+
oldid = mt->trkid;
147+
count = 0;
142148

143-
for (i = 0; i < dev->mtsize; ++i) {
144-
struct input_mt_slot *ps = &dev->mt[i];
149+
for (i = 0; i < mt->num_slots; ++i) {
150+
struct input_mt_slot *ps = &mt->slots[i];
145151
int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
146152

147153
if (id < 0)

drivers/input/input.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ static void input_stop_autorepeat(struct input_dev *dev)
166166
static int input_handle_abs_event(struct input_dev *dev,
167167
unsigned int code, int *pval)
168168
{
169+
struct input_mt *mt = dev->mt;
169170
bool is_mt_event;
170171
int *pold;
171172

@@ -174,8 +175,8 @@ static int input_handle_abs_event(struct input_dev *dev,
174175
* "Stage" the event; we'll flush it later, when we
175176
* get actual touch data.
176177
*/
177-
if (*pval >= 0 && *pval < dev->mtsize)
178-
dev->slot = *pval;
178+
if (mt && *pval >= 0 && *pval < mt->num_slots)
179+
mt->slot = *pval;
179180

180181
return INPUT_IGNORE_EVENT;
181182
}
@@ -184,9 +185,8 @@ static int input_handle_abs_event(struct input_dev *dev,
184185

185186
if (!is_mt_event) {
186187
pold = &dev->absinfo[code].value;
187-
} else if (dev->mt) {
188-
struct input_mt_slot *mtslot = &dev->mt[dev->slot];
189-
pold = &mtslot->abs[code - ABS_MT_FIRST];
188+
} else if (mt) {
189+
pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST];
190190
} else {
191191
/*
192192
* Bypass filtering for multi-touch events when
@@ -205,9 +205,9 @@ static int input_handle_abs_event(struct input_dev *dev,
205205
}
206206

207207
/* Flush pending "slot" event */
208-
if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
209-
input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
210-
input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->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, mt->slot);
210+
input_pass_event(dev, EV_ABS, ABS_MT_SLOT, mt->slot);
211211
}
212212

213213
return INPUT_PASS_TO_HANDLERS;
@@ -1751,8 +1751,8 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
17511751
int i;
17521752
unsigned int events;
17531753

1754-
if (dev->mtsize) {
1755-
mt_slots = dev->mtsize;
1754+
if (dev->mt) {
1755+
mt_slots = dev->mt->num_slots;
17561756
} else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
17571757
mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
17581758
dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,

include/linux/input.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,11 +1203,7 @@ struct ff_effect {
12031203
* software autorepeat
12041204
* @timer: timer for software autorepeat
12051205
* @rep: current values for autorepeat parameters (delay, rate)
1206-
* @mt: pointer to array of struct input_mt_slot holding current values
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
1206+
* @mt: pointer to multitouch state
12111207
* @absinfo: array of &struct input_absinfo elements holding information
12121208
* about absolute axes (current value, min, max, flat, fuzz,
12131209
* resolution)
@@ -1287,10 +1283,7 @@ struct input_dev {
12871283

12881284
int rep[REP_CNT];
12891285

1290-
struct input_mt_slot *mt;
1291-
int mtsize;
1292-
int slot;
1293-
int trkid;
1286+
struct input_mt *mt;
12941287

12951288
struct input_absinfo *absinfo;
12961289

include/linux/input/mt.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ struct input_mt_slot {
2323
int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
2424
};
2525

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+
2640
static inline void input_mt_set_value(struct input_mt_slot *slot,
2741
unsigned code, int value)
2842
{
@@ -38,9 +52,9 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot,
3852
int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots);
3953
void input_mt_destroy_slots(struct input_dev *dev);
4054

41-
static inline int input_mt_new_trkid(struct input_dev *dev)
55+
static inline int input_mt_new_trkid(struct input_mt *mt)
4256
{
43-
return dev->trkid++ & TRKID_MAX;
57+
return mt->trkid++ & TRKID_MAX;
4458
}
4559

4660
static inline void input_mt_slot(struct input_dev *dev, int slot)

0 commit comments

Comments
 (0)