mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-20 04:30:07 +01:00
Purge libreis from the repo
libreis was intended for an intermediary to set some information that the libei client cannot be entrusted with. In particular this was the application name, the allowed capabilities, and some properties that - once set - the client could no longer change (appid as probably the only really useful one). The price for this was a rather complicated version negotiation dance before the initial CONNECT request. Now that we have a clear view of what's going to happen - RemoteDesktop.ConnectToEIS and the InputCapture portal - there is no longer any need for libreis. The extra information that libreis would've sent is communicated out-of-band in both portals and are known to the compositor at the time the connection is being established. So we can simply drop this, it's no longer required and dropping it makes the protocol significantly simpler anyway.
This commit is contained in:
parent
8d7d6ca8b7
commit
479bda259a
17 changed files with 11 additions and 855 deletions
23
README.md
23
README.md
|
|
@ -2,10 +2,9 @@ libei
|
|||
=====
|
||||
|
||||
**libei** is a library for Emulated Input, primarily aimed at the Wayland
|
||||
stack. It provides four parts:
|
||||
stack. It provides three parts:
|
||||
- 🥚 EI (Emulated Input) for the client side (`libei`)
|
||||
- 🍦 EIS (Emulated Input Server) for the server side (`libeis`)
|
||||
- 🍚 REIS (Restrictions for the EIS) for the portal in between (`libreis`)
|
||||
- 🚌 oeffis is an optional helper library for DBus communication with the
|
||||
XDG RemoteDesktop portal (`liboeffis`)
|
||||
|
||||
|
|
@ -15,7 +14,7 @@ for EI, or 🥣 brei. In the future, 🥣 brei may become a stable protocol. For
|
|||
now, this C library is it.
|
||||
|
||||
For the purpose of this document, **libei** refers to the project,
|
||||
`libei`/`libeis`/`libreis` to the libraries provided.
|
||||
`libei`/`libeis` to the libraries provided.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
|
@ -165,20 +164,6 @@ For a `synergy` use-case, the setup requires:
|
|||
captured, it merely provides the transport layer for events once that decision
|
||||
has been made.
|
||||
|
||||
Using REIS
|
||||
----------
|
||||
|
||||
`libreis` is designed to allow a third-party that does not have a full
|
||||
context to manage restrictions. This is aimed at portals that only have the
|
||||
file descriptor to the EIS implementation but cannot initiate a full EI
|
||||
context.
|
||||
|
||||
`libreis` works so that this third-party can configure the EIS
|
||||
implementation to restrict the abilities of an EI client (later) connected
|
||||
to this implementation. For example, a portal can set the client name
|
||||
using `libreis` based on the app-id. A client cannot override this name
|
||||
later.
|
||||
|
||||
Differences between XTest vs libei
|
||||
----------------------------------
|
||||
|
||||
|
|
@ -245,9 +230,7 @@ The current approach works so that
|
|||
- `xdg-desktop-portal` provides `org.freedesktop.portal.RemoteDesktop.ConnectToEIS`
|
||||
- a client connects to the `xdg-desktop-portal` to request emulated input
|
||||
- `xdg-desktop-portal` authenticates a client and opens the initial
|
||||
connection to the `libeis` socket. It restricts the capabilities available
|
||||
on that socket (e.g. sets the client name based on `app-id` using
|
||||
`libreis`).
|
||||
connection to the `libeis` socket.
|
||||
- `xdg-desktop-portal` hands over the file descriptor to the client which
|
||||
can initialize a `libei` context
|
||||
- from then on, `libei` and `libeis` talk directly to each other, the portal
|
||||
|
|
|
|||
27
meson.build
27
meson.build
|
|
@ -55,7 +55,6 @@ config_h.set_quoted('EI_VERSION', meson.project_version())
|
|||
config_h.set_quoted('EIS_VERSION', meson.project_version())
|
||||
config_h.set('EI_PROTOCOL_VERSION', protocol_version)
|
||||
config_h.set('EIS_PROTOCOL_VERSION', protocol_version)
|
||||
config_h.set('REIS_PROTOCOL_VERSION', protocol_version)
|
||||
|
||||
subdir('proto')
|
||||
|
||||
|
|
@ -171,32 +170,6 @@ pkgconfig.generate(lib_libeis,
|
|||
],
|
||||
)
|
||||
|
||||
lib_libreis = shared_library('reis',
|
||||
'src/libreis.h',
|
||||
'src/libreis.c',
|
||||
proto_headers,
|
||||
dependencies: [dep_libutil, dep_protobuf],
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
install: true,
|
||||
include_directories: [inc_src],
|
||||
)
|
||||
install_headers('src/libreis.h')
|
||||
|
||||
dep_libreis = declare_dependency(link_with: lib_libreis,
|
||||
include_directories: [inc_src])
|
||||
meson.override_dependency('libreis', dep_libreis)
|
||||
|
||||
pkgconfig.generate(lib_libreis,
|
||||
filebase: 'libreis',
|
||||
name: 'libREIS',
|
||||
description: 'Restriction handler for Emulated Input servers',
|
||||
version: meson.project_version(),
|
||||
libraries: lib_libreis,
|
||||
variables: [
|
||||
'protocol_version=' + protocol_version.to_string(),
|
||||
],
|
||||
)
|
||||
|
||||
dep_libxkbcommon = dependency('xkbcommon', required: false)
|
||||
config_h.set10('HAVE_LIBXKBCOMMON', dep_libxkbcommon.found())
|
||||
dep_libevdev = dependency('libevdev', required: false)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ syntax = "proto3";
|
|||
* ServerMessage → sent from the server to the client
|
||||
*
|
||||
* A normal sequence consists of:
|
||||
* [0. - proxy configures connection, see the section below]
|
||||
* 1. - client establishes connection to server
|
||||
* [1. - client establishes connection to server
|
||||
* 2. - client sends "Connect"
|
||||
* 2.a - server replies with "Connected" or
|
||||
* 2.b - server replies with "Disconnected" and closes its end of the socket
|
||||
|
|
@ -32,20 +31,6 @@ syntax = "proto3";
|
|||
*
|
||||
* Where a connection error occurs, the library (libei or libeis) will
|
||||
* unroll the state as seen from the API.
|
||||
*
|
||||
* Pre-configuring a connection
|
||||
* ----------------------------
|
||||
*
|
||||
* Where a proxy is in place (e.g. a portal), the client connection can be
|
||||
* pre-configured to match the permissions model. The proxy opens or obtains a
|
||||
* socket to the server, writes the Configure* messages onto that socket and
|
||||
* then passes the fd to the client to create a libei context from that.
|
||||
*
|
||||
* The proxy can force a client name and/or restrict other options. This is
|
||||
* invisible to the client, it does not know what restrictions are in place.
|
||||
*
|
||||
* Configure messages may only be sent before the client connection. Sending
|
||||
* Configure messages after a client has connected will be silently ignored.
|
||||
*/
|
||||
|
||||
/* Request the server version. This request MAY be sent at any time and/or
|
||||
|
|
@ -63,57 +48,6 @@ message GetVersion {
|
|||
string ei = 1; /* always "EI" */
|
||||
}
|
||||
|
||||
/* Start a transaction of one or more Configure* messages, using the given protocol version.
|
||||
* This MUST be the first Configure message sent and the transaction MUST be
|
||||
* concluded by a ConfigureFinish message.
|
||||
*
|
||||
* Multiple transactions are permitted.
|
||||
*/
|
||||
message ConfigureStart {
|
||||
fixed32 version = 1; /* Must be equal or less to the server's GetVersion response */
|
||||
}
|
||||
|
||||
/* Signals the end of Configure transaction. Typically, this indicates that the
|
||||
* connection will be passed to a diffent process (e.g. from a portal to the
|
||||
* actual EI client).
|
||||
*
|
||||
* A new Configure transaction (with a different version, if applicable) may
|
||||
* start after this transaction.
|
||||
*/
|
||||
message ConfigureFinish {
|
||||
}
|
||||
|
||||
/* ConfigureName *must* be sent before the Connect event. Once a name is set,
|
||||
* subsequent attempts to change the name are ignored, including the name
|
||||
* provided in the Connect message.
|
||||
*/
|
||||
message ConfigureName {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
/* Changes the capability policy and allows or denies specific capabilities.
|
||||
* By default, a client starts with all capabilities permitted. If one or more
|
||||
* ConfigureCapabilities messages are sent, the allowed capabilities is the
|
||||
* binary AND of all allowed_capabilities masks.
|
||||
*
|
||||
* In other words, it is only possible to remove a capability with
|
||||
* (subsequent) ConfigureCapabilities messages.
|
||||
*/
|
||||
message ConfigureCapabilities {
|
||||
fixed32 allowed_capabilities = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* ConfigureProperty *must* be sent before the Connect event. Once the client
|
||||
* is connected or if sent outside a ConfigureStart/ConfigureFinish
|
||||
* transaction, this message is ignored.
|
||||
*/
|
||||
message ConfigureProperty {
|
||||
string name = 1;
|
||||
string value = 2;
|
||||
fixed32 permissions = 3;
|
||||
}
|
||||
|
||||
message Connect {
|
||||
fixed32 version = 1; /* Must be equal or less to the server's GetVersion response */
|
||||
string name = 2;
|
||||
|
|
@ -241,13 +175,6 @@ message ClientMessage {
|
|||
TouchMotion touch_motion = 30;
|
||||
TouchUp touch_up = 31;
|
||||
Frame frame = 32;
|
||||
|
||||
/* Pre-connection configuration */
|
||||
ConfigureStart configure_start = 100;
|
||||
ConfigureFinish configure_finish = 101;
|
||||
ConfigureName configure_name = 102;
|
||||
ConfigureCapabilities configure_capabilities = 103;
|
||||
ConfigureProperty configure_property = 104;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -258,11 +258,6 @@ log_wire_message(struct ei *ei, const ClientMessage *msg, int error)
|
|||
MSG_STRING_CASE(TOUCH_MOTION);
|
||||
MSG_STRING_CASE(TOUCH_UP);
|
||||
MSG_STRING_CASE(FRAME);
|
||||
MSG_STRING_CASE(CONFIGURE_START);
|
||||
MSG_STRING_CASE(CONFIGURE_FINISH);
|
||||
MSG_STRING_CASE(CONFIGURE_NAME);
|
||||
MSG_STRING_CASE(CONFIGURE_CAPABILITIES);
|
||||
MSG_STRING_CASE(CONFIGURE_PROPERTY);
|
||||
}
|
||||
if (message == NULL)
|
||||
assert(!"Unimplemented message type");
|
||||
|
|
|
|||
|
|
@ -280,8 +280,6 @@ eis_client_disconnect(struct eis_client *client)
|
|||
eis_queue_disconnect_event(client);
|
||||
_fallthrough_;
|
||||
case EIS_CLIENT_STATE_NEW:
|
||||
case EIS_CLIENT_STATE_CONFIGURING:
|
||||
case EIS_CLIENT_STATE_CONFIGURED:
|
||||
client_send_disconnect(client);
|
||||
client->state = EIS_CLIENT_STATE_DISCONNECTED;
|
||||
source_remove(client->source);
|
||||
|
|
@ -503,129 +501,6 @@ client_msg_touch_up(struct eis_client *client, uint32_t deviceid, uint32_t touch
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static tristate
|
||||
client_is_in_configure_transaction(struct eis_client *client)
|
||||
{
|
||||
tristate t = tristate_connected;
|
||||
|
||||
switch (client->state) {
|
||||
case EIS_CLIENT_STATE_NEW:
|
||||
case EIS_CLIENT_STATE_CONFIGURED:
|
||||
t = tristate_finished;
|
||||
break;
|
||||
case EIS_CLIENT_STATE_CONFIGURING:
|
||||
t = tristate_started;
|
||||
break;
|
||||
case EIS_CLIENT_STATE_CONNECTING:
|
||||
case EIS_CLIENT_STATE_CONNECTED:
|
||||
case EIS_CLIENT_STATE_DISCONNECTED:
|
||||
t = tristate_connected;
|
||||
break;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_configure_start(struct eis_client *client, uint32_t version)
|
||||
{
|
||||
tristate t = client_is_in_configure_transaction(client);
|
||||
|
||||
if (tristate_is_started(t))
|
||||
return -EPROTO;
|
||||
|
||||
/* Once the client is connected, we silently ignore all Configure
|
||||
requests so a broken portal can't accidentally disconnect a client */
|
||||
if (tristate_is_connected(t))
|
||||
return 0;
|
||||
|
||||
if (version == 0)
|
||||
return -EINVAL;
|
||||
|
||||
client->configure_version = version;
|
||||
client->state = EIS_CLIENT_STATE_CONFIGURING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_configure_finish(struct eis_client *client)
|
||||
{
|
||||
tristate t = client_is_in_configure_transaction(client);
|
||||
|
||||
if (tristate_is_finished(t))
|
||||
return -EPROTO;
|
||||
|
||||
/* Once the client is connected, we silently ignore all Configure
|
||||
requests so a broken portal can't accidentally disconnect a client */
|
||||
if (tristate_is_connected(t))
|
||||
return 0;
|
||||
|
||||
client->configure_version = 0;
|
||||
client->state = EIS_CLIENT_STATE_CONFIGURED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_configure_name(struct eis_client *client, const char *name)
|
||||
{
|
||||
tristate t = client_is_in_configure_transaction(client);
|
||||
|
||||
if (tristate_is_finished(t))
|
||||
return -EPROTO;
|
||||
|
||||
/* Once the client is connected, we silently ignore all Configure
|
||||
requests so a broken portal can't accidentally disconnect a client */
|
||||
if (tristate_is_connected(t))
|
||||
return 0;
|
||||
|
||||
if (client->name)
|
||||
return 0;
|
||||
|
||||
client->name = xstrdup(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_configure_capabilities(struct eis_client *client, uint32_t allowed_caps)
|
||||
{
|
||||
tristate t = client_is_in_configure_transaction(client);
|
||||
|
||||
if (tristate_is_finished(t))
|
||||
return -EPROTO;
|
||||
|
||||
/* Once the client is connected, we silently ignore all Configure
|
||||
requests so a broken portal can't accidentally disconnect a client */
|
||||
if (tristate_is_connected(t))
|
||||
return 0;
|
||||
|
||||
/* restrictions can only be reduced */
|
||||
client->restrictions.cap_allow_mask &= allowed_caps;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_configure_property(struct eis_client *client,
|
||||
const char *name, const char *value,
|
||||
uint32_t permissions)
|
||||
{
|
||||
tristate t = client_is_in_configure_transaction(client);
|
||||
|
||||
if (tristate_is_finished(t))
|
||||
return -EPROTO;
|
||||
|
||||
/* Once the client is connected, we silently ignore all Configure
|
||||
requests so a broken portal can't accidentally disconnect a client */
|
||||
if (tristate_is_connected(t))
|
||||
return 0;
|
||||
|
||||
eis_property_update_from_client(client, name, value, permissions);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_msg_connect(struct eis_client *client, uint32_t version,
|
||||
const char *name, bool is_sender)
|
||||
|
|
@ -691,24 +566,12 @@ static const struct eis_proto_interface intf_state_new = {
|
|||
.connect_done = client_msg_connect_done,
|
||||
.disconnect = client_msg_disconnect,
|
||||
.get_version = client_msg_get_version,
|
||||
|
||||
.configure_start = client_msg_configure_start,
|
||||
.configure_finish = client_msg_configure_finish,
|
||||
.configure_name = client_msg_configure_name,
|
||||
.configure_capabilities = client_msg_configure_capabilities,
|
||||
.configure_property = client_msg_configure_property,
|
||||
};
|
||||
|
||||
/* Client is waiting for us, shouldn't send anything except disconnect */
|
||||
static const struct eis_proto_interface intf_state_connecting = {
|
||||
.disconnect = client_msg_disconnect,
|
||||
.get_version = client_msg_get_version,
|
||||
|
||||
.configure_start = client_msg_configure_start,
|
||||
.configure_finish = client_msg_configure_finish,
|
||||
.configure_name = client_msg_configure_name,
|
||||
.configure_capabilities = client_msg_configure_capabilities,
|
||||
.configure_property = client_msg_configure_property,
|
||||
};
|
||||
|
||||
static const struct eis_proto_interface intf_state_connected = {
|
||||
|
|
@ -732,19 +595,10 @@ static const struct eis_proto_interface intf_state_connected = {
|
|||
.touch_motion = client_msg_touch_motion,
|
||||
.touch_up = client_msg_touch_up,
|
||||
.frame = client_msg_frame,
|
||||
|
||||
/* configuration */
|
||||
.configure_start = client_msg_configure_start,
|
||||
.configure_finish = client_msg_configure_finish,
|
||||
.configure_name = client_msg_configure_name,
|
||||
.configure_capabilities = client_msg_configure_capabilities,
|
||||
.configure_property = client_msg_configure_property,
|
||||
};
|
||||
|
||||
static const struct eis_proto_interface *interfaces[] = {
|
||||
[EIS_CLIENT_STATE_NEW] = &intf_state_new,
|
||||
[EIS_CLIENT_STATE_CONFIGURING] = &intf_state_new,
|
||||
[EIS_CLIENT_STATE_CONFIGURED] = &intf_state_new,
|
||||
[EIS_CLIENT_STATE_CONNECTING] = &intf_state_connecting,
|
||||
[EIS_CLIENT_STATE_CONNECTED] = &intf_state_connected,
|
||||
[EIS_CLIENT_STATE_DISCONNECTED] = NULL,
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ struct eis {
|
|||
|
||||
enum eis_client_state {
|
||||
EIS_CLIENT_STATE_NEW, /* just connected */
|
||||
EIS_CLIENT_STATE_CONFIGURING, /* in a Configure transaction */
|
||||
EIS_CLIENT_STATE_CONFIGURED, /* finished a Configure transaction */
|
||||
EIS_CLIENT_STATE_CONNECTING, /* client requested connect */
|
||||
EIS_CLIENT_STATE_CONNECTED, /* server has sent connect */
|
||||
EIS_CLIENT_STATE_DISCONNECTED,
|
||||
|
|
|
|||
|
|
@ -616,26 +616,6 @@ eis_proto_handle_message(struct eis_client *client,
|
|||
case CLIENT_MESSAGE__MSG_FRAME:
|
||||
rc = call(frame, client, proto->frame->deviceid, proto->frame->timestamp);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CONFIGURE_START:
|
||||
rc = call(configure_start, client,
|
||||
proto->configure_start->version);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CONFIGURE_FINISH:
|
||||
rc = call(configure_finish, client);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CONFIGURE_NAME:
|
||||
rc = call(configure_name, client,
|
||||
proto->configure_name->name);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CONFIGURE_CAPABILITIES:
|
||||
rc = call(configure_capabilities, client,
|
||||
proto->configure_capabilities->allowed_capabilities);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CONFIGURE_PROPERTY:
|
||||
rc = call(configure_property, client, proto->configure_property->name,
|
||||
proto->configure_property->value[0] ? proto->configure_property->value : NULL,
|
||||
proto->configure_property->permissions);
|
||||
break;
|
||||
default:
|
||||
rc = -EBADMSG;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -61,14 +61,6 @@ struct eis_proto_interface {
|
|||
uint32_t tid, double x, double y);
|
||||
int (*touch_up)(struct eis_client *client, uint32_t deviceid, uint32_t tid);
|
||||
int (*frame) (struct eis_client *client, uint32_t deviceid, uint64_t time);
|
||||
|
||||
/* configuration */
|
||||
int (*configure_start)(struct eis_client *client, uint32_t version);
|
||||
int (*configure_finish)(struct eis_client *client);
|
||||
int (*configure_name)(struct eis_client *client, const char *name);
|
||||
int (*configure_capabilities)(struct eis_client *client, uint32_t allow);
|
||||
int (*configure_property)(struct eis_client *client, const char *name,
|
||||
const char *value, uint32_t permissions);
|
||||
};
|
||||
|
||||
struct eis_proto_requests {
|
||||
|
|
|
|||
|
|
@ -404,9 +404,7 @@ const char *
|
|||
eis_client_property_get(struct eis_client *client, const char *property);
|
||||
|
||||
/**
|
||||
* Returns true if the client is allowed this capability. By default, clients
|
||||
* can use any capability but where a reis intermediary is present, those
|
||||
* capabilities may be reduced.
|
||||
* Returns true if the client is allowed this capability.
|
||||
*/
|
||||
bool
|
||||
eis_client_has_capability(struct eis_client *client,
|
||||
|
|
|
|||
199
src/libreis.c
199
src/libreis.c
|
|
@ -1,199 +0,0 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "libreis.h"
|
||||
|
||||
#include "util-bits.h"
|
||||
#include "util-object.h"
|
||||
#include "util-macros.h"
|
||||
#include "util-strings.h"
|
||||
#include "util-mem.h"
|
||||
#include "util-io.h"
|
||||
#include "util-version.h"
|
||||
|
||||
#include "proto/ei.pb-c.h"
|
||||
|
||||
struct reis {
|
||||
struct object object;
|
||||
int eisfd;
|
||||
|
||||
uint32_t version;
|
||||
bool in_transaction;
|
||||
};
|
||||
|
||||
static void
|
||||
reis_destroy(struct reis *reis)
|
||||
{
|
||||
xclose(reis->eisfd);
|
||||
}
|
||||
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_UNREF_CLEANUP(reis);
|
||||
static
|
||||
OBJECT_IMPLEMENT_CREATE(reis);
|
||||
|
||||
static int
|
||||
send_msg(int fd, const ClientMessage *msg)
|
||||
{
|
||||
size_t msglen = client_message__get_packed_size(msg);
|
||||
uint8_t buf[4 + msglen];
|
||||
*(uint32_t*)buf = msglen;
|
||||
client_message__pack(msg, buf + 4);
|
||||
return min(0, xsend(fd, buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
_public_ struct reis *
|
||||
reis_new(int eisfd)
|
||||
{
|
||||
_unref_(reis) *reis = reis_create(NULL);
|
||||
|
||||
reis->eisfd = xdup(eisfd);
|
||||
if (reis->eisfd == -1)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: technically we should check the server's version before we
|
||||
* send our own, but that requires adding reis_dispatch() and the code
|
||||
* in the caller for this too.
|
||||
*
|
||||
* Since all we support right now is version 1 and any server will
|
||||
* support that, so we don't need to care much.
|
||||
*/
|
||||
|
||||
reis->version = VERSION_V(REIS_PROTOCOL_VERSION);
|
||||
|
||||
return steal(&reis);
|
||||
}
|
||||
|
||||
#define prepare_msg(_type, _struct, _field) \
|
||||
ClientMessage msg = CLIENT_MESSAGE__INIT; \
|
||||
_struct _field = _type##__INIT; \
|
||||
msg.msg_case = CLIENT_MESSAGE__MSG_##_type; \
|
||||
msg._field = &_field
|
||||
|
||||
static int
|
||||
reis_start(struct reis *reis)
|
||||
{
|
||||
if (reis->in_transaction)
|
||||
return 0;
|
||||
|
||||
reis->in_transaction = true;
|
||||
|
||||
prepare_msg(CONFIGURE_START, ConfigureStart, configure_start);
|
||||
configure_start.version = reis->version;
|
||||
|
||||
return send_msg(reis->eisfd, &msg);
|
||||
}
|
||||
|
||||
static int
|
||||
reis_finish(struct reis *reis)
|
||||
{
|
||||
if (!reis->in_transaction)
|
||||
return 0;
|
||||
|
||||
reis->in_transaction = false;
|
||||
|
||||
prepare_msg(CONFIGURE_FINISH, ConfigureFinish, configure_finish);
|
||||
|
||||
return send_msg(reis->eisfd, &msg);
|
||||
}
|
||||
|
||||
_public_ int
|
||||
reis_set_property_with_permissions(struct reis *reis,
|
||||
const char *name, const char *value,
|
||||
uint32_t permissions)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = reis_start(reis)) != 0)
|
||||
return rc;
|
||||
|
||||
prepare_msg(CONFIGURE_PROPERTY, ConfigureProperty, configure_property);
|
||||
|
||||
configure_property.name = (char*)name;
|
||||
configure_property.value = value ? (char*)value : "";
|
||||
configure_property.permissions = permissions;
|
||||
|
||||
rc = send_msg(reis->eisfd, &msg);
|
||||
if (rc == 0)
|
||||
return rc;
|
||||
|
||||
return reis_finish(reis);
|
||||
}
|
||||
|
||||
_public_ int
|
||||
reis_set_name(struct reis *reis, const char *name)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = reis_start(reis)) != 0)
|
||||
return rc;
|
||||
|
||||
prepare_msg(CONFIGURE_NAME, ConfigureName, configure_name);
|
||||
configure_name.name = (char*)name;
|
||||
|
||||
rc = send_msg(reis->eisfd, &msg);
|
||||
if (rc == 0)
|
||||
return rc;
|
||||
|
||||
return reis_finish(reis);
|
||||
}
|
||||
|
||||
_public_ int
|
||||
reis_allow_capability(struct reis *reis, enum reis_device_capability capability, ...)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = reis_start(reis)) != 0)
|
||||
return rc;
|
||||
|
||||
enum reis_device_capability cap = capability;
|
||||
uint32_t caps = 0;
|
||||
va_list args;
|
||||
|
||||
va_start(args, capability);
|
||||
do {
|
||||
switch (cap) {
|
||||
case REIS_DEVICE_CAP_POINTER:
|
||||
case REIS_DEVICE_CAP_POINTER_ABSOLUTE:
|
||||
case REIS_DEVICE_CAP_KEYBOARD:
|
||||
case REIS_DEVICE_CAP_TOUCH:
|
||||
caps |= bit(cap);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
} while ((cap = va_arg(args, enum reis_device_capability)) > 0);
|
||||
va_end(args);
|
||||
|
||||
prepare_msg(CONFIGURE_CAPABILITIES, ConfigureCapabilities, configure_capabilities);
|
||||
configure_capabilities.allowed_capabilities = caps;
|
||||
|
||||
rc = send_msg(reis->eisfd, &msg);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return reis_finish(reis);
|
||||
}
|
||||
125
src/libreis.h
125
src/libreis.h
|
|
@ -1,125 +0,0 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define _sentinel_ __attribute__((sentinel))
|
||||
|
||||
/**
|
||||
* REIS is the library for Restrictions for EIS. This library is used by
|
||||
* intermediaries between EI and EIS to reduce the capabilities that an EI
|
||||
* client has available.
|
||||
*
|
||||
* It is a helper library that does not initiate a full EI or EIS
|
||||
* context but works on the file descriptor instead.
|
||||
*
|
||||
* Restricting capabilities is a one-way-road. A default EIS context has
|
||||
* full permissions, consecutive calls can only restrict the current
|
||||
* permissions but not loosen them.
|
||||
*/
|
||||
|
||||
struct reis;
|
||||
|
||||
enum reis_device_capability {
|
||||
REIS_DEVICE_CAP_POINTER = 1,
|
||||
REIS_DEVICE_CAP_POINTER_ABSOLUTE,
|
||||
REIS_DEVICE_CAP_KEYBOARD,
|
||||
REIS_DEVICE_CAP_TOUCH,
|
||||
|
||||
REIS_DEVICE_CAP_ALL = ~0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum reis_property_permission
|
||||
*
|
||||
* A set of masks for operations permitted on properties. Note that property
|
||||
* permissions only affect the libreis client, the server has full access to the
|
||||
* properties at any time.
|
||||
*/
|
||||
enum reis_property_permission {
|
||||
REIS_PROPERTY_PERM_NONE = 0,
|
||||
REIS_PROPERTY_PERM_READ = (1 << 0),
|
||||
REIS_PROPERTY_PERM_WRITE = (1 << 1),
|
||||
REIS_PROPERTY_PERM_DELETE = (1 << 2),
|
||||
|
||||
REIS_PROPERTY_PERM_ALL = (REIS_PROPERTY_PERM_READ|REIS_PROPERTY_PERM_WRITE|REIS_PROPERTY_PERM_DELETE),
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new reis context based on the EIS connection at the other end of
|
||||
* @a eisfd. The EIS context does not need to be in any
|
||||
* specific state and no checking is done that there is indeed an EIS
|
||||
* context at the other end of the fd.
|
||||
*/
|
||||
struct reis *
|
||||
reis_new(int eisfd);
|
||||
|
||||
struct reis *
|
||||
reis_unref(struct reis* reis);
|
||||
|
||||
/**
|
||||
* See ei_property_set_with_permissions(), but the permissions are
|
||||
* left as-is. If the property does not exist, it is created with permissions
|
||||
* @ref REIS_PROPERTY_PERM_ALL.
|
||||
*/
|
||||
int
|
||||
reis_set_property_with_permissions(struct reis *reis,
|
||||
const char *property, const char *value,
|
||||
uint32_t permission);
|
||||
|
||||
/**
|
||||
* Set the name for the client on this connection.
|
||||
*
|
||||
* This function has no effect if the EI client has already sent the
|
||||
* connection message to the server. IOW this can only be used to *set* the
|
||||
* name but not to *change* the name of the client.
|
||||
*
|
||||
* Calling this function multiple times has no effect, only the first name
|
||||
* is used.
|
||||
*
|
||||
* @return zero on success or a negative errno otherwise
|
||||
*/
|
||||
int
|
||||
reis_set_name(struct reis *reis, const char *name);
|
||||
|
||||
/**
|
||||
* Explicitly allow the given capabilities. The argument list must be
|
||||
* terminated with zero.
|
||||
*
|
||||
* By default, an EIS implementation will allow any capability. Calling this
|
||||
* function changes the EIS implementation's default behavior to deny all
|
||||
* capabilities EXCEPT the ones given in this call. For example, the following
|
||||
* code only allows the pointer and keyboard capabilty:
|
||||
*
|
||||
* @code
|
||||
* reis_allow_capability(reis, REIS_DEVICE_CAP_POINTER,
|
||||
* REIS_DEVICE_CAP_KEYBOARD, 0);
|
||||
* @endcode
|
||||
*
|
||||
* @return Zero on success or a negative errno on failure
|
||||
*/
|
||||
_sentinel_ int
|
||||
reis_allow_capability(struct reis *reis, enum reis_device_capability cap, ...);
|
||||
|
|
@ -7,10 +7,6 @@
|
|||
#include <libeis.h>
|
||||
#endif
|
||||
|
||||
#if INCLUDE_LIBREIS
|
||||
#include <libreis.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ struct peck {
|
|||
struct object object;
|
||||
struct ei *ei;
|
||||
struct eis *eis;
|
||||
struct reis *reis;
|
||||
uint32_t eis_behavior;
|
||||
uint32_t ei_behavior;
|
||||
struct logger *logger;
|
||||
|
|
@ -120,7 +119,6 @@ peck_destroy(struct peck *peck)
|
|||
|
||||
ei_unref(peck->ei);
|
||||
eis_unref(peck->eis);
|
||||
reis_unref(peck->reis);
|
||||
logger_unref(peck->logger);
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +127,6 @@ OBJECT_IMPLEMENT_CREATE(peck);
|
|||
OBJECT_IMPLEMENT_UNREF(peck);
|
||||
OBJECT_IMPLEMENT_GETTER(peck, ei, struct ei*);
|
||||
OBJECT_IMPLEMENT_GETTER(peck, eis, struct eis*);
|
||||
OBJECT_IMPLEMENT_GETTER(peck, reis, struct reis*);
|
||||
|
||||
void
|
||||
peck_drop_ei(struct peck *peck)
|
||||
|
|
@ -338,7 +335,7 @@ peck_log_handler(struct logger *logger,
|
|||
}
|
||||
|
||||
static struct peck *
|
||||
new_context(enum peck_ei_mode ei_mode, bool with_reis)
|
||||
new_context(enum peck_ei_mode ei_mode)
|
||||
{
|
||||
struct peck *peck = peck_create(NULL);
|
||||
|
||||
|
|
@ -362,27 +359,15 @@ new_context(enum peck_ei_mode ei_mode, bool with_reis)
|
|||
ei_log_set_handler(ei, peck_ei_log_handler);
|
||||
ei_log_set_priority(ei, EI_LOG_PRIORITY_DEBUG);
|
||||
ei_configure_name(ei, "eierpecken test context");
|
||||
/* Setting up a backend sends out the CONNECT event - if
|
||||
we want libreis do so something beforehand we need to
|
||||
keep the fd and set up the backend later */
|
||||
if (!with_reis) {
|
||||
rc = ei_setup_backend_fd(ei, fd);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
peck->ei_socket_fd = -1;
|
||||
} else {
|
||||
peck->ei_socket_fd = fd;
|
||||
}
|
||||
rc = ei_setup_backend_fd(ei, fd);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
peck->ei_socket_fd = -1;
|
||||
peck->ei = ei;
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSTART);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_FRAME);
|
||||
|
||||
if (with_reis) {
|
||||
struct reis *reis = reis_new(fd);
|
||||
peck->reis = reis;
|
||||
}
|
||||
|
||||
peck->logger = logger_new("peck", peck);
|
||||
logger_set_handler(peck->logger, peck_log_handler);
|
||||
logger_set_priority(peck->logger, LOGGER_DEBUG);
|
||||
|
|
@ -393,7 +378,7 @@ new_context(enum peck_ei_mode ei_mode, bool with_reis)
|
|||
struct peck *
|
||||
peck_new_context(enum peck_ei_mode ei_mode)
|
||||
{
|
||||
return new_context(ei_mode, false);
|
||||
return new_context(ei_mode);
|
||||
}
|
||||
|
||||
struct peck *
|
||||
|
|
@ -402,12 +387,6 @@ peck_new(void)
|
|||
return peck_new_context(PECK_EI_SENDER);
|
||||
}
|
||||
|
||||
struct peck *
|
||||
peck_new_context_with_reis(enum peck_ei_mode ei_mode)
|
||||
{
|
||||
return new_context(ei_mode, true);
|
||||
}
|
||||
|
||||
void
|
||||
peck_ei_connect(struct peck *peck)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "libei.h"
|
||||
#include "libeis.h"
|
||||
#include "libreis.h"
|
||||
|
||||
#include "util-mem.h"
|
||||
|
||||
|
|
@ -144,9 +143,6 @@ peck_new(void);
|
|||
struct peck *
|
||||
peck_new_context(enum peck_ei_mode ei_mode);
|
||||
|
||||
struct peck *
|
||||
peck_new_context_with_reis(enum peck_ei_mode ei_mode);
|
||||
|
||||
void
|
||||
peck_ei_connect(struct peck *peck);
|
||||
|
||||
|
|
@ -163,9 +159,6 @@ peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior);
|
|||
struct ei *
|
||||
peck_get_ei(struct peck *peck);
|
||||
|
||||
struct reis *
|
||||
peck_get_reis(struct peck *peck);
|
||||
|
||||
void
|
||||
peck_drop_ei(struct peck *peck);
|
||||
|
||||
|
|
@ -341,7 +334,6 @@ DEFINE_UNREF_CLEANUP_FUNC(eis_region);
|
|||
of a test handles server vs client */
|
||||
#define with_server(peck_) for (struct eis *eis = peck_get_eis(peck_); eis; eis = NULL)
|
||||
#define with_client(peck_) for (struct ei *ei = peck_get_ei(peck_); ei; ei = NULL)
|
||||
#define with_reis(peck_) for (struct reis *reis = peck_get_reis(peck_); reis; reis = NULL)
|
||||
#define with_emulation(d_) for (bool _loop = ({ ei_device_start_emulating(d_); true;});\
|
||||
_loop; \
|
||||
({ ei_device_stop_emulating(d_); _loop = false; }))
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ lib_eierpecken = static_library('eierpecken',
|
|||
'eierpecken.h',
|
||||
'eierpecken.c',
|
||||
include_directories: [inc_src, inc_builddir],
|
||||
dependencies: [munit, dep_libutil, dep_libei, dep_libeis, dep_libreis],
|
||||
dependencies: [munit, dep_libutil, dep_libei, dep_libeis],
|
||||
)
|
||||
|
||||
test('eierpecken',
|
||||
|
|
@ -74,7 +74,6 @@ test('eierpecken',
|
|||
'test-ei-device.c',
|
||||
'test-ei-seat.c',
|
||||
'test-eis.c',
|
||||
'test-reis.c',
|
||||
link_with: lib_eierpecken,
|
||||
include_directories: [inc_builddir],
|
||||
dependencies: [dep_unittest, dep_libei, dep_libeis]))
|
||||
|
|
@ -107,13 +106,6 @@ executable('test-build-libeis',
|
|||
c_args : ['-Werror', '-DINCLUDE_LIBEIS=1'],
|
||||
install : false)
|
||||
|
||||
executable('test-build-libreis',
|
||||
'buildtest.c',
|
||||
dependencies : [dep_libreis],
|
||||
include_directories : [inc_src],
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBREIS=1'],
|
||||
install : false)
|
||||
|
||||
if add_languages('cpp', required: false)
|
||||
executable('test-build-cxx',
|
||||
'buildtest.cc',
|
||||
|
|
|
|||
|
|
@ -373,60 +373,3 @@ MUNIT_TEST(eistest_device_ignore_paused_device)
|
|||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_property_list_on_connect)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context_with_reis(PECK_EI_RECEIVER);
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_reis(peck) {
|
||||
reis_set_property_with_permissions(reis, "testprop.all", "all", REIS_PROPERTY_PERM_ALL);
|
||||
reis_set_property_with_permissions(reis, "testprop.r", "r", REIS_PROPERTY_PERM_READ);
|
||||
reis_set_property_with_permissions(reis, "testprop.rw", "rw", REIS_PROPERTY_PERM_READ|REIS_PROPERTY_PERM_WRITE);
|
||||
reis_set_property_with_permissions(reis, "testprop.w", "w", REIS_PROPERTY_PERM_WRITE);
|
||||
}
|
||||
|
||||
peck_ei_connect(peck);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
_unref_(ei_event) *connect = peck_ei_next_event(ei, EI_EVENT_CONNECT);
|
||||
_unref_(ei_event) *prop_all = peck_ei_next_event(ei, EI_EVENT_PROPERTY);
|
||||
_unref_(ei_event) *prop_r = peck_ei_next_event(ei, EI_EVENT_PROPERTY);
|
||||
_unref_(ei_event) *prop_rw = peck_ei_next_event(ei, EI_EVENT_PROPERTY);
|
||||
|
||||
const char *name, *value;
|
||||
uint32_t perms;
|
||||
|
||||
name = ei_event_property_get_name(prop_all);
|
||||
value = ei_event_property_get_value(prop_all);
|
||||
perms = ei_event_property_get_permissions(prop_all);
|
||||
|
||||
munit_assert_string_equal(name, "testprop.all");
|
||||
munit_assert_string_equal(value, "all");
|
||||
munit_assert_uint32(perms, ==, EI_PROPERTY_PERM_ALL);
|
||||
|
||||
name = ei_event_property_get_name(prop_r);
|
||||
value = ei_event_property_get_value(prop_r);
|
||||
perms = ei_event_property_get_permissions(prop_r);
|
||||
|
||||
munit_assert_string_equal(name, "testprop.r");
|
||||
munit_assert_string_equal(value, "r");
|
||||
munit_assert_uint32(perms, ==, EI_PROPERTY_PERM_READ);
|
||||
|
||||
name = ei_event_property_get_name(prop_rw);
|
||||
value = ei_event_property_get_value(prop_rw);
|
||||
perms = ei_event_property_get_permissions(prop_rw);
|
||||
|
||||
munit_assert_string_equal(name, "testprop.rw");
|
||||
munit_assert_string_equal(value, "rw");
|
||||
munit_assert_uint32(perms, ==, EI_PROPERTY_PERM_READ|EI_PROPERTY_PERM_WRITE);
|
||||
|
||||
peck_assert_no_ei_events(ei);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
|
|
|||
122
test/test-reis.c
122
test/test-reis.c
|
|
@ -1,122 +0,0 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "util-munit.h"
|
||||
#include "eierpecken.h"
|
||||
|
||||
MUNIT_TEST(test_reis_set_name)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context_with_reis(PECK_EI_SENDER);
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
/* Not sent until CONNECT */
|
||||
ei_configure_name(ei, "gohan");
|
||||
}
|
||||
|
||||
with_reis(peck) {
|
||||
reis_set_name(reis, "meshi");
|
||||
}
|
||||
|
||||
peck_ei_connect(peck);
|
||||
|
||||
with_reis(peck) {
|
||||
/* After connect, should be ignored */
|
||||
reis_set_name(reis, "kome");
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
peck_assert_no_eis_events(eis);
|
||||
|
||||
struct eis_client *client = peck_eis_get_default_client(peck);
|
||||
munit_assert_string_equal(eis_client_get_name(client), "meshi");
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_reis_set_capabilities)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context_with_reis(PECK_EI_SENDER);
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_reis(peck) {
|
||||
reis_allow_capability(reis, REIS_DEVICE_CAP_POINTER, REIS_DEVICE_CAP_TOUCH, NULL);
|
||||
}
|
||||
|
||||
peck_ei_connect(peck);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
peck_assert_no_eis_events(eis);
|
||||
|
||||
struct eis_client *client = peck_eis_get_default_client(peck);
|
||||
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_TOUCH));
|
||||
munit_assert_false(eis_client_has_capability(client, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_client_has_capability(client, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_reis_set_capabilities_reducing)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context_with_reis(PECK_EI_SENDER);
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_reis(peck) {
|
||||
reis_allow_capability(reis, REIS_DEVICE_CAP_POINTER, REIS_DEVICE_CAP_TOUCH, NULL);
|
||||
/* now reduce even further */
|
||||
reis_allow_capability(reis, REIS_DEVICE_CAP_POINTER, NULL);
|
||||
}
|
||||
|
||||
peck_ei_connect(peck);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
peck_assert_no_eis_events(eis);
|
||||
|
||||
struct eis_client *client = peck_eis_get_default_client(peck);
|
||||
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_false(eis_client_has_capability(client, EIS_DEVICE_CAP_TOUCH));
|
||||
munit_assert_false(eis_client_has_capability(client, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_false(eis_client_has_capability(client, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue