2022-03-03 09:15:57 +10:00
|
|
|
/* SPDX-License-Identifier: MIT */
|
2020-08-05 17:12:54 +10:00
|
|
|
/*
|
|
|
|
|
* 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"
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "libei.h"
|
|
|
|
|
#include "libeis.h"
|
|
|
|
|
|
|
|
|
|
#include "util-mem.h"
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* An enum to define basic server behavior in peck_dispatch_eis().
|
|
|
|
|
* Where a flag is **not** set for any specific behaviour, that event will
|
|
|
|
|
* remain on the event queue after peck_dispatch_eis(). For example, a
|
|
|
|
|
* caller setting @ref PECK_EIS_BEHAVIOR_ACCEPT_CLIENT will see
|
|
|
|
|
* the device added event as first event in the queue.
|
|
|
|
|
*/
|
|
|
|
|
enum peck_eis_behavior {
|
|
|
|
|
/**
|
2020-08-19 13:39:32 +10:00
|
|
|
* Behavior of EIS is implemented in the test case.
|
2020-08-05 17:12:54 +10:00
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_NONE,
|
2020-09-14 17:16:50 +10:00
|
|
|
/**
|
2021-07-16 18:17:15 +10:00
|
|
|
* Accept all client connection requests, create default seats
|
2020-08-19 13:39:32 +10:00
|
|
|
* **and** resume any device immediately after add.
|
2020-08-05 17:12:54 +10:00
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_ACCEPT_ALL,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Process connect/disconnect requests from the client.
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_ACCEPT_CLIENT,
|
|
|
|
|
PECK_EIS_BEHAVIOR_REJECT_CLIENT,
|
|
|
|
|
|
|
|
|
|
/**
|
2021-07-16 18:17:15 +10:00
|
|
|
* Create a "default" seat. This behavior is enabled as part of
|
|
|
|
|
* PECK_EIS_BEHAVIOR_ACCEPT_ALL.
|
2020-08-05 17:12:54 +10:00
|
|
|
*/
|
2021-07-16 18:17:15 +10:00
|
|
|
PECK_EIS_BEHAVIOR_DEFAULT_SEAT,
|
|
|
|
|
/**
|
|
|
|
|
* Do not create a "default" seat.
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_NO_DEFAULT_SEAT,
|
2020-08-18 13:04:01 +10:00
|
|
|
|
2021-07-16 18:17:15 +10:00
|
|
|
/**
|
2021-07-21 10:22:09 +10:00
|
|
|
* Handle the bind seat request
|
2021-07-16 18:17:15 +10:00
|
|
|
*/
|
2021-07-21 10:22:09 +10:00
|
|
|
PECK_EIS_BEHAVIOR_HANDLE_BIND_SEAT,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle the seat unbind request
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_HANDLE_UNBIND_SEAT,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle the device close. This behavior is enabled as part of
|
|
|
|
|
* PECK_EIS_BEHAVIOR_ACCEPT_ALL.
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_HANDLE_CLOSE_DEVICE,
|
2020-08-05 17:12:54 +10:00
|
|
|
|
2021-08-23 10:50:23 +10:00
|
|
|
/**
|
|
|
|
|
* Handle frame events. This behavior is enabled by default.
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_HANDLE_FRAME,
|
2021-08-24 09:53:10 +10:00
|
|
|
/**
|
|
|
|
|
* Handle the start/stop emulation event. This behavior is enabled as part of
|
|
|
|
|
* PECK_EIS_BEHAVIOR_ACCEPT_ALL.
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_HANDLE_START_EMULATING,
|
|
|
|
|
PECK_EIS_BEHAVIOR_HANDLE_STOP_EMULATING,
|
2021-08-23 10:50:23 +10:00
|
|
|
|
2021-07-16 18:17:15 +10:00
|
|
|
/**
|
|
|
|
|
* Create default devices
|
|
|
|
|
*/
|
|
|
|
|
PECK_EIS_BEHAVIOR_ADD_DEVICES, /**< add all of the below */
|
|
|
|
|
PECK_EIS_BEHAVIOR_ADD_POINTER,
|
|
|
|
|
PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE,
|
|
|
|
|
PECK_EIS_BEHAVIOR_ADD_KEYBOARD,
|
|
|
|
|
PECK_EIS_BEHAVIOR_ADD_TOUCH,
|
2020-08-19 13:39:32 +10:00
|
|
|
|
|
|
|
|
PECK_EIS_BEHAVIOR_RESUME_DEVICE,
|
|
|
|
|
PECK_EIS_BEHAVIOR_SUSPEND_DEVICE,
|
2020-08-05 17:12:54 +10:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum peck_ei_behavior {
|
|
|
|
|
PECK_EI_BEHAVIOR_NONE,
|
2020-09-14 17:16:50 +10:00
|
|
|
/* enabled by default - handle the Connect event */
|
2021-07-16 18:17:15 +10:00
|
|
|
PECK_EI_BEHAVIOR_AUTOCONNECT,
|
2020-09-14 17:16:50 +10:00
|
|
|
/* enabled by default - handle the first seat added event, setting
|
2021-07-16 18:17:15 +10:00
|
|
|
* the default seat to the first seat and bind to it */
|
2020-09-14 17:16:50 +10:00
|
|
|
PECK_EI_BEHAVIOR_AUTOSEAT,
|
|
|
|
|
/* handle Connect/Seat/Added/Resumed events, i.e. anything until the
|
|
|
|
|
* first real device event */
|
2020-09-22 13:18:57 +10:00
|
|
|
PECK_EI_BEHAVIOR_AUTODEVICES,
|
2021-08-24 09:53:10 +10:00
|
|
|
/**
|
|
|
|
|
* Immediately send a StartEmulating request once a device is resumed.
|
|
|
|
|
*/
|
|
|
|
|
PECK_EI_BEHAVIOR_AUTOSTART,
|
2020-08-05 17:12:54 +10:00
|
|
|
PECK_EI_BEHAVIOR_HANDLE_ADDED,
|
|
|
|
|
PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER,
|
2020-09-22 13:17:54 +10:00
|
|
|
PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER_ABSOLUTE,
|
2020-08-05 17:12:54 +10:00
|
|
|
PECK_EI_BEHAVIOR_HANDLE_ADDED_KEYBOARD,
|
|
|
|
|
PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH,
|
2020-08-19 13:39:32 +10:00
|
|
|
|
|
|
|
|
PECK_EI_BEHAVIOR_HANDLE_RESUMED,
|
2021-08-23 08:25:33 +10:00
|
|
|
PECK_EI_BEHAVIOR_HANDLE_PAUSED,
|
2020-08-05 17:12:54 +10:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct peck;
|
|
|
|
|
|
|
|
|
|
struct peck *
|
|
|
|
|
peck_new(void);
|
|
|
|
|
|
2022-03-03 13:46:18 +10:00
|
|
|
void _peck_mark(struct peck *peck, const char *func, int line);
|
|
|
|
|
/** Add debug marker to the log output */
|
|
|
|
|
#define peck_mark(peck_) _peck_mark(peck_, __func__, __LINE__)
|
|
|
|
|
|
2020-08-05 17:12:54 +10:00
|
|
|
void
|
|
|
|
|
peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior);
|
|
|
|
|
|
|
|
|
|
struct ei *
|
|
|
|
|
peck_get_ei(struct peck *peck);
|
|
|
|
|
|
2020-10-27 11:34:10 +10:00
|
|
|
void
|
|
|
|
|
peck_drop_ei(struct peck *peck);
|
|
|
|
|
|
2020-08-05 17:12:54 +10:00
|
|
|
struct eis *
|
|
|
|
|
peck_get_eis(struct peck *peck);
|
|
|
|
|
|
2020-09-14 17:16:50 +10:00
|
|
|
struct eis_client *
|
|
|
|
|
peck_eis_get_default_client(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct eis_seat *
|
|
|
|
|
peck_eis_get_default_seat(struct peck *peck);
|
|
|
|
|
|
2021-07-16 18:17:15 +10:00
|
|
|
struct eis_device *
|
|
|
|
|
peck_eis_get_default_pointer(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct eis_device *
|
|
|
|
|
peck_eis_get_default_keyboard(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct eis_device *
|
|
|
|
|
peck_eis_get_default_pointer_absolute(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct eis_device *
|
|
|
|
|
peck_eis_get_default_touch(struct peck *peck);
|
|
|
|
|
|
2020-09-14 17:16:50 +10:00
|
|
|
struct ei_seat *
|
|
|
|
|
peck_ei_get_default_seat(struct peck *peck);
|
|
|
|
|
|
2021-07-16 18:17:15 +10:00
|
|
|
struct ei_device *
|
|
|
|
|
peck_ei_get_default_pointer(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct ei_device *
|
|
|
|
|
peck_ei_get_default_keyboard(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct ei_device *
|
|
|
|
|
peck_ei_get_default_pointer_absolute(struct peck *peck);
|
|
|
|
|
|
|
|
|
|
struct ei_device *
|
|
|
|
|
peck_ei_get_default_touch(struct peck *peck);
|
|
|
|
|
|
2020-08-19 10:23:03 +10:00
|
|
|
/**
|
|
|
|
|
* Dispatch all events according to the currently defined behavior.
|
|
|
|
|
* When this function returns false, the connection is in a "stable" state
|
|
|
|
|
* and futher calls to this function will not change that state. This stable
|
|
|
|
|
* state may mean either there are no events or events pending to be
|
|
|
|
|
* processed by the caller.
|
|
|
|
|
*
|
|
|
|
|
* @return true if at least one event was processed according to the current
|
|
|
|
|
* behavior
|
|
|
|
|
*/
|
2020-09-23 14:18:12 +10:00
|
|
|
#define peck_dispatch_eis(_p) \
|
|
|
|
|
_peck_dispatch_eis(_p, __LINE__)
|
2020-08-18 14:26:43 +10:00
|
|
|
bool
|
2020-09-23 14:18:12 +10:00
|
|
|
_peck_dispatch_eis(struct peck *peck, int lineno);
|
2020-08-05 17:12:54 +10:00
|
|
|
|
2020-08-19 10:23:03 +10:00
|
|
|
/**
|
|
|
|
|
* Dispatch all events according to the currently defined behavior.
|
|
|
|
|
* When this function returns false, the connection is in a "stable" state
|
|
|
|
|
* and futher calls to this function will not change that state. This stable
|
|
|
|
|
* state may mean either there are no events or events pending to be
|
|
|
|
|
* processed by the caller.
|
|
|
|
|
*
|
|
|
|
|
* @return true if at least one behavior was processes according to the
|
|
|
|
|
* current behavior
|
|
|
|
|
*/
|
2020-09-23 14:18:12 +10:00
|
|
|
#define peck_dispatch_ei(_p) \
|
|
|
|
|
_peck_dispatch_ei(_p, __LINE__)
|
2020-08-18 14:26:43 +10:00
|
|
|
bool
|
2020-09-23 14:18:12 +10:00
|
|
|
_peck_dispatch_ei(struct peck *peck, int lineno);
|
2020-08-05 17:12:54 +10:00
|
|
|
|
|
|
|
|
struct peck *
|
|
|
|
|
peck_unref(struct peck *peck);
|
|
|
|
|
|
2020-08-19 10:23:03 +10:00
|
|
|
/**
|
|
|
|
|
* Dispatch both EIS and EI until a stable state is reached, i.e. until
|
|
|
|
|
* either there are no events pending or until either (or both) have events
|
|
|
|
|
* pending that are not processed by the current behaviors.
|
|
|
|
|
*/
|
2020-08-18 14:26:43 +10:00
|
|
|
void
|
2020-09-22 13:19:41 +10:00
|
|
|
_peck_dispatch_until_stable(struct peck *peck, int lineno);
|
|
|
|
|
|
|
|
|
|
#define peck_dispatch_until_stable(_p) \
|
|
|
|
|
_peck_dispatch_until_stable((_p), __LINE__)
|
2020-08-18 14:26:43 +10:00
|
|
|
|
2020-08-19 10:23:03 +10:00
|
|
|
/**
|
|
|
|
|
* Discard all pending events.
|
|
|
|
|
*/
|
2020-08-05 17:12:54 +10:00
|
|
|
void
|
|
|
|
|
peck_drain_eis(struct eis *eis);
|
|
|
|
|
|
2020-08-19 10:23:03 +10:00
|
|
|
/**
|
|
|
|
|
* Discard all pending events.
|
|
|
|
|
*/
|
2020-08-05 17:12:54 +10:00
|
|
|
void
|
|
|
|
|
peck_drain_ei(struct ei *ei);
|
|
|
|
|
|
2020-08-19 14:21:12 +10:00
|
|
|
void
|
|
|
|
|
peck_assert_no_eis_events(struct eis *eis);
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
peck_assert_no_ei_events(struct ei *ei);
|
|
|
|
|
|
2020-09-23 14:18:12 +10:00
|
|
|
#define peck_ei_next_event(_ei, _type) \
|
|
|
|
|
_peck_ei_next_event(_ei, _type, __LINE__)
|
2020-08-18 14:38:43 +10:00
|
|
|
struct ei_event *
|
2020-09-23 14:18:12 +10:00
|
|
|
_peck_ei_next_event(struct ei *ei, enum ei_event_type type, int lineno);
|
2020-08-18 14:38:43 +10:00
|
|
|
|
2020-09-23 14:18:12 +10:00
|
|
|
#define peck_eis_next_event(_eis, _type) \
|
|
|
|
|
_peck_eis_next_event(_eis, _type, __LINE__)
|
2020-08-18 14:38:43 +10:00
|
|
|
struct eis_event *
|
2020-09-23 14:18:12 +10:00
|
|
|
_peck_eis_next_event(struct eis *eis, enum eis_event_type type, int lineno);
|
2020-08-18 14:38:43 +10:00
|
|
|
|
2020-09-22 14:40:43 +10:00
|
|
|
#define peck_eis_touch_down(_eis, _x, _y) \
|
|
|
|
|
_peck_eis_touch_event(_eis, EIS_EVENT_TOUCH_DOWN, _x, _y, __LINE__)
|
|
|
|
|
#define peck_eis_touch_motion(_eis, _x, _y) \
|
|
|
|
|
_peck_eis_touch_event(_eis, EIS_EVENT_TOUCH_MOTION, _x, _y, __LINE__)
|
|
|
|
|
#define peck_eis_touch_up(_eis) \
|
|
|
|
|
_peck_eis_next_event(_eis, EIS_EVENT_TOUCH_UP, __LINE__)
|
|
|
|
|
|
|
|
|
|
struct eis_event *
|
|
|
|
|
_peck_eis_touch_event(struct eis *eis, enum eis_event_type type,
|
|
|
|
|
double x, double y, int lineno);
|
|
|
|
|
|
2020-08-18 14:06:36 +10:00
|
|
|
const char *
|
|
|
|
|
peck_ei_event_name(struct ei_event *e);
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
peck_eis_event_name(struct eis_event *e);
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
peck_ei_event_type_name(enum ei_event_type type);
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
peck_eis_event_type_name(enum eis_event_type type);
|
|
|
|
|
|
2020-08-05 17:12:54 +10:00
|
|
|
/* Define a bunch of _cleanup_foo_ macros for a struct foo */
|
2020-10-21 10:29:00 +10:00
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei_event);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei_device);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei_touch);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei_keymap);
|
2021-07-16 18:17:15 +10:00
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei_seat);
|
2021-07-21 14:52:04 +10:00
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(ei_region);
|
2020-08-05 17:12:54 +10:00
|
|
|
|
2020-10-21 10:29:00 +10:00
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis_client);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis_event);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis_device);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis_keymap);
|
|
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis_seat);
|
2021-07-21 14:52:04 +10:00
|
|
|
DEFINE_UNREF_CLEANUP_FUNC(eis_region);
|
2020-08-12 14:35:41 +10:00
|
|
|
|
|
|
|
|
/* Macros intended just for readability to make it more obvious which part
|
|
|
|
|
of a test handles server vs client */
|
|
|
|
|
#define with_server(peck_) for (struct eis *eis = peck_get_eis(peck_); eis; eis = NULL)
|
|
|
|
|
#define with_client(peck_) for (struct ei *ei = peck_get_ei(peck_); ei; ei = NULL)
|
2021-08-24 09:53:10 +10:00
|
|
|
#define with_emulation(d_) for (bool _loop = ({ ei_device_start_emulating(d_); true;});\
|
|
|
|
|
_loop; \
|
|
|
|
|
({ ei_device_stop_emulating(d_); _loop = false; }))
|
2020-09-28 13:10:20 +10:00
|
|
|
|
|
|
|
|
#define peck_errno_check(_rc) { \
|
|
|
|
|
const int xrc = (_rc); \
|
|
|
|
|
if (xrc != 0) \
|
|
|
|
|
munit_errorf("errno is not 0: %d - %s\n", -xrc, strerror(-xrc)); \
|
|
|
|
|
}
|