evdev: Make MT tracking IDs monotonically increasing sequence.
MFC after: 2 weeks
This commit is contained in:
parent
059360287e
commit
66bd52f5e2
@ -701,15 +701,23 @@ evdev_modify_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
|
||||
break;
|
||||
|
||||
case EV_ABS:
|
||||
fuzz = evdev->ev_absinfo[code].fuzz;
|
||||
if (fuzz == 0 || code == ABS_MT_SLOT)
|
||||
if (code == ABS_MT_SLOT)
|
||||
break;
|
||||
else if (!ABS_IS_MT(code))
|
||||
old_value = evdev->ev_absinfo[code].value;
|
||||
else if (bit_test(evdev->ev_abs_flags, ABS_MT_SLOT))
|
||||
else if (!bit_test(evdev->ev_abs_flags, ABS_MT_SLOT))
|
||||
/* Pass MT protocol type A events as is */
|
||||
break;
|
||||
else if (code == ABS_MT_TRACKING_ID) {
|
||||
*value = evdev_mt_reassign_id(evdev,
|
||||
evdev_mt_get_last_slot(evdev), *value);
|
||||
break;
|
||||
} else
|
||||
old_value = evdev_mt_get_value(evdev,
|
||||
evdev_mt_get_last_slot(evdev), code);
|
||||
else /* Pass MT protocol type A events as is */
|
||||
|
||||
fuzz = evdev->ev_absinfo[code].fuzz;
|
||||
if (fuzz == 0)
|
||||
break;
|
||||
|
||||
abs_change = abs(*value - old_value);
|
||||
|
@ -90,6 +90,7 @@ extern int evdev_sysmouse_t_axis;
|
||||
* current MT protocol type B report */
|
||||
#define EVDEV_FLAG_EXT_EPOCH 0x03 /* evdev_push_* is allways called with
|
||||
* input (global) epoch entered */
|
||||
#define EVDEV_FLAG_MT_KEEPID 0x04 /* Do not reassign tracking ID */
|
||||
#define EVDEV_FLAG_MAX 0x1F
|
||||
#define EVDEV_FLAG_CNT (EVDEV_FLAG_MAX + 1)
|
||||
|
||||
|
@ -62,6 +62,8 @@ struct {
|
||||
|
||||
struct evdev_mt {
|
||||
int last_reported_slot;
|
||||
uint16_t tracking_id;
|
||||
int32_t tracking_ids[MAX_MT_SLOTS];
|
||||
u_int mtst_events;
|
||||
/* the set of slots with active touches */
|
||||
slotset_t touches;
|
||||
@ -93,6 +95,9 @@ evdev_mt_init(struct evdev_dev *evdev)
|
||||
for (slot = 0; slot < slots; slot++)
|
||||
evdev->ev_mt->slots[slot].id = -1;
|
||||
|
||||
if (!bit_test(evdev->ev_flags, EVDEV_FLAG_MT_KEEPID))
|
||||
evdev_support_abs(evdev,
|
||||
ABS_MT_TRACKING_ID, -1, UINT16_MAX, 0, 0, 0);
|
||||
if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
|
||||
evdev_support_mt_compat(evdev);
|
||||
}
|
||||
@ -208,7 +213,7 @@ evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, int32_t tracking_id)
|
||||
int slot;
|
||||
|
||||
FOREACHBIT(mt->touches, slot)
|
||||
if (mt->slots[slot].id == tracking_id)
|
||||
if (mt->tracking_ids[slot] == tracking_id)
|
||||
return (slot);
|
||||
/*
|
||||
* Do not allow allocation of new slot in a place of just
|
||||
@ -217,6 +222,34 @@ evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, int32_t tracking_id)
|
||||
return (ffc_slot(evdev, mt->touches | mt->frame));
|
||||
}
|
||||
|
||||
int32_t
|
||||
evdev_mt_reassign_id(struct evdev_dev *evdev, int slot, int32_t id)
|
||||
{
|
||||
struct evdev_mt *mt = evdev->ev_mt;
|
||||
int32_t nid;
|
||||
|
||||
if (id == -1 || bit_test(evdev->ev_flags, EVDEV_FLAG_MT_KEEPID)) {
|
||||
mt->tracking_ids[slot] = id;
|
||||
return (id);
|
||||
}
|
||||
|
||||
nid = evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID);
|
||||
if (nid != -1) {
|
||||
KASSERT(id == mt->tracking_ids[slot],
|
||||
("MT-slot tracking id has changed"));
|
||||
return (nid);
|
||||
}
|
||||
|
||||
mt->tracking_ids[slot] = id;
|
||||
again:
|
||||
nid = mt->tracking_id++;
|
||||
FOREACHBIT(mt->touches, slot)
|
||||
if (evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID) == nid)
|
||||
goto again;
|
||||
|
||||
return (nid);
|
||||
}
|
||||
|
||||
static inline int32_t
|
||||
evdev_mt_normalize(int32_t value, int32_t mtmin, int32_t mtmax, int32_t stmax)
|
||||
{
|
||||
|
@ -284,6 +284,7 @@ int evdev_mt_get_last_slot(struct evdev_dev *);
|
||||
void evdev_mt_set_last_slot(struct evdev_dev *, int);
|
||||
int32_t evdev_mt_get_value(struct evdev_dev *, int, int16_t);
|
||||
void evdev_mt_set_value(struct evdev_dev *, int, int16_t, int32_t);
|
||||
int32_t evdev_mt_reassign_id(struct evdev_dev *, int, int32_t);
|
||||
|
||||
/* Utility functions: */
|
||||
void evdev_client_dumpqueue(struct evdev_client *);
|
||||
|
@ -495,6 +495,7 @@ uinput_ioctl_sub(struct uinput_cdev_state *state, u_long cmd, caddr_t data)
|
||||
|
||||
evdev_set_methods(state->ucs_evdev, state, &uinput_ev_methods);
|
||||
evdev_set_flag(state->ucs_evdev, EVDEV_FLAG_SOFTREPEAT);
|
||||
evdev_set_flag(state->ucs_evdev, EVDEV_FLAG_MT_KEEPID);
|
||||
ret = evdev_register(state->ucs_evdev);
|
||||
if (ret == 0)
|
||||
state->ucs_state = UINPUT_RUNNING;
|
||||
|
Loading…
Reference in New Issue
Block a user