mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-02-08 22:00:37 +01:00
proto: allow the client to set the protocol version
Let the client set the version number it wants on Connect. There is new public API to query the client/server's version as set once the connect finished (eis_client_get_version() and ei_get_version()) but there is currently no public API for the client to select the version it actually wants, other than whatever both support. IOW, it's not possible for the client to say "I want version 8 but if that's not supported, use version 5".
This commit is contained in:
parent
08a4ce4aac
commit
5535692ee0
13 changed files with 94 additions and 11 deletions
|
|
@ -84,8 +84,9 @@ message ConfigureCapabilities {
|
|||
}
|
||||
|
||||
message Connect {
|
||||
string name = 1;
|
||||
bool is_sender = 2;
|
||||
uint32 version = 1; /* Must be equal or less to the server's GetVersion response */
|
||||
string name = 2;
|
||||
bool is_sender = 3;
|
||||
}
|
||||
|
||||
message ConnectDone {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ struct ei {
|
|||
|
||||
bool is_sender;
|
||||
uint32_t server_version;
|
||||
uint32_t client_version;
|
||||
};
|
||||
|
||||
enum ei_seat_state {
|
||||
|
|
|
|||
|
|
@ -325,12 +325,13 @@ ei_proto_send_get_version(struct ei *ei)
|
|||
}
|
||||
|
||||
static int
|
||||
ei_proto_send_connect(struct ei *ei)
|
||||
ei_proto_send_connect(struct ei *ei, uint32_t version)
|
||||
{
|
||||
prepare_msg(CONNECT, Connect, connect);
|
||||
|
||||
connect.name = ei->name;
|
||||
connect.is_sender = ei->is_sender;
|
||||
connect.version = version;
|
||||
|
||||
return ei_proto_send_msg(ei, &msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ struct ei_proto_interface {
|
|||
};
|
||||
|
||||
struct ei_proto_requests {
|
||||
int (*connect)(struct ei *ei);
|
||||
int (*connect)(struct ei *ei, uint32_t version);
|
||||
int (*connect_done)(struct ei *ei);
|
||||
int (*disconnect)(struct ei *ei);
|
||||
int (*bind_seat)(struct ei_seat *seat, enum ei_device_capability cap);
|
||||
|
|
|
|||
33
src/libei.c
33
src/libei.c
|
|
@ -52,7 +52,7 @@ _Static_assert(sizeof(enum ei_event_type) == sizeof(int), "Invalid enum size");
|
|||
_Static_assert(sizeof(enum ei_log_priority) == sizeof(int), "Invalid enum size");
|
||||
|
||||
static int
|
||||
ei_finish_set_connection(struct ei *ei);
|
||||
ei_finish_set_connection(struct ei *ei, uint32_t version);
|
||||
|
||||
static struct ei_seat *
|
||||
ei_find_seat(struct ei *ei, uint32_t seatid)
|
||||
|
|
@ -196,6 +196,27 @@ ei_get_fd(struct ei *ei)
|
|||
return sink_get_fd(ei->sink);
|
||||
}
|
||||
|
||||
_public_ uint32_t
|
||||
ei_get_version(struct ei *ei)
|
||||
{
|
||||
switch (ei->state) {
|
||||
case EI_STATE_NEW:
|
||||
case EI_STATE_BACKEND:
|
||||
case EI_STATE_VERSION_QUERY:
|
||||
case EI_STATE_CONNECTING:
|
||||
break;
|
||||
case EI_STATE_CONNECTED:
|
||||
case EI_STATE_DISCONNECTING:
|
||||
return ei->client_version;
|
||||
case EI_STATE_DISCONNECTED:
|
||||
break;
|
||||
}
|
||||
|
||||
log_bug(ei, "Version is only available on successful connection");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_dispatch(struct ei *ei)
|
||||
{
|
||||
|
|
@ -1354,7 +1375,11 @@ handle_msg_version_during_connection(struct ei *ei, uint32_t version)
|
|||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
return ei_finish_set_connection(ei);
|
||||
const uint32_t our_version = VERSION_V(1);
|
||||
|
||||
ei->client_version = min(our_version, version);
|
||||
|
||||
return ei_finish_set_connection(ei, ei->client_version);
|
||||
}
|
||||
|
||||
static const struct ei_proto_interface intf_state_backend = {
|
||||
|
|
@ -1487,9 +1512,9 @@ ei_set_connection(struct ei *ei, int fd)
|
|||
}
|
||||
|
||||
static int
|
||||
ei_finish_set_connection(struct ei *ei)
|
||||
ei_finish_set_connection(struct ei *ei, uint32_t version)
|
||||
{
|
||||
int rc = ei->requests->connect(ei);
|
||||
int rc = ei->requests->connect(ei, version);
|
||||
|
||||
struct ei_property *prop;
|
||||
list_for_each_safe(prop, &ei->properties, link) {
|
||||
|
|
|
|||
15
src/libei.h
15
src/libei.h
|
|
@ -656,6 +656,21 @@ ei_get_fd(struct ei *ei);
|
|||
void
|
||||
ei_dispatch(struct ei *ei);
|
||||
|
||||
/**
|
||||
* Return the protocol version for this client. Version negotiation is handled by libei
|
||||
* during the initial connection, the client's version is the minimum version between
|
||||
* the server's version and the client supported version.
|
||||
*
|
||||
* @note libei currently has no API to request specific versions
|
||||
*
|
||||
* It is an application bug to call this function before receiving the @ref
|
||||
* EI_EVENT_CONNECT event.
|
||||
*
|
||||
* @return The protocol version.
|
||||
*/
|
||||
uint32_t
|
||||
ei_get_version(struct ei *ei);
|
||||
|
||||
/**
|
||||
* Return the next event from the event queue, removing it from the queue.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ OBJECT_IMPLEMENT_UNREF_CLEANUP(eis_client);
|
|||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_client, name, const char*);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_client, version, uint32_t);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_SETTER(eis_client, user_data, void*);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_client, user_data, void*);
|
||||
|
|
@ -524,8 +526,14 @@ client_msg_configure_capabilities(struct eis_client *client, uint32_t allowed_ca
|
|||
}
|
||||
|
||||
static int
|
||||
client_msg_connect(struct eis_client *client, const char *name, bool is_sender)
|
||||
client_msg_connect(struct eis_client *client, uint32_t version,
|
||||
const char *name, bool is_sender)
|
||||
{
|
||||
if (client->version > EIS_PROTOCOL_VERSION)
|
||||
return -EPROTO;
|
||||
|
||||
client->version = version;
|
||||
|
||||
if (client->name == NULL)
|
||||
client->name = xstrdup(name);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ struct eis_client {
|
|||
void *user_data;
|
||||
struct list link;
|
||||
struct source *source;
|
||||
uint32_t version;
|
||||
uint32_t id;
|
||||
enum eis_client_state state;
|
||||
char *name;
|
||||
|
|
|
|||
|
|
@ -524,7 +524,8 @@ eis_proto_handle_message(struct eis_client *client,
|
|||
int rc;
|
||||
switch (proto->msg_case) {
|
||||
case CLIENT_MESSAGE__MSG_CONNECT:
|
||||
rc = call(connect, client, proto->connect->name, proto->connect->is_sender);
|
||||
rc = call(connect, client, proto->connect->version,
|
||||
proto->connect->name, proto->connect->is_sender);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CONNECT_DONE:
|
||||
rc = call(connect_done, client);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
/* callbacks invoked during eis_proto_parse_message() */
|
||||
struct eis_proto_interface {
|
||||
int (*connect)(struct eis_client *client, const char *name, bool is_sender);
|
||||
int (*connect)(struct eis_client *client, uint32_t version, const char *name, bool is_sender);
|
||||
int (*connect_done)(struct eis_client *client);
|
||||
int (*disconnect)(struct eis_client *client);
|
||||
int (*bind_seat)(struct eis_client *client, uint32_t seatid, enum eis_device_capability cap);
|
||||
|
|
|
|||
|
|
@ -517,6 +517,12 @@ eis_client_set_user_data(struct eis_client *eis_client, void *user_data);
|
|||
const char *
|
||||
eis_client_get_name(struct eis_client *client);
|
||||
|
||||
/**
|
||||
* Return the protocol version supported by this client.
|
||||
*/
|
||||
uint32_t
|
||||
eis_client_get_version(struct eis_client *client);
|
||||
|
||||
/**
|
||||
* Allow connection from the client. This can only be done once, further
|
||||
* calls to this functions are ignored.
|
||||
|
|
|
|||
|
|
@ -731,6 +731,9 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
switch (eis_event_get_type(e)) {
|
||||
case EIS_EVENT_CLIENT_CONNECT:
|
||||
case EIS_EVENT_CLIENT_DISCONNECT:
|
||||
/* version is currently hardcoded, remove when necessary */
|
||||
munit_assert_int(eis_client_get_version(eis_event_get_client(e)), ==, 1);
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT) ||
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_CLIENT))
|
||||
process_event = tristate_yes;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "util-munit.h"
|
||||
#include "util-version.h"
|
||||
|
||||
#include "eierpecken.h"
|
||||
|
||||
|
|
@ -45,6 +46,26 @@ MUNIT_TEST(eistest_ref_unref)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_version)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *connect = peck_eis_next_event(eis, EIS_EVENT_CLIENT_CONNECT);
|
||||
struct eis_client *client = eis_event_get_client(connect);
|
||||
|
||||
/* We can't set the client version yet, but we know it's hardcoded to 1 */
|
||||
munit_assert_int(eis_client_get_version(client), ==, VERSION_V(1));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_name)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue