mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-24 22:50:05 +01:00
touchpad: factor out fake finger handling
We need this for determining hovering touches on some semi-mt touchpads. This makes the fake_touches mask use bit 0 for BTN_TOUCH, and the other bits for BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, etc. BTN_TOUCH is independent of the rest, the others are mutually exclusive in the kernel. Since the mask isn't a straightforward bitmask anymore, abstract it all through helper functions. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
c8dc81b48f
commit
99cb908722
2 changed files with 59 additions and 20 deletions
|
|
@ -135,6 +135,57 @@ tp_get_touch(struct tp_dispatch *tp, unsigned int slot)
|
|||
return &tp->touches[slot];
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
tp_fake_finger_count(struct tp_dispatch *tp)
|
||||
{
|
||||
unsigned int fake_touches, nfake_touches;
|
||||
|
||||
/* don't count BTN_TOUCH */
|
||||
fake_touches = tp->fake_touches >> 1;
|
||||
nfake_touches = 0;
|
||||
while (fake_touches) {
|
||||
nfake_touches++;
|
||||
fake_touches >>= 1;
|
||||
}
|
||||
|
||||
return nfake_touches;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
tp_fake_finger_is_touching(struct tp_dispatch *tp)
|
||||
{
|
||||
return tp->fake_touches & 0x1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_fake_finger_set(struct tp_dispatch *tp,
|
||||
unsigned int code,
|
||||
bool is_press)
|
||||
{
|
||||
unsigned int shift;
|
||||
|
||||
switch (code) {
|
||||
case BTN_TOUCH:
|
||||
shift = 0;
|
||||
break;
|
||||
case BTN_TOOL_FINGER:
|
||||
shift = 1;
|
||||
break;
|
||||
case BTN_TOOL_DOUBLETAP:
|
||||
case BTN_TOOL_TRIPLETAP:
|
||||
case BTN_TOOL_QUADTAP:
|
||||
shift = code - BTN_TOOL_DOUBLETAP + 2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_press)
|
||||
tp->fake_touches |= 1 << shift;
|
||||
else
|
||||
tp->fake_touches &= ~(0x1 << shift);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
||||
{
|
||||
|
|
@ -253,30 +304,13 @@ tp_process_fake_touch(struct tp_dispatch *tp,
|
|||
uint64_t time)
|
||||
{
|
||||
struct tp_touch *t;
|
||||
unsigned int fake_touches;
|
||||
unsigned int nfake_touches;
|
||||
unsigned int i, start;
|
||||
unsigned int shift;
|
||||
|
||||
if (e->code != BTN_TOUCH &&
|
||||
(e->code < BTN_TOOL_DOUBLETAP || e->code > BTN_TOOL_QUADTAP))
|
||||
return;
|
||||
tp_fake_finger_set(tp, e->code, e->value != 0);
|
||||
|
||||
shift = e->code == BTN_TOUCH ? 0 : (e->code - BTN_TOOL_DOUBLETAP + 1);
|
||||
nfake_touches = tp_fake_finger_count(tp);
|
||||
|
||||
if (e->value)
|
||||
tp->fake_touches |= 1 << shift;
|
||||
else
|
||||
tp->fake_touches &= ~(0x1 << shift);
|
||||
|
||||
fake_touches = tp->fake_touches;
|
||||
nfake_touches = 0;
|
||||
while (fake_touches) {
|
||||
nfake_touches++;
|
||||
fake_touches >>= 1;
|
||||
}
|
||||
|
||||
/* For single touch tps we use BTN_TOUCH for begin / end of touch 0 */
|
||||
start = tp->has_mt ? tp->real_touches : 0;
|
||||
for (i = start; i < tp->ntouches; i++) {
|
||||
t = tp_get_touch(tp, i);
|
||||
|
|
|
|||
|
|
@ -197,7 +197,12 @@ struct tp_dispatch {
|
|||
unsigned int real_touches; /* number of slots */
|
||||
unsigned int ntouches; /* no slots inc. fakes */
|
||||
struct tp_touch *touches; /* len == ntouches */
|
||||
unsigned int fake_touches; /* fake touch mask */
|
||||
/* bit 0: BTN_TOUCH
|
||||
* bit 1: BTN_TOOL_FINGER
|
||||
* bit 2: BTN_TOOL_DOUBLETAP
|
||||
* ...
|
||||
*/
|
||||
unsigned int fake_touches;
|
||||
|
||||
struct {
|
||||
int32_t margin_x;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue