mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-05 00:48:02 +02:00
Change to allow dynamic binding of capabilities
Previously, a client could only bind to a capability immediately after SEAT_ADDED and with a rather awkward API to confirm the capabilities. Change this to allow for dynamic binding of capabilities, i.e. a client calls ei_bind_capability() or ei_unbind_capability() whenever it feels like, causing the respective devices of this capabilty to be added or removed. This allows for clients that are temporarily disinterested in a capability but may require said capability later. The default function takes one capability, a helper for enable/disable multiple capabilities in one go is provided as well. On the protocol, only the "bind" request exists which always represents the currently wanted set of capabilities. Note that the helper functions for multiple capabilities require NULL (not zero) as sentinel, thanks to gcc.
This commit is contained in:
parent
7b760e5950
commit
9d85b1289d
23 changed files with 390 additions and 342 deletions
|
|
@ -74,10 +74,6 @@ message BindSeat {
|
|||
uint32 capabilities = 2;
|
||||
}
|
||||
|
||||
message UnbindSeat {
|
||||
uint32 seatid = 1;
|
||||
}
|
||||
|
||||
message CloseDevice {
|
||||
uint32 deviceid = 1;
|
||||
}
|
||||
|
|
@ -169,7 +165,6 @@ message ClientMessage {
|
|||
ConnectDone connect_done = 2;
|
||||
Disconnect disconnect = 3;
|
||||
BindSeat bind_seat = 4;
|
||||
UnbindSeat unbind_seat = 5;
|
||||
CloseDevice close_device = 6;
|
||||
ConfigureName configure_name = 7;
|
||||
ConfigureCapabilities configure_capabilities = 8;
|
||||
|
|
|
|||
|
|
@ -73,8 +73,6 @@ struct ei {
|
|||
|
||||
enum ei_seat_state {
|
||||
EI_SEAT_STATE_NEW,
|
||||
EI_SEAT_STATE_BOUND,
|
||||
EI_SEAT_STATE_UNBOUND,
|
||||
EI_SEAT_STATE_REMOVED,
|
||||
};
|
||||
|
||||
|
|
@ -87,7 +85,7 @@ struct ei_seat {
|
|||
struct list devices_removed; /* removed from seat but client still has a ref */
|
||||
uint32_t id;
|
||||
uint32_t capabilities;
|
||||
uint32_t capabilities_confirmed;
|
||||
uint32_t capabilities_bound;
|
||||
char *name;
|
||||
};
|
||||
|
||||
|
|
@ -260,9 +258,6 @@ ei_send_property(struct ei *ei, const char *name, const char *value, uint32_t pe
|
|||
int
|
||||
ei_send_seat_bind(struct ei_seat *seat, uint32_t capabilities);
|
||||
|
||||
int
|
||||
ei_send_seat_unbind(struct ei_seat *seat);
|
||||
|
||||
int
|
||||
ei_send_close_device(struct ei_device *device);
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,6 @@ log_wire_message(struct ei *ei, const ClientMessage *msg, int error)
|
|||
MSG_STRING_CASE(CONNECT_DONE);
|
||||
MSG_STRING_CASE(DISCONNECT);
|
||||
MSG_STRING_CASE(BIND_SEAT);
|
||||
MSG_STRING_CASE(UNBIND_SEAT);
|
||||
MSG_STRING_CASE(CLOSE_DEVICE);
|
||||
MSG_STRING_CASE(CONFIGURE_NAME);
|
||||
MSG_STRING_CASE(CONFIGURE_CAPABILITIES);
|
||||
|
|
@ -346,16 +345,6 @@ ei_proto_send_bind_seat(struct ei_seat *seat, uint32_t capabilities)
|
|||
return ei_proto_send_msg(ei_seat_get_context(seat), &msg);
|
||||
}
|
||||
|
||||
static int
|
||||
ei_proto_send_unbind_seat(struct ei_seat *seat)
|
||||
{
|
||||
prepare_msg(UNBIND_SEAT, UnbindSeat, unbind_seat);
|
||||
|
||||
unbind_seat.seatid = seat->id;
|
||||
|
||||
return ei_proto_send_msg(ei_seat_get_context(seat), &msg);
|
||||
}
|
||||
|
||||
static int
|
||||
ei_proto_send_close_device(struct ei_device *device)
|
||||
{
|
||||
|
|
@ -549,7 +538,6 @@ static const struct ei_proto_requests requests = {
|
|||
.connect_done = ei_proto_send_connect_done,
|
||||
.disconnect = ei_proto_send_disconnect,
|
||||
.bind_seat = ei_proto_send_bind_seat,
|
||||
.unbind_seat = ei_proto_send_unbind_seat,
|
||||
.property = ei_proto_send_property,
|
||||
.close_device = ei_proto_send_close_device,
|
||||
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ struct ei_proto_requests {
|
|||
int (*connect)(struct ei *ei);
|
||||
int (*connect_done)(struct ei *ei);
|
||||
int (*disconnect)(struct ei *ei);
|
||||
int (*bind_seat)(struct ei_seat *seat, uint32_t capabilities);
|
||||
int (*unbind_seat)(struct ei_seat *seat);
|
||||
int (*bind_seat)(struct ei_seat *seat, enum ei_device_capability cap);
|
||||
int (*unbind_seat)(struct ei_seat *seat, enum ei_device_capability cap);
|
||||
int (*close_device)(struct ei_device *device);
|
||||
int (*start_emulating)(struct ei_device *device);
|
||||
int (*stop_emulating)(struct ei_device *device);
|
||||
|
|
|
|||
112
src/libei-seat.c
112
src/libei-seat.c
|
|
@ -25,6 +25,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "util-bits.h"
|
||||
#include "util-macros.h"
|
||||
|
|
@ -70,7 +71,7 @@ ei_seat_new(struct ei *ei, uint32_t id, const char *name, uint32_t capabilities)
|
|||
seat->name = xstrdup(name);
|
||||
seat->id = id;
|
||||
seat->capabilities = capabilities;
|
||||
seat->capabilities_confirmed = 0;
|
||||
seat->capabilities_bound = 0;
|
||||
|
||||
list_init(&seat->devices);
|
||||
list_init(&seat->devices_removed);
|
||||
|
|
@ -140,44 +141,107 @@ ei_seat_has_capability(struct ei_seat *seat,
|
|||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_confirm_capability(struct ei_seat *seat, enum ei_device_capability cap)
|
||||
ei_seat_bind_capability(struct ei_seat *seat, enum ei_device_capability cap)
|
||||
{
|
||||
if (seat->state != EI_SEAT_STATE_NEW) {
|
||||
log_bug_client(ei_seat_get_context(seat), "Seat is already bound\n");
|
||||
return;
|
||||
ei_seat_bind_capabilities(seat, cap, NULL);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_known_cap(enum ei_device_capability cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case EI_DEVICE_CAP_POINTER_ABSOLUTE:
|
||||
case EI_DEVICE_CAP_POINTER:
|
||||
case EI_DEVICE_CAP_KEYBOARD:
|
||||
case EI_DEVICE_CAP_TOUCH:
|
||||
return true;
|
||||
}
|
||||
|
||||
flag_set(seat->capabilities_confirmed, cap);
|
||||
return false;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_bind(struct ei_seat *seat)
|
||||
{
|
||||
if (seat->state != EI_SEAT_STATE_NEW) {
|
||||
log_bug_client(ei_seat_get_context(seat), "Seat is already bound\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ei_send_seat_bind(seat, seat->capabilities & seat->capabilities_confirmed);
|
||||
seat->state = EI_SEAT_STATE_BOUND;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_unbind(struct ei_seat *seat)
|
||||
ei_seat_bind_capabilities(struct ei_seat *seat, ...)
|
||||
{
|
||||
switch (seat->state) {
|
||||
case EI_SEAT_STATE_NEW:
|
||||
case EI_SEAT_STATE_BOUND:
|
||||
break;
|
||||
case EI_SEAT_STATE_UNBOUND:
|
||||
case EI_SEAT_STATE_REMOVED:
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t mask = seat->capabilities_bound;
|
||||
enum ei_device_capability cap;
|
||||
|
||||
va_list args;
|
||||
va_start(args, seat);
|
||||
while ((cap = va_arg(args, enum ei_device_capability)) > 0) {
|
||||
if (!is_known_cap(cap))
|
||||
continue;
|
||||
|
||||
flag_set(mask, cap);
|
||||
}
|
||||
|
||||
mask &= seat->capabilities;
|
||||
|
||||
if (seat->capabilities_bound == mask)
|
||||
return;
|
||||
|
||||
seat->capabilities_bound = mask;
|
||||
ei_send_seat_bind(seat, seat->capabilities_bound);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_unbind_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap)
|
||||
{
|
||||
switch (seat->state) {
|
||||
case EI_SEAT_STATE_NEW:
|
||||
break;
|
||||
case EI_SEAT_STATE_REMOVED:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!flag_is_set(seat->capabilities_bound, cap))
|
||||
return;
|
||||
|
||||
flag_clear(seat->capabilities_bound, cap);
|
||||
|
||||
struct ei_device *device;
|
||||
list_for_each(device, &seat->devices, link) {
|
||||
ei_device_close(device);
|
||||
if (ei_device_has_capability(device, cap))
|
||||
ei_device_close(device);
|
||||
}
|
||||
ei_send_seat_unbind(seat);
|
||||
seat->state = EI_SEAT_STATE_UNBOUND;
|
||||
ei_send_seat_bind(seat, seat->capabilities_bound);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_unbind_capabilities(struct ei_seat *seat, ...)
|
||||
{
|
||||
switch (seat->state) {
|
||||
case EI_SEAT_STATE_NEW:
|
||||
break;
|
||||
case EI_SEAT_STATE_REMOVED:
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t mask = 0;
|
||||
enum ei_device_capability cap;
|
||||
|
||||
va_list args;
|
||||
va_start(args, seat);
|
||||
while ((cap = va_arg(args, enum ei_device_capability)) > 0) {
|
||||
if (!is_known_cap(cap))
|
||||
continue;
|
||||
|
||||
flag_set(mask, cap);
|
||||
}
|
||||
|
||||
mask = seat->capabilities & ~mask;
|
||||
|
||||
if (seat->capabilities_bound == mask)
|
||||
return;
|
||||
|
||||
seat->capabilities_bound = mask;
|
||||
ei_send_seat_bind(seat, seat->capabilities_bound);
|
||||
}
|
||||
|
|
|
|||
14
src/libei.c
14
src/libei.c
|
|
@ -826,20 +826,6 @@ ei_send_seat_bind(struct ei_seat *seat, uint32_t capabilities)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_seat_unbind(struct ei_seat *seat)
|
||||
{
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
|
||||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
int rc = ei->requests->unbind_seat(seat);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_frame(struct ei_device *device)
|
||||
{
|
||||
|
|
|
|||
58
src/libei.h
58
src/libei.h
|
|
@ -655,47 +655,51 @@ ei_seat_has_capability(struct ei_seat *seat,
|
|||
enum ei_device_capability cap);
|
||||
|
||||
/**
|
||||
* Confirm a capability from this seat before calling ei_seat_bind().
|
||||
* Bind this client to the given seat capability. Once bound, the server may
|
||||
* create devices for the requested capability and send the respective @ref
|
||||
* EI_EVENT_DEVICE_ADDED events. To undo, call ei_seat_unbind_capability().
|
||||
*
|
||||
* A client must call this function for every capability on the seat it wants
|
||||
* to receive devices for. Only devices with one or more supported
|
||||
* capabilities will be added to this client.
|
||||
* Note that binding to a capability does not guarantee a device for that
|
||||
* capability becomes available. Devices may be added and removed at any time.
|
||||
*
|
||||
* Calling this function for a capability that ei_seat_has_capability()
|
||||
* returns false for is a noop and permitted.
|
||||
* It is an application bug to call this function for a capability already
|
||||
* bound - call ei_seat_unbind_capability() first.
|
||||
*
|
||||
* This function has no effect if called after ei_seat_bind().
|
||||
* Calling this function for a capability that does not exist on the seat is
|
||||
* permitted (but obviously a noop)
|
||||
*/
|
||||
void
|
||||
ei_seat_confirm_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap);
|
||||
ei_seat_bind_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap);
|
||||
|
||||
/**
|
||||
* Bind this client to the given seat for the confirmed seat's capabilities.
|
||||
* This function can only be called once per seat. Once bound, the server will
|
||||
* create devices for the seat's capabilities and send the respective @ref
|
||||
* EI_EVENT_DEVICE_ADDED events.
|
||||
*
|
||||
* A client must call ei_seat_confirm_capability() before calling
|
||||
* ei_seat_bind().
|
||||
*
|
||||
* Devices may be added and removed at any time.
|
||||
* Same as ei_seat_bind_capability() but takes multiple capabilities,
|
||||
* terminated by NULL.
|
||||
*/
|
||||
__attribute__((sentinel))
|
||||
void
|
||||
ei_seat_bind(struct ei_seat *seat);
|
||||
ei_seat_bind_capabilities(struct ei_seat *seat, ...);
|
||||
|
||||
/**
|
||||
* Unbind a seat and remove it from the server.
|
||||
* Unbind a seat's capability. This function indicates the the application is
|
||||
* no longer interested in devices with the given capability.
|
||||
*
|
||||
* If called on a seat immediately after @ref EI_EVENT_SEAT_ADDED, this
|
||||
* function indicates that the client is not interested in this seat.
|
||||
* If called on a seat after ei_seat_bind(), this function implicitly calls
|
||||
* ei_device_close() on all devices for this seat.
|
||||
*
|
||||
* The server responds with an @ref EI_EVENT_SEAT_REMOVED event.
|
||||
* If any devices with the given capability are present, libei automatically
|
||||
* calls ei_device_close() on those devices (and thus the server will send
|
||||
* @ref EI_EVENT_DEVICE_REMOVED for those devices).
|
||||
*/
|
||||
void
|
||||
ei_seat_unbind(struct ei_seat *seat);
|
||||
ei_seat_unbind_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap);
|
||||
|
||||
/**
|
||||
* Same as ei_seat_unbind_capability() but takes multiple capabilities, terminated
|
||||
* by NULL.
|
||||
*/
|
||||
__attribute__((sentinel))
|
||||
void
|
||||
ei_seat_unbind_capabilities(struct ei_seat *seat, ...);
|
||||
|
||||
|
||||
struct ei_seat *
|
||||
ei_seat_ref(struct ei_seat *seat);
|
||||
|
|
|
|||
|
|
@ -263,17 +263,6 @@ client_msg_bind_seat(struct eis_client *client, uint32_t seatid, uint32_t caps)
|
|||
return seat ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_unbind_seat(struct eis_client *client, uint32_t seatid)
|
||||
{
|
||||
struct eis_seat *seat = eis_client_find_seat(client, seatid);
|
||||
|
||||
if (seat)
|
||||
eis_seat_unbind(seat);
|
||||
|
||||
return seat ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
#define DISCONNECT_IF_ACTIVE_CONTEXT(client_) do { \
|
||||
if (!(client_)->is_active) { \
|
||||
struct eis *_ctx = eis_client_get_context(client_); \
|
||||
|
|
@ -556,7 +545,6 @@ static const struct eis_proto_interface intf_state_connected = {
|
|||
.disconnect = client_msg_disconnect,
|
||||
.property = client_msg_property_with_event,
|
||||
.bind_seat = client_msg_bind_seat,
|
||||
.unbind_seat = client_msg_unbind_seat,
|
||||
.close_device = client_msg_close_device,
|
||||
.configure_name = client_msg_configure_name,
|
||||
.configure_capabilities = client_msg_configure_capabilities,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ eis_event_destroy(struct eis_event *event)
|
|||
case EIS_EVENT_CLIENT_CONNECT:
|
||||
case EIS_EVENT_CLIENT_DISCONNECT:
|
||||
case EIS_EVENT_SEAT_BIND:
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
case EIS_EVENT_DEVICE_START_EMULATING:
|
||||
case EIS_EVENT_DEVICE_STOP_EMULATING:
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ enum eis_seat_state {
|
|||
EIS_SEAT_STATE_PENDING,
|
||||
EIS_SEAT_STATE_ADDED,
|
||||
EIS_SEAT_STATE_BOUND,
|
||||
EIS_SEAT_STATE_UNBOUND,
|
||||
EIS_SEAT_STATE_REMOVED_INTERNALLY, /* Removed internally but eis_seat_remove() may be called */
|
||||
EIS_SEAT_STATE_REMOVED, /* Removed but still waiting for some devices to be removed */
|
||||
EIS_SEAT_STATE_DEAD, /* Removed from our list */
|
||||
|
|
@ -270,9 +269,6 @@ eis_client_keyboard_modifiers(struct eis_client *client, struct eis_device *devi
|
|||
void
|
||||
eis_seat_bind(struct eis_seat *seat, uint32_t cap);
|
||||
|
||||
void
|
||||
eis_seat_unbind(struct eis_seat *seat);
|
||||
|
||||
void
|
||||
eis_seat_drop(struct eis_seat *seat);
|
||||
|
||||
|
|
@ -365,9 +361,6 @@ eis_queue_property_event(struct eis_client *client, const char *name,
|
|||
void
|
||||
eis_queue_seat_bind_event(struct eis_seat *seat, uint32_t capabilities);
|
||||
|
||||
void
|
||||
eis_queue_seat_unbind_event(struct eis_seat *seat);
|
||||
|
||||
void
|
||||
eis_queue_device_closed_event(struct eis_device *device);
|
||||
|
||||
|
|
|
|||
|
|
@ -521,10 +521,6 @@ eis_proto_handle_message(struct eis_client *client,
|
|||
proto->bind_seat->seatid,
|
||||
proto->bind_seat->capabilities);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_UNBIND_SEAT:
|
||||
rc = call(unbind_seat, client,
|
||||
proto->bind_seat->seatid);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CLOSE_DEVICE:
|
||||
rc = call(close_device, client,
|
||||
proto->close_device->deviceid);
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ struct eis_proto_interface {
|
|||
int (*connect)(struct eis_client *client, const char *name, bool is_active);
|
||||
int (*connect_done)(struct eis_client *client);
|
||||
int (*disconnect)(struct eis_client *client);
|
||||
int (*bind_seat)(struct eis_client *client, uint32_t seatid, uint32_t capabilities);
|
||||
int (*unbind_seat)(struct eis_client *client, uint32_t seatid);
|
||||
int (*bind_seat)(struct eis_client *client, uint32_t seatid, enum eis_device_capability cap);
|
||||
int (*unbind_seat)(struct eis_client *client, uint32_t seatid, enum eis_device_capability cap);
|
||||
int (*close_device)(struct eis_client *client, uint32_t deviceid);
|
||||
int (*configure_name)(struct eis_client *client, const char *name);
|
||||
int (*configure_capabilities)(struct eis_client *client, uint32_t allow);
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ eis_seat_add(struct eis_seat *seat)
|
|||
break;
|
||||
case EIS_SEAT_STATE_ADDED:
|
||||
case EIS_SEAT_STATE_BOUND:
|
||||
case EIS_SEAT_STATE_UNBOUND:
|
||||
case EIS_SEAT_STATE_REMOVED:
|
||||
case EIS_SEAT_STATE_REMOVED_INTERNALLY:
|
||||
case EIS_SEAT_STATE_DEAD:
|
||||
|
|
@ -109,10 +108,9 @@ eis_seat_bind(struct eis_seat *seat, uint32_t caps)
|
|||
|
||||
switch (seat->state) {
|
||||
case EIS_SEAT_STATE_ADDED:
|
||||
case EIS_SEAT_STATE_BOUND:
|
||||
break;
|
||||
case EIS_SEAT_STATE_PENDING:
|
||||
case EIS_SEAT_STATE_BOUND:
|
||||
case EIS_SEAT_STATE_UNBOUND:
|
||||
case EIS_SEAT_STATE_REMOVED:
|
||||
case EIS_SEAT_STATE_REMOVED_INTERNALLY:
|
||||
case EIS_SEAT_STATE_DEAD:
|
||||
|
|
@ -121,39 +119,17 @@ eis_seat_bind(struct eis_seat *seat, uint32_t caps)
|
|||
return;
|
||||
}
|
||||
|
||||
caps &= seat->capabilities_mask;
|
||||
|
||||
seat->state = EIS_SEAT_STATE_BOUND;
|
||||
seat->capabilities_mask &= caps;
|
||||
eis_queue_seat_bind_event(seat, caps);
|
||||
}
|
||||
|
||||
void
|
||||
eis_seat_unbind(struct eis_seat *seat)
|
||||
{
|
||||
struct eis_client *client = eis_seat_get_client(seat);
|
||||
|
||||
switch (seat->state) {
|
||||
case EIS_SEAT_STATE_BOUND:
|
||||
break;
|
||||
case EIS_SEAT_STATE_ADDED:
|
||||
case EIS_SEAT_STATE_PENDING:
|
||||
case EIS_SEAT_STATE_UNBOUND:
|
||||
case EIS_SEAT_STATE_REMOVED:
|
||||
case EIS_SEAT_STATE_REMOVED_INTERNALLY:
|
||||
case EIS_SEAT_STATE_DEAD:
|
||||
log_bug_client(eis_client_get_context(client),
|
||||
"%s: seat cannot be unbound\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
seat->state = EIS_SEAT_STATE_UNBOUND;
|
||||
eis_queue_seat_unbind_event(seat);
|
||||
}
|
||||
|
||||
void
|
||||
eis_seat_drop(struct eis_seat *seat)
|
||||
{
|
||||
if (seat->state == EIS_SEAT_STATE_BOUND)
|
||||
eis_seat_unbind(seat);
|
||||
eis_seat_bind(seat, 0);
|
||||
|
||||
struct eis_device *d;
|
||||
list_for_each_safe(d, &seat->devices, link) {
|
||||
|
|
@ -176,7 +152,6 @@ eis_seat_remove(struct eis_seat *seat)
|
|||
case EIS_SEAT_STATE_PENDING:
|
||||
case EIS_SEAT_STATE_ADDED:
|
||||
case EIS_SEAT_STATE_BOUND:
|
||||
case EIS_SEAT_STATE_UNBOUND:
|
||||
eis_seat_drop(s);
|
||||
s->state = EIS_SEAT_STATE_REMOVED;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ eis_event_type_to_string(enum eis_event_type type)
|
|||
CASE_RETURN_STRING(EIS_EVENT_CLIENT_DISCONNECT);
|
||||
CASE_RETURN_STRING(EIS_EVENT_CLIENT_PROPERTY);
|
||||
CASE_RETURN_STRING(EIS_EVENT_SEAT_BIND);
|
||||
CASE_RETURN_STRING(EIS_EVENT_SEAT_UNBIND);
|
||||
CASE_RETURN_STRING(EIS_EVENT_DEVICE_CLOSED);
|
||||
CASE_RETURN_STRING(EIS_EVENT_DEVICE_START_EMULATING);
|
||||
CASE_RETURN_STRING(EIS_EVENT_DEVICE_STOP_EMULATING);
|
||||
|
|
@ -183,14 +182,6 @@ eis_queue_seat_bind_event(struct eis_seat *seat, uint32_t capabilities)
|
|||
eis_queue_event(e);
|
||||
}
|
||||
|
||||
void
|
||||
eis_queue_seat_unbind_event(struct eis_seat *seat)
|
||||
{
|
||||
struct eis_event *e = eis_event_new_for_seat(seat);
|
||||
e->type = EIS_EVENT_SEAT_UNBIND;
|
||||
eis_queue_event(e);
|
||||
}
|
||||
|
||||
void
|
||||
eis_queue_device_closed_event(struct eis_device *device)
|
||||
{
|
||||
|
|
|
|||
13
src/libeis.h
13
src/libeis.h
|
|
@ -136,16 +136,12 @@ enum eis_event_type {
|
|||
EIS_EVENT_CLIENT_PROPERTY,
|
||||
|
||||
/**
|
||||
* The client wants to bind to a seat. Devices associated with this
|
||||
* seat should be sent to the client.
|
||||
* The client wants to bind or unbind a capability on this seat.
|
||||
* Devices associated with this seat should be sent to the client or
|
||||
* removed if the capability is no longer bound
|
||||
*/
|
||||
EIS_EVENT_SEAT_BIND,
|
||||
|
||||
/**
|
||||
* The client wants to unbind from this seat.
|
||||
*/
|
||||
EIS_EVENT_SEAT_UNBIND,
|
||||
|
||||
/**
|
||||
* The client no longer listens to events from this device. The caller
|
||||
* should released resources associated with this device.
|
||||
|
|
@ -952,6 +948,9 @@ eis_touch_get_device(struct eis_touch *touch);
|
|||
/**
|
||||
* For an event of type @ref EIS_EVENT_SEAT_BIND, return the capabilities
|
||||
* requested by the client.
|
||||
*
|
||||
* This is the set of *all* capabilities bound by the client as of this event,
|
||||
* not just the changed ones.
|
||||
*/
|
||||
bool
|
||||
eis_event_seat_has_capability(struct eis_event *event, enum eis_device_capability cap);
|
||||
|
|
|
|||
|
|
@ -391,7 +391,6 @@ peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior)
|
|||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT:
|
||||
case PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT:
|
||||
case PECK_EIS_BEHAVIOR_HANDLE_CLOSE_DEVICE:
|
||||
case PECK_EIS_BEHAVIOR_HANDLE_FRAME:
|
||||
case PECK_EIS_BEHAVIOR_HANDLE_START_EMULATING:
|
||||
|
|
@ -496,9 +495,6 @@ peck_eis_create_pointer(struct peck *peck, struct eis_seat *seat, const char *na
|
|||
eis_device_configure_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_pointer)
|
||||
peck->eis_pointer = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
@ -516,9 +512,6 @@ peck_eis_create_pointer_absolute(struct peck *peck, struct eis_seat *seat, const
|
|||
eis_region_add(region);
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_abs)
|
||||
peck->eis_abs = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
@ -531,9 +524,6 @@ peck_eis_create_keyboard(struct peck *peck, struct eis_seat *seat, const char *n
|
|||
eis_device_configure_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_keyboard)
|
||||
peck->eis_keyboard = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
@ -551,9 +541,6 @@ peck_eis_create_touch(struct peck *peck, struct eis_seat *seat, const char *name
|
|||
eis_region_add(region);
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_touch)
|
||||
peck->eis_touch = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
@ -564,47 +551,88 @@ peck_handle_eis_seat_bind(struct peck *peck, struct eis_event *e)
|
|||
|
||||
log_debug(peck, "EIS binding seat: '%s'\n", eis_seat_get_name(seat));
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_POINTER)) {
|
||||
log_debug(peck, "EIS creating default pointer\n");
|
||||
_unref_(eis_device) *ptr = peck_eis_create_pointer(peck, seat, "default pointer");
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_POINTER) && !peck->eis_pointer) {
|
||||
log_debug(peck, "EIS creating default pointer\n");
|
||||
_unref_(eis_device) *ptr = peck_eis_create_pointer(peck, seat, "default pointer");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(ptr);
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(ptr);
|
||||
|
||||
peck->eis_pointer = eis_device_ref(ptr);
|
||||
}
|
||||
} else {
|
||||
if (peck->eis_pointer) {
|
||||
log_debug(peck, "EIS removing default pointer\n");
|
||||
|
||||
_unref_(eis_device) *ptr = steal(&peck->eis_pointer);
|
||||
eis_device_remove(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE)) {
|
||||
log_debug(peck, "EIS creating default abs pointer\n");
|
||||
_unref_(eis_device) *abs = peck_eis_create_pointer_absolute(peck, seat, "default abs");
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE) && !peck->eis_abs) {
|
||||
log_debug(peck, "EIS creating default abs pointer\n");
|
||||
_unref_(eis_device) *abs = peck_eis_create_pointer_absolute(peck, seat, "default abs");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(abs);
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(abs);
|
||||
|
||||
peck->eis_abs = eis_device_ref(abs);
|
||||
}
|
||||
} else {
|
||||
if (peck->eis_abs) {
|
||||
log_debug(peck, "EIS removing default abs\n");
|
||||
|
||||
_unref_(eis_device) *abs = steal(&peck->eis_abs);
|
||||
eis_device_remove(abs);
|
||||
}
|
||||
}
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_KEYBOARD) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_KEYBOARD)) {
|
||||
log_debug(peck, "EIS creating default keyboard\n");
|
||||
_unref_(eis_device) *kbd = peck_eis_create_keyboard(peck, seat, "default keyboard");
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_KEYBOARD)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_KEYBOARD) && !peck->eis_keyboard) {
|
||||
log_debug(peck, "EIS creating default keyboard\n");
|
||||
_unref_(eis_device) *kbd = peck_eis_create_keyboard(peck, seat, "default keyboard");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(kbd);
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(kbd);
|
||||
|
||||
peck->eis_keyboard = eis_device_ref(kbd);
|
||||
}
|
||||
} else {
|
||||
if (peck->eis_keyboard) {
|
||||
log_debug(peck, "EIS removing default pointer\n");
|
||||
|
||||
_unref_(eis_device) *kbd = steal(&peck->eis_keyboard);
|
||||
eis_device_remove(kbd);
|
||||
}
|
||||
}
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_TOUCH) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_TOUCH)) {
|
||||
log_debug(peck, "EIS creating default touch\n");
|
||||
_unref_(eis_device) *touch = peck_eis_create_touch(peck, seat, "default touch");
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_TOUCH)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_TOUCH) && !peck->eis_touch) {
|
||||
log_debug(peck, "EIS creating default touch\n");
|
||||
_unref_(eis_device) *touch = peck_eis_create_touch(peck, seat, "default touch");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(touch);
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(touch);
|
||||
|
||||
peck->eis_touch = eis_device_ref(touch);
|
||||
}
|
||||
} else {
|
||||
if (peck->eis_touch) {
|
||||
log_debug(peck, "EIS removing default touch\n");
|
||||
|
||||
_unref_(eis_device) *touch = steal(&peck->eis_touch);
|
||||
eis_device_remove(touch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
peck_handle_eis_seat_unbind(struct peck *peck, struct eis_seat *seat)
|
||||
{
|
||||
eis_seat_remove(seat);
|
||||
/* Removing all caps means removing the seat */
|
||||
if (!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER) &&
|
||||
!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_KEYBOARD) &&
|
||||
!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_TOUCH))
|
||||
eis_seat_remove(seat);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -651,12 +679,6 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
else
|
||||
process_event = tristate_no;
|
||||
break;
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT))
|
||||
process_event = tristate_yes;
|
||||
else
|
||||
process_event = tristate_no;
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_HANDLE_CLOSE_DEVICE))
|
||||
process_event = tristate_yes;
|
||||
|
|
@ -705,9 +727,6 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
case EIS_EVENT_SEAT_BIND:
|
||||
peck_handle_eis_seat_bind(peck, e);
|
||||
break;
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
peck_handle_eis_seat_unbind(peck, eis_event_get_seat(e));
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
peck_eis_device_remove(peck, eis_event_get_device(e));
|
||||
break;
|
||||
|
|
@ -814,11 +833,11 @@ _peck_dispatch_ei(struct peck *peck, int lineno)
|
|||
munit_assert_ptr_null(peck->ei_seat);
|
||||
peck->ei_seat = ei_seat_ref(seat);
|
||||
log_debug(peck, "default seat: %s\n", ei_seat_get_name(peck->ei_seat));
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capabilities(seat,
|
||||
EI_DEVICE_CAP_POINTER,
|
||||
EI_DEVICE_CAP_POINTER_ABSOLUTE,
|
||||
EI_DEVICE_CAP_KEYBOARD,
|
||||
EI_DEVICE_CAP_TOUCH, NULL);
|
||||
break;
|
||||
}
|
||||
case EI_EVENT_DEVICE_ADDED:
|
||||
|
|
@ -1080,7 +1099,6 @@ peck_eis_event_type_name(enum eis_event_type type)
|
|||
CASE_STRING(CLIENT_DISCONNECT);
|
||||
CASE_STRING(CLIENT_PROPERTY);
|
||||
CASE_STRING(SEAT_BIND);
|
||||
CASE_STRING(SEAT_UNBIND);
|
||||
CASE_STRING(DEVICE_CLOSED);
|
||||
CASE_STRING(DEVICE_START_EMULATING);
|
||||
CASE_STRING(DEVICE_STOP_EMULATING);
|
||||
|
|
|
|||
|
|
@ -75,11 +75,6 @@ enum peck_eis_behavior {
|
|||
*/
|
||||
PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT,
|
||||
|
||||
/**
|
||||
* Handle the seat unbind request
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT,
|
||||
|
||||
/**
|
||||
* Handle the device close. This behavior is enabled as part of
|
||||
* PECK_EIS_BEHAVIOR_ACCEPT_ALL.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ MUNIT_TEST(test_ei_seat_bind_unbind)
|
|||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -45,11 +44,8 @@ MUNIT_TEST(test_ei_seat_bind_unbind)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
seat = ei_seat_ref(ei_event_get_seat(event));
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
}
|
||||
|
||||
/* server has the Bind event now and creates devices */
|
||||
|
|
@ -64,7 +60,8 @@ MUNIT_TEST(test_ei_seat_bind_unbind)
|
|||
dev1 = ei_device_ref(ei_event_get_device(e1));
|
||||
dev2 = ei_device_ref(ei_event_get_device(e2));
|
||||
|
||||
ei_seat_unbind(seat);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
}
|
||||
|
||||
/* Dispatch, server is aware of the ei_seat_unbind() */
|
||||
|
|
@ -97,7 +94,6 @@ MUNIT_TEST(test_ei_seat_bind_unbind_noref)
|
|||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -105,11 +101,8 @@ MUNIT_TEST(test_ei_seat_bind_unbind_noref)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
seat = ei_seat_ref(ei_event_get_seat(event));
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
}
|
||||
|
||||
/* server has the Bind event now and creates devices */
|
||||
|
|
@ -126,7 +119,8 @@ MUNIT_TEST(test_ei_seat_bind_unbind_noref)
|
|||
* one ref inside libei for this seat, so this tests ensures
|
||||
* we don't rely on a caller ref to keep everything alive. */
|
||||
ei_seat_unref(seat);
|
||||
ei_seat_unbind(seat);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
}
|
||||
|
||||
/* Dispatch, server is aware of the ei_seat_unbind() */
|
||||
|
|
@ -149,7 +143,6 @@ MUNIT_TEST(test_ei_seat_bind_unbind_immediately)
|
|||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -157,12 +150,10 @@ MUNIT_TEST(test_ei_seat_bind_unbind_immediately)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
seat = ei_event_get_seat(event);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_unbind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ MUNIT_TEST(test_ei_disconnect_after_bind_before_received)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(event);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
/* We have *not* called eis_dispatch, so the seat bind hasn't been
|
||||
|
|
@ -678,7 +678,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_before_received)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(event);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
/* Disconnect before the server can process the bind event */
|
||||
peck_drop_ei(peck);
|
||||
ei_unref(ei);
|
||||
|
|
@ -692,7 +692,11 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_before_received)
|
|||
_unref_(eis_event) *bind =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
_unref_(eis_event) *unbind =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_TOUCH));
|
||||
_unref_(eis_event) *disconnect =
|
||||
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);
|
||||
}
|
||||
|
|
@ -713,7 +717,7 @@ MUNIT_TEST(test_ei_disconnect_after_bind_after_received)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(event);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
/* Receive the Bind event but don't actually add any devices,
|
||||
|
|
@ -749,7 +753,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_after_received)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(event);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
/* Make sure server sees Bind, then disconnect from server */
|
||||
|
|
@ -766,7 +770,11 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_after_received)
|
|||
_unref_(eis_event) *bind =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
_unref_(eis_event) *unbind =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_TOUCH));
|
||||
_unref_(eis_event) *disconnect =
|
||||
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);
|
||||
}
|
||||
|
|
@ -787,7 +795,7 @@ MUNIT_TEST(test_ei_disconnect_after_unbind_before_received)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
seat = ei_seat_ref(ei_event_get_seat(event));
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
|
|
@ -796,7 +804,7 @@ MUNIT_TEST(test_ei_disconnect_after_unbind_before_received)
|
|||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
ei_seat_unbind(seat);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
/* No server dispatch here so the server isn't aware of the
|
||||
|
|
@ -831,14 +839,14 @@ MUNIT_TEST(test_ei_disconnect_after_unbind_after_received)
|
|||
with_client(peck) {
|
||||
_unref_(ei_event) *event = peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
seat = ei_seat_ref(ei_event_get_seat(event));
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
/* server has the Bind event now */
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
ei_seat_unbind(seat);
|
||||
ei_seat_unbind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
}
|
||||
|
||||
/* Dispatch, server is aware of the ei_seat_unbind() */
|
||||
|
|
@ -929,7 +937,11 @@ MUNIT_TEST(test_xdotool_rel_motion)
|
|||
_unref_(eis_event) *close =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_CLOSED);
|
||||
_unref_(eis_event) *unbind =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_UNBIND);
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_event_seat_has_capability(unbind, EIS_DEVICE_CAP_TOUCH));
|
||||
_unref_(eis_event) *disconnect =
|
||||
peck_eis_next_event(eis, EIS_EVENT_CLIENT_DISCONNECT);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,25 +81,39 @@ MUNIT_TEST(eistest_cliend_bind_all_caps)
|
|||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
struct ei_seat *seat = peck_ei_get_default_seat(peck);
|
||||
ei_seat_bind(seat);
|
||||
_unref_(ei_event) *seat_added =
|
||||
peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(seat_added);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *event =
|
||||
_unref_(eis_event) *bind_ptr =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_ptr, EIS_DEVICE_CAP_POINTER));
|
||||
|
||||
/* Our default seat has all caps */
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_TOUCH));
|
||||
_unref_(eis_event) *bind_abs =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_abs, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
|
||||
_unref_(eis_event) *bind_kbd =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_KEYBOARD));
|
||||
|
||||
_unref_(eis_event) *bind_touch =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_TOUCH));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
|
|
@ -129,34 +143,28 @@ MUNIT_TEST(eistest_cliend_bind_some_caps)
|
|||
_unref_(ei_event) *event =
|
||||
peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(event);
|
||||
munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_true(ei_seat_has_capability(seat, EI_DEVICE_CAP_TOUCH));
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_confirm_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_bind(seat);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_bind_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *event =
|
||||
_unref_(eis_event) *bind_kbd =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
|
||||
/* Our default seat has all caps */
|
||||
munit_assert_false(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_TOUCH));
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_false(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_TOUCH));
|
||||
|
||||
/* Now that the client bound the seat with a subset, our
|
||||
eis seat has a subset too */
|
||||
struct eis_seat *seat = peck_eis_get_default_seat(peck);
|
||||
munit_assert_false(eis_seat_has_capability(seat, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_true(eis_seat_has_capability(seat, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(eis_seat_has_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_seat_has_capability(seat, EIS_DEVICE_CAP_TOUCH));
|
||||
_unref_(eis_event) *bind_touch =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_false(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_true(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_TOUCH));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
|
|
|
|||
|
|
@ -312,11 +312,10 @@ int main(int argc, char **argv)
|
|||
}
|
||||
default_seat = ei_seat_ref(ei_event_get_seat(e));
|
||||
colorprint("seat added: %s\n", ei_seat_get_name(default_seat));
|
||||
ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_confirm_capability(default_seat, EI_DEVICE_CAP_TOUCH);
|
||||
ei_seat_bind(default_seat);
|
||||
ei_seat_bind_capability(default_seat, EI_DEVICE_CAP_POINTER);
|
||||
ei_seat_bind_capability(default_seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_bind_capability(default_seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
ei_seat_bind_capability(default_seat, EI_DEVICE_CAP_TOUCH);
|
||||
break;
|
||||
}
|
||||
case EI_EVENT_SEAT_REMOVED:
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ eis_demo_server_uinput_handle_event(struct eis_demo_server *server,
|
|||
{
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
|
||||
/* FIXME: does not handle device removal */
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER)) {
|
||||
struct eis_device *device = NULL;
|
||||
int rc = create_mouse(server, seat, &device);
|
||||
|
|
@ -175,9 +177,6 @@ eis_demo_server_uinput_handle_event(struct eis_demo_server *server,
|
|||
* demo-server so we can just ignore that */
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
/* FIXME */
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,74 @@ handle_key(struct eis_demo_server *server, uint32_t keycode, bool is_press)
|
|||
keysym_name);
|
||||
}
|
||||
|
||||
static struct eis_device *
|
||||
add_device(struct eis_demo_server *server, struct eis_client *client,
|
||||
struct eis_seat *seat, enum eis_device_capability cap)
|
||||
{
|
||||
struct eis_device *device = NULL;
|
||||
switch (cap) {
|
||||
case EIS_DEVICE_CAP_POINTER:
|
||||
{
|
||||
struct eis_device *ptr = eis_seat_new_device(seat);
|
||||
eis_device_configure_name(ptr, "test pointer");
|
||||
eis_device_configure_capability(ptr, EIS_DEVICE_CAP_POINTER);
|
||||
_unref_(eis_region) *rel_region = eis_device_new_region(ptr);
|
||||
eis_region_set_size(rel_region, 1920, 1080);
|
||||
eis_region_set_offset(rel_region, 0, 0);
|
||||
eis_region_add(rel_region);
|
||||
colorprint("Creating pointer device %s for %s\n", eis_device_get_name(ptr),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(ptr);
|
||||
eis_device_resume(ptr);
|
||||
if (!eis_client_is_active(client))
|
||||
eis_device_start_emulating(ptr);
|
||||
device = steal(&ptr);
|
||||
break;
|
||||
}
|
||||
case EIS_DEVICE_CAP_POINTER_ABSOLUTE:
|
||||
{
|
||||
struct eis_device *abs = eis_seat_new_device(seat);
|
||||
eis_device_configure_name(abs, "test abs pointer");
|
||||
eis_device_configure_capability(abs, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
_unref_(eis_region) *region = eis_device_new_region(abs);
|
||||
eis_region_set_size(region, 1920, 1080);
|
||||
eis_region_set_offset(region, 0, 0);
|
||||
eis_region_add(region);
|
||||
colorprint("Creating abs pointer device %s for %s\n", eis_device_get_name(abs),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(abs);
|
||||
eis_device_resume(abs);
|
||||
if (!eis_client_is_active(client))
|
||||
eis_device_start_emulating(abs);
|
||||
device = steal(&abs);
|
||||
break;
|
||||
}
|
||||
case EIS_DEVICE_CAP_KEYBOARD:
|
||||
{
|
||||
struct eis_device *kbd = eis_seat_new_device(seat);
|
||||
eis_device_configure_name(kbd, "test keyboard");
|
||||
eis_device_configure_capability(kbd, EIS_DEVICE_CAP_KEYBOARD);
|
||||
if (server->layout)
|
||||
setup_keymap(server, kbd);
|
||||
colorprint("Creating keyboard device %s for %s\n", eis_device_get_name(kbd),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(kbd);
|
||||
eis_device_resume(kbd);
|
||||
if (!eis_client_is_active(client))
|
||||
eis_device_start_emulating(kbd);
|
||||
device = steal(&kbd);
|
||||
break;
|
||||
}
|
||||
case EIS_DEVICE_CAP_TOUCH:
|
||||
assert(!"Not implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The simplest event handler. Connect any client and any device and just
|
||||
* printf the events as the come in. This is an incomplete implementation,
|
||||
|
|
@ -249,60 +317,45 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
|
|||
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
|
||||
struct eis_device *ptr = eis_seat_new_device(seat);
|
||||
eis_device_configure_name(ptr, "test pointer");
|
||||
eis_device_configure_capability(ptr, EIS_DEVICE_CAP_POINTER);
|
||||
_unref_(eis_region) *rel_region = eis_device_new_region(ptr);
|
||||
eis_region_set_size(rel_region, 1920, 1080);
|
||||
eis_region_set_offset(rel_region, 0, 0);
|
||||
eis_region_add(rel_region);
|
||||
colorprint("Creating pointer device %s for %s\n", eis_device_get_name(ptr),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(ptr);
|
||||
eis_device_resume(ptr);
|
||||
if (!eis_client_is_active(client))
|
||||
eis_device_start_emulating(ptr);
|
||||
democlient->ptr = steal(&ptr);
|
||||
|
||||
|
||||
struct eis_device *kbd = eis_seat_new_device(seat);
|
||||
eis_device_configure_name(kbd, "test keyboard");
|
||||
eis_device_configure_capability(kbd, EIS_DEVICE_CAP_KEYBOARD);
|
||||
if (server->layout)
|
||||
setup_keymap(server, kbd);
|
||||
colorprint("Creating keyboard device %s for %s\n", eis_device_get_name(kbd),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(kbd);
|
||||
eis_device_resume(kbd);
|
||||
if (!eis_client_is_active(client))
|
||||
eis_device_start_emulating(kbd);
|
||||
democlient->kbd = steal(&kbd);
|
||||
|
||||
|
||||
struct eis_device *abs = eis_seat_new_device(seat);
|
||||
eis_device_configure_name(abs, "test abs pointer");
|
||||
eis_device_configure_capability(abs, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
_unref_(eis_region) *region = eis_device_new_region(abs);
|
||||
eis_region_set_size(region, 1920, 1080);
|
||||
eis_region_set_offset(region, 0, 0);
|
||||
eis_region_add(region);
|
||||
colorprint("Creating abs pointer device %s for %s\n", eis_device_get_name(abs),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(abs);
|
||||
eis_device_resume(abs);
|
||||
if (!eis_client_is_active(client))
|
||||
eis_device_start_emulating(abs);
|
||||
democlient->abs = steal(&abs);
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER)) {
|
||||
if (!democlient->ptr)
|
||||
democlient->ptr = add_device(server, client, seat, EIS_DEVICE_CAP_POINTER);
|
||||
} else {
|
||||
if (democlient->ptr) {
|
||||
eis_device_remove(democlient->ptr);
|
||||
democlient->ptr = eis_device_unref(democlient->ptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
{
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
/* FIXME: remove all devices? we need a devices_foreach
|
||||
* function on the eis seat */
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
if (!democlient->abs)
|
||||
democlient->abs = add_device(server, client, seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
} else {
|
||||
if (democlient->abs) {
|
||||
eis_device_remove(democlient->abs);
|
||||
democlient->abs = eis_device_unref(democlient->abs);
|
||||
}
|
||||
}
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER)) {
|
||||
if (!democlient->kbd)
|
||||
democlient->kbd = add_device(server, client, seat, EIS_DEVICE_CAP_POINTER);
|
||||
} else {
|
||||
if (democlient->kbd) {
|
||||
eis_device_remove(democlient->kbd);
|
||||
democlient->kbd = eis_device_unref(democlient->kbd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Special "Feature", if all caps are unbound remove the seat.
|
||||
* This is a demo server after all, so let's demo this. */
|
||||
if (!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER) &&
|
||||
!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
!eis_event_seat_has_capability(e, EIS_DEVICE_CAP_KEYBOARD))
|
||||
eis_seat_remove(seat);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
{
|
||||
struct eis_client *client = eis_event_get_client(e);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue