mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-29 14:50:08 +01:00
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.
This commit is contained in:
parent
01a2ff2d72
commit
fadc1853c9
11 changed files with 363 additions and 350 deletions
|
|
@ -86,10 +86,6 @@
|
|||
<request name="disconnect">
|
||||
</request>
|
||||
|
||||
<request name="close_device">
|
||||
<arg name="device_id" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="pointer_relative">
|
||||
<arg name="device_id" type="uint"/>
|
||||
<arg name="x" type="float"/>
|
||||
|
|
@ -228,48 +224,6 @@
|
|||
<arg name="version" type="uint" summary="the interface version"/>
|
||||
</event>
|
||||
|
||||
<event name="device_added">
|
||||
<arg name="device_id" type="uint"/>
|
||||
<arg name="capabilities" type="uint"/>
|
||||
<arg name="name" type="string"/>
|
||||
<arg name="seat_id" type="uint"/>
|
||||
<arg name="type" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="device_keymap">
|
||||
<arg name="device_id" type="uint"/>
|
||||
<arg name="keymap_type" type="uint"/>
|
||||
<arg name="keymap_size" type="uint"/>
|
||||
<arg name="keymap" type="fd"/>
|
||||
</event>
|
||||
|
||||
<event name="device_region">
|
||||
<arg name="device_id" type="uint"/>
|
||||
<arg name="offset_x" type="uint"/>
|
||||
<arg name="offset_y" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="hight" type="uint"/>
|
||||
<arg name="scale" type="float"/>
|
||||
</event>
|
||||
|
||||
<event name="device_done">
|
||||
<arg name="device_id" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="device_removed">
|
||||
<arg name="device_id" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="device_resumed">
|
||||
<arg name="device_id" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="device_paused">
|
||||
<arg name="device_id" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="pointer_relative">
|
||||
<arg name="device_id" type="uint"/>
|
||||
<arg name="x" type="float"/>
|
||||
|
|
@ -484,6 +438,105 @@
|
|||
the client can set up this seat now.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="device" since="1">
|
||||
<description summary="Device presence notification">
|
||||
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.
|
||||
</description>
|
||||
<arg name="device" type="new_id" interface="ei_device"/>
|
||||
<arg name="version" type="uint" summary="the interface version"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="ei_device" version="1">
|
||||
<request name="release">
|
||||
<description summary="Device removal request">
|
||||
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.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="destroyed" since="1">
|
||||
<description summary="Device removal notification">
|
||||
This device has been removed and a client should release all
|
||||
associated resources.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="name" since="1">
|
||||
<description summary="device name notification">
|
||||
The name of this device, if any. This event is optional and sent once immediately
|
||||
after object creation.
|
||||
</description>
|
||||
<arg name="name" type="string" help="the device name"/>
|
||||
</event>
|
||||
|
||||
<enum name="capabilities" since="1">
|
||||
<entry name="pointer" value="2"/>
|
||||
<entry name="pointer_absolute" value="4"/>
|
||||
<entry name="keyboard" value="8"/>
|
||||
<entry name="touch" value="16"/>
|
||||
</enum>
|
||||
|
||||
<event name="capabilities" since="1">
|
||||
<description summary="device capability notification">
|
||||
A bitmask of the capabilties of this device.
|
||||
</description>
|
||||
<arg name="capabilities" type="uint" enum="capabilities" help="the device name"/>
|
||||
</event>
|
||||
|
||||
<enum name="device_type" since="1">
|
||||
<entry name="virtual" value="1"/>
|
||||
<entry name="physical" value="2"/>
|
||||
</enum>
|
||||
|
||||
<event name="type" since="1">
|
||||
<description summary="device type notification">
|
||||
The device type, one of virtual or physical.
|
||||
</description>
|
||||
<arg name="type" type="uint" enum="device_type" help="the device type"/>
|
||||
</event>
|
||||
|
||||
<event name="dimensions" since="1">
|
||||
<description summary="device dimensions notification">
|
||||
The device dimensions in mm.
|
||||
</description>
|
||||
<arg name="width" type="uint" help="the device physical width"/>
|
||||
<arg name="height" type="uint" help="the device physical height"/>
|
||||
</event>
|
||||
|
||||
<event name="keymap" since="1">
|
||||
<arg name="type" type="uint" enum="keymap_type" help="the keymap type"/>
|
||||
<arg name="size" type="uint" help="the keymap size in bytes"/>
|
||||
<arg name="keymap" type="fd" help="file descriptor to the keymap"/>
|
||||
</event>
|
||||
|
||||
<event name="region" since="1">
|
||||
<arg name="offset_x" type="uint"/>
|
||||
<arg name="offset_y" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="hight" type="uint"/>
|
||||
<arg name="scale" type="float"/>
|
||||
</event>
|
||||
|
||||
<event name="done" since="1">
|
||||
<description summary="device setup completion notification">
|
||||
Notification that the initial burst of events is complete and
|
||||
the client can set up this device now.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="resumed">
|
||||
</event>
|
||||
|
||||
<event name="paused">
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
210
src/libei.c
210
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue