diff --git a/proto/ei.proto b/proto/ei.proto index e02fb74..ab7b756 100644 --- a/proto/ei.proto +++ b/proto/ei.proto @@ -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 { diff --git a/src/libei-device.c b/src/libei-device.c index 77a8ba1..f8b6b4e 100644 --- a/src/libei-device.c +++ b/src/libei-device.c @@ -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 }, }; diff --git a/src/libei-private.h b/src/libei-private.h index a8ba3f3..dd9620d 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -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 { diff --git a/src/libei.c b/src/libei.c index 58b54c9..9ce1f02 100644 --- a/src/libei.c +++ b/src/libei.c @@ -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; diff --git a/src/libeis-client.c b/src/libeis-client.c index bba06d1..20e70ab 100644 --- a/src/libeis-client.c +++ b/src/libeis-client.c @@ -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; diff --git a/src/libeis-device.c b/src/libeis-device.c index 3526c64..84b60e4 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -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) diff --git a/src/libeis-private.h b/src/libeis-private.h index 58aa4f9..db58e97 100644 --- a/src/libeis-private.h +++ b/src/libeis-private.h @@ -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); diff --git a/src/util-structs.h b/src/util-structs.h new file mode 100644 index 0000000..fe21b1f --- /dev/null +++ b/src/util-structs.h @@ -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 + +struct dimensions { + uint32_t width; + uint32_t height; +}; diff --git a/test/eierpecken.c b/test/eierpecken.c index fc8b3b1..82f1196 100644 --- a/test/eierpecken.c +++ b/test/eierpecken.c @@ -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 }, }; diff --git a/test/eierpecken.h b/test/eierpecken.h index 029e2ca..02c388f 100644 --- a/test/eierpecken.h +++ b/test/eierpecken.h @@ -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, diff --git a/test/test-eis.c b/test/test-eis.c index 28239bf..322136f 100644 --- a/test/test-eis.c +++ b/test/test-eis.c @@ -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 }, };