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,