libei: add the hooks for pointer/touch ranges

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-08-18 13:04:01 +10:00
parent 4b0976c36c
commit 4565fb6851
11 changed files with 293 additions and 3 deletions

View file

@ -82,6 +82,10 @@ message Disconnect {
message AddDevice {
uint32 deviceid = 1;
uint32 capabilities = 2;
uint32 pointer_width = 3;
uint32 pointer_height = 4;
uint32 touch_width = 5;
uint32 touch_height = 6;
}
message RemoveDevice {

View file

@ -103,6 +103,38 @@ ei_device_configure_capability(struct ei_device *device,
return false;
}
_public_ void
ei_device_configure_pointer_range(struct ei_device *device,
uint32_t width,
uint32_t height)
{
if (device->state != EI_DEVICE_STATE_NEW ||
!flag_is_set(device->capabilities, EI_DEVICE_CAP_POINTER_ABSOLUTE))
return;
if (width == 0 || height == 0)
return;
device->abs.dim.width = width;
device->abs.dim.height = height;
}
_public_ void
ei_device_configure_touch_range(struct ei_device *device,
uint32_t width,
uint32_t height)
{
if (device->state != EI_DEVICE_STATE_NEW ||
!flag_is_set(device->capabilities, EI_DEVICE_CAP_TOUCH))
return;
if (width == 0 || height == 0)
return;
device->touch.dim.width = width;
device->touch.dim.height = height;
}
_public_ void
ei_device_add(struct ei_device *device)
{
@ -147,6 +179,30 @@ ei_device_has_capability(struct ei_device *device,
return false;
}
_public_ uint32_t
ei_device_get_pointer_width(struct ei_device *device)
{
return device->abs.dim.width;
}
_public_ uint32_t
ei_device_get_pointer_height(struct ei_device *device)
{
return device->abs.dim.height;
}
_public_ uint32_t
ei_device_get_touch_width(struct ei_device *device)
{
return device->touch.dim.width;
}
_public_ uint32_t
ei_device_get_touch_height(struct ei_device *device)
{
return device->touch.dim.height;
}
_public_ void
ei_device_pointer_motion(struct ei_device *device,
double x, double y)
@ -283,6 +339,72 @@ test_device_context(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_device_pointer_ranges(const MunitParameter params[], void *user_data)
{
struct ei ei = {0};
_cleanup_ei_device_ struct ei_device *d = ei_device_new(&ei);
/* Missing the cap */
ei_device_configure_pointer_range(d, 1920, 1200);
munit_assert_int(ei_device_get_pointer_width(d), ==, 0);
munit_assert_int(ei_device_get_pointer_height(d), ==, 0);
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER_ABSOLUTE));
ei_device_configure_pointer_range(d, 1024, 768);
munit_assert_int(ei_device_get_pointer_width(d), ==, 1024);
munit_assert_int(ei_device_get_pointer_height(d), ==, 768);
/* Twice is fine before adding the device */
ei_device_configure_pointer_range(d, 640, 480);
munit_assert_int(ei_device_get_pointer_width(d), ==, 640);
munit_assert_int(ei_device_get_pointer_height(d), ==, 480);
/* But zero is silently rejected */
ei_device_configure_pointer_range(d, 0, 480);
munit_assert_int(ei_device_get_pointer_width(d), ==, 640);
munit_assert_int(ei_device_get_pointer_height(d), ==, 480);
ei_device_configure_pointer_range(d, 640, 0);
munit_assert_int(ei_device_get_pointer_width(d), ==, 640);
munit_assert_int(ei_device_get_pointer_height(d), ==, 480);
return MUNIT_OK;
}
static MunitResult
test_device_touch_ranges(const MunitParameter params[], void *user_data)
{
struct ei ei = {0};
_cleanup_ei_device_ struct ei_device *d = ei_device_new(&ei);
/* Missing the cap */
ei_device_configure_touch_range(d, 1920, 1200);
munit_assert_int(ei_device_get_touch_width(d), ==, 0);
munit_assert_int(ei_device_get_touch_height(d), ==, 0);
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_TOUCH));
ei_device_configure_touch_range(d, 1024, 768);
munit_assert_int(ei_device_get_touch_width(d), ==, 1024);
munit_assert_int(ei_device_get_touch_height(d), ==, 768);
/* Twice is fine before adding the device */
ei_device_configure_touch_range(d, 640, 480);
munit_assert_int(ei_device_get_touch_width(d), ==, 640);
munit_assert_int(ei_device_get_touch_height(d), ==, 480);
/* But zero is silently rejected */
ei_device_configure_touch_range(d, 0, 480);
munit_assert_int(ei_device_get_touch_width(d), ==, 640);
munit_assert_int(ei_device_get_touch_height(d), ==, 480);
ei_device_configure_touch_range(d, 640, 0);
munit_assert_int(ei_device_get_touch_width(d), ==, 640);
munit_assert_int(ei_device_get_touch_height(d), ==, 480);
return MUNIT_OK;
}
#define TEST(_func) \
{ .name = #_func, .test = _func }
static MunitTest ei_device_tests[] = {
@ -291,6 +413,8 @@ static MunitTest ei_device_tests[] = {
TEST(test_device_ref_unref),
TEST(test_device_cap),
TEST(test_device_context),
TEST(test_device_pointer_ranges),
TEST(test_device_touch_ranges),
{ NULL },
};

View file

@ -28,6 +28,7 @@
#include "libei.h"
#include "util-list.h"
#include "util-sources.h"
#include "util-structs.h"
struct ei_backend_interface {
void (*destroy)(struct ei *ei, void *backend);
@ -70,6 +71,14 @@ struct ei_device {
enum ei_device_state state;
uint32_t capabilities;
char *name;
struct {
struct dimensions dim;
} abs;
struct {
struct dimensions dim;
} touch;
};
struct ei_event {

View file

@ -310,6 +310,10 @@ connection_send_add(struct ei *ei, struct ei_device *device)
add.deviceid = device->id;
add.capabilities = device->capabilities;
add.pointer_width = device->abs.dim.width;
add.pointer_height = device->abs.dim.height;
add.touch_width = device->touch.dim.width;
add.touch_height = device->touch.dim.height;
msg.add_device = &add;
msg.msg_case = CLIENT_MESSAGE__MSG_ADD_DEVICE;

View file

@ -35,6 +35,7 @@
#include "util-mem.h"
#include "util-sources.h"
#include "util-strings.h"
#include "util-structs.h"
#include "libeis-private.h"
@ -66,6 +67,8 @@ struct message {
struct message_add_device {
uint32_t deviceid;
uint32_t capabilities;
struct dimensions dim_pointer;
struct dimensions dim_touch;
} add_device;
struct message_remove_device {
uint32_t deviceid;
@ -285,7 +288,9 @@ eis_client_disconnect(struct eis_client *client)
static int
client_new_device(struct eis_client *client,
uint32_t id, uint32_t capabilities)
uint32_t id, uint32_t capabilities,
const struct dimensions *dim_pointer,
const struct dimensions *dim_touch)
{
/* Check for duplicate IDs */
struct eis_device *d;
@ -304,6 +309,14 @@ client_new_device(struct eis_client *client,
struct eis_device *device = eis_device_new(client, id, capabilities);
list_append(&client->devices, &device->link);
if (flag_is_set(capabilities, EIS_DEVICE_CAP_POINTER_ABSOLUTE))
eis_device_set_pointer_range(device, dim_pointer->width,
dim_pointer->height);
if (flag_is_set(capabilities, EIS_DEVICE_CAP_TOUCH))
eis_device_set_touch_range(device, dim_touch->width,
dim_touch->height);
log_debug(eis_client_parent(client), "New device %d caps: %#x\n",
id, capabilities);
@ -474,7 +487,9 @@ client_connected_handle_msg(struct eis_client *client,
break;
case MESSAGE_ADD_DEVICE:
rc = client_new_device(client, msg->add_device.deviceid,
msg->add_device.capabilities);
msg->add_device.capabilities,
&msg->add_device.dim_pointer,
&msg->add_device.dim_touch);
break;
case MESSAGE_REMOVE_DEVICE:
/* FIXME: remove device */
@ -558,6 +573,10 @@ client_parse_message(const char *data, size_t *len)
.type = MESSAGE_ADD_DEVICE,
.add_device.deviceid = a->deviceid,
.add_device.capabilities = a->capabilities,
.add_device.dim_pointer.width = a->pointer_width,
.add_device.dim_pointer.height = a->pointer_height,
.add_device.dim_touch.width = a->touch_width,
.add_device.dim_touch.height = a->touch_height,
};
}
break;

View file

@ -61,6 +61,22 @@ eis_device_new(struct eis_client *client,
return device;
}
void
eis_device_set_pointer_range(struct eis_device *device,
uint32_t w, uint32_t h)
{
device->abs.dim.width = w;
device->abs.dim.height = h;
}
void
eis_device_set_touch_range(struct eis_device *device,
uint32_t w, uint32_t h)
{
device->touch.dim.width = w;
device->touch.dim.height = h;
}
_public_
bool
eis_device_has_capability(struct eis_device *device,
@ -91,6 +107,30 @@ eis_device_disable_capability(struct eis_device *device,
}
}
_public_ uint32_t
eis_device_get_pointer_width(struct eis_device *device)
{
return device->abs.dim.width;
}
_public_ uint32_t
eis_device_get_pointer_height(struct eis_device *device)
{
return device->abs.dim.height;
}
_public_ uint32_t
eis_device_get_touch_width(struct eis_device *device)
{
return device->touch.dim.width;
}
_public_ uint32_t
eis_device_get_touch_height(struct eis_device *device)
{
return device->touch.dim.height;
}
int
eis_device_pointer_rel(struct eis_device *device,
int x, int y)

View file

@ -28,6 +28,7 @@
#include "libeis.h"
#include "util-list.h"
#include "util-sources.h"
#include "util-structs.h"
struct eis_backend_interface {
void (*destroy)(struct eis *eis, void *backend);
@ -84,6 +85,13 @@ struct eis_device {
uint32_t id;
enum eis_device_state state;
uint32_t capabilities;
struct {
struct dimensions dim;
} abs;
struct {
struct dimensions dim;
} touch;
};
struct eis_event {
@ -138,6 +146,13 @@ eis_device_new(struct eis_client *client,
uint32_t id,
uint32_t capabilities);
void
eis_device_set_pointer_range(struct eis_device *device,
uint32_t w, uint32_t h);
void
eis_device_set_touch_range(struct eis_device *device,
uint32_t w, uint32_t h);
int
eis_device_pointer_rel(struct eis_device *device,
int x, int y);

35
src/util-structs.h Normal file
View file

@ -0,0 +1,35 @@
/*
* 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.
*/
/* Just a collection of useful structs */
#pragma once
#include "config.h"
#include <stdint.h>
struct dimensions {
uint32_t width;
uint32_t height;
};

View file

@ -192,7 +192,7 @@ peck_handle_eis_added(struct peck *peck, struct eis_event *e)
enum peck_eis_behavior behavior;
} map[] = {
{ EIS_DEVICE_CAP_POINTER, PECK_EIS_BEHAVIOR_ACCEPT_POINTER },
// { EIS_DEVICE_CAP_POINTER_ABSOLUTE, PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE },
{ EIS_DEVICE_CAP_POINTER_ABSOLUTE, PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE },
{ EIS_DEVICE_CAP_KEYBOARD, PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD },
{ EIS_DEVICE_CAP_TOUCH, PECK_EIS_BEHAVIOR_ACCEPT_TOUCH },
};

View file

@ -68,6 +68,9 @@ enum peck_eis_behavior {
PECK_EIS_BEHAVIOR_ACCEPT_POINTER,
PECK_EIS_BEHAVIOR_DROP_POINTER,
PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE,
PECK_EIS_BEHAVIOR_DROP_POINTER_ABSOLUTE,
PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD,
PECK_EIS_BEHAVIOR_DROP_KEYBOARD,

View file

@ -76,9 +76,46 @@ eistest_name(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
eistest_ranges(const MunitParameter params[], void *user_data)
{
_cleanup_peck_ struct peck *peck = peck_new();
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_dispatch_until_event(peck);
with_client(peck) {
_cleanup_ei_device_ struct ei_device *d = ei_device_new(ei);
ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER_ABSOLUTE);
ei_device_configure_capability(d, EI_DEVICE_CAP_TOUCH);
ei_device_configure_pointer_range(d, 1024, 768);
ei_device_configure_touch_range(d, 1920, 1200);
ei_device_add(d);
}
peck_dispatch_until_event(peck);
with_server(peck) {
_cleanup_eis_event_ struct eis_event *event =
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
struct eis_device *device = eis_event_get_device(event);
munit_assert(eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
munit_assert(eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH));
munit_assert_int(eis_device_get_pointer_width(device), ==, 1024);
munit_assert_int(eis_device_get_pointer_height(device), ==, 768);
munit_assert_int(eis_device_get_touch_width(device), ==, 1920);
munit_assert_int(eis_device_get_touch_height(device), ==, 1200);
}
return MUNIT_OK;
}
static MunitTest eis_tests[] = {
{ .name = "/ref", .test = eistest_ref_unref },
{ .name = "/name", .test = eistest_name },
{ .name = "/ranges", .test = eistest_ranges },
{ NULL },
};