From fadc1853c9ab8dc3162813362eea5637c00a308a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 3 Feb 2023 17:04:54 +1000 Subject: [PATCH] protocol: add the ei_device interface Sitting nested below the ei_seat, the client gets a notification for a device through the ei_seat.device event. --- proto/protocol.xml | 145 +++++++++++++++-------- src/libei-device.c | 150 +++++++++++++++++++++++- src/libei-device.h | 8 +- src/libei-private.h | 12 +- src/libei-seat.c | 14 +++ src/libei.c | 210 +++------------------------------- src/libeis-client.c | 81 +------------ src/libeis-client.h | 13 +-- src/libeis-connection-setup.c | 1 + src/libeis-device.c | 73 +++++++++++- src/libeis-device.h | 6 + 11 files changed, 363 insertions(+), 350 deletions(-) diff --git a/proto/protocol.xml b/proto/protocol.xml index 4223be7..6865c2f 100644 --- a/proto/protocol.xml +++ b/proto/protocol.xml @@ -86,10 +86,6 @@ - - - - @@ -228,48 +224,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -484,6 +438,105 @@ the client can set up this seat now. + + + + Notification that a new device has been added. + + The interface version is equal or less to the client-supported + version in ei_connection_setup.interface for the "ei_device" + interface. + + + + + + + + + + Notification that the client is no longer interested in this device. + The EIS implementation will release any resources related to this device and + send the ei_device.destroyed event once complete. + + + + + + This device has been removed and a client should release all + associated resources. + + + + + + The name of this device, if any. This event is optional and sent once immediately + after object creation. + + + + + + + + + + + + + + A bitmask of the capabilties of this device. + + + + + + + + + + + + The device type, one of virtual or physical. + + + + + + + The device dimensions in mm. + + + + + + + + + + + + + + + + + + + + + + Notification that the initial burst of events is complete and + the client can set up this device now. + + + + + + + + + diff --git a/src/libei-device.c b/src/libei-device.c index 9c11114..0f651cb 100644 --- a/src/libei-device.c +++ b/src/libei-device.c @@ -33,6 +33,9 @@ #include "util-strings.h" #include "libei-private.h" +#include "ei-proto.h" + +DEFINE_UNREF_CLEANUP_FUNC(ei_region); static const char * ei_device_state_to_string(enum ei_device_state state) @@ -103,6 +106,7 @@ OBJECT_IMPLEMENT_SETTER(ei_device, user_data, void *); OBJECT_IMPLEMENT_GETTER(ei_device, width, uint32_t); OBJECT_IMPLEMENT_GETTER(ei_device, height, uint32_t); OBJECT_IMPLEMENT_GETTER(ei_device, id, uint32_t); +OBJECT_IMPLEMENT_GETTER_AS_REF(ei_device, proto_object, const struct brei_object *); _public_ struct ei_seat * ei_device_get_seat(struct ei_device *device) @@ -117,10 +121,132 @@ ei_device_get_context(struct ei_device *device) return ei_seat_get_context(ei_device_get_seat(device)); } +static int +handle_msg_destroy(struct ei_device *device) +{ + struct ei *ei = ei_device_get_context(device); + log_debug(ei, "Removed device %#x", ei_device_get_id(device)); + ei_device_removed_by_server(device); + return 0; +} + +static int +handle_msg_name(struct ei_device *device, const char *name) +{ + ei_device_set_name(device, name); + return 0; +} + +static int +handle_msg_capabilities(struct ei_device *device, uint32_t caps) +{ + ei_device_set_capabilities(device, caps); + return 0; +} + +static int +handle_msg_type(struct ei_device *device, enum ei_device_type type) +{ + ei_device_set_type(device, type); + return 0; +} + +static int +handle_msg_dimensions(struct ei_device *device, uint32_t width, uint32_t height) +{ + ei_device_set_size(device, width, height); + return 0; +} + +static int +handle_msg_region(struct ei_device *device, uint32_t x, uint32_t y, + uint32_t w, uint32_t h, float scale) +{ + _unref_(ei_region) *r = ei_region_new(); + ei_region_set_offset(r, x, y); + ei_region_set_size(r, w, h); + ei_region_set_physical_scale(r, scale); + ei_device_add_region(device, r); + + return 0; +} + +static int +handle_msg_keymap(struct ei_device *device, uint32_t keymap_type, uint32_t keymap_sz, int keymap_fd) +{ + ei_device_set_keymap(device, keymap_type, keymap_fd, keymap_sz); + return 0; +} + + +static int +handle_msg_done(struct ei_device *device) +{ + struct ei *ei = ei_device_get_context(device); + + ei_device_added(device); + ei_queue_device_added_event(device); + ei_device_done(device); + log_debug(ei, + "Added device %#x '%s' caps: %s%s%s%s seat: %s", + ei_device_get_id(device), ei_device_get_name(device), + ei_device_has_capability(device, EI_DEVICE_CAP_POINTER) ? "p" : "", + ei_device_has_capability(device, EI_DEVICE_CAP_POINTER_ABSOLUTE) ? "a" : "", + ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD) ? "k" : "", + ei_device_has_capability(device, EI_DEVICE_CAP_TOUCH) ? "t" : "", + ei_seat_get_name(ei_device_get_seat(device))); + return 0; +} + +static int +handle_msg_resumed(struct ei_device *device) +{ + ei_device_resumed(device); + ei_queue_device_resumed_event(device); + + return 0; +} + +static int +handle_msg_paused(struct ei_device *device) +{ + ei_device_paused(device); + ei_queue_device_paused_event(device); + + return 0; +} + +static const struct ei_device_interface interface = { + .destroyed = handle_msg_destroy, + .name = handle_msg_name, + .capabilities = handle_msg_capabilities, + .type = handle_msg_type, + .dimensions = handle_msg_dimensions, + .region = handle_msg_region, + .keymap = handle_msg_keymap, + .done = handle_msg_done, + .resumed = handle_msg_resumed, + .paused = handle_msg_paused, +}; + +const struct ei_device_interface * +ei_device_get_interface(struct ei_device *device) +{ + return &interface; +} + struct ei_device * -ei_device_new(struct ei_seat *seat, uint32_t deviceid) +ei_device_new(struct ei_seat *seat, uint32_t deviceid, uint32_t version) { struct ei_device *device = ei_device_create(&seat->object); + struct ei *ei = ei_seat_get_context(seat); + + device->proto_object.id = deviceid, + device->proto_object.implementation = device; + device->proto_object.interface = &ei_device_proto_interface; + device->proto_object.version = version; + list_init(&device->proto_object.link); + ei_register_object(ei, &device->proto_object); device->capabilities = 0; device->id = deviceid; @@ -136,10 +262,6 @@ ei_device_new(struct ei_seat *seat, uint32_t deviceid) */ ei_seat_ref(seat); - /* this list "owns" the ref for this device */ - ei_device_ref(device); - list_append(&seat->devices, &device->link); - return device; } @@ -238,6 +360,20 @@ ei_device_set_keymap(struct ei_device *device, device->keymap = ei_keymap_ref(keymap); } +static int +ei_device_send_release(struct ei_device *device) +{ + struct ei *ei = ei_device_get_context(device); + + if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED) + return 0; + + int rc = ei_device_request_release(device); + if (rc) + ei_disconnect(ei); + return rc; +} + _public_ void ei_device_close(struct ei_device *device) @@ -255,7 +391,7 @@ ei_device_close(struct ei_device *device) case EI_DEVICE_STATE_PAUSED: case EI_DEVICE_STATE_RESUMED: ei_device_set_state(device, EI_DEVICE_STATE_REMOVED_FROM_CLIENT); - ei_send_close_device(device); + ei_device_send_release(device); break; } } @@ -264,6 +400,7 @@ void ei_device_removed_by_server(struct ei_device *device) { struct ei_seat *seat = ei_device_get_seat(device); + struct ei *ei = ei_device_get_context(device); switch (device->state) { case EI_DEVICE_STATE_NEW: @@ -274,6 +411,7 @@ ei_device_removed_by_server(struct ei_device *device) case EI_DEVICE_STATE_PAUSED: case EI_DEVICE_STATE_RESUMED: case EI_DEVICE_STATE_EMULATING: + ei_unregister_object(ei, &device->proto_object); ei_queue_device_removed_event(device); ei_device_set_state(device, EI_DEVICE_STATE_DEAD); /* Device is dead now. Move it from the devices list to diff --git a/src/libei-device.h b/src/libei-device.h index 898de83..82ca242 100644 --- a/src/libei-device.h +++ b/src/libei-device.h @@ -54,8 +54,10 @@ enum ei_device_state { struct ei_device { struct object object; void *user_data; + struct brei_object proto_object; + struct list link; - uint32_t id; + uint32_t id; /* FIXME: remove this one */ enum ei_device_state state; uint32_t capabilities; char *name; @@ -102,13 +104,15 @@ struct ei_touch { }; OBJECT_DECLARE_GETTER(ei_device, id, uint32_t); +OBJECT_DECLARE_GETTER(ei_device, proto_object, const struct brei_object *); +OBJECT_DECLARE_GETTER(ei_device, interface, const struct ei_device_interface *); OBJECT_DECLARE_SETTER(ei_device, type, enum ei_device_type); OBJECT_DECLARE_SETTER(ei_device, name, const char*); OBJECT_DECLARE_SETTER(ei_device, seat, const char*); OBJECT_DECLARE_SETTER(ei_device, capabilities, uint32_t); struct ei_device * -ei_device_new(struct ei_seat *seat, uint32_t deviceid); +ei_device_new(struct ei_seat *seat, uint32_t deviceid, uint32_t version); void ei_device_add_region(struct ei_device *device, struct ei_region *r); diff --git a/src/libei-private.h b/src/libei-private.h index 0fecd2f..77153ac 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -114,9 +114,6 @@ ei_send_message(struct ei *ei, const struct brei_object *object, void ei_add_seat(struct ei_seat *seat); -int -ei_send_close_device(struct ei_device *device); - int ei_send_start_emulating(struct ei_device *device, uint32_t sequence); @@ -129,6 +126,15 @@ ei_send_frame(struct ei_device *device, uint64_t time); void ei_queue_device_removed_event(struct ei_device *device); +void +ei_queue_device_added_event(struct ei_device *device); + +void +ei_queue_device_resumed_event(struct ei_device *device); + +void +ei_queue_device_paused_event(struct ei_device *device); + void ei_insert_device_removed_event(struct ei_device *device); diff --git a/src/libei-seat.c b/src/libei-seat.c index aa23b0c..931dc37 100644 --- a/src/libei-seat.c +++ b/src/libei-seat.c @@ -109,11 +109,25 @@ static int handle_msg_done(struct ei_seat *seat) return 0; } +static int handle_msg_device(struct ei_seat *seat, uint32_t id, uint32_t version) +{ + struct ei *ei = ei_seat_get_context(seat); + + log_debug(ei, "Added device %#x@v%u", id, version); + /* device is in the seat's device list */ + struct ei_device *device = ei_device_new(seat, id, version); + /* this list "owns" the ref for this device */ + list_append(&seat->devices, &device->link); + + return 0; +} + static const struct ei_seat_interface interface = { .destroyed = handle_msg_destroyed, .name = handle_msg_name, .capabilities = handle_msg_capabilities, .done = handle_msg_done, + .device = handle_msg_device, }; const struct ei_seat_interface * diff --git a/src/libei.c b/src/libei.c index 211d6ff..2c0ea64 100644 --- a/src/libei.c +++ b/src/libei.c @@ -50,19 +50,6 @@ _Static_assert(sizeof(enum ei_keymap_type) == sizeof(int), "Invalid enum size"); _Static_assert(sizeof(enum ei_event_type) == sizeof(int), "Invalid enum size"); _Static_assert(sizeof(enum ei_log_priority) == sizeof(int), "Invalid enum size"); -static struct ei_seat * -ei_find_seat(struct ei *ei, uint32_t seatid) -{ - struct ei_seat *seat; - - list_for_each(seat, &ei->seats, link) { - if (ei_seat_get_id(seat) == seatid) - return seat; - } - - return NULL; -} - static struct ei_device * ei_find_device(struct ei *ei, uint32_t deviceid) { @@ -367,8 +354,8 @@ insert_device_removed_event(struct ei_device *device) insert_event(ei, e); } -static void -queue_paused_event(struct ei_device *device) +void +ei_queue_device_paused_event(struct ei_device *device) { struct ei *ei= ei_device_get_context(device); struct ei_event *e = ei_event_new_for_device(device); @@ -378,8 +365,8 @@ queue_paused_event(struct ei_device *device) queue_event(ei, e); } -static void -queue_resumed_event(struct ei_device *device) +void +ei_queue_device_resumed_event(struct ei_device *device) { struct ei *ei= ei_device_get_context(device); struct ei_event *e = ei_event_new_for_device(device); @@ -616,129 +603,24 @@ handle_msg_seat(struct ei_connection *connection, uint32_t seat_id, uint32_t ver return 0; } -static int -handle_msg_device_added(struct ei_connection *connection, uint32_t deviceid, uint32_t capabilities, - const char *name, uint32_t seatid, uint32_t type, - uint32_t width, uint32_t height) -{ - struct ei *ei = ei_connection_get_context(connection); - struct ei_seat *seat = ei_find_seat(ei, seatid); - - if (!seat) { - log_bug(ei, "Invalid seat id %#x for device %s (%#x)", - seatid, name, deviceid); - return 0; - } - - - /* Wrong device id or a device already removed by the client but we - * won't know which unless we keep some device ID table. Not worth - * it, so just silently ignore */ - if (ei_seat_find_device(seat, deviceid)) { - log_error(ei, "Server sent duplicate device id %#x", deviceid); - return -EINVAL; - } - - switch (type) { - case EI_DEVICE_TYPE_PHYSICAL: - case EI_DEVICE_TYPE_VIRTUAL: - break; - default: - log_error(ei, "Server sent invalid device type %u", type); - return -EINVAL; - } - - _unref_(ei_device) *device = ei_device_new(seat, deviceid); - ei_device_set_type(device, type); - if (type == EI_DEVICE_TYPE_PHYSICAL) - ei_device_set_size(device, width, height); - ei_device_set_name(device, name); - ei_device_set_capabilities(device, capabilities); - ei_device_added(device); - - log_debug(ei, - "Added device %#x '%s' caps: %s%s%s%s seat: %s", - deviceid, name, - ei_device_has_capability(device, EI_DEVICE_CAP_POINTER) ? "p" : "", - ei_device_has_capability(device, EI_DEVICE_CAP_POINTER_ABSOLUTE) ? "a" : "", - ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD) ? "k" : "", - ei_device_has_capability(device, EI_DEVICE_CAP_TOUCH) ? "t" : "", - ei_seat_get_name(seat)); - - return 0; -} - -static int -handle_msg_device_keymap(struct ei_connection *connection, uint32_t deviceid, - enum ei_keymap_type keymap_type, - uint32_t keymap_sz, int keymap_fd) -{ - struct ei *ei = ei_connection_get_context(connection); - - log_debug(ei, "Adding keymap for %#x", deviceid); - - struct ei_device *device = ei_find_device(ei, deviceid); - if (!device) - return 0; - - ei_device_set_keymap(device, keymap_type, keymap_fd, keymap_sz); - - return 0; -} - void ei_queue_device_removed_event(struct ei_device *device) { queue_device_removed_event(device); } +void +ei_queue_device_added_event(struct ei_device *device) +{ + queue_device_added_event(device); +} + void ei_insert_device_removed_event(struct ei_device *device) { insert_device_removed_event(device); } -static int -handle_msg_device_added_done(struct ei_connection *connection, uint32_t deviceid) -{ - struct ei *ei = ei_connection_get_context(connection); - - log_debug(ei, "Done with device %#x", deviceid); - - struct ei_device *device = ei_find_device(ei, deviceid); - if (!device) - return 0; - - queue_device_added_event(device); - ei_device_done(device); - - return 0; -} - -static int -handle_msg_device_region(struct ei_connection *connection, uint32_t deviceid, - uint32_t x, uint32_t y, - uint32_t w, uint32_t h, - float scale) -{ - struct ei *ei = ei_connection_get_context(connection); - - log_debug(ei, "Adding device region for %#x", deviceid); - - struct ei_device *device = ei_find_device(ei, deviceid); - if (!device) - return 0; - - _unref_(ei_region) *r = ei_region_new(); - ei_region_set_offset(r, x, y); - ei_region_set_size(r, w, h); - ei_region_set_physical_scale(r, scale); - - ei_device_add_region(device, r); - - return 0; -} - static int handle_msg_keyboard_modifiers(struct ei_connection *connection, uint32_t deviceid, uint32_t depressed, uint32_t locked, @@ -768,68 +650,6 @@ handle_msg_keyboard_modifiers(struct ei_connection *connection, uint32_t devicei return 0; } -static int -handle_msg_device_removed(struct ei_connection *connection, uint32_t deviceid) -{ - struct ei *ei = ei_connection_get_context(connection); - - log_debug(ei, "Removed device %#x", deviceid); - - struct ei_device *device = ei_find_device(ei, deviceid); - if (!device) - return 0; - - ei_device_removed_by_server(device); - - return 0; -} - -static int -handle_msg_device_resumed(struct ei_connection *connection, uint32_t deviceid) -{ - struct ei *ei = ei_connection_get_context(connection); - - log_debug(ei, "Resumed device %#x", deviceid); - - struct ei_device *device = ei_find_device(ei, deviceid); - if (device) { - ei_device_resumed(device); - queue_resumed_event(device); - } - - return 0; -} - -static int -handle_msg_device_paused(struct ei_connection *connection, uint32_t deviceid) -{ - struct ei *ei = ei_connection_get_context(connection); - - log_debug(ei, "Paused device %#x", deviceid); - - struct ei_device *device = ei_find_device(ei, deviceid); - if (device) { - ei_device_paused(device); - queue_paused_event(device); - } - - return 0; -} - -int -ei_send_close_device(struct ei_device *device) -{ - struct ei *ei = ei_device_get_context(device); - - if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED) - return 0; - - int rc = ei_connection_request_close_device(ei->connection, device->id); - if (rc) - ei_disconnect(ei); - return rc; -} - int ei_send_start_emulating(struct ei_device *device, uint32_t sequence) { @@ -1326,6 +1146,7 @@ handle_msg_connection_setup(struct ei_connection *connection, uint32_t new_id, u ei_connection_setup_request_interface(setup, "ei_connection", VERSION_V(1)); ei_connection_setup_request_interface(setup, "ei_callback", VERSION_V(1)); ei_connection_setup_request_interface(setup, "ei_seat", VERSION_V(1)); + ei_connection_setup_request_interface(setup, "ei_device", VERSION_V(1)); } ei_connection_setup_request_done(setup); ei_connection_setup_unref(setup); @@ -1351,13 +1172,6 @@ static const struct ei_connection_interface intf_state_connected = { .connection_setup = NULL, /* EPROTO */ .disconnected = handle_msg_disconnected, .seat = handle_msg_seat, - .device_added = handle_msg_device_added, - .device_removed = handle_msg_device_removed, - .device_resumed = handle_msg_device_resumed, - .device_paused = handle_msg_device_paused, - .device_region = handle_msg_device_region, - .device_keymap = handle_msg_device_keymap, - .device_done = handle_msg_device_added_done, .keyboard_modifiers = handle_msg_keyboard_modifiers, /* events */ @@ -1406,6 +1220,8 @@ lookup_object(uint32_t object_id, struct brei_object **object, void *userdata) } } + log_debug(ei, "Failed to find object %#x", object_id); + return -ENOENT; } diff --git a/src/libeis-client.c b/src/libeis-client.c index 91ed6b0..62046d2 100644 --- a/src/libeis-client.c +++ b/src/libeis-client.c @@ -202,47 +202,6 @@ client_send_seat_added(struct eis_client *client, struct eis_seat *seat) eis_seat_get_version(seat)); } -static int -client_send_device_added(struct eis_client *client, struct eis_device *device) -{ - struct eis_seat *seat = eis_device_get_seat(device); - int rc = eis_connection_event_device_added(client->connection, device->id, device->capabilities, - device->name, eis_seat_get_id(seat), - device->type, device->width, device->height); - - if (rc >= 0 && device->keymap) - rc = eis_connection_event_device_keymap(client->connection, device->id, device->keymap->type, device->keymap->size, device->keymap->fd); - - if (rc >= 0 && device->type == EIS_DEVICE_TYPE_VIRTUAL) { - struct eis_region *r; - list_for_each(r, &device->regions, link) { - rc = eis_connection_event_device_region(client->connection, device->id, r->x, r->y, r->width, r->height, r->physical_scale); - } - } - - if (rc >= 0) - rc = eis_connection_event_device_done(client->connection, device->id); - return rc; -} - -static int -client_send_device_removed(struct eis_client *client, struct eis_device *device) -{ - return eis_connection_event_device_removed(client->connection, device->id); -} - -static int -client_send_device_paused(struct eis_client *client, struct eis_device *device) -{ - return eis_connection_event_device_paused(client->connection, device->id); -} - -static int -client_send_device_resumed(struct eis_client *client, struct eis_device *device) -{ - return eis_connection_event_device_resumed(client->connection, device->id); -} - static int client_send_keyboard_modifiers(struct eis_client *client, struct eis_device *device, const struct eis_xkb_modifiers *mods) @@ -315,18 +274,6 @@ eis_client_setup_done(struct eis_client *client, const char *name, bool is_sende client->state = EIS_CLIENT_STATE_CONNECTING; } -static int -client_msg_close_device(struct eis_connection *connection, uint32_t deviceid) -{ - struct eis_client *client = eis_connection_get_client(connection); - struct eis_device *device = eis_client_find_device(client, deviceid); - - if (device) - eis_device_closed_by_client(device); - - return 0; -} - #define DISCONNECT_IF_RECEIVER_CONTEXT(client_) do { \ if (!(client_)->is_sender) { \ struct eis *_ctx = eis_client_get_context(client_); \ @@ -579,7 +526,6 @@ static const struct eis_connection_interface intf_state_connecting = { static const struct eis_connection_interface intf_state_connected = { .sync = client_msg_sync, .disconnect = client_msg_disconnect, - .close_device = client_msg_close_device, /* events */ .start_emulating = client_msg_start_emulating, @@ -624,6 +570,8 @@ lookup_object(uint32_t object_id, struct brei_object **object, void *userdata) } } + log_debug(eis_client_get_context(client), "Failed to find object %#x", object_id); + return -ENOENT; } @@ -677,6 +625,7 @@ eis_client_new(struct eis *eis, int fd) .ei_connection_setup = VERSION_V(1), .ei_callback = VERSION_V(1), .ei_seat = VERSION_V(1), + .ei_device = VERSION_V(1), }; client->connection = eis_connection_new(client); @@ -721,30 +670,6 @@ eis_client_add_seat(struct eis_client *client, struct eis_seat *seat) client_send_seat_added(client, seat); } -void -eis_client_add_device(struct eis_client *client, struct eis_device *device) -{ - client_send_device_added(client, device); -} - -void -eis_client_remove_device(struct eis_client *client, struct eis_device *device) -{ - client_send_device_removed(client, device); -} - -void -eis_client_pause_device(struct eis_client *client, struct eis_device *device) -{ - client_send_device_paused(client, device); -} - -void -eis_client_resume_device(struct eis_client *client, struct eis_device *device) -{ - client_send_device_resumed(client, device); -} - void eis_client_keyboard_modifiers(struct eis_client *client, struct eis_device *device, uint32_t depressed, uint32_t latched, uint32_t locked, diff --git a/src/libeis-client.h b/src/libeis-client.h index 1d42ef3..1d92426 100644 --- a/src/libeis-client.h +++ b/src/libeis-client.h @@ -42,6 +42,7 @@ struct eis_client_interface_versions { uint32_t ei_connection_setup; uint32_t ei_callback; uint32_t ei_seat; + uint32_t ei_device; }; struct eis_client { @@ -103,18 +104,6 @@ eis_client_send_message(struct eis_client *client, const struct brei_object *obj void eis_client_add_seat(struct eis_client *client, struct eis_seat *seat); -void -eis_client_add_device(struct eis_client *client, struct eis_device *device); -void -eis_client_remove_device(struct eis_client *client, struct eis_device *device); - -void -eis_client_resume_device(struct eis_client *client, - struct eis_device *device); -void -eis_client_pause_device(struct eis_client *client, - struct eis_device *device); - void eis_client_keyboard_modifiers(struct eis_client *client, struct eis_device *device, uint32_t depressed, uint32_t latched, uint32_t locked, diff --git a/src/libeis-connection-setup.c b/src/libeis-connection-setup.c index fd3da05..900c6c8 100644 --- a/src/libeis-connection-setup.c +++ b/src/libeis-connection-setup.c @@ -134,6 +134,7 @@ client_msg_interface(struct eis_connection_setup *setup, const char *name, uint3 VERSION_ENTRY(ei_connection), VERSION_ENTRY(ei_connection_setup), VERSION_ENTRY(ei_seat), + VERSION_ENTRY(ei_device), #undef VERSION_ENTRY }; diff --git a/src/libeis-device.c b/src/libeis-device.c index 8e2d08e..328f750 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -34,6 +34,13 @@ #include "libeis-private.h" #include "eis-proto.h" +static_assert((1 << EIS_DEVICE_CAP_POINTER) == EIS_DEVICE_CAPABILITIES_POINTER, "ABI mismatch"); +static_assert((1 << EIS_DEVICE_CAP_POINTER_ABSOLUTE) == EIS_DEVICE_CAPABILITIES_POINTER_ABSOLUTE, "ABI mismatch"); +static_assert((1 << EIS_DEVICE_CAP_KEYBOARD) == EIS_DEVICE_CAPABILITIES_KEYBOARD, "ABI mismatch"); +static_assert((1 << EIS_DEVICE_CAP_TOUCH) == EIS_DEVICE_CAPABILITIES_TOUCH, "ABI mismatch"); +static_assert((int)EIS_DEVICE_TYPE_VIRTUAL == EIS_DEVICE_DEVICE_TYPE_VIRTUAL, "ABI mismatch"); +static_assert((int)EIS_DEVICE_TYPE_PHYSICAL == EIS_DEVICE_DEVICE_TYPE_PHYSICAL, "ABI mismatch"); + _public_ OBJECT_IMPLEMENT_REF(eis_keymap); _public_ @@ -167,6 +174,7 @@ OBJECT_IMPLEMENT_GETTER(eis_device, width, uint32_t); _public_ OBJECT_IMPLEMENT_GETTER(eis_device, height, uint32_t); OBJECT_IMPLEMENT_GETTER(eis_device, id, uint32_t); +OBJECT_IMPLEMENT_GETTER_AS_REF(eis_device, proto_object, const struct brei_object *); _public_ struct eis_seat * eis_device_get_seat(struct eis_device *device) @@ -186,13 +194,37 @@ eis_device_get_client(struct eis_device *device) return eis_seat_get_client(eis_device_get_seat(device)); } +static int +client_msg_release(struct eis_device *device) +{ + eis_device_closed_by_client(device); + return 0; +} + +static const struct eis_device_interface interface = { + .release = client_msg_release, +}; + +const struct eis_device_interface * +eis_device_get_interface(struct eis_device *device) +{ + return &interface; +} + _public_ struct eis_device * eis_seat_new_device(struct eis_seat *seat) { - static uint32_t deviceid; struct eis_device *device = eis_device_create(&seat->object); + struct eis_client *client = eis_seat_get_client(seat); - device->id = eis_seat_get_id(seat) << 16 | ++deviceid; + device->proto_object.id = eis_client_get_new_id(client); + device->proto_object.implementation = device; + device->proto_object.interface = &eis_device_proto_interface; + device->proto_object.version = client->interface_versions.ei_device; + assert(device->proto_object.version != 0); + list_init(&device->proto_object.link); + + device->id = device->proto_object.id; /* FIXME: remove once all messages are in the device */ device->name = xstrdup("unnamed device"); device->capabilities = 0; device->state = EIS_DEVICE_STATE_NEW; @@ -264,6 +296,9 @@ eis_device_configure_size(struct eis_device *device, uint32_t width, uint32_t he _public_ void eis_device_add(struct eis_device *device) { + struct eis_client *client = eis_device_get_client(device); + struct eis_seat *seat = eis_device_get_seat(device); + if (device->state != EIS_DEVICE_STATE_NEW) { log_bug_client(eis_device_get_context(device), "%s: device already (dis)connected", __func__); @@ -276,12 +311,36 @@ eis_device_add(struct eis_device *device) } device->state = EIS_DEVICE_STATE_PAUSED; - eis_client_add_device(eis_device_get_client(device), device); + eis_client_register_object(client, &device->proto_object); + eis_seat_event_device(seat, device->proto_object.id, device->proto_object.version); + int rc = eis_device_event_name(device, device->name); + if (rc == 0) + rc = eis_device_event_capabilities(device, device->capabilities); + if (rc == 0) + rc = eis_device_event_type(device, device->type); + if (rc == 0 && device->type == EIS_DEVICE_TYPE_PHYSICAL) + rc = eis_device_event_dimensions(device, device->width, device->height); + if (rc == 0 &&device->type == EIS_DEVICE_TYPE_VIRTUAL) { + struct eis_region *r; + list_for_each(r, &device->regions, link) { + rc = eis_device_event_region(device, r->x, r->y, r->width, r->height, r->physical_scale); + if (rc != 0) + break; + } + } + if (rc >= 0 && device->keymap) + rc = eis_device_event_keymap(device, device->keymap->type, device->keymap->size, device->keymap->fd); + if (rc == 0) + eis_device_event_done(device); + + /* FIXME: check rc */ } _public_ void eis_device_remove(struct eis_device *device) { + struct eis_client *client = eis_device_get_client(device); + if (device->state == EIS_DEVICE_STATE_DEAD) return; @@ -289,8 +348,10 @@ eis_device_remove(struct eis_device *device) !eis_client_is_sender(eis_device_get_client(device))) eis_device_stop_emulating(device); + if (device->state != EIS_DEVICE_STATE_NEW) + eis_device_event_destroyed(device); device->state = EIS_DEVICE_STATE_DEAD; - eis_client_remove_device(eis_device_get_client(device), device); + eis_client_unregister_object(client, &device->proto_object); list_remove(&device->link); eis_device_unref(device); } @@ -972,7 +1033,7 @@ eis_device_pause(struct eis_device *device) return; device->state = EIS_DEVICE_STATE_PAUSED; - eis_client_pause_device(eis_device_get_client(device), device); + eis_device_event_paused(device); } _public_ void @@ -982,7 +1043,7 @@ eis_device_resume(struct eis_device *device) return; device->state = EIS_DEVICE_STATE_RESUMED; - eis_client_resume_device(eis_device_get_client(device), device); + eis_device_event_resumed(device); } _public_ void diff --git a/src/libeis-device.h b/src/libeis-device.h index bbcdf3e..ca2a5fd 100644 --- a/src/libeis-device.h +++ b/src/libeis-device.h @@ -28,6 +28,7 @@ #include "util-object.h" #include "util-list.h" +#include "brei-shared.h" enum eis_device_state { EIS_DEVICE_STATE_NEW, @@ -41,6 +42,9 @@ enum eis_device_state { struct eis_device { struct object object; /* parent is ei_seat, and we have a ref to it */ struct list link; + + struct brei_object proto_object; + uint32_t id; char *name; enum eis_device_state state; @@ -99,6 +103,8 @@ struct eis_xkb_modifiers { OBJECT_DECLARE_GETTER(eis_device, id, uint32_t); OBJECT_DECLARE_GETTER(eis_device, context, struct eis *); +OBJECT_DECLARE_GETTER(eis_device, proto_object, const struct brei_object *); +OBJECT_DECLARE_GETTER(eis_device, interface, const struct eis_device_interface *); void eis_device_set_client_keymap(struct eis_device *device,