mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-23 17:50:54 +01:00
tablet: expand the button mask to allow for BTN_LEFT, RIGHT, MIDDLE
Expand the mask to fit KEY_CNT buttons, the mouse has LMR buttons and a few more, trying to squash the range is more error-prone than having the full key range instead. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Stephen Chandler Paul <thatslyude@gmail.com>
This commit is contained in:
parent
5cac5248fc
commit
733fef5a67
2 changed files with 52 additions and 33 deletions
|
|
@ -35,10 +35,37 @@
|
|||
#define tablet_unset_status(tablet_,s_) (tablet_)->status &= ~(s_)
|
||||
#define tablet_has_status(tablet_,s_) (!!((tablet_)->status & (s_)))
|
||||
|
||||
#define tablet_get_pressed_buttons(tablet_,field_) \
|
||||
((tablet_)->button_state.field_ & ~((tablet_)->prev_button_state.field_))
|
||||
#define tablet_get_released_buttons(tablet_,field_) \
|
||||
((tablet_)->prev_button_state.field_ & ~((tablet_)->button_state.field_))
|
||||
static inline void
|
||||
tablet_get_pressed_buttons(struct tablet_dispatch *tablet,
|
||||
unsigned char *buttons,
|
||||
unsigned int buttons_len)
|
||||
{
|
||||
size_t i;
|
||||
const struct button_state *state = &tablet->button_state,
|
||||
*prev_state = &tablet->prev_button_state;
|
||||
|
||||
assert(buttons_len <= ARRAY_LENGTH(state->stylus_buttons));
|
||||
|
||||
for (i = 0; i < buttons_len; i++)
|
||||
buttons[i] = state->stylus_buttons[i] &
|
||||
~(prev_state->stylus_buttons[i]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tablet_get_released_buttons(struct tablet_dispatch *tablet,
|
||||
unsigned char *buttons,
|
||||
unsigned int buttons_len)
|
||||
{
|
||||
size_t i;
|
||||
const struct button_state *state = &tablet->button_state,
|
||||
*prev_state = &tablet->prev_button_state;
|
||||
|
||||
assert(buttons_len <= ARRAY_LENGTH(state->stylus_buttons));
|
||||
|
||||
for (i = 0; i < buttons_len; i++)
|
||||
buttons[i] = prev_state->stylus_buttons[i] &
|
||||
~(state->stylus_buttons[i]);
|
||||
}
|
||||
|
||||
static int
|
||||
tablet_device_has_axis(struct tablet_dispatch *tablet,
|
||||
|
|
@ -248,14 +275,11 @@ tablet_update_button(struct tablet_dispatch *tablet,
|
|||
uint32_t evcode,
|
||||
uint32_t enable)
|
||||
{
|
||||
uint32_t button, *mask;
|
||||
|
||||
/* XXX: This really depends on the expected buttons fitting in the mask */
|
||||
if (evcode >= BTN_MISC && evcode <= BTN_TASK) {
|
||||
return;
|
||||
} else if (evcode >= BTN_TOUCH && evcode <= BTN_STYLUS2) {
|
||||
mask = &tablet->button_state.stylus_buttons;
|
||||
button = evcode - BTN_TOUCH;
|
||||
/* noop */
|
||||
} else {
|
||||
log_info(tablet->device->base.seat->libinput,
|
||||
"Unhandled button %s (%#x)\n",
|
||||
|
|
@ -263,13 +287,11 @@ tablet_update_button(struct tablet_dispatch *tablet,
|
|||
return;
|
||||
}
|
||||
|
||||
assert(button < 32);
|
||||
|
||||
if (enable) {
|
||||
(*mask) |= 1 << button;
|
||||
set_bit(tablet->button_state.stylus_buttons, evcode);
|
||||
tablet_set_status(tablet, TABLET_BUTTONS_PRESSED);
|
||||
} else {
|
||||
(*mask) &= ~(1 << button);
|
||||
clear_bit(tablet->button_state.stylus_buttons, evcode);
|
||||
tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
|
||||
}
|
||||
}
|
||||
|
|
@ -452,28 +474,23 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet,
|
|||
struct evdev_device *device,
|
||||
uint32_t time,
|
||||
struct libinput_tool *tool,
|
||||
uint32_t buttons,
|
||||
uint32_t button_base,
|
||||
const unsigned char *buttons,
|
||||
unsigned int buttons_len,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
struct libinput_device *base = &device->base;
|
||||
int32_t num_button = 0;
|
||||
size_t i;
|
||||
size_t nbits = 8 * sizeof(buttons[0]) * buttons_len;
|
||||
|
||||
while (buttons) {
|
||||
int enabled;
|
||||
|
||||
num_button++;
|
||||
enabled = (buttons & 1);
|
||||
buttons >>= 1;
|
||||
|
||||
if (!enabled)
|
||||
for (i = 0; i < nbits; i++) {
|
||||
if (!bit_is_set(buttons, i))
|
||||
continue;
|
||||
|
||||
tablet_notify_button(base,
|
||||
time,
|
||||
tool,
|
||||
tablet->axes,
|
||||
num_button + button_base - 1,
|
||||
i,
|
||||
state);
|
||||
}
|
||||
}
|
||||
|
|
@ -485,21 +502,21 @@ tablet_notify_buttons(struct tablet_dispatch *tablet,
|
|||
struct libinput_tool *tool,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
uint32_t stylus_buttons;
|
||||
unsigned char buttons[ARRAY_LENGTH(tablet->button_state.stylus_buttons)];
|
||||
|
||||
if (state == LIBINPUT_BUTTON_STATE_PRESSED)
|
||||
stylus_buttons =
|
||||
tablet_get_pressed_buttons(tablet, stylus_buttons);
|
||||
tablet_get_pressed_buttons(tablet, buttons, sizeof(buttons));
|
||||
else
|
||||
stylus_buttons =
|
||||
tablet_get_released_buttons(tablet, stylus_buttons);
|
||||
tablet_get_released_buttons(tablet,
|
||||
buttons,
|
||||
sizeof(buttons));
|
||||
|
||||
tablet_notify_button_mask(tablet,
|
||||
device,
|
||||
time,
|
||||
tool,
|
||||
stylus_buttons,
|
||||
BTN_TOUCH,
|
||||
buttons,
|
||||
sizeof(buttons),
|
||||
state);
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +559,9 @@ tablet_flush(struct tablet_dispatch *tablet,
|
|||
|
||||
if (tablet_has_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY)) {
|
||||
/* Release all stylus buttons */
|
||||
tablet->button_state.stylus_buttons = 0;
|
||||
memset(tablet->button_state.stylus_buttons,
|
||||
0,
|
||||
sizeof(tablet->button_state.stylus_buttons));
|
||||
tablet_set_status(tablet, TABLET_BUTTONS_RELEASED);
|
||||
} else if (tablet_has_status(tablet, TABLET_AXES_UPDATED) ||
|
||||
tablet_has_status(tablet, TABLET_TOOL_ENTERING_PROXIMITY)) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ enum tablet_status {
|
|||
};
|
||||
|
||||
struct button_state {
|
||||
uint32_t stylus_buttons; /* bitmask of evcode - BTN_TOUCH */
|
||||
unsigned char stylus_buttons[NCHARS(KEY_CNT)];
|
||||
};
|
||||
|
||||
struct tablet_dispatch {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue