mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-28 17:50:07 +01:00
brei: add the brei_result object and bubble it up as error case
Add a new simple object "brei_result" that maps to the protocol-type reason + explanation. That object is now returned instead of the errno, giving us better debugging options. This changes the dispatcher functions from returning an int to returning a brei_result instead (default NULL for success). A helper function for converting a neg errno to a result is provided for convenience for now, eventually all these paths should deal with things correctly.
This commit is contained in:
parent
579f0d07d2
commit
e67a0a7777
14 changed files with 392 additions and 241 deletions
|
|
@ -28,8 +28,10 @@
|
|||
|
||||
#include "util-mem.h"
|
||||
#include "util-io.h"
|
||||
#include "util-strings.h"
|
||||
|
||||
#include "brei-shared.h"
|
||||
#include "brei-proto.h"
|
||||
|
||||
struct brei_context {
|
||||
struct object object;
|
||||
|
|
@ -51,6 +53,59 @@ OBJECT_IMPLEMENT_UNREF_CLEANUP(brei_context);
|
|||
OBJECT_IMPLEMENT_SETTER(brei_context, log_func, brei_logfunc_t);
|
||||
OBJECT_IMPLEMENT_SETTER(brei_context, log_context, void *);
|
||||
|
||||
static void
|
||||
brei_result_destroy(struct brei_result *res)
|
||||
{
|
||||
free(res->explanation);
|
||||
}
|
||||
|
||||
static
|
||||
OBJECT_IMPLEMENT_CREATE(brei_result);
|
||||
OBJECT_IMPLEMENT_GETTER(brei_result, data, void *);
|
||||
OBJECT_IMPLEMENT_SETTER(brei_result, data, void *);
|
||||
OBJECT_IMPLEMENT_GETTER(brei_result, reason, int);
|
||||
OBJECT_IMPLEMENT_GETTER(brei_result, explanation, const char *);
|
||||
OBJECT_IMPLEMENT_REF(brei_result);
|
||||
OBJECT_IMPLEMENT_UNREF_CLEANUP(brei_result);
|
||||
|
||||
struct brei_result *
|
||||
brei_result_new(int reason,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
struct brei_result *result = brei_result_create(NULL);
|
||||
result->reason = reason;
|
||||
if (format) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
result->explanation = xvaprintf(format, args);
|
||||
va_end(args);
|
||||
} else {
|
||||
assert(reason == 0); /* Any error needs an explanation */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct brei_result *
|
||||
brei_result_new_success(void *data)
|
||||
{
|
||||
struct brei_result *result = brei_result_new(0, NULL);
|
||||
|
||||
result->data = data;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct brei_result *
|
||||
brei_result_new_from_neg_errno(int err)
|
||||
{
|
||||
if (err >= 0)
|
||||
return NULL;
|
||||
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"%s", strerror(-err));
|
||||
}
|
||||
|
||||
struct brei_context *
|
||||
brei_context_new(void *parent_context)
|
||||
{
|
||||
|
|
@ -107,13 +162,14 @@ bytes_to_int32(uint32_t count)
|
|||
return (uint32_t)(((uint64_t)count + 3)/4);
|
||||
}
|
||||
|
||||
static int
|
||||
brei_demarshal(struct brei_context *brei, struct iobuf *buf, const char *signature, union brei_arg **args_out)
|
||||
static struct brei_result *
|
||||
brei_demarshal(struct brei_context *brei, struct iobuf *buf, const char *signature,
|
||||
size_t *nargs_out, union brei_arg **args_out)
|
||||
{
|
||||
size_t nargs = strlen(signature);
|
||||
if (nargs > 256) {
|
||||
log_bug(brei, "Too many arguments in signature (%zu)", nargs);
|
||||
return -EPROTO;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Too many arguments in signature (%zu)", nargs);
|
||||
}
|
||||
|
||||
/* This over-allocates if we have more than one char per type but meh */
|
||||
|
|
@ -146,16 +202,16 @@ brei_demarshal(struct brei_context *brei, struct iobuf *buf, const char *signatu
|
|||
|
||||
uint32_t slen32 = bytes_to_int32(slen);
|
||||
if (end - p < slen32) {
|
||||
log_bug_client(brei, "Invalid string length %zu, only %li bytes remaining", slen, (end - p) * 4);
|
||||
return -EINVAL;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Invalid string length %zu, only %li bytes remaining", slen, (end - p) * 4);
|
||||
}
|
||||
|
||||
const char *str = (char*)p;
|
||||
|
||||
/* strings must be null-terminated */
|
||||
if (slen && str[slen - 1] != '\0') {
|
||||
log_bug_client(brei, "Message string not zero-terminated");
|
||||
return -EINVAL;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Message string not zero-terminated");
|
||||
}
|
||||
|
||||
arg->s = str;
|
||||
|
|
@ -163,8 +219,8 @@ brei_demarshal(struct brei_context *brei, struct iobuf *buf, const char *signatu
|
|||
break;
|
||||
}
|
||||
default:
|
||||
log_bug(brei, "Invalid signature '%c'", *s);
|
||||
return -EBADMSG;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Invalid signature '%c'", *s);
|
||||
}
|
||||
arg++;
|
||||
s++;
|
||||
|
|
@ -172,11 +228,12 @@ brei_demarshal(struct brei_context *brei, struct iobuf *buf, const char *signatu
|
|||
}
|
||||
|
||||
*args_out = steal(&args);
|
||||
*nargs_out = nargs;
|
||||
|
||||
return nargs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
brei_marshal(struct brei_context *brei, struct iobuf *buf, const char *signature, size_t nargs, va_list args)
|
||||
{
|
||||
const char *s = signature;
|
||||
|
|
@ -220,23 +277,22 @@ brei_marshal(struct brei_context *brei, struct iobuf *buf, const char *signature
|
|||
break;
|
||||
}
|
||||
default:
|
||||
log_bug(brei, "Invalid signature '%c'", *s);
|
||||
return -EBADMSG;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Invalid signature '%c'", *s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
brei_send_message(struct brei_context *brei,
|
||||
int fd,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
size_t nargs,
|
||||
va_list args)
|
||||
struct brei_result *
|
||||
brei_marshal_message(struct brei_context *brei,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
size_t nargs,
|
||||
va_list args)
|
||||
{
|
||||
uint32_t message_len = 0; /* we'll overwrite this later */
|
||||
|
||||
|
|
@ -245,31 +301,33 @@ brei_send_message(struct brei_context *brei,
|
|||
iobuf_append(buf, (const char *)&id, 4);
|
||||
iobuf_append(buf, (const char *)&opcode, 4);
|
||||
|
||||
int rc = brei_marshal(brei, buf, signature, nargs, args);
|
||||
_unref_(brei_result) *result = brei_marshal(brei, buf, signature, nargs, args);
|
||||
if (result)
|
||||
return steal(&result);
|
||||
|
||||
if (rc == 0) {
|
||||
/* now write the actual message length, including header */
|
||||
*(uint32_t*)iobuf_data(buf) = iobuf_len(buf);
|
||||
rc = iobuf_send(buf, fd);
|
||||
}
|
||||
/* now write the actual message length, including header */
|
||||
*(uint32_t*)iobuf_data(buf) = iobuf_len(buf);
|
||||
|
||||
return rc;
|
||||
return brei_result_new_success(steal(&buf));
|
||||
}
|
||||
|
||||
int
|
||||
struct brei_result *
|
||||
brei_dispatch(struct brei_context *brei,
|
||||
int fd,
|
||||
int (*lookup_object)(uint32_t object_id, struct brei_object **object, void *user_data),
|
||||
void *user_data)
|
||||
{
|
||||
_unref_(brei_result) *result = NULL;
|
||||
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(64);
|
||||
int rc = iobuf_recv_from_fd(buf, fd);
|
||||
if (rc == -EAGAIN) {
|
||||
return 0;
|
||||
return NULL;
|
||||
} else if (rc == 0) {
|
||||
return -ECANCELED;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"socket disconnected");
|
||||
} else if (rc < 0) {
|
||||
return rc;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"error: %s", strerror(-rc));
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
|
@ -295,8 +353,11 @@ brei_dispatch(struct brei_context *brei,
|
|||
iobuf_pop(buf, msglen);
|
||||
continue;
|
||||
}
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
result = brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"lookup_object failed with %d (%s)", -rc, strerror(-rc));
|
||||
goto error;
|
||||
}
|
||||
|
||||
assert(object);
|
||||
|
||||
|
|
@ -306,9 +367,9 @@ brei_dispatch(struct brei_context *brei,
|
|||
assert(interface);
|
||||
|
||||
if (opcode >= interface->nincoming) {
|
||||
log_bug_client(brei, "opcode %u exceeds interface %s method count %u",
|
||||
opcode, interface->name, interface->nincoming);
|
||||
rc = -EINVAL;
|
||||
result = brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"opcode %u exceeds interface %s method count %u",
|
||||
opcode, interface->name, interface->nincoming);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -317,28 +378,28 @@ brei_dispatch(struct brei_context *brei,
|
|||
/* Demarshal the protocol into a set of arguments */
|
||||
_cleanup_free_ union brei_arg * args = NULL;
|
||||
const char *signature = interface->incoming[opcode].signature;
|
||||
int nargs = brei_demarshal(brei, buf, signature, &args);
|
||||
if (nargs < 0) {
|
||||
rc = nargs;
|
||||
size_t nargs = 0;
|
||||
result = brei_demarshal(brei, buf, signature, &nargs, &args);
|
||||
if (result)
|
||||
goto error;
|
||||
}
|
||||
|
||||
log_debug(brei, "dispatching %s.%s() on object %#x", interface->name, interface->incoming[opcode].name, object_id);
|
||||
|
||||
/* Success! Let's pass this on to the
|
||||
* context to process */
|
||||
rc = interface->dispatcher(object->implementation, opcode, nargs, args);
|
||||
if (rc < 0) {
|
||||
log_error(brei, "dispatch failed with %d (%s)", -rc, strerror(-rc));
|
||||
result = interface->dispatcher(object->implementation, opcode, nargs, args);
|
||||
if (result)
|
||||
goto error;
|
||||
}
|
||||
|
||||
iobuf_pop(buf, msglen - headersize);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
error:
|
||||
return rc;
|
||||
if (result) {
|
||||
log_error(brei, "%s", brei_result_get_explanation(result));
|
||||
return steal(&result);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -355,15 +416,15 @@ brei_drain_fd(int fd)
|
|||
#ifdef _enable_tests_
|
||||
#include "util-munit.h"
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
brei_marshal_va(struct brei_context *brei, struct iobuf *buf, const char *signature, size_t nargs, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, nargs);
|
||||
int rc = brei_marshal(brei, buf, signature, nargs, args);
|
||||
struct brei_result *result = brei_marshal(brei, buf, signature, nargs, args);
|
||||
va_end(args);
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_brei_marshal)
|
||||
|
|
@ -372,12 +433,16 @@ MUNIT_TEST(test_brei_marshal)
|
|||
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(64);
|
||||
const char *str = "eierspeise";
|
||||
|
||||
int rc = brei_marshal_va(brei, buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
{
|
||||
_unref_(brei_result) *result = brei_marshal_va(brei, buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
munit_assert_ptr_null(result);
|
||||
}
|
||||
|
||||
_cleanup_free_ union brei_arg *args = NULL;
|
||||
rc = brei_demarshal(brei, buf, "noiusf", &args);
|
||||
munit_assert_int(rc, ==, 6);
|
||||
size_t nargs = 0;
|
||||
_unref_(brei_result) *result = brei_demarshal(brei, buf, "noiusf", &nargs, &args);
|
||||
munit_assert_ptr_null(result);
|
||||
munit_assert_int(nargs, ==, 6);
|
||||
|
||||
munit_assert_int(args[0].o, ==, 0xab);
|
||||
munit_assert_int(args[1].o, ==, 0xcd);
|
||||
|
|
@ -395,16 +460,41 @@ MUNIT_TEST(test_brei_marshal_bad_sig)
|
|||
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(64);
|
||||
const char *str = "eierspeise";
|
||||
|
||||
int rc = brei_marshal_va(brei, buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
{
|
||||
_unref_(brei_result) *result = brei_marshal_va(brei, buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
munit_assert_ptr_null(result);
|
||||
}
|
||||
|
||||
_cleanup_free_ union brei_arg *args = NULL;
|
||||
rc = brei_demarshal(brei, buf, "nxoiusf", &args);
|
||||
munit_assert_int(rc, ==, -EBADMSG);
|
||||
size_t nargs = 789;
|
||||
_unref_(brei_result) *result = brei_demarshal(brei, buf, "nxoiusf", &nargs, &args);
|
||||
munit_assert_ptr_not_null(result);
|
||||
munit_assert_int(brei_result_get_reason(result), ==,
|
||||
BREI_CONNECTION_DISCONNECT_REASON_ERROR);
|
||||
munit_assert_int(nargs, ==, 789); /* nargs must not be touched on error */
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
brei_send_message(struct brei_context *brei,
|
||||
int fd,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
size_t nargs,
|
||||
va_list args)
|
||||
{
|
||||
_unref_(brei_result) *result = brei_marshal_message(brei, id, opcode, signature, nargs, args);
|
||||
|
||||
if (brei_result_get_reason(result) != 0)
|
||||
return -EBADMSG;
|
||||
|
||||
_cleanup_iobuf_ struct iobuf *buf = NULL;
|
||||
buf = brei_result_get_data(result);
|
||||
return iobuf_send(buf, fd);
|
||||
}
|
||||
|
||||
static int
|
||||
brei_send_message_va(int fd, uint32_t id, uint32_t opcode,
|
||||
const char *signature, size_t nargs, ...)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "util-macros.h"
|
||||
#include "util-list.h"
|
||||
#include "util-object.h"
|
||||
|
||||
|
|
@ -39,6 +40,29 @@ struct brei_object;
|
|||
|
||||
struct brei_context;
|
||||
|
||||
struct brei_result {
|
||||
struct object object;
|
||||
int reason; /* enum ei(s)_connection_disconnect_reason */
|
||||
char *explanation;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct brei_result *
|
||||
brei_result_new_success(void *data);
|
||||
|
||||
struct brei_result *
|
||||
brei_result_new_from_neg_errno(int err);
|
||||
|
||||
_printf_(2, 3) struct brei_result *
|
||||
brei_result_new(int reson, const char *format, ...);
|
||||
|
||||
OBJECT_DECLARE_GETTER(brei_result, data, void *);
|
||||
OBJECT_DECLARE_SETTER(brei_result, data, void *);
|
||||
OBJECT_DECLARE_GETTER(brei_result, reason, int);
|
||||
OBJECT_DECLARE_GETTER(brei_result, explanation, const char *);
|
||||
OBJECT_DECLARE_REF(brei_result);
|
||||
OBJECT_DECLARE_UNREF(brei_result);
|
||||
|
||||
enum brei_log_priority {
|
||||
BREI_LOG_PRIORITY_DEBUG = 10,
|
||||
BREI_LOG_PRIORITY_INFO = 20,
|
||||
|
|
@ -73,8 +97,8 @@ struct brei_message {
|
|||
const struct brei_interface **types;
|
||||
};
|
||||
|
||||
typedef int (*brei_event_dispatcher)(void *object, uint32_t opcode,
|
||||
size_t nargs, union brei_arg *args);
|
||||
typedef struct brei_result * (*brei_event_dispatcher)(void *object, uint32_t opcode,
|
||||
size_t nargs, union brei_arg *args);
|
||||
|
||||
struct brei_interface {
|
||||
const char *name;
|
||||
|
|
@ -98,14 +122,18 @@ struct brei_object {
|
|||
struct list link; /* in the ei/eis object list */
|
||||
};
|
||||
|
||||
int
|
||||
brei_send_message(struct brei_context *brei,
|
||||
int fd,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
size_t nargs,
|
||||
va_list args);
|
||||
/**
|
||||
* Marshal the message for the given object id, opcode and signature into
|
||||
* a struct iobuf. On succes, the returned result has that iobuf
|
||||
* as brei_result_get_data(), otherwise the result is the error.
|
||||
*/
|
||||
struct brei_result *
|
||||
brei_marshal_message(struct brei_context *brei,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
size_t nargs,
|
||||
va_list args);
|
||||
|
||||
/**
|
||||
* Dispatch messages for the data on fd.
|
||||
|
|
@ -115,9 +143,9 @@ brei_send_message(struct brei_context *brei,
|
|||
* On success, the callback must return the number of bytes consumed in msgdata
|
||||
* On failure, the callback must return a negative errno
|
||||
*
|
||||
* @return zero on success or a negative errno otherwise
|
||||
* @return NULL on success or a struct with the error reason
|
||||
*/
|
||||
int
|
||||
struct brei_result *
|
||||
brei_dispatch(struct brei_context *brei,
|
||||
int fd,
|
||||
int (*lookup_object)(uint32_t object_id, struct brei_object **object, void *user_data),
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include "brei-shared.h"
|
||||
#include "brei-proto.h"
|
||||
|
||||
{% if headerfile %}
|
||||
#include "{{headerfile}}"
|
||||
|
|
@ -101,7 +102,7 @@ int
|
|||
* The dispatcher for the {{interface.name}} interface is the function called by
|
||||
* brei with the messages parsed from the wire.
|
||||
*/
|
||||
static int
|
||||
static struct brei_result *
|
||||
{{interface.name}}_dispatcher(
|
||||
{{interface.as_arg}},
|
||||
uint32_t opcode,
|
||||
|
|
@ -116,13 +117,15 @@ static int
|
|||
{% for incoming in interface.incoming %}
|
||||
case {{incoming.fqdn.upper()}}:
|
||||
if (obj->version < {{incoming.fqdn.upper()}}_SINCE_VERSION)
|
||||
return -ENOTSUP;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Opcode %u not supported in this interface version\n", opcode);
|
||||
assert(interface->{{incoming.name}} != NULL);
|
||||
return interface->{{incoming.name}}({{interface.name}}{% for arg in incoming.arguments %}, (args + {{loop.index - 1}})->{{arg.signature}}{% endfor %});
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
return -EINVAL;
|
||||
return brei_result_new(BREI_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
"Opcode %u not supported in this interface version\n", opcode);
|
||||
}
|
||||
|
||||
static const struct brei_message {{interface.name}}_requests[] = {
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ extern int
|
|||
*/
|
||||
struct {{interface.name}}_interface {
|
||||
{% for incoming in interface.incoming %}
|
||||
int (*{{incoming.name}})({{interface.as_arg}}{%- for arg in incoming.arguments %}, {{arg.as_arg}}{% endfor %});
|
||||
struct brei_result * (*{{incoming.name}})({{interface.as_arg}}{%- for arg in incoming.arguments %}, {{arg.as_arg}}{% endfor %});
|
||||
{% endfor %}
|
||||
};
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -68,11 +68,11 @@ ei_callback_get_id(struct ei_callback *callback)
|
|||
return callback->proto_object.id;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_done(struct ei_callback *callback, uint32_t callback_data)
|
||||
{
|
||||
callback->func(callback, callback->callback_data, callback_data);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_callback_interface interface = {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ ei_connection_setup_initialize(struct ei_connection_setup *setup, uint32_t versi
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_interface_version(struct ei_connection_setup *setup, const char *name, uint32_t version)
|
||||
{
|
||||
struct ei *ei = ei_connection_setup_get_context(setup);
|
||||
|
|
@ -128,7 +128,7 @@ handle_msg_interface_version(struct ei_connection_setup *setup, const char *name
|
|||
|
||||
#undef VERSION_UPDATE
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -143,7 +143,7 @@ connected(struct ei_connection *connection, void *user_data)
|
|||
ei_connected(ei);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_connection(struct ei_connection_setup *setup, uint32_t id, uint32_t version)
|
||||
{
|
||||
struct ei *ei = ei_connection_setup_get_context(setup);
|
||||
|
|
@ -159,7 +159,7 @@ handle_msg_connection(struct ei_connection_setup *setup, uint32_t id, uint32_t v
|
|||
* sync callback, we didn't immediately get disconnected */
|
||||
ei_connection_sync(ei->connection, connected, NULL);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_connection_setup_interface interface = {
|
||||
|
|
|
|||
|
|
@ -125,44 +125,44 @@ ei_device_get_context(struct ei_device *device)
|
|||
return ei_seat_get_context(ei_device_get_seat(device));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_destroy(struct ei_device *device)
|
||||
{
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
log_debug(ei, "Removed device %#x", ei_device_get_id(device));
|
||||
ei_device_removed_by_server(device);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_name(struct ei_device *device, const char *name)
|
||||
{
|
||||
ei_device_set_name(device, name);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_capabilities(struct ei_device *device, uint32_t caps)
|
||||
{
|
||||
ei_device_set_capabilities(device, caps);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_type(struct ei_device *device, enum ei_device_type type)
|
||||
{
|
||||
ei_device_set_type(device, type);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_dimensions(struct ei_device *device, uint32_t width, uint32_t height)
|
||||
{
|
||||
ei_device_set_size(device, width, height);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_region(struct ei_device *device, uint32_t x, uint32_t y,
|
||||
uint32_t w, uint32_t h, float scale)
|
||||
{
|
||||
|
|
@ -172,10 +172,10 @@ handle_msg_region(struct ei_device *device, uint32_t x, uint32_t y,
|
|||
ei_region_set_physical_scale(r, scale);
|
||||
ei_device_add_region(device, r);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_done(struct ei_device *device)
|
||||
{
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
|
|
@ -191,37 +191,37 @@ handle_msg_done(struct ei_device *device)
|
|||
ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD) ? "k" : "",
|
||||
ei_device_has_capability(device, EI_DEVICE_CAP_TOUCH) ? "t" : "",
|
||||
ei_seat_get_name(ei_device_get_seat(device)));
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_resumed(struct ei_device *device)
|
||||
{
|
||||
ei_device_resumed(device);
|
||||
ei_queue_device_resumed_event(device);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_paused(struct ei_device *device)
|
||||
{
|
||||
ei_device_paused(device);
|
||||
ei_queue_device_paused_event(device);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define DISCONNECT_IF_SENDER_CONTEXT(device_) do {\
|
||||
struct ei *ei_ = ei_device_get_context(device_); \
|
||||
if (ei_is_sender(ei_)) { \
|
||||
log_bug_client(ei_, "Invalid event from receiver EIS context. Disconnecting"); \
|
||||
return -ECANCELED; \
|
||||
return brei_result_new_from_neg_errno(-ECANCELED); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_start_emulating(struct ei_device *device, uint32_t sequence)
|
||||
{
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
|
@ -241,10 +241,10 @@ handle_msg_start_emulating(struct ei_device *device, uint32_t sequence)
|
|||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_stop_emulating(struct ei_device *device)
|
||||
{
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
|
@ -264,50 +264,50 @@ handle_msg_stop_emulating(struct ei_device *device)
|
|||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_frame(struct ei_device *device, uint32_t time, uint32_t micros)
|
||||
{
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
ei_queue_frame_event(device, ms2us(time) + micros);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer(struct ei_device *device, uint32_t id, uint32_t version)
|
||||
{
|
||||
if (device->pointer)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
device->pointer = ei_pointer_new(device, id, version);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_keyboard(struct ei_device *device, uint32_t id, uint32_t version)
|
||||
{
|
||||
if (device->keyboard)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
device->keyboard = ei_keyboard_new(device, id, version);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_touchscreen(struct ei_device *device, uint32_t id, uint32_t version)
|
||||
{
|
||||
if (device->touchscreen)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
device->touchscreen = ei_touchscreen_new(device, id, version);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_device_interface interface = {
|
||||
|
|
@ -334,27 +334,27 @@ ei_device_get_interface(struct ei_device *device)
|
|||
return &interface;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_rel(struct ei_pointer *pointer, float x, float y)
|
||||
{
|
||||
struct ei_device *device = ei_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_pointer_rel(device, x, y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_rel(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_abs(struct ei_pointer *pointer, float x, float y)
|
||||
{
|
||||
struct ei_device *device = ei_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_pointer_abs(device, x, y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_abs(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_button(struct ei_pointer *pointer,
|
||||
uint32_t button, uint32_t state)
|
||||
{
|
||||
|
|
@ -362,20 +362,20 @@ handle_msg_pointer_button(struct ei_pointer *pointer,
|
|||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_pointer_button(device, button, !!state);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_button(device, button, !!state));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_scroll(struct ei_pointer *pointer, float x, float y)
|
||||
{
|
||||
struct ei_device *device = ei_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_pointer_scroll(device, x, y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_scroll(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_scroll_discrete(struct ei_pointer *pointer,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
|
|
@ -383,10 +383,10 @@ handle_msg_pointer_scroll_discrete(struct ei_pointer *pointer,
|
|||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_pointer_scroll_discrete(device, x, y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_scroll_discrete(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_scroll_stop(struct ei_pointer *pointer,
|
||||
uint32_t x, uint32_t y, uint32_t is_cancel)
|
||||
{
|
||||
|
|
@ -395,20 +395,20 @@ handle_msg_pointer_scroll_stop(struct ei_pointer *pointer,
|
|||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
if (is_cancel)
|
||||
return ei_device_event_pointer_scroll_cancel(device, !!x, !!y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_scroll_cancel(device, !!x, !!y));
|
||||
else
|
||||
return ei_device_event_pointer_scroll_stop(device, !!x, !!y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_pointer_scroll_stop(device, !!x, !!y));
|
||||
|
||||
return -EINVAL;
|
||||
return brei_result_new_from_neg_errno(-EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_pointer_destroy(struct ei_pointer *pointer)
|
||||
{
|
||||
struct ei_device *device = ei_pointer_get_device(pointer);
|
||||
ei_pointer_unref(steal(&device->pointer));
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_pointer_interface pointer_interface = {
|
||||
|
|
@ -427,27 +427,27 @@ ei_device_get_pointer_interface(struct ei_device *device)
|
|||
return &pointer_interface;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_keymap(struct ei_keyboard *keyboard, uint32_t keymap_type, uint32_t keymap_sz, int keymap_fd)
|
||||
{
|
||||
struct ei_device *device = ei_keyboard_get_device(keyboard);
|
||||
|
||||
ei_device_set_keymap(device, keymap_type, keymap_fd, keymap_sz);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_keyboard_key(struct ei_keyboard *keyboard, uint32_t key, uint32_t state)
|
||||
{
|
||||
struct ei_device *device = ei_keyboard_get_device(keyboard);
|
||||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_keyboard_key(device, key, !!state);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_keyboard_key(device, key, !!state));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_keyboard_modifiers(struct ei_keyboard *keyboard, uint32_t depressed,
|
||||
uint32_t locked, uint32_t latched, uint32_t group)
|
||||
{
|
||||
|
|
@ -456,7 +456,7 @@ handle_msg_keyboard_modifiers(struct ei_keyboard *keyboard, uint32_t depressed,
|
|||
|
||||
if (!ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD)) {
|
||||
log_bug(ei,"Modifier event for non-keyboard");
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
}
|
||||
|
||||
struct ei_xkb_modifiers mods = {
|
||||
|
|
@ -468,17 +468,17 @@ handle_msg_keyboard_modifiers(struct ei_keyboard *keyboard, uint32_t depressed,
|
|||
|
||||
ei_queue_keyboard_modifiers_event(device, &mods);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_keyboard_destroy(struct ei_keyboard *keyboard)
|
||||
{
|
||||
|
||||
struct ei_device *device = ei_keyboard_get_device(keyboard);
|
||||
ei_keyboard_unref(steal(&device->keyboard));
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_keyboard_interface keyboard_interface = {
|
||||
|
|
@ -494,7 +494,7 @@ ei_device_get_keyboard_interface(struct ei_device *device)
|
|||
return &keyboard_interface;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_touch_down(struct ei_touchscreen *touchscreen,
|
||||
uint32_t touchid, float x, float y)
|
||||
{
|
||||
|
|
@ -502,10 +502,10 @@ handle_msg_touch_down(struct ei_touchscreen *touchscreen,
|
|||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_touch_down(device, touchid, x, y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_touch_down(device, touchid, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_touch_motion(struct ei_touchscreen *touchscreen,
|
||||
uint32_t touchid, float x, float y)
|
||||
{
|
||||
|
|
@ -513,27 +513,27 @@ handle_msg_touch_motion(struct ei_touchscreen *touchscreen,
|
|||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_touch_motion(device, touchid, x, y);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_touch_motion(device, touchid, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_touch_up(struct ei_touchscreen *touchscreen, uint32_t touchid)
|
||||
{
|
||||
struct ei_device *device = ei_touchscreen_get_device(touchscreen);
|
||||
|
||||
DISCONNECT_IF_SENDER_CONTEXT(device);
|
||||
|
||||
return ei_device_event_touch_up(device, touchid);
|
||||
return brei_result_new_from_neg_errno(ei_device_event_touch_up(device, touchid));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_touchscreen_destroy(struct ei_touchscreen *touchscreen)
|
||||
{
|
||||
|
||||
struct ei_device *device = ei_touchscreen_get_device(touchscreen);
|
||||
ei_touchscreen_unref(steal(&device->touchscreen));
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_touchscreen_interface touchscreen_interface = {
|
||||
|
|
|
|||
|
|
@ -69,36 +69,40 @@ ei_seat_get_id(struct ei_seat *seat) {
|
|||
return seat->proto_object.id;
|
||||
}
|
||||
|
||||
static int handle_msg_destroyed(struct ei_seat *seat)
|
||||
static struct brei_result *
|
||||
handle_msg_destroyed(struct ei_seat *seat)
|
||||
{
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
|
||||
log_debug(ei, "server removed seat %s", seat->name);
|
||||
ei_seat_remove(seat);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int handle_msg_name(struct ei_seat *seat, const char * name)
|
||||
static struct brei_result *
|
||||
handle_msg_name(struct ei_seat *seat, const char * name)
|
||||
{
|
||||
if (seat->name != NULL)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
seat->name = xstrdup(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_msg_capabilities(struct ei_seat *seat, uint32_t capabilities)
|
||||
static struct brei_result *
|
||||
handle_msg_capabilities(struct ei_seat *seat, uint32_t capabilities)
|
||||
{
|
||||
if (seat->capabilities != 0)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
seat->capabilities = capabilities;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_msg_done(struct ei_seat *seat)
|
||||
static struct brei_result *
|
||||
handle_msg_done(struct ei_seat *seat)
|
||||
{
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
|
||||
|
|
@ -106,10 +110,11 @@ static int handle_msg_done(struct ei_seat *seat)
|
|||
log_debug(ei, "Added seat '%s' with caps %#x", seat->name, seat->capabilities);
|
||||
ei_add_seat(seat);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int handle_msg_device(struct ei_seat *seat, uint32_t id, uint32_t version)
|
||||
static struct brei_result *
|
||||
handle_msg_device(struct ei_seat *seat, uint32_t id, uint32_t version)
|
||||
{
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
|
||||
|
|
@ -119,7 +124,7 @@ static int handle_msg_device(struct ei_seat *seat, uint32_t id, uint32_t version
|
|||
/* this list "owns" the ref for this device */
|
||||
list_append(&seat->devices, &device->link);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ei_seat_interface interface = {
|
||||
|
|
|
|||
46
src/libei.c
46
src/libei.c
|
|
@ -81,6 +81,7 @@ _public_
|
|||
OBJECT_IMPLEMENT_GETTER(ei, user_data, void *);
|
||||
OBJECT_IMPLEMENT_GETTER(ei, connection, struct ei_connection *);
|
||||
|
||||
DEFINE_UNREF_CLEANUP_FUNC(brei_result);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_device);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_region);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_pingpong);
|
||||
|
|
@ -594,7 +595,7 @@ ei_disconnect(struct ei *ei)
|
|||
ei->source = source_unref(ei->source);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_seat(struct ei_connection *connection, uint32_t seat_id, uint32_t version)
|
||||
{
|
||||
struct ei *ei = ei_connection_get_context(connection);
|
||||
|
|
@ -608,7 +609,7 @@ handle_msg_seat(struct ei_connection *connection, uint32_t seat_id, uint32_t ver
|
|||
/* seats list owns the ref */
|
||||
list_append(&ei->seats, &seat->link);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -660,7 +661,7 @@ ei_connected(struct ei *ei)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_disconnected(struct ei_connection *connection, uint32_t reason, const char *explanation)
|
||||
{
|
||||
struct ei *ei = ei_connection_get_context(connection);
|
||||
|
|
@ -670,20 +671,20 @@ handle_msg_disconnected(struct ei_connection *connection, uint32_t reason, const
|
|||
else
|
||||
log_info(ei, "Disconnected after error: %s", explanation);
|
||||
|
||||
return -ECANCELED;
|
||||
return brei_result_new_from_neg_errno(-ECANCELED);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_invalid_object(struct ei_connection *connection, uint32_t object)
|
||||
{
|
||||
struct ei *ei = ei_connection_get_context(connection);
|
||||
|
||||
log_bug(ei, "Invalid object %#x, I don't yet know how to handle that", object);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
handle_msg_ping(struct ei_connection *connection, uint32_t id, uint32_t version)
|
||||
{
|
||||
struct ei *ei = ei_connection_get_context(connection);
|
||||
|
|
@ -691,7 +692,7 @@ handle_msg_ping(struct ei_connection *connection, uint32_t id, uint32_t version
|
|||
|
||||
ei_pingpong_request_done(pingpong, 0);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define DISCONNECT_IF_SENDER_CONTEXT(ei_) do {\
|
||||
|
|
@ -738,8 +739,9 @@ connection_dispatch(struct source *source, void *userdata)
|
|||
struct ei *ei = userdata;
|
||||
enum ei_state old_state = ei->state;
|
||||
|
||||
int rc = brei_dispatch(ei->brei, source_get_fd(source), lookup_object, ei);
|
||||
if (rc < 0) {
|
||||
_unref_(brei_result) *result = brei_dispatch(ei->brei, source_get_fd(source),
|
||||
lookup_object, ei);
|
||||
if (result) {
|
||||
brei_drain_fd(source_get_fd(source));
|
||||
ei_disconnect(ei);
|
||||
}
|
||||
|
|
@ -752,10 +754,8 @@ connection_dispatch(struct source *source, void *userdata)
|
|||
"DISCONNECTED",
|
||||
"DISCONNECTING",
|
||||
};
|
||||
if (rc == -ECANCELED)
|
||||
log_info(ei, "Disconnected");
|
||||
else if (rc)
|
||||
log_warn(ei, "Connection error: %s", strerror(-rc));
|
||||
if (result)
|
||||
log_warn(ei, "Connection error: %s", brei_result_get_explanation(result));
|
||||
|
||||
if (old_state != ei->state)
|
||||
log_debug(ei, "Connection dispatch: %s -> %s",
|
||||
|
|
@ -767,8 +767,6 @@ int
|
|||
ei_send_message(struct ei *ei, const struct brei_object *object,
|
||||
uint32_t opcode, const char *signature, size_t nargs, ...)
|
||||
{
|
||||
int fd = source_get_fd(ei->source);
|
||||
|
||||
log_debug(ei, "sending: object %#x (%s@v%u:%s(%u)) signature '%s'",
|
||||
object->id,
|
||||
object->interface->name,
|
||||
|
|
@ -779,8 +777,22 @@ ei_send_message(struct ei *ei, const struct brei_object *object,
|
|||
|
||||
va_list args;
|
||||
va_start(args, nargs);
|
||||
int rc = brei_send_message(ei->brei, fd, object->id, opcode, signature, nargs, args);
|
||||
_unref_(brei_result) *result = brei_marshal_message(ei->brei,
|
||||
object->id,
|
||||
opcode, signature,
|
||||
nargs, args);
|
||||
va_end(args);
|
||||
|
||||
if (brei_result_get_reason(result) != 0) {
|
||||
log_warn(ei, "failed to marshal message: %s",
|
||||
brei_result_get_explanation(result));
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
_cleanup_iobuf_ struct iobuf *buf = brei_result_get_data(result);
|
||||
assert(buf);
|
||||
int fd = source_get_fd(ei->source);
|
||||
int rc = iobuf_send(buf, fd);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "eis-proto.h"
|
||||
|
||||
DEFINE_TRISTATE(started, finished, connected);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(brei_result);
|
||||
|
||||
static void
|
||||
eis_client_destroy(struct eis_client *client)
|
||||
|
|
@ -147,7 +148,6 @@ eis_client_send_message(struct eis_client *client, const struct brei_object *obj
|
|||
uint32_t opcode, const char *signature, size_t nargs, ...)
|
||||
{
|
||||
struct eis *eis = eis_client_get_context(client);
|
||||
int fd = source_get_fd(client->source);
|
||||
|
||||
log_debug(eis, "sending: object %#x (%s@v%u:%s(%u)) signature '%s'",
|
||||
object->id,
|
||||
|
|
@ -159,8 +159,22 @@ eis_client_send_message(struct eis_client *client, const struct brei_object *obj
|
|||
|
||||
va_list args;
|
||||
va_start(args, nargs);
|
||||
int rc = brei_send_message(client->brei, fd, object->id, opcode, signature, nargs, args);
|
||||
_unref_(brei_result) *result = brei_marshal_message(client->brei,
|
||||
object->id,
|
||||
opcode, signature,
|
||||
nargs, args);
|
||||
va_end(args);
|
||||
|
||||
if (brei_result_get_reason(result) != 0) {
|
||||
log_warn(eis, "failed to marshal message: %s",
|
||||
brei_result_get_explanation(result));
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
_cleanup_iobuf_ struct iobuf *buf = brei_result_get_data(result);
|
||||
assert(buf);
|
||||
int fd = source_get_fd(client->source);
|
||||
int rc = iobuf_send(buf, fd);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
|
|
@ -251,26 +265,26 @@ eis_client_setup_done(struct eis_client *client, const char *name, bool is_sende
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_disconnect(struct eis_connection *connection)
|
||||
{
|
||||
struct eis_client * client = eis_connection_get_client(connection);
|
||||
client_disconnect(client, EIS_CONNECTION_DISCONNECT_REASON_DISCONNECTED, NULL);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_sync(struct eis_connection *connection, uint32_t new_id)
|
||||
{
|
||||
if (new_id == 0)
|
||||
return -EINVAL;
|
||||
return brei_result_new_from_neg_errno(-EINVAL);
|
||||
|
||||
struct eis_client *client = eis_connection_get_client(connection);
|
||||
struct eis_callback *callback = eis_callback_new(client, new_id, client->interface_versions.ei_callback);
|
||||
log_debug(eis_client_get_context(client) , "object %u: connection sync done", new_id);
|
||||
int rc = eis_callback_event_done(callback, 0);
|
||||
eis_callback_unref(callback);
|
||||
return rc;
|
||||
return brei_result_new_from_neg_errno(rc);
|
||||
}
|
||||
|
||||
static const struct eis_connection_interface intf_state_new = {
|
||||
|
|
@ -329,12 +343,13 @@ client_dispatch(struct source *source, void *userdata)
|
|||
_unref_(eis_client) *client = eis_client_ref(userdata);
|
||||
enum eis_client_state old_state = client->state;
|
||||
|
||||
int rc = brei_dispatch(client->brei, source_get_fd(source), lookup_object, client);
|
||||
if (rc < 0) {
|
||||
_unref_(brei_result) *result = brei_dispatch(client->brei, source_get_fd(source),
|
||||
lookup_object, client);
|
||||
if (result) {
|
||||
brei_drain_fd(source_get_fd(source));
|
||||
client_disconnect(client,
|
||||
EIS_CONNECTION_DISCONNECT_REASON_ERROR,
|
||||
strerror(-rc));
|
||||
brei_result_get_reason(result),
|
||||
brei_result_get_explanation(result));
|
||||
}
|
||||
|
||||
static const char *client_states[] = {
|
||||
|
|
@ -343,11 +358,9 @@ client_dispatch(struct source *source, void *userdata)
|
|||
"CONNECTED",
|
||||
"DISCONNECTED",
|
||||
};
|
||||
if (rc == -ECANCELED)
|
||||
log_info(eis_client_get_context(client), "Disconnected");
|
||||
else if (rc)
|
||||
if (result)
|
||||
log_warn(eis_client_get_context(client), "Client error: %s",
|
||||
strerror(-rc));
|
||||
brei_result_get_explanation(result));
|
||||
if (old_state != client->state) {
|
||||
assert(old_state < ARRAY_LENGTH(client_states));
|
||||
assert(client->state < ARRAY_LENGTH(client_states));
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ pong(struct eis_connection *connection, void *user_data)
|
|||
eis_queue_connect_event(client);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_done(struct eis_connection_setup *setup)
|
||||
{
|
||||
struct eis_client *client = eis_connection_setup_get_client(setup);
|
||||
|
|
@ -91,7 +91,7 @@ client_msg_done(struct eis_connection_setup *setup)
|
|||
if (setup->client_versions.ei_connection == 0 ||
|
||||
setup->client_versions.ei_callback == 0 ||
|
||||
setup->client_versions.ei_pingpong == 0)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
/* ei_callback needs a client-created object, so tell the client
|
||||
* about our version */
|
||||
|
|
@ -117,21 +117,21 @@ client_msg_done(struct eis_connection_setup *setup)
|
|||
|
||||
client->setup = eis_connection_setup_unref(setup);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_name(struct eis_connection_setup *setup, const char *name)
|
||||
{
|
||||
if (setup->name)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
setup->name = xstrdup(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_context_type(struct eis_connection_setup *setup, uint32_t type)
|
||||
{
|
||||
switch(type) {
|
||||
|
|
@ -141,10 +141,10 @@ client_msg_context_type(struct eis_connection_setup *setup, uint32_t type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_interface_version(struct eis_connection_setup *setup, const char *name, uint32_t version)
|
||||
{
|
||||
struct eis_client *client = eis_connection_setup_get_client(setup);
|
||||
|
|
@ -174,14 +174,14 @@ client_msg_interface_version(struct eis_connection_setup *setup, const char *nam
|
|||
log_debug(eis, "client %#x supports %s version %u", client->id, name, version);
|
||||
|
||||
if (version == 0)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
|
||||
struct v *v;
|
||||
ARRAY_FOR_EACH(version_map, v) {
|
||||
if (streq(v->name, name)) {
|
||||
/* Versions must not be set twice */
|
||||
if (*v->client_version != 0)
|
||||
return -EPROTO;
|
||||
return brei_result_new_from_neg_errno(-EPROTO);
|
||||
*v->client_version = min(*v->server_version, version);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,11 +203,11 @@ eis_device_get_client(struct eis_device *device)
|
|||
return eis_seat_get_client(eis_device_get_seat(device));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_release(struct eis_device *device)
|
||||
{
|
||||
eis_device_closed_by_client(device);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define DISCONNECT_IF_RECEIVER_CONTEXT(device_) do { \
|
||||
|
|
@ -215,12 +215,12 @@ client_msg_release(struct eis_device *device)
|
|||
if (!eis_client_is_sender(client_)) { \
|
||||
struct eis *_ctx = eis_client_get_context(client_); \
|
||||
log_bug_client(_ctx, "Invalid event from receiver ei context. Disconnecting client"); \
|
||||
return -EINVAL; \
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_ERROR, "Invalid event from receiver ei context"); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_start_emulating(struct eis_device *device, uint32_t sequence)
|
||||
{
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
|
@ -242,7 +242,7 @@ client_msg_start_emulating(struct eis_device *device, uint32_t sequence)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_stop_emulating(struct eis_device *device)
|
||||
{
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
|
@ -263,17 +263,17 @@ client_msg_stop_emulating(struct eis_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_frame(struct eis_device *device, uint32_t time, uint32_t micros)
|
||||
{
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
return brei_result_new_from_neg_errno(-EINVAL);
|
||||
|
||||
eis_queue_frame_event(device, ms2us(time) + micros);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -290,57 +290,57 @@ eis_device_get_interface(struct eis_device *device)
|
|||
return &interface;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_rel(struct eis_pointer *pointer, float x, float y)
|
||||
{
|
||||
struct eis_device *device = eis_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_pointer_rel(device, x, y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_rel(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_abs(struct eis_pointer *pointer, float x, float y)
|
||||
{
|
||||
struct eis_device *device = eis_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_pointer_abs(device, x, y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_abs(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_button(struct eis_pointer *pointer, uint32_t button, uint32_t state)
|
||||
{
|
||||
struct eis_device *device = eis_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_pointer_button(device, button, !!state);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_button(device, button, !!state));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_scroll(struct eis_pointer *pointer, float x, float y)
|
||||
{
|
||||
struct eis_device *device = eis_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_pointer_scroll(device, x, y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_scroll_discrete(struct eis_pointer *pointer, int32_t x, int32_t y)
|
||||
{
|
||||
struct eis_device *device = eis_pointer_get_device(pointer);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_pointer_scroll_discrete(device, x, y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll_discrete(device, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_scroll_stop(struct eis_pointer *pointer,
|
||||
uint32_t x, uint32_t y, uint32_t is_cancel)
|
||||
{
|
||||
|
|
@ -349,12 +349,12 @@ client_msg_pointer_scroll_stop(struct eis_pointer *pointer,
|
|||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
if (is_cancel)
|
||||
return eis_device_event_pointer_scroll_cancel(device, !!x, !!y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll_cancel(device, !!x, !!y));
|
||||
else
|
||||
return eis_device_event_pointer_scroll_stop(device, !!x, !!y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll_stop(device, !!x, !!y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_pointer_release(struct eis_pointer *pointer)
|
||||
{
|
||||
struct eis_device *device = eis_pointer_get_device(pointer);
|
||||
|
|
@ -379,17 +379,17 @@ eis_device_get_pointer_interface(struct eis_device *device)
|
|||
return &pointer_interface;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_keyboard_key(struct eis_keyboard *keyboard, uint32_t key, uint32_t state)
|
||||
{
|
||||
struct eis_device *device = eis_keyboard_get_device(keyboard);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_keyboard_key(device, key, !!state);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_keyboard_key(device, key, !!state));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_keyboard_release(struct eis_keyboard *keyboard)
|
||||
{
|
||||
struct eis_device *device = eis_keyboard_get_device(keyboard);
|
||||
|
|
@ -409,7 +409,7 @@ eis_device_get_keyboard_interface(struct eis_device *device)
|
|||
return &keyboard_interface;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_touch_down(struct eis_touchscreen *touchscreen,
|
||||
uint32_t touchid, float x, float y)
|
||||
{
|
||||
|
|
@ -417,10 +417,10 @@ client_msg_touch_down(struct eis_touchscreen *touchscreen,
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_touch_down(device, touchid, x, y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_touch_down(device, touchid, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_touch_motion(struct eis_touchscreen *touchscreen,
|
||||
uint32_t touchid, float x, float y)
|
||||
{
|
||||
|
|
@ -428,26 +428,26 @@ client_msg_touch_motion(struct eis_touchscreen *touchscreen,
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_touch_motion(device, touchid, x, y);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_touch_motion(device, touchid, x, y));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_touch_up(struct eis_touchscreen *touchscreen, uint32_t touchid)
|
||||
{
|
||||
struct eis_device *device = eis_touchscreen_get_device(touchscreen);
|
||||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return eis_device_event_touch_up(device, touchid);
|
||||
return brei_result_new_from_neg_errno(eis_device_event_touch_up(device, touchid));
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_touchscreen_release(struct eis_touchscreen *touchscreen)
|
||||
{
|
||||
struct eis_device *device = eis_touchscreen_get_device(touchscreen);
|
||||
eis_touchscreen_event_destroyed(device->touchscreen);
|
||||
eis_touchscreen_unref(steal(&device->touchscreen));
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct eis_touchscreen_interface touchscreen_interface = {
|
||||
|
|
|
|||
|
|
@ -80,11 +80,11 @@ eis_pingpong_get_version(struct eis_pingpong *pingpong)
|
|||
return pingpong->proto_object.version;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_done(struct eis_pingpong *pingpong, uint32_t pingpong_data)
|
||||
{
|
||||
pingpong->func(pingpong, pingpong->pingpong_data, pingpong_data);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct eis_pingpong_interface interface = {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ eis_seat_get_client(struct eis_seat *seat)
|
|||
return eis_seat_parent(seat);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_release(struct eis_seat *seat)
|
||||
{
|
||||
/* There is no public API in libei to remove a seat, and there's no
|
||||
|
|
@ -88,10 +88,10 @@ client_msg_release(struct eis_seat *seat)
|
|||
* and remove it, that should do the trick.
|
||||
*/
|
||||
eis_seat_drop(seat);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct brei_result *
|
||||
client_msg_bind(struct eis_seat *seat, uint32_t caps)
|
||||
{
|
||||
uint32_t allowed_caps = 0;
|
||||
|
|
@ -106,11 +106,11 @@ client_msg_bind(struct eis_seat *seat, uint32_t caps)
|
|||
allowed_caps |= EIS_SEAT_CAPABILITIES_TOUCHSCREEN;
|
||||
|
||||
if (caps & ~allowed_caps)
|
||||
return -EINVAL;
|
||||
return brei_result_new_from_neg_errno(-EINVAL);
|
||||
|
||||
eis_seat_bind(seat, caps);
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct eis_seat_interface interface = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue