0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/input/mt.h>
0009 #include <linux/export.h>
0010 #include <linux/slab.h>
0011 #include "input-core-private.h"
0012
0013 #define TRKID_SGN ((TRKID_MAX + 1) >> 1)
0014
0015 static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
0016 {
0017 if (dev->absinfo && test_bit(src, dev->absbit)) {
0018 dev->absinfo[dst] = dev->absinfo[src];
0019 dev->absinfo[dst].fuzz = 0;
0020 __set_bit(dst, dev->absbit);
0021 }
0022 }
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
0040 unsigned int flags)
0041 {
0042 struct input_mt *mt = dev->mt;
0043 int i;
0044
0045 if (!num_slots)
0046 return 0;
0047 if (mt)
0048 return mt->num_slots != num_slots ? -EINVAL : 0;
0049
0050 mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL);
0051 if (!mt)
0052 goto err_mem;
0053
0054 mt->num_slots = num_slots;
0055 mt->flags = flags;
0056 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
0057 input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, TRKID_MAX, 0, 0);
0058
0059 if (flags & (INPUT_MT_POINTER | INPUT_MT_DIRECT)) {
0060 __set_bit(EV_KEY, dev->evbit);
0061 __set_bit(BTN_TOUCH, dev->keybit);
0062
0063 copy_abs(dev, ABS_X, ABS_MT_POSITION_X);
0064 copy_abs(dev, ABS_Y, ABS_MT_POSITION_Y);
0065 copy_abs(dev, ABS_PRESSURE, ABS_MT_PRESSURE);
0066 }
0067 if (flags & INPUT_MT_POINTER) {
0068 __set_bit(BTN_TOOL_FINGER, dev->keybit);
0069 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
0070 if (num_slots >= 3)
0071 __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
0072 if (num_slots >= 4)
0073 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
0074 if (num_slots >= 5)
0075 __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
0076 __set_bit(INPUT_PROP_POINTER, dev->propbit);
0077 }
0078 if (flags & INPUT_MT_DIRECT)
0079 __set_bit(INPUT_PROP_DIRECT, dev->propbit);
0080 if (flags & INPUT_MT_SEMI_MT)
0081 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
0082 if (flags & INPUT_MT_TRACK) {
0083 unsigned int n2 = num_slots * num_slots;
0084 mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL);
0085 if (!mt->red)
0086 goto err_mem;
0087 }
0088
0089
0090 for (i = 0; i < num_slots; i++)
0091 input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1);
0092
0093
0094 mt->frame = 1;
0095
0096 dev->mt = mt;
0097 return 0;
0098 err_mem:
0099 kfree(mt);
0100 return -ENOMEM;
0101 }
0102 EXPORT_SYMBOL(input_mt_init_slots);
0103
0104
0105
0106
0107
0108
0109
0110
0111 void input_mt_destroy_slots(struct input_dev *dev)
0112 {
0113 if (dev->mt) {
0114 kfree(dev->mt->red);
0115 kfree(dev->mt);
0116 }
0117 dev->mt = NULL;
0118 }
0119 EXPORT_SYMBOL(input_mt_destroy_slots);
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 bool input_mt_report_slot_state(struct input_dev *dev,
0136 unsigned int tool_type, bool active)
0137 {
0138 struct input_mt *mt = dev->mt;
0139 struct input_mt_slot *slot;
0140 int id;
0141
0142 if (!mt)
0143 return false;
0144
0145 slot = &mt->slots[mt->slot];
0146 slot->frame = mt->frame;
0147
0148 if (!active) {
0149 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
0150 return false;
0151 }
0152
0153 id = input_mt_get_value(slot, ABS_MT_TRACKING_ID);
0154 if (id < 0)
0155 id = input_mt_new_trkid(mt);
0156
0157 input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
0158 input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
0159
0160 return true;
0161 }
0162 EXPORT_SYMBOL(input_mt_report_slot_state);
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 void input_mt_report_finger_count(struct input_dev *dev, int count)
0176 {
0177 input_event(dev, EV_KEY, BTN_TOOL_FINGER, count == 1);
0178 input_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, count == 2);
0179 input_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, count == 3);
0180 input_event(dev, EV_KEY, BTN_TOOL_QUADTAP, count == 4);
0181 input_event(dev, EV_KEY, BTN_TOOL_QUINTTAP, count == 5);
0182 }
0183 EXPORT_SYMBOL(input_mt_report_finger_count);
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
0197 {
0198 struct input_mt *mt = dev->mt;
0199 struct input_mt_slot *oldest;
0200 int oldid, count, i;
0201
0202 if (!mt)
0203 return;
0204
0205 oldest = NULL;
0206 oldid = mt->trkid;
0207 count = 0;
0208
0209 for (i = 0; i < mt->num_slots; ++i) {
0210 struct input_mt_slot *ps = &mt->slots[i];
0211 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
0212
0213 if (id < 0)
0214 continue;
0215 if ((id - oldid) & TRKID_SGN) {
0216 oldest = ps;
0217 oldid = id;
0218 }
0219 count++;
0220 }
0221
0222 input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
0223
0224 if (use_count) {
0225 if (count == 0 &&
0226 !test_bit(ABS_MT_DISTANCE, dev->absbit) &&
0227 test_bit(ABS_DISTANCE, dev->absbit) &&
0228 input_abs_get_val(dev, ABS_DISTANCE) != 0) {
0229
0230
0231
0232
0233
0234
0235 count = 1;
0236 }
0237
0238 input_mt_report_finger_count(dev, count);
0239 }
0240
0241 if (oldest) {
0242 int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
0243 int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
0244
0245 input_event(dev, EV_ABS, ABS_X, x);
0246 input_event(dev, EV_ABS, ABS_Y, y);
0247
0248 if (test_bit(ABS_MT_PRESSURE, dev->absbit)) {
0249 int p = input_mt_get_value(oldest, ABS_MT_PRESSURE);
0250 input_event(dev, EV_ABS, ABS_PRESSURE, p);
0251 }
0252 } else {
0253 if (test_bit(ABS_MT_PRESSURE, dev->absbit))
0254 input_event(dev, EV_ABS, ABS_PRESSURE, 0);
0255 }
0256 }
0257 EXPORT_SYMBOL(input_mt_report_pointer_emulation);
0258
0259 static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt)
0260 {
0261 int i;
0262
0263 lockdep_assert_held(&dev->event_lock);
0264
0265 for (i = 0; i < mt->num_slots; i++) {
0266 if (input_mt_is_active(&mt->slots[i]) &&
0267 !input_mt_is_used(mt, &mt->slots[i])) {
0268 input_handle_event(dev, EV_ABS, ABS_MT_SLOT, i);
0269 input_handle_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
0270 }
0271 }
0272 }
0273
0274
0275
0276
0277
0278
0279
0280 void input_mt_drop_unused(struct input_dev *dev)
0281 {
0282 struct input_mt *mt = dev->mt;
0283
0284 if (mt) {
0285 unsigned long flags;
0286
0287 spin_lock_irqsave(&dev->event_lock, flags);
0288
0289 __input_mt_drop_unused(dev, mt);
0290 mt->frame++;
0291
0292 spin_unlock_irqrestore(&dev->event_lock, flags);
0293 }
0294 }
0295 EXPORT_SYMBOL(input_mt_drop_unused);
0296
0297
0298
0299
0300
0301
0302
0303 void input_mt_release_slots(struct input_dev *dev)
0304 {
0305 struct input_mt *mt = dev->mt;
0306
0307 lockdep_assert_held(&dev->event_lock);
0308
0309 if (mt) {
0310
0311 mt->frame++;
0312
0313 __input_mt_drop_unused(dev, mt);
0314
0315 if (test_bit(ABS_PRESSURE, dev->absbit))
0316 input_handle_event(dev, EV_ABS, ABS_PRESSURE, 0);
0317
0318 mt->frame++;
0319 }
0320 }
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330 void input_mt_sync_frame(struct input_dev *dev)
0331 {
0332 struct input_mt *mt = dev->mt;
0333 bool use_count = false;
0334
0335 if (!mt)
0336 return;
0337
0338 if (mt->flags & INPUT_MT_DROP_UNUSED) {
0339 unsigned long flags;
0340
0341 spin_lock_irqsave(&dev->event_lock, flags);
0342 __input_mt_drop_unused(dev, mt);
0343 spin_unlock_irqrestore(&dev->event_lock, flags);
0344 }
0345
0346 if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
0347 use_count = true;
0348
0349 input_mt_report_pointer_emulation(dev, use_count);
0350
0351 mt->frame++;
0352 }
0353 EXPORT_SYMBOL(input_mt_sync_frame);
0354
0355 static int adjust_dual(int *begin, int step, int *end, int eq, int mu)
0356 {
0357 int f, *p, s, c;
0358
0359 if (begin == end)
0360 return 0;
0361
0362 f = *begin;
0363 p = begin + step;
0364 s = p == end ? f + 1 : *p;
0365
0366 for (; p != end; p += step) {
0367 if (*p < f) {
0368 s = f;
0369 f = *p;
0370 } else if (*p < s) {
0371 s = *p;
0372 }
0373 }
0374
0375 c = (f + s + 1) / 2;
0376 if (c == 0 || (c > mu && (!eq || mu > 0)))
0377 return 0;
0378
0379 if (s < 0 && mu <= 0)
0380 c *= 2;
0381
0382 for (p = begin; p != end; p += step)
0383 *p -= c;
0384
0385 return (c < s && s <= 0) || (f >= 0 && f < c);
0386 }
0387
0388 static void find_reduced_matrix(int *w, int nr, int nc, int nrc, int mu)
0389 {
0390 int i, k, sum;
0391
0392 for (k = 0; k < nrc; k++) {
0393 for (i = 0; i < nr; i++)
0394 adjust_dual(w + i, nr, w + i + nrc, nr <= nc, mu);
0395 sum = 0;
0396 for (i = 0; i < nrc; i += nr)
0397 sum += adjust_dual(w + i, 1, w + i + nr, nc <= nr, mu);
0398 if (!sum)
0399 break;
0400 }
0401 }
0402
0403 static int input_mt_set_matrix(struct input_mt *mt,
0404 const struct input_mt_pos *pos, int num_pos,
0405 int mu)
0406 {
0407 const struct input_mt_pos *p;
0408 struct input_mt_slot *s;
0409 int *w = mt->red;
0410 int x, y;
0411
0412 for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
0413 if (!input_mt_is_active(s))
0414 continue;
0415 x = input_mt_get_value(s, ABS_MT_POSITION_X);
0416 y = input_mt_get_value(s, ABS_MT_POSITION_Y);
0417 for (p = pos; p != pos + num_pos; p++) {
0418 int dx = x - p->x, dy = y - p->y;
0419 *w++ = dx * dx + dy * dy - mu;
0420 }
0421 }
0422
0423 return w - mt->red;
0424 }
0425
0426 static void input_mt_set_slots(struct input_mt *mt,
0427 int *slots, int num_pos)
0428 {
0429 struct input_mt_slot *s;
0430 int *w = mt->red, j;
0431
0432 for (j = 0; j != num_pos; j++)
0433 slots[j] = -1;
0434
0435 for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
0436 if (!input_mt_is_active(s))
0437 continue;
0438
0439 for (j = 0; j != num_pos; j++) {
0440 if (w[j] < 0) {
0441 slots[j] = s - mt->slots;
0442 break;
0443 }
0444 }
0445
0446 w += num_pos;
0447 }
0448
0449 for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
0450 if (input_mt_is_active(s))
0451 continue;
0452
0453 for (j = 0; j != num_pos; j++) {
0454 if (slots[j] < 0) {
0455 slots[j] = s - mt->slots;
0456 break;
0457 }
0458 }
0459 }
0460 }
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480 int input_mt_assign_slots(struct input_dev *dev, int *slots,
0481 const struct input_mt_pos *pos, int num_pos,
0482 int dmax)
0483 {
0484 struct input_mt *mt = dev->mt;
0485 int mu = 2 * dmax * dmax;
0486 int nrc;
0487
0488 if (!mt || !mt->red)
0489 return -ENXIO;
0490 if (num_pos > mt->num_slots)
0491 return -EINVAL;
0492 if (num_pos < 1)
0493 return 0;
0494
0495 nrc = input_mt_set_matrix(mt, pos, num_pos, mu);
0496 find_reduced_matrix(mt->red, num_pos, nrc / num_pos, nrc, mu);
0497 input_mt_set_slots(mt, slots, num_pos);
0498
0499 return 0;
0500 }
0501 EXPORT_SYMBOL(input_mt_assign_slots);
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515 int input_mt_get_slot_by_key(struct input_dev *dev, int key)
0516 {
0517 struct input_mt *mt = dev->mt;
0518 struct input_mt_slot *s;
0519
0520 if (!mt)
0521 return -1;
0522
0523 for (s = mt->slots; s != mt->slots + mt->num_slots; s++)
0524 if (input_mt_is_active(s) && s->key == key)
0525 return s - mt->slots;
0526
0527 for (s = mt->slots; s != mt->slots + mt->num_slots; s++)
0528 if (!input_mt_is_active(s) && !input_mt_is_used(mt, s)) {
0529 s->key = key;
0530 return s - mt->slots;
0531 }
0532
0533 return -1;
0534 }
0535 EXPORT_SYMBOL(input_mt_get_slot_by_key);