mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-14 13:28:10 +02:00
We need some sort of length field to be able to know how long the next message is. But for simplicity, we might as well just write that explicitly on the wire instead of wrapping our messages into yet another message. This makes the wire format slightly simpler since the first 4 bytes are now always the length, without the previous 0x0d prefix caused by the protobuf encoding. 0x0d == (field number << 3) | wire_type == 1 << 3 | 5 (see https://protobuf.dev/programming-guides/encoding/#structure)
646 lines
18 KiB
C
646 lines
18 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
/*
|
|
* Copyright © 2020 Red Hat, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "util-object.h"
|
|
#include "util-io.h"
|
|
#include "util-strings.h"
|
|
#include "util-tristate.h"
|
|
|
|
#include "ei.pb-c.h"
|
|
#include "libeis-proto.h"
|
|
#include "brei-shared.h"
|
|
|
|
static inline void
|
|
log_wire_message(struct eis *eis, const ServerMessage *msg)
|
|
{
|
|
const char *message = NULL;
|
|
|
|
#define MSG_STRING_CASE(_name) \
|
|
case SERVER_MESSAGE__MSG_##_name: message = #_name; break;
|
|
|
|
switch (msg->msg_case) {
|
|
#if PROTOBUF_C_VERSION_NUMBER >= 1004000
|
|
case _SERVER_MESSAGE__MSG__CASE_IS_INT_SIZE:
|
|
#else
|
|
case _SERVER_MESSAGE__MSG_IS_INT_SIZE:
|
|
#endif
|
|
/* protobuf-internal thing */
|
|
return;
|
|
case SERVER_MESSAGE__MSG__NOT_SET:
|
|
assert(!"SERVER_MESSAGE__MSG__NOT_SET");
|
|
MSG_STRING_CASE(CONNECTED);
|
|
MSG_STRING_CASE(DISCONNECTED);
|
|
MSG_STRING_CASE(SEAT_ADDED);
|
|
MSG_STRING_CASE(SEAT_REMOVED);
|
|
MSG_STRING_CASE(DEVICE_ADDED);
|
|
MSG_STRING_CASE(DEVICE_DONE);
|
|
MSG_STRING_CASE(DEVICE_KEYMAP);
|
|
MSG_STRING_CASE(DEVICE_REGION);
|
|
MSG_STRING_CASE(DEVICE_REMOVED);
|
|
MSG_STRING_CASE(DEVICE_RESUMED);
|
|
MSG_STRING_CASE(DEVICE_PAUSED);
|
|
MSG_STRING_CASE(KEYBOARD_MODIFIERS);
|
|
MSG_STRING_CASE(PROPERTY);
|
|
MSG_STRING_CASE(VERSION);
|
|
/* events */
|
|
MSG_STRING_CASE(START_EMULATING);
|
|
MSG_STRING_CASE(STOP_EMULATING);
|
|
MSG_STRING_CASE(POINTER_RELATIVE);
|
|
MSG_STRING_CASE(POINTER_ABSOLUTE);
|
|
MSG_STRING_CASE(POINTER_BUTTON);
|
|
MSG_STRING_CASE(POINTER_SCROLL);
|
|
MSG_STRING_CASE(POINTER_SCROLL_STOP);
|
|
MSG_STRING_CASE(POINTER_SCROLL_DISCRETE);
|
|
MSG_STRING_CASE(KEYBOARD_KEY);
|
|
MSG_STRING_CASE(TOUCH_DOWN);
|
|
MSG_STRING_CASE(TOUCH_MOTION);
|
|
MSG_STRING_CASE(TOUCH_UP);
|
|
MSG_STRING_CASE(FRAME);
|
|
break;
|
|
}
|
|
if (message == NULL)
|
|
assert(!"Unimplemented message type");
|
|
|
|
log_debug(eis, "sending wire message %s", message);
|
|
|
|
#undef MSG_STRING_CASE
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_msg(struct eis_client *client, const ServerMessage *msg)
|
|
{
|
|
log_wire_message(eis_client_get_context(client), msg);
|
|
|
|
size_t msglen = server_message__get_packed_size(msg);
|
|
uint8_t buf[4 + msglen];
|
|
*(uint32_t*)buf = msglen;
|
|
server_message__pack(msg, buf + 4);
|
|
return min(0, xsend(source_get_fd(client->source), buf, sizeof(buf)));
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_msg_with_fds(struct eis_client *client, const ServerMessage *msg, int *fds)
|
|
{
|
|
log_wire_message(eis_client_get_context(client), msg);
|
|
|
|
size_t msglen = server_message__get_packed_size(msg);
|
|
uint8_t buf[4 + msglen];
|
|
*(uint32_t*)buf = msglen;
|
|
server_message__pack(msg, buf + 4);
|
|
|
|
return min(0, xsend_with_fd(source_get_fd(client->source), buf, sizeof(buf), fds));
|
|
}
|
|
|
|
#define prepare_msg(_type, _struct, _field) \
|
|
ServerMessage msg = SERVER_MESSAGE__INIT; \
|
|
_struct _field = _type##__INIT; \
|
|
msg.msg_case = SERVER_MESSAGE__MSG_##_type; \
|
|
msg._field = &_field
|
|
|
|
static int
|
|
eis_proto_send_version(struct eis_client *client, uint32_t v)
|
|
{
|
|
prepare_msg(VERSION, Version, version);
|
|
version.version = v;
|
|
version.eis = "EIS";
|
|
|
|
return eis_proto_send_msg(client, &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_disconnected(struct eis_client *client)
|
|
{
|
|
prepare_msg(DISCONNECTED, Disconnected, disconnected);
|
|
|
|
return eis_proto_send_msg(client, &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_connected(struct eis_client *client)
|
|
{
|
|
prepare_msg(CONNECTED, Connected, connected);
|
|
|
|
return eis_proto_send_msg(client, &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_seat_added(struct eis_seat *seat)
|
|
{
|
|
prepare_msg(SEAT_ADDED, SeatAdded, seat_added);
|
|
|
|
seat_added.seatid = seat->id;
|
|
seat_added.name = seat->name;
|
|
seat_added.capabilities = seat->capabilities_mask;
|
|
|
|
return eis_proto_send_msg(eis_seat_get_client(seat), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_seat_removed(struct eis_seat *seat)
|
|
{
|
|
prepare_msg(SEAT_REMOVED, SeatRemoved, seat_removed);
|
|
|
|
seat_removed.seatid = seat->id;
|
|
|
|
return eis_proto_send_msg(eis_seat_get_client(seat), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_device_added(struct eis_device *device)
|
|
{
|
|
prepare_msg(DEVICE_ADDED, DeviceAdded, device_added);
|
|
|
|
struct eis_seat *seat = eis_device_get_seat(device);
|
|
device_added.deviceid = device->id;
|
|
device_added.seatid = seat->id;
|
|
device_added.name = device->name;
|
|
device_added.capabilities = device->capabilities;
|
|
device_added.type = device->type;
|
|
device_added.width = device->width;
|
|
device_added.height = device->height;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_device_keymap(struct eis_device *device)
|
|
{
|
|
prepare_msg(DEVICE_KEYMAP, DeviceKeymap, device_keymap);
|
|
|
|
int fds[2] = {-1, -1};
|
|
|
|
if (!device->keymap)
|
|
return 0;
|
|
|
|
struct eis_keymap *k = device->keymap;
|
|
device_keymap.deviceid = device->id;
|
|
device_keymap.keymap_type = k->type;
|
|
device_keymap.keymap_size = k->size;
|
|
fds[0] = k->fd;
|
|
|
|
|
|
return eis_proto_send_msg_with_fds(eis_device_get_client(device), &msg, fds);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_device_done(struct eis_device *device)
|
|
{
|
|
prepare_msg(DEVICE_DONE, DeviceDone, device_done);
|
|
|
|
device_done.deviceid = device->id;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_device_region(struct eis_device *device, const struct eis_region *r)
|
|
{
|
|
prepare_msg(DEVICE_REGION, DeviceRegion, device_region);
|
|
|
|
device_region.deviceid = device->id;
|
|
device_region.offset_x = r->x;
|
|
device_region.offset_y = r->y;
|
|
device_region.width = r->width;
|
|
device_region.height = r->height;
|
|
device_region.scale = r->physical_scale;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_keyboard_modifiers(struct eis_device *device, const struct eis_xkb_modifiers *mods)
|
|
{
|
|
prepare_msg(KEYBOARD_MODIFIERS, KeyboardModifiers, keyboard_modifiers);
|
|
|
|
keyboard_modifiers.deviceid = device->id;
|
|
keyboard_modifiers.depressed = mods->depressed;
|
|
keyboard_modifiers.locked = mods->locked;
|
|
keyboard_modifiers.latched = mods->latched;
|
|
keyboard_modifiers.group = mods->group;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
|
|
static int
|
|
eis_proto_send_device_removed(struct eis_device *device)
|
|
{
|
|
prepare_msg(DEVICE_REMOVED, DeviceRemoved, device_removed);
|
|
|
|
device_removed.deviceid = device->id;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_device_paused(struct eis_device *device)
|
|
{
|
|
prepare_msg(DEVICE_PAUSED, DevicePaused, device_paused);
|
|
|
|
device_paused.deviceid = device->id;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_device_resumed(struct eis_device *device)
|
|
{
|
|
prepare_msg(DEVICE_RESUMED, DeviceResumed, device_resumed);
|
|
|
|
device_resumed.deviceid = device->id;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_property(struct eis_client *client, const char *name,
|
|
const char *value, uint32_t permissions)
|
|
{
|
|
|
|
prepare_msg(PROPERTY, Property, property);
|
|
|
|
property.name = (char*)name;
|
|
property.value = (char*)value;
|
|
property.permissions = permissions;
|
|
|
|
return eis_proto_send_msg(client, &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_start_emulating(struct eis_device *device, uint32_t deviceid)
|
|
{
|
|
prepare_msg(START_EMULATING, StartEmulating, start_emulating);
|
|
|
|
start_emulating.deviceid = device->id;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_stop_emulating(struct eis_device *device, uint32_t deviceid)
|
|
{
|
|
prepare_msg(STOP_EMULATING, StopEmulating, stop_emulating);
|
|
|
|
stop_emulating.deviceid = device->id;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_rel(struct eis_device *device, uint32_t deviceid, double x, double y)
|
|
{
|
|
prepare_msg(POINTER_RELATIVE, PointerRelative, pointer_relative);
|
|
|
|
pointer_relative.deviceid = device->id;
|
|
pointer_relative.x = x;
|
|
pointer_relative.y = y;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_abs(struct eis_device *device, uint32_t deviceid, double x, double y)
|
|
{
|
|
prepare_msg(POINTER_ABSOLUTE, PointerAbsolute, pointer_absolute);
|
|
|
|
pointer_absolute.deviceid = device->id;
|
|
pointer_absolute.x = x;
|
|
pointer_absolute.y = y;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_button(struct eis_device *device, uint32_t deviceid,
|
|
uint32_t button, bool is_press)
|
|
{
|
|
prepare_msg(POINTER_BUTTON, PointerButton, pointer_button);
|
|
|
|
pointer_button.deviceid = device->id;
|
|
pointer_button.button = button;
|
|
pointer_button.state = is_press;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_key(struct eis_device *device, uint32_t deviceid,
|
|
uint32_t key, bool is_press)
|
|
{
|
|
prepare_msg(KEYBOARD_KEY, KeyboardKey, keyboard_key);
|
|
|
|
keyboard_key.deviceid = device->id;
|
|
keyboard_key.key = key;
|
|
keyboard_key.state = is_press;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_scroll(struct eis_device *device, uint32_t deviceid,
|
|
double x, double y)
|
|
{
|
|
prepare_msg(POINTER_SCROLL, PointerScroll, pointer_scroll);
|
|
|
|
pointer_scroll.deviceid = device->id;
|
|
pointer_scroll.x = x;
|
|
pointer_scroll.y = y;
|
|
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_scroll_stop(struct eis_device *device, uint32_t deviceid,
|
|
bool x, bool y, bool is_cancel)
|
|
{
|
|
prepare_msg(POINTER_SCROLL_STOP, PointerScrollStop, pointer_scroll_stop);
|
|
|
|
pointer_scroll_stop.deviceid = device->id;
|
|
pointer_scroll_stop.x = x;
|
|
pointer_scroll_stop.y = y;
|
|
pointer_scroll_stop.is_cancel = is_cancel;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_scroll_discrete(struct eis_device *device, uint32_t deviceid,
|
|
int32_t x, int32_t y)
|
|
{
|
|
|
|
prepare_msg(POINTER_SCROLL_DISCRETE, PointerScrollDiscrete, pointer_scroll_discrete);
|
|
|
|
pointer_scroll_discrete.deviceid = device->id;
|
|
pointer_scroll_discrete.x = x;
|
|
pointer_scroll_discrete.y = y;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_touch_down(struct eis_device *device, uint32_t deviceid,
|
|
uint32_t tid, double x, double y)
|
|
{
|
|
prepare_msg(TOUCH_DOWN, TouchDown, touch_down);
|
|
|
|
touch_down.deviceid = device->id;
|
|
touch_down.touchid = tid;
|
|
touch_down.x = x;
|
|
touch_down.y = y;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_touch_motion(struct eis_device *device, uint32_t deviceid,
|
|
uint32_t tid, double x, double y)
|
|
{
|
|
prepare_msg(TOUCH_MOTION, TouchMotion, touch_motion);
|
|
|
|
touch_motion.deviceid = device->id;
|
|
touch_motion.touchid = tid;
|
|
touch_motion.x = x;
|
|
touch_motion.y = y;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_touch_up(struct eis_device *device, uint32_t deviceid, uint32_t tid)
|
|
{
|
|
prepare_msg(TOUCH_UP, TouchUp, touch_up);
|
|
|
|
touch_up.deviceid = device->id;
|
|
touch_up.touchid = tid;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static int
|
|
eis_proto_send_frame(struct eis_device *device, uint32_t deviceid, uint64_t time)
|
|
{
|
|
prepare_msg(FRAME, Frame, frame);
|
|
|
|
frame.deviceid = device->id;
|
|
frame.timestamp = time;
|
|
|
|
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
|
}
|
|
|
|
static const struct eis_proto_requests requests = {
|
|
.disconnected = eis_proto_send_disconnected,
|
|
.connected = eis_proto_send_connected,
|
|
.seat_added = eis_proto_send_seat_added,
|
|
.seat_removed = eis_proto_send_seat_removed,
|
|
.device_added = eis_proto_send_device_added,
|
|
.device_removed = eis_proto_send_device_removed,
|
|
.device_paused = eis_proto_send_device_paused,
|
|
.device_resumed = eis_proto_send_device_resumed,
|
|
.device_keymap = eis_proto_send_device_keymap,
|
|
.device_done = eis_proto_send_device_done,
|
|
.device_region = eis_proto_send_device_region,
|
|
.keyboard_modifiers = eis_proto_send_keyboard_modifiers,
|
|
.property = eis_proto_send_property,
|
|
.version = eis_proto_send_version,
|
|
|
|
/* events */
|
|
.start_emulating = eis_proto_send_start_emulating,
|
|
.stop_emulating = eis_proto_send_stop_emulating,
|
|
.rel = eis_proto_send_rel,
|
|
.abs = eis_proto_send_abs,
|
|
.button = eis_proto_send_button,
|
|
.scroll = eis_proto_send_scroll,
|
|
.scroll_stop = eis_proto_send_scroll_stop,
|
|
.scroll_discrete = eis_proto_send_scroll_discrete,
|
|
.key = eis_proto_send_key,
|
|
.touch_down = eis_proto_send_touch_down,
|
|
.touch_motion = eis_proto_send_touch_motion,
|
|
.touch_up = eis_proto_send_touch_up,
|
|
.frame = eis_proto_send_frame,
|
|
};
|
|
|
|
const struct eis_proto_requests *
|
|
eis_proto_get_requests(void) {
|
|
return &requests;
|
|
}
|
|
|
|
static void clientmessage_cleanup(ClientMessage **m) {
|
|
if (*m)
|
|
client_message__free_unpacked(*m, NULL);
|
|
}
|
|
#define _cleanup_clientmessage_ _cleanup_(clientmessage_cleanup)
|
|
|
|
int
|
|
eis_proto_handle_message(struct eis_client *client,
|
|
const struct eis_proto_interface *interface,
|
|
struct brei_message *bmsg)
|
|
{
|
|
_cleanup_clientmessage_ ClientMessage *proto = client_message__unpack(NULL, bmsg->len,
|
|
(const unsigned char*)bmsg->data);
|
|
if (!proto)
|
|
return -EAGAIN;
|
|
|
|
#define call(field, ...) \
|
|
({ \
|
|
int r = (interface->field == NULL) ? -EPROTO : interface->field(__VA_ARGS__); \
|
|
log_debug(eis_client_get_context(client), "message type '" #field "': errno %d (%s)", -r, strerror(-r)); \
|
|
r; \
|
|
})
|
|
|
|
int rc;
|
|
switch (proto->msg_case) {
|
|
case CLIENT_MESSAGE__MSG_CONNECT:
|
|
rc = call(connect, client, proto->connect->version,
|
|
proto->connect->name, proto->connect->is_sender);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CONNECT_DONE:
|
|
rc = call(connect_done, client);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_DISCONNECT:
|
|
rc = call(disconnect, client);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_BIND_SEAT:
|
|
rc = call(bind_seat, client,
|
|
proto->bind_seat->seatid,
|
|
proto->bind_seat->capabilities);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CLOSE_DEVICE:
|
|
rc = call(close_device, client,
|
|
proto->close_device->deviceid);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_SET_PROPERTY:
|
|
rc = call(set_property, client, proto->set_property->name,
|
|
proto->set_property->value[0] ? proto->set_property->value : NULL,
|
|
proto->set_property->permissions);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_GET_VERSION:
|
|
rc = call(get_version, client);
|
|
break;
|
|
/* Events */
|
|
case CLIENT_MESSAGE__MSG_START_EMULATING:
|
|
rc = call(start_emulating, client,
|
|
proto->start_emulating->deviceid);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_STOP_EMULATING:
|
|
rc = call(stop_emulating, client,
|
|
proto->stop_emulating->deviceid);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_POINTER_RELATIVE:
|
|
rc = call(rel, client,
|
|
proto->pointer_relative->deviceid,
|
|
proto->pointer_relative->x,
|
|
proto->pointer_relative->y);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_POINTER_ABSOLUTE:
|
|
rc = call(abs, client,
|
|
proto->pointer_absolute->deviceid,
|
|
proto->pointer_absolute->x,
|
|
proto->pointer_absolute->y);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_POINTER_BUTTON:
|
|
rc = call(button, client,
|
|
proto->pointer_button->deviceid,
|
|
proto->pointer_button->button,
|
|
proto->pointer_button->state);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_POINTER_SCROLL:
|
|
rc = call(scroll, client,
|
|
proto->pointer_scroll->deviceid,
|
|
proto->pointer_scroll->x,
|
|
proto->pointer_scroll->y);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_POINTER_SCROLL_STOP:
|
|
rc = call(scroll_stop, client,
|
|
proto->pointer_scroll_stop->deviceid,
|
|
proto->pointer_scroll_stop->x,
|
|
proto->pointer_scroll_stop->y,
|
|
proto->pointer_scroll_stop->is_cancel);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_POINTER_SCROLL_DISCRETE:
|
|
rc = call(scroll_discrete, client,
|
|
proto->pointer_scroll_discrete->deviceid,
|
|
proto->pointer_scroll_discrete->x,
|
|
proto->pointer_scroll_discrete->y);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_KEYBOARD_KEY:
|
|
rc = call(key, client,
|
|
proto->keyboard_key->deviceid,
|
|
proto->keyboard_key->key,
|
|
proto->keyboard_key->state);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_TOUCH_DOWN:
|
|
rc = call(touch_down, client,
|
|
proto->touch_down->deviceid,
|
|
proto->touch_down->touchid,
|
|
proto->touch_down->x,
|
|
proto->touch_down->y);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_TOUCH_MOTION:
|
|
rc = call(touch_motion, client,
|
|
proto->touch_motion->deviceid,
|
|
proto->touch_motion->touchid,
|
|
proto->touch_motion->x,
|
|
proto->touch_motion->y);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_TOUCH_UP:
|
|
rc = call(touch_up, client,
|
|
proto->touch_up->deviceid,
|
|
proto->touch_up->touchid);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_FRAME:
|
|
rc = call(frame, client, proto->frame->deviceid, proto->frame->timestamp);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CONFIGURE_START:
|
|
rc = call(configure_start, client,
|
|
proto->configure_start->version);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CONFIGURE_FINISH:
|
|
rc = call(configure_finish, client);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CONFIGURE_NAME:
|
|
rc = call(configure_name, client,
|
|
proto->configure_name->name);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CONFIGURE_CAPABILITIES:
|
|
rc = call(configure_capabilities, client,
|
|
proto->configure_capabilities->allowed_capabilities);
|
|
break;
|
|
case CLIENT_MESSAGE__MSG_CONFIGURE_PROPERTY:
|
|
rc = call(configure_property, client, proto->configure_property->name,
|
|
proto->configure_property->value[0] ? proto->configure_property->value : NULL,
|
|
proto->configure_property->permissions);
|
|
break;
|
|
default:
|
|
rc = -EBADMSG;
|
|
break;
|
|
}
|
|
|
|
return rc < 0 ? rc : (int)bmsg->len;
|
|
}
|
|
|