diff --git a/proto/ei.proto b/proto/ei.proto index 03567b0..b84ca3c 100644 --- a/proto/ei.proto +++ b/proto/ei.proto @@ -90,6 +90,7 @@ message AddDevice { /* keymap is passed as fd if type is not none */ uint32 keymap_type = 8; uint32 keymap_size = 9; + string name = 10; } message RemoveDevice { @@ -141,6 +142,7 @@ message DeviceAdded { bool keymap_from_server = 3; uint32 keymap_type = 4; uint32 keymap_size = 5; + string name = 6; } message DeviceRemoved { diff --git a/src/libei-device.c b/src/libei-device.c index 0a57ee5..87074ef 100644 --- a/src/libei-device.c +++ b/src/libei-device.c @@ -248,6 +248,13 @@ ei_device_added(struct ei_device *device) ei_device_suspended(device); } +void +ei_device_set_name(struct ei_device *device, const char *name) +{ + free(device->name); + device->name = xstrdup(name); +} + void ei_device_set_capabilities(struct ei_device *device, uint32_t capabilities) diff --git a/src/libei-private.h b/src/libei-private.h index 37b25e8..bf4aa8e 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -137,6 +137,9 @@ ei_device_suspended(struct ei_device *device); void ei_device_resumed(struct ei_device *device); +void +ei_device_set_name(struct ei_device *device, const char *name); + void ei_device_set_capabilities(struct ei_device *device, uint32_t capabilities); diff --git a/src/libei-proto.c b/src/libei-proto.c index 517605a..5302268 100644 --- a/src/libei-proto.c +++ b/src/libei-proto.c @@ -38,6 +38,7 @@ message_free(struct message *msg) switch (msg->type) { case MESSAGE_DEVICE_ADDED: xclose(msg->added.keymap_fd); + free(msg->added.name); break; default: break; @@ -82,6 +83,7 @@ ei_proto_parse_message(struct brei_message *bmsg, size_t *consumed) *msg = (struct message) { .type = MESSAGE_DEVICE_ADDED, .added.deviceid = a->deviceid, + .added.name = a->name[0] ? xstrdup(a->name) : NULL, .added.capabilities = a->capabilities, .added.keymap_fd = -1, .added.keymap_type = a->keymap_type, @@ -227,6 +229,7 @@ ei_proto_send_add(struct ei *ei, struct ei_device *device) AddDevice add = ADD_DEVICE__INIT; add.deviceid = device->id; + add.name = device->name; add.capabilities = device->capabilities; add.pointer_width = device->abs.dim.width; add.pointer_height = device->abs.dim.height; diff --git a/src/libei-proto.h b/src/libei-proto.h index 31d9925..2841377 100644 --- a/src/libei-proto.h +++ b/src/libei-proto.h @@ -66,6 +66,7 @@ struct message { } disconnected; struct message_device_added { uint32_t deviceid; + char *name; uint32_t capabilities; enum ei_keymap_type keymap_type; bool keymap_from_server; diff --git a/src/libei.c b/src/libei.c index 35acc47..2bc656f 100644 --- a/src/libei.c +++ b/src/libei.c @@ -370,16 +370,18 @@ ei_remove_device(struct ei_device *device) } static int -handle_msg_added(struct ei *ei, uint32_t deviceid, uint32_t capabilities, +handle_msg_added(struct ei *ei, uint32_t deviceid, + const char *name, uint32_t capabilities, bool keymap_from_server, enum ei_keymap_type keymap_type, int keymap_fd, size_t keymap_sz) { struct ei_device *d; - log_debug(ei, "Added device %d with caps %#x\n", deviceid, capabilities); + log_debug(ei, "Added device %d '%s' with caps %#x\n", deviceid, name, capabilities); list_for_each(d, &ei->devices, link) { if (d->id == deviceid) { + ei_device_set_name(d, name); ei_device_set_capabilities(d, capabilities); if (keymap_from_server) ei_device_set_keymap(d, keymap_type, keymap_fd, keymap_sz); @@ -556,7 +558,8 @@ connection_connected_handle_msg(struct ei *ei, struct message *msg) rc = -ECANCELED; break; case MESSAGE_DEVICE_ADDED: - rc = handle_msg_added(ei, msg->added.deviceid, msg->added.capabilities, + rc = handle_msg_added(ei, msg->added.deviceid, + msg->added.name, msg->added.capabilities, msg->added.keymap_from_server, msg->added.keymap_type, msg->added.keymap_fd, msg->added.keymap_size); break; diff --git a/src/libeis-client.c b/src/libeis-client.c index 278a37c..3d71e56 100644 --- a/src/libeis-client.c +++ b/src/libeis-client.c @@ -154,7 +154,7 @@ eis_client_disconnect(struct eis_client *client) static int client_new_device(struct eis_client *client, - uint32_t id, uint32_t capabilities, + uint32_t id, const char *name, uint32_t capabilities, const struct dimensions *dim_pointer, const struct dimensions *dim_touch, enum eis_keymap_type keymap_type, @@ -174,7 +174,7 @@ client_new_device(struct eis_client *client, bit(EIS_DEVICE_CAP_TOUCH))) return -EINVAL; - struct eis_device *device = eis_device_new(client, id, capabilities); + struct eis_device *device = eis_device_new(client, id, name, capabilities); list_append(&client->devices, &device->link); if (flag_is_set(capabilities, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) @@ -188,8 +188,8 @@ client_new_device(struct eis_client *client, eis_device_set_client_keymap(device, keymap_type, keymap_fd, keymap_sz); log_debug(eis_client_parent(client), - "New device %d caps: %s%s%s%s\n", - id, + "New device %d '%s' caps: %s%s%s%s\n", + id, name, eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) ? "p" : "", eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) ? "a" : "", eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD) ? "k" : "", @@ -376,6 +376,7 @@ client_connected_handle_msg(struct eis_client *client, break; case MESSAGE_ADD_DEVICE: rc = client_new_device(client, msg->add_device.deviceid, + msg->add_device.name, msg->add_device.capabilities, &msg->add_device.dim_pointer, &msg->add_device.dim_touch, diff --git a/src/libeis-device.c b/src/libeis-device.c index 0604158..da09a77 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -34,6 +34,7 @@ static void eis_device_destroy(struct eis_device *device) { + free(device->name); xclose(device->keymap.fd); } @@ -49,6 +50,18 @@ _public_ OBJECT_IMPLEMENT_GETTER(eis_device, user_data, void *); _public_ OBJECT_IMPLEMENT_SETTER(eis_device, user_data, void *); +_public_ +OBJECT_IMPLEMENT_GETTER(eis_device, name, const char *); + +_public_ void +eis_device_set_name(struct eis_device *device, const char *name) +{ + if (device->state != EIS_DEVICE_STATE_NEW) + return; + + free(device->name); + device->name = xstrdup(name); +} _public_ struct eis_client * eis_device_get_client(struct eis_device *device) @@ -59,10 +72,12 @@ eis_device_get_client(struct eis_device *device) struct eis_device * eis_device_new(struct eis_client *client, uint32_t id, + const char *name, uint32_t capabilities) { struct eis_device *device = eis_device_create(&client->object); + device->name = xstrdup(name); device->capabilities_mask = 0; device->capabilities = capabilities; device->id = id; diff --git a/src/libeis-private.h b/src/libeis-private.h index c0d835f..b437087 100644 --- a/src/libeis-private.h +++ b/src/libeis-private.h @@ -90,6 +90,7 @@ struct eis_device { struct object object; struct list link; uint32_t id; + char *name; enum eis_device_state state; uint32_t capabilities; uint32_t capabilities_mask; @@ -162,6 +163,7 @@ eis_client_suspend_device(struct eis_client *client, struct eis_device * eis_device_new(struct eis_client *client, uint32_t id, + const char *name, uint32_t capabilities); void diff --git a/src/libeis-proto.c b/src/libeis-proto.c index f2cf1ae..70380cd 100644 --- a/src/libeis-proto.c +++ b/src/libeis-proto.c @@ -38,6 +38,9 @@ void message_free(struct message *msg) { switch (msg->type) { + case MESSAGE_ADD_DEVICE: + free(msg->add_device.name); + break; case MESSAGE_CONNECT: free(msg->connect.name); break; @@ -141,6 +144,7 @@ eis_proto_send_device_added(struct eis_client *client, struct eis_device *device DeviceAdded added = DEVICE_ADDED__INIT; added.deviceid = device->id; + added.name = device->name; added.capabilities = device->capabilities; added.keymap_type = device->keymap.type; added.keymap_size = device->keymap.size; @@ -232,6 +236,7 @@ eis_proto_parse_message(struct brei_message *bmsg, size_t *consumed) *msg = (struct message) { .type = MESSAGE_ADD_DEVICE, .add_device.deviceid = a->deviceid, + .add_device.name = a->name[0] ? xstrdup(a->name) : NULL, .add_device.capabilities = a->capabilities, .add_device.dim_pointer.width = a->pointer_width, .add_device.dim_pointer.height = a->pointer_height, diff --git a/src/libeis-proto.h b/src/libeis-proto.h index c2b8933..5b02af1 100644 --- a/src/libeis-proto.h +++ b/src/libeis-proto.h @@ -58,6 +58,7 @@ struct message { } disconnect; struct message_add_device { uint32_t deviceid; + char *name; uint32_t capabilities; struct dimensions dim_pointer; struct dimensions dim_touch; diff --git a/src/libeis.h b/src/libeis.h index 5b183be..02a5998 100644 --- a/src/libeis.h +++ b/src/libeis.h @@ -305,7 +305,7 @@ eis_device_get_name(struct eis_device *device); * Set the name of the device. This function has no effect if called after * eis_device_connect() */ -const char * +void eis_device_set_name(struct eis_device *device, const char *name); bool diff --git a/test/eierpecken.c b/test/eierpecken.c index 61a0794..c94133d 100644 --- a/test/eierpecken.c +++ b/test/eierpecken.c @@ -329,12 +329,14 @@ peck_handle_eis_added(struct peck *peck, struct eis_event *e) } if (!mask) { - log_debug(peck, "EIS refusing device\n"); - eis_device_disconnect(eis_event_get_device(e)); + log_debug(peck, "EIS refusing device: '%s'\n", + eis_device_get_name(device)); + eis_device_disconnect(device); return false; } else { - log_debug(peck, "EIS adding device\n"); - eis_device_connect(eis_event_get_device(e)); + log_debug(peck, "EIS adding device: '%s'\n", + eis_device_get_name(device)); + eis_device_connect(device); return true; } } diff --git a/test/test-ei.c b/test/test-ei.c index 3a30d2b..1b0741c 100644 --- a/test/test-ei.c +++ b/test/test-ei.c @@ -316,6 +316,92 @@ MUNIT_TEST(test_ei_device_basics) return MUNIT_OK; } +MUNIT_TEST(test_ei_device_set_name) +{ + _cleanup_peck_ struct peck *peck = peck_new(); + _cleanup_ei_device_ struct ei_device *d1 = NULL; + _cleanup_ei_device_ struct ei_device *d2 = NULL; + _cleanup_ei_device_ struct ei_device *d3 = NULL; + + peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT); + peck_dispatch_until_stable(peck); + + with_client(peck) { + d1 = ei_device_new(ei); + ei_device_configure_name(d1, "first device"); + ei_device_configure_capability(d1, EI_DEVICE_CAP_POINTER); + ei_device_add(d1); + + d2 = ei_device_new(ei); + munit_assert_not_null(d2); + ei_device_configure_name(d2, "second device"); + ei_device_configure_capability(d2, EI_DEVICE_CAP_POINTER); + ei_device_add(d2); + + d3 = ei_device_new(ei); + munit_assert_not_null(d3); + ei_device_configure_name(d3, "third device"); + ei_device_configure_capability(d3, EI_DEVICE_CAP_POINTER); + ei_device_add(d3); + } + + peck_dispatch_until_stable(peck); + + with_server(peck) { + _cleanup_eis_event_ struct eis_event *e1 = + peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED); + + struct eis_device *d1 = eis_event_get_device(e1); + munit_assert_string_equal(eis_device_get_name(d1), "first device"); + /* change the name */ + eis_device_set_name(d1, "other name"); + munit_assert_string_equal(eis_device_get_name(d1), "other name"); + eis_device_allow_capability(d1, EIS_DEVICE_CAP_POINTER); + eis_device_connect(d1); + + _cleanup_eis_event_ struct eis_event *e2 = + peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED); + struct eis_device *d2 = eis_event_get_device(e2); + + munit_assert_string_equal(eis_device_get_name(d2), "second device"); + /* unset the name */ + eis_device_set_name(d2, NULL); + munit_assert_ptr_null(eis_device_get_name(d2)); + eis_device_allow_capability(d2, EIS_DEVICE_CAP_POINTER); + eis_device_connect(d2); + + _cleanup_eis_event_ struct eis_event *e3 = + peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED); + struct eis_device *d3 = eis_event_get_device(e3); + + munit_assert_string_equal(eis_device_get_name(d3), "third device"); + /* leave the name as-is */ + eis_device_allow_capability(d3, EIS_DEVICE_CAP_POINTER); + eis_device_connect(d3); + } + + peck_dispatch_until_stable(peck); + + with_client(peck) { + _cleanup_ei_event_ struct ei_event *e1 = + peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED); + munit_assert_ptr_equal(d1, ei_event_get_device(e1)); + munit_assert_string_equal(ei_device_get_name(d1), "other name"); + + _cleanup_ei_event_ struct ei_event *e2 = + peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED); + munit_assert_ptr_equal(d2, ei_event_get_device(e2)); + munit_assert_ptr_null(ei_device_get_name(d2)); + + _cleanup_ei_event_ struct ei_event *e3 = + peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED); + munit_assert_ptr_equal(d3, ei_event_get_device(e3)); + munit_assert_string_equal(ei_device_get_name(d3), "third device"); + } + + return MUNIT_OK; +} + MUNIT_TEST(test_ei_device_add_remove) { _cleanup_peck_ struct peck *peck = peck_new();