fallback: make the paired keyboard list a struct list

This removes the artificial 3 keyboard limit. If you have more internal
keyboards than that, something is wrong in your setup but that shouldn't stop
us from working. Or more specificially: this can happen easily when running
tests so let's not fail the test suite because we created a few hundred
keyboards.

We'll still throw out a log message though.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2018-05-28 11:27:06 +10:00
parent d5c705a539
commit bcbc873651
2 changed files with 58 additions and 49 deletions

View file

@ -660,7 +660,7 @@ fallback_lid_toggle_keyboard_listeners(struct fallback_dispatch *dispatch,
{ {
struct paired_keyboard *kbd; struct paired_keyboard *kbd;
ARRAY_FOR_EACH(dispatch->lid.paired_keyboard, kbd) { list_for_each(kbd, &dispatch->lid.paired_keyboard_list, link) {
if (!kbd->device) if (!kbd->device)
continue; continue;
@ -1006,19 +1006,28 @@ fallback_interface_suspend(struct evdev_dispatch *evdev_dispatch,
fallback_return_to_neutral_state(dispatch, device); fallback_return_to_neutral_state(dispatch, device);
} }
static void
fallback_paired_keyboard_destroy(struct paired_keyboard *kbd)
{
kbd->device = NULL;
libinput_device_remove_event_listener(&kbd->listener);
list_remove(&kbd->link);
free(kbd);
}
static void static void
fallback_interface_remove(struct evdev_dispatch *evdev_dispatch) fallback_interface_remove(struct evdev_dispatch *evdev_dispatch)
{ {
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch); struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
struct paired_keyboard *kbd; struct paired_keyboard *kbd, *tmp;
libinput_device_remove_event_listener(&dispatch->tablet_mode.other.listener); libinput_device_remove_event_listener(&dispatch->tablet_mode.other.listener);
ARRAY_FOR_EACH(dispatch->lid.paired_keyboard, kbd) { list_for_each_safe(kbd,
if (!kbd->device) tmp,
continue; &dispatch->lid.paired_keyboard_list,
link) {
libinput_device_remove_event_listener(&kbd->listener); fallback_paired_keyboard_destroy(kbd);
} }
} }
@ -1096,7 +1105,7 @@ fallback_lid_pair_keyboard(struct evdev_device *lid_switch,
struct fallback_dispatch *dispatch = struct fallback_dispatch *dispatch =
fallback_dispatch(lid_switch->dispatch); fallback_dispatch(lid_switch->dispatch);
struct paired_keyboard *kbd; struct paired_keyboard *kbd;
bool paired = false; size_t count = 0;
if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0 || if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0 ||
(lid_switch->tags & EVDEV_TAG_LID_SWITCH) == 0) (lid_switch->tags & EVDEV_TAG_LID_SWITCH) == 0)
@ -1105,30 +1114,30 @@ fallback_lid_pair_keyboard(struct evdev_device *lid_switch,
if ((keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD) == 0) if ((keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD) == 0)
return; return;
ARRAY_FOR_EACH(dispatch->lid.paired_keyboard, kbd) { list_for_each(kbd, &dispatch->lid.paired_keyboard_list, link) {
if (kbd->device) count++;
continue; if (count > 3) {
evdev_log_info(lid_switch,
kbd->device = keyboard; "lid: too many internal keyboards\n");
evdev_log_debug(lid_switch, break;
"lid: keyboard paired with %s<->%s\n", }
lid_switch->devname,
keyboard->devname);
/* We need to init the event listener now only if the
* reported state is closed. */
if (dispatch->lid.is_closed)
fallback_lid_toggle_keyboard_listener(
dispatch,
kbd,
dispatch->lid.is_closed);
paired = true;
break;
} }
if (!paired) kbd = zalloc(sizeof(*kbd));
evdev_log_bug_libinput(lid_switch, kbd->device = keyboard;
"lid: too many internal keyboards\n"); libinput_device_init_event_listener(&kbd->listener);
list_insert(&dispatch->lid.paired_keyboard_list, &kbd->link);
evdev_log_debug(lid_switch,
"lid: keyboard paired with %s<->%s\n",
lid_switch->devname,
keyboard->devname);
/* We need to init the event listener now only if the
* reported state is closed. */
if (dispatch->lid.is_closed)
fallback_lid_toggle_keyboard_listener(dispatch,
kbd,
dispatch->lid.is_closed);
} }
static void static void
@ -1229,18 +1238,19 @@ fallback_interface_device_removed(struct evdev_device *device,
{ {
struct fallback_dispatch *dispatch = struct fallback_dispatch *dispatch =
fallback_dispatch(device->dispatch); fallback_dispatch(device->dispatch);
struct paired_keyboard *kbd; struct paired_keyboard *kbd, *tmp;
ARRAY_FOR_EACH(dispatch->lid.paired_keyboard, kbd) { list_for_each_safe(kbd,
tmp,
&dispatch->lid.paired_keyboard_list,
link) {
if (!kbd->device) if (!kbd->device)
continue; continue;
if (kbd->device != removed_device) if (kbd->device != removed_device)
continue; continue;
libinput_device_remove_event_listener(&kbd->listener); fallback_paired_keyboard_destroy(kbd);
libinput_device_init_event_listener(&kbd->listener);
kbd->device = NULL;
} }
if (removed_device == dispatch->tablet_mode.other.sw_device) { if (removed_device == dispatch->tablet_mode.other.sw_device) {
@ -1435,12 +1445,9 @@ fallback_dispatch_init_switch(struct fallback_dispatch *dispatch,
{ {
int val; int val;
list_init(&dispatch->lid.paired_keyboard_list);
if (device->tags & EVDEV_TAG_LID_SWITCH) { if (device->tags & EVDEV_TAG_LID_SWITCH) {
struct paired_keyboard *kbd;
ARRAY_FOR_EACH(dispatch->lid.paired_keyboard, kbd)
libinput_device_init_event_listener(&kbd->listener);
dispatch->lid.reliability = evdev_read_switch_reliability_prop(device); dispatch->lid.reliability = evdev_read_switch_reliability_prop(device);
dispatch->lid.is_closed = false; dispatch->lid.is_closed = false;
} }
@ -1466,6 +1473,7 @@ fallback_dispatch_create(struct libinput_device *libinput_device)
dispatch->base.dispatch_type = DISPATCH_FALLBACK; dispatch->base.dispatch_type = DISPATCH_FALLBACK;
dispatch->base.interface = &fallback_interface; dispatch->base.interface = &fallback_interface;
dispatch->pending_event = EVDEV_NONE; dispatch->pending_event = EVDEV_NONE;
list_init(&dispatch->lid.paired_keyboard_list);
fallback_dispatch_init_rel(dispatch, device); fallback_dispatch_init_rel(dispatch, device);
fallback_dispatch_init_abs(dispatch, device); fallback_dispatch_init_abs(dispatch, device);

View file

@ -45,6 +45,12 @@ enum debounce_state {
DEBOUNCE_STATE_DISABLED = 999, DEBOUNCE_STATE_DISABLED = 999,
}; };
struct paired_keyboard {
struct list link;
struct evdev_device *device;
struct libinput_event_listener listener;
};
struct fallback_dispatch { struct fallback_dispatch {
struct evdev_dispatch base; struct evdev_dispatch base;
struct evdev_device *device; struct evdev_device *device;
@ -117,17 +123,12 @@ struct fallback_dispatch {
bool is_closed; bool is_closed;
bool is_closed_client_state; bool is_closed_client_state;
/* We allow up to 3 paired keyboards for the lid switch /* We allow multiple paired keyboards for the lid switch
* listener. Only one keyboard should exist, but that can * listener. Only one keyboard should exist, but that can
* have more than one event node. * have more than one event node. And it's a list because
* * otherwise the test suite run fails too often.
* Note: this is a sparse list, any element may have a
* non-NULL device.
*/ */
struct paired_keyboard { struct list paired_keyboard_list;
struct evdev_device *device;
struct libinput_event_listener listener;
} paired_keyboard[3];
} lid; } lid;
}; };