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:
Peter Hutterer 2023-02-16 13:16:57 +10:00
parent 579f0d07d2
commit e67a0a7777
14 changed files with 392 additions and 241 deletions

View file

@ -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, ...)

View file

@ -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),

View file

@ -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[] = {

View file

@ -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 %}

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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;
}

View file

@ -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));

View file

@ -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;
}

View file

@ -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 = {

View file

@ -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 = {

View file

@ -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 = {