mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-25 22:10:06 +01:00
Let the client set the version number it wants on Connect. There is new public API to query the client/server's version as set once the connect finished (eis_client_get_version() and ei_get_version()) but there is currently no public API for the client to select the version it actually wants, other than whatever both support. IOW, it's not possible for the client to say "I want version 8 but if that's not supported, use version 5".
432 lines
14 KiB
C
432 lines
14 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 "util-munit.h"
|
|
#include "util-version.h"
|
|
|
|
#include "eierpecken.h"
|
|
|
|
MUNIT_TEST(eistest_ref_unref)
|
|
{
|
|
struct eis *eis = eis_new(NULL);
|
|
|
|
struct eis *refd = eis_ref(eis);
|
|
munit_assert_ptr_equal(eis, refd);
|
|
|
|
struct eis *unrefd = eis_unref(eis);
|
|
munit_assert_ptr_null(unrefd);
|
|
unrefd = eis_unref(eis);
|
|
munit_assert_ptr_null(unrefd);
|
|
|
|
/* memleak only shows up in valgrind */
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_version)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
_unref_(eis_event) *connect = peck_eis_next_event(eis, EIS_EVENT_CLIENT_CONNECT);
|
|
struct eis_client *client = eis_event_get_client(connect);
|
|
|
|
/* We can't set the client version yet, but we know it's hardcoded to 1 */
|
|
munit_assert_int(eis_client_get_version(client), ==, VERSION_V(1));
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_name)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
|
|
|
/* The name is set by peck_new() and immutable after the
|
|
* backend was set, which peck_new() does for us as well.
|
|
* So the name we should see is the one hardcoded in peck_new()
|
|
*/
|
|
|
|
with_client(peck) {
|
|
ei_configure_name(ei, "this name should not be used");
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
_unref_(eis_event) *event = eis_get_event(eis);
|
|
munit_assert_ptr_not_null(event);
|
|
munit_assert_int(eis_event_get_type(event), ==, EIS_EVENT_CLIENT_CONNECT);
|
|
|
|
struct eis_client *client = eis_event_get_client(event);
|
|
munit_assert_string_equal(eis_client_get_name(client), "eierpecken test context");
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_capabilities)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
struct eis_client *client = peck_eis_get_default_client(peck);
|
|
|
|
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_POINTER));
|
|
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_TOUCH));
|
|
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_KEYBOARD));
|
|
munit_assert_true(eis_client_has_capability(client, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
|
munit_assert_false(eis_client_has_capability(client, 0));
|
|
munit_assert_false(eis_client_has_capability(client, EIS_DEVICE_CAP_TOUCH + 1));
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_cliend_bind_all_caps)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_client(peck) {
|
|
_unref_(ei_event) *seat_added =
|
|
peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
|
struct ei_seat *seat = ei_event_get_seat(seat_added);
|
|
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER);
|
|
ei_seat_bind_capability(seat, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
|
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
|
ei_seat_bind_capability(seat, EI_DEVICE_CAP_TOUCH);
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
_unref_(eis_event) *bind_ptr =
|
|
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
|
munit_assert_true(eis_event_seat_has_capability(bind_ptr, EIS_DEVICE_CAP_POINTER));
|
|
|
|
_unref_(eis_event) *bind_abs =
|
|
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
|
munit_assert_true(eis_event_seat_has_capability(bind_abs, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
|
|
|
_unref_(eis_event) *bind_kbd =
|
|
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
|
munit_assert_true(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_KEYBOARD));
|
|
|
|
_unref_(eis_event) *bind_touch =
|
|
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
|
munit_assert_true(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_TOUCH));
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_cliend_bind_some_caps)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
/* Before the clients binds to the seat, our seat has all caps */
|
|
with_server(peck) {
|
|
struct eis_seat *seat = peck_eis_get_default_seat(peck);
|
|
munit_assert_true(eis_seat_has_capability(seat, EIS_DEVICE_CAP_KEYBOARD));
|
|
munit_assert_true(eis_seat_has_capability(seat, EIS_DEVICE_CAP_POINTER));
|
|
munit_assert_true(eis_seat_has_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
|
munit_assert_true(eis_seat_has_capability(seat, EIS_DEVICE_CAP_TOUCH));
|
|
}
|
|
|
|
with_client(peck) {
|
|
_unref_(ei_event) *event =
|
|
peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
|
struct ei_seat *seat = ei_event_get_seat(event);
|
|
ei_seat_bind_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
|
ei_seat_bind_capability(seat, EI_DEVICE_CAP_TOUCH);
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
_unref_(eis_event) *bind_kbd =
|
|
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
|
|
|
munit_assert_true(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_KEYBOARD));
|
|
munit_assert_false(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_POINTER));
|
|
munit_assert_false(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
|
munit_assert_false(eis_event_seat_has_capability(bind_kbd, EIS_DEVICE_CAP_TOUCH));
|
|
|
|
_unref_(eis_event) *bind_touch =
|
|
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
|
|
|
munit_assert_true(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_KEYBOARD));
|
|
munit_assert_false(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_POINTER));
|
|
munit_assert_false(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
|
munit_assert_true(eis_event_seat_has_capability(bind_touch, EIS_DEVICE_CAP_TOUCH));
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
#if 0
|
|
MUNIT_TEST(eistest_ranges)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_client(peck) {
|
|
struct ei_seat *seat = peck_ei_get_default_seat(peck);
|
|
_unref_(ei_device) *d = ei_device_new(seat);
|
|
ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER_ABSOLUTE);
|
|
ei_device_configure_capability(d, EI_DEVICE_CAP_TOUCH);
|
|
ei_device_pointer_configure_range(d, 1024, 768);
|
|
ei_device_touch_configure_range(d, 1920, 1200);
|
|
ei_device_add(d);
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
_unref_(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_pointer_get_width(device), ==, 1024);
|
|
munit_assert_int(eis_device_pointer_get_height(device), ==, 768);
|
|
munit_assert_int(eis_device_touch_get_width(device), ==, 1920);
|
|
munit_assert_int(eis_device_touch_get_height(device), ==, 1200);
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
#endif
|
|
|
|
MUNIT_TEST(eistest_device_resume_pause_twice)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED);
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_server(peck) {
|
|
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
|
|
|
/* Resuming multiple times should only trigger one event */
|
|
eis_device_resume(device);
|
|
eis_device_resume(device); /* noop */
|
|
eis_device_resume(device); /* noop */
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_client(peck) {
|
|
_unref_(ei_event) *resumed =
|
|
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
|
|
|
|
peck_assert_no_ei_events(ei);
|
|
}
|
|
|
|
/* Pausing multiple times should only trigger one event */
|
|
with_server(peck) {
|
|
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
|
|
|
eis_device_pause(device);
|
|
eis_device_pause(device); /* noop */
|
|
eis_device_pause(device); /* noop */
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_client(peck) {
|
|
_unref_(ei_event) *paused =
|
|
peck_ei_next_event(ei, EI_EVENT_DEVICE_PAUSED);
|
|
|
|
peck_assert_no_ei_events(ei);
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_device_ignore_paused_device)
|
|
{
|
|
_unref_(peck) *peck = peck_new();
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_START_EMULATING);
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_client(peck) {
|
|
_unref_(ei_event) *added =
|
|
peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED);
|
|
struct ei_device *device = ei_event_get_device(added);
|
|
|
|
peck_assert_no_ei_events(ei);
|
|
ei_device_pointer_motion(device, 1, 1);
|
|
}
|
|
|
|
|
|
for (size_t i = 0; i < 3; i++) {
|
|
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
|
|
|
/* Device is paused */
|
|
with_server(peck) {
|
|
peck_assert_no_eis_events(eis);
|
|
eis_device_resume(device);
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
/* Device is resumed */
|
|
with_client(peck) {
|
|
_unref_(ei_event) *resumed =
|
|
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
|
|
struct ei_device *device = ei_event_get_device(resumed);
|
|
|
|
peck_assert_no_ei_events(ei);
|
|
with_emulation(device) {
|
|
ei_device_pointer_motion(device, 1, 1);
|
|
}
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
/* Device is resumed */
|
|
with_server(peck) {
|
|
_unref_(eis_event) *rel =
|
|
peck_eis_next_event(eis, EIS_EVENT_POINTER_MOTION);
|
|
_unref_(eis_event) *stop =
|
|
peck_eis_next_event(eis, EIS_EVENT_DEVICE_STOP_EMULATING);
|
|
peck_assert_no_eis_events(eis);
|
|
eis_device_pause(device);
|
|
}
|
|
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
/* Device is paused */
|
|
with_client(peck) {
|
|
_unref_(ei_event) *paused =
|
|
peck_ei_next_event(ei, EI_EVENT_DEVICE_PAUSED);
|
|
struct ei_device *device = ei_event_get_device(paused);
|
|
|
|
peck_assert_no_ei_events(ei);
|
|
ei_device_pointer_motion(device, 1, 1);
|
|
}
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|
|
|
|
MUNIT_TEST(eistest_property_list_on_connect)
|
|
{
|
|
_unref_(peck) *peck = peck_new_context_with_reis(PECK_EI_RECEIVER);
|
|
|
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_reis(peck) {
|
|
reis_set_property_with_permissions(reis, "testprop.all", "all", REIS_PROPERTY_PERM_ALL);
|
|
reis_set_property_with_permissions(reis, "testprop.r", "r", REIS_PROPERTY_PERM_READ);
|
|
reis_set_property_with_permissions(reis, "testprop.rw", "rw", REIS_PROPERTY_PERM_READ|REIS_PROPERTY_PERM_WRITE);
|
|
reis_set_property_with_permissions(reis, "testprop.w", "w", REIS_PROPERTY_PERM_WRITE);
|
|
}
|
|
|
|
peck_ei_connect(peck);
|
|
peck_dispatch_until_stable(peck);
|
|
|
|
with_client(peck) {
|
|
_unref_(ei_event) *connect = peck_ei_next_event(ei, EI_EVENT_CONNECT);
|
|
_unref_(ei_event) *prop_all = peck_ei_next_event(ei, EI_EVENT_PROPERTY);
|
|
_unref_(ei_event) *prop_r = peck_ei_next_event(ei, EI_EVENT_PROPERTY);
|
|
_unref_(ei_event) *prop_rw = peck_ei_next_event(ei, EI_EVENT_PROPERTY);
|
|
|
|
const char *name, *value;
|
|
uint32_t perms;
|
|
|
|
name = ei_event_property_get_name(prop_all);
|
|
value = ei_event_property_get_value(prop_all);
|
|
perms = ei_event_property_get_permissions(prop_all);
|
|
|
|
munit_assert_string_equal(name, "testprop.all");
|
|
munit_assert_string_equal(value, "all");
|
|
munit_assert_uint32(perms, ==, EI_PROPERTY_PERM_ALL);
|
|
|
|
name = ei_event_property_get_name(prop_r);
|
|
value = ei_event_property_get_value(prop_r);
|
|
perms = ei_event_property_get_permissions(prop_r);
|
|
|
|
munit_assert_string_equal(name, "testprop.r");
|
|
munit_assert_string_equal(value, "r");
|
|
munit_assert_uint32(perms, ==, EI_PROPERTY_PERM_READ);
|
|
|
|
name = ei_event_property_get_name(prop_rw);
|
|
value = ei_event_property_get_value(prop_rw);
|
|
perms = ei_event_property_get_permissions(prop_rw);
|
|
|
|
munit_assert_string_equal(name, "testprop.rw");
|
|
munit_assert_string_equal(value, "rw");
|
|
munit_assert_uint32(perms, ==, EI_PROPERTY_PERM_READ|EI_PROPERTY_PERM_WRITE);
|
|
|
|
peck_assert_no_ei_events(ei);
|
|
}
|
|
|
|
return MUNIT_OK;
|
|
}
|