diff --git a/src/libei-private.h b/src/libei-private.h index 573784b..6f399c5 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -87,7 +87,7 @@ struct ei_seat { struct list devices_removed; /* removed from seat but client still has a ref */ uint32_t id; uint32_t capabilities; - uint32_t capabilities_mask; + uint32_t capabilities_confirmed; char *name; }; diff --git a/src/libei-seat.c b/src/libei-seat.c index 499b77e..d65dda3 100644 --- a/src/libei-seat.c +++ b/src/libei-seat.c @@ -70,7 +70,7 @@ ei_seat_new(struct ei *ei, uint32_t id, const char *name, uint32_t capabilities) seat->name = xstrdup(name); seat->id = id; seat->capabilities = capabilities; - seat->capabilities_mask = ~0; /* Masked out by client */ + seat->capabilities_confirmed = 0; list_init(&seat->devices); list_init(&seat->devices_removed); @@ -134,21 +134,20 @@ ei_seat_has_capability(struct ei_seat *seat, case EI_DEVICE_CAP_POINTER_ABSOLUTE: case EI_DEVICE_CAP_KEYBOARD: case EI_DEVICE_CAP_TOUCH: - return flag_is_set(seat->capabilities_mask, cap); + return flag_is_set(seat->capabilities, cap); } return false; } _public_ void -ei_seat_drop_capability(struct ei_seat *seat, - enum ei_device_capability cap) +ei_seat_confirm_capability(struct ei_seat *seat, enum ei_device_capability cap) { if (seat->state != EI_SEAT_STATE_NEW) { log_bug_client(ei_seat_get_context(seat), "Seat is already bound\n"); return; } - flag_clear(seat->capabilities_mask, cap); + flag_set(seat->capabilities_confirmed, cap); } _public_ void @@ -159,7 +158,7 @@ ei_seat_bind(struct ei_seat *seat) return; } - ei_send_seat_bind(seat, seat->capabilities & seat->capabilities_mask); + ei_send_seat_bind(seat, seat->capabilities & seat->capabilities_confirmed); seat->state = EI_SEAT_STATE_BOUND; } diff --git a/src/libei.h b/src/libei.h index 5b25402..c9ee12a 100644 --- a/src/libei.h +++ b/src/libei.h @@ -134,7 +134,7 @@ struct ei_region; * device with capabilities unsupported by the client. * * Capabilities are initialized by the EIS implementation but the client may - * further reduce the requested capabilities, see ei_seat_drop_capability(). + * further reduce the requested capabilities, see ei_seat_confirm_capability(). * For example, a client may bind to a seat with the pointer and keyboard * capability but only the former is permitted by the EIS implementation. * Keyboard events sent through such a device will be treated as client bug @@ -646,28 +646,40 @@ ei_event_unref(struct ei_event *event); const char * ei_seat_get_name(struct ei_seat *seat); +/** + * Return true if the capabilitiy is available on this seat or false + * otherwise. The return value of this function is not affected by + * ei_seat_confirm_capability(). + */ bool ei_seat_has_capability(struct ei_seat *seat, enum ei_device_capability cap); /** - * Remove a capability from this seat before calling ei_seat_bind(). - * Devices with only the dropped capability will never be added to this - * client, devices with multiple capabilities will not show the dropped - * capabilities. + * Confirm a capability from this seat before calling ei_seat_bind(). + * + * A client must call this function for every capability on the seat it wants + * to receive devices for. Only devices with one or more supported + * capabilities will be added to this client. + * + * Calling this function for a capability that ei_seat_has_capability() + * returns false for is a noop and permitted. * * This function has no effect if called after ei_seat_bind(). */ void -ei_seat_drop_capability(struct ei_seat *seat, - enum ei_device_capability cap); +ei_seat_confirm_capability(struct ei_seat *seat, + enum ei_device_capability cap); /** - * Bind this client to the given seat for the seat's capabilities. + * Bind this client to the given seat for the confirmed seat's capabilities. * This function can only be called once per seat. Once bound, the server will - * create devices for the seat's capabillities and send the respective @ref + * create devices for the seat's capabilities and send the respective @ref * EI_EVENT_DEVICE_ADDED events. * + * A client must call ei_seat_confirm_capability() before calling + * ei_seat_bind(). + * * Devices may be added and removed at any time. */ void diff --git a/test/eierpecken.c b/test/eierpecken.c index cc90214..fc81903 100644 --- a/test/eierpecken.c +++ b/test/eierpecken.c @@ -814,6 +814,10 @@ _peck_dispatch_ei(struct peck *peck, int lineno) munit_assert_ptr_null(peck->ei_seat); peck->ei_seat = ei_seat_ref(seat); log_debug(peck, "default seat: %s\n", ei_seat_get_name(peck->ei_seat)); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH); ei_seat_bind(seat); break; } diff --git a/test/test-ei-seat.c b/test/test-ei-seat.c index 8061c1b..8b09483 100644 --- a/test/test-ei-seat.c +++ b/test/test-ei-seat.c @@ -45,6 +45,10 @@ MUNIT_TEST(test_ei_seat_bind_unbind) with_client(peck) { _unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED); seat = ei_seat_ref(ei_event_get_seat(event)); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH); ei_seat_bind(seat); } @@ -101,6 +105,10 @@ MUNIT_TEST(test_ei_seat_bind_unbind_noref) with_client(peck) { _unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED); seat = ei_seat_ref(ei_event_get_seat(event)); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH); ei_seat_bind(seat); } @@ -149,6 +157,10 @@ MUNIT_TEST(test_ei_seat_bind_unbind_immediately) with_client(peck) { _unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED); seat = ei_event_get_seat(event); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH); ei_seat_bind(seat); ei_seat_unbind(seat); } diff --git a/test/test-eis.c b/test/test-eis.c index deaa463..6e02038 100644 --- a/test/test-eis.c +++ b/test/test-eis.c @@ -120,8 +120,12 @@ MUNIT_TEST(eistest_cliend_bind_some_caps) _unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED); struct ei_seat *seat = ei_event_get_seat(event); - ei_seat_drop_capability(seat, EI_DEVICE_CAP_KEYBOARD); - ei_seat_drop_capability(seat, EI_DEVICE_CAP_TOUCH); + munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_KEYBOARD)); + munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_POINTER)); + munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE)); + munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_TOUCH)); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER); + ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE); ei_seat_bind(seat); } diff --git a/tools/ei-demo-client.c b/tools/ei-demo-client.c index e9ab43b..d1d6e72 100644 --- a/tools/ei-demo-client.c +++ b/tools/ei-demo-client.c @@ -312,6 +312,10 @@ int main(int argc, char **argv) } default_seat = ei_seat_ref(ei_event_get_seat(e)); colorprint("seat added: %s\n", ei_seat_get_name(default_seat)); + ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_POINTER); + ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_POINTER_ABSOLUTE); + ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_KEYBOARD); + ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_TOUCH); ei_seat_bind(default_seat); break; }