mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-05 06:38:02 +02:00
eis: remove some indirection from the device event handling
Now that we only have one nice hook as entry point for those events, let's move (and harden) the code there.
This commit is contained in:
parent
876e4044ab
commit
03d7f96ddd
2 changed files with 164 additions and 268 deletions
|
|
@ -203,6 +203,19 @@ eis_device_get_client(struct eis_device *device)
|
|||
return eis_seat_get_client(eis_device_get_seat(device));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
eis_device_in_region(struct eis_device *device, double x, double y)
|
||||
{
|
||||
struct eis_region *r;
|
||||
|
||||
list_for_each(r, &device->regions, link) {
|
||||
if (eis_region_contains(r, x, y))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
client_msg_release(struct eis_device *device)
|
||||
{
|
||||
|
|
@ -274,17 +287,45 @@ client_msg_stop_emulating(struct eis_device *device)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
static struct brei_result *
|
||||
maybe_error_on_device_state(struct eis_device *device, const char *event_type)
|
||||
{
|
||||
switch (device->state) {
|
||||
case EIS_DEVICE_STATE_RESUMED:
|
||||
/* could be a race condition, but it's unlikely unless the
|
||||
* EIS implementation pauses and resumes immediately without
|
||||
* giving the client a chance to catch up. So let's
|
||||
* treat this as error until we see real issues.
|
||||
*/
|
||||
break;
|
||||
case EIS_DEVICE_STATE_PAUSED:
|
||||
/* we paused the device but the client sent us an event
|
||||
* - most likely a race condition, so let's ignore it */
|
||||
return NULL;
|
||||
case EIS_DEVICE_STATE_EMULATING:
|
||||
return NULL;
|
||||
case EIS_DEVICE_STATE_NEW:
|
||||
case EIS_DEVICE_STATE_CLOSED_BY_CLIENT:
|
||||
case EIS_DEVICE_STATE_DEAD:
|
||||
break;
|
||||
}
|
||||
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Invalid device state %ud for a %s event", device->state, event_type);
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
client_msg_frame(struct eis_device *device, uint32_t time, uint32_t micros)
|
||||
{
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return brei_result_new_from_neg_errno(-EINVAL);
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_frame_event(device, ms2us(time) + micros);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eis_queue_frame_event(device, ms2us(time) + micros);
|
||||
|
||||
return NULL;
|
||||
return maybe_error_on_device_state(device, "frame");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -308,7 +349,17 @@ client_msg_pointer_rel(struct eis_pointer *pointer, float x, float y)
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_rel(device, x, y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Pointer rel event for non-pointer device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_pointer_rel_event(device, x, y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "pointer rel");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -318,7 +369,18 @@ client_msg_pointer_abs(struct eis_pointer *pointer, float x, float y)
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_abs(device, x, y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Pointer abs event for non-pointer device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
if (eis_device_in_region(device, x, y))
|
||||
eis_queue_pointer_abs_event(device, x, y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "pointer abs");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -328,7 +390,18 @@ client_msg_pointer_button(struct eis_pointer *pointer, uint32_t button, uint32_t
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_button(device, button, !!state));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Pointer button event for non-pointer device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_pointer_button_event(device, button, !!state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "pointer button");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -338,7 +411,18 @@ client_msg_pointer_scroll(struct eis_pointer *pointer, float x, float y)
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll(device, x, y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Pointer scroll event for non-pointer device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_pointer_scroll_event(device, x, y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "pointer scroll");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -348,7 +432,18 @@ client_msg_pointer_scroll_discrete(struct eis_pointer *pointer, int32_t x, int32
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll_discrete(device, x, y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Pointer scroll discrete event for non-pointer device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_pointer_scroll_discrete_event(device, x, y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "pointer scroll discrete");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -359,10 +454,21 @@ client_msg_pointer_scroll_stop(struct eis_pointer *pointer,
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
if (is_cancel)
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll_cancel(device, !!x, !!y));
|
||||
else
|
||||
return brei_result_new_from_neg_errno(eis_device_event_pointer_scroll_stop(device, !!x, !!y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Pointer scroll stop event for non-pointer device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
if (is_cancel)
|
||||
eis_queue_pointer_scroll_cancel_event(device, !!x, !!y);
|
||||
else
|
||||
eis_queue_pointer_scroll_stop_event(device, !!x, !!y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "pointer scroll stop");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -397,7 +503,17 @@ client_msg_keyboard_key(struct eis_keyboard *keyboard, uint32_t key, uint32_t st
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_keyboard_key(device, key, !!state));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Key event for non-keyboard device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_keyboard_key_event(device, key, !!state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "key");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -428,7 +544,17 @@ client_msg_touch_down(struct eis_touchscreen *touchscreen,
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_touch_down(device, touchid, x, y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Touch down event for non-touch device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_touch_down_event(device, touchid, x, y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "touch down");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -439,7 +565,17 @@ client_msg_touch_motion(struct eis_touchscreen *touchscreen,
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_touch_motion(device, touchid, x, y));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Touch motion event for non-touch device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_touch_motion_event(device, touchid, x, y);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "touch motion");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -449,7 +585,17 @@ client_msg_touch_up(struct eis_touchscreen *touchscreen, uint32_t touchid)
|
|||
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(device);
|
||||
|
||||
return brei_result_new_from_neg_errno(eis_device_event_touch_up(device, touchid));
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Touch up event for non-touch device");
|
||||
}
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_touch_up_event(device, touchid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return maybe_error_on_device_state(device, "touch up");
|
||||
}
|
||||
|
||||
static struct brei_result *
|
||||
|
|
@ -1052,217 +1198,6 @@ eis_device_frame(struct eis_device *device, uint64_t time)
|
|||
eis_device_event_frame(device, us2ms(time), time % 1000);
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_rel(struct eis_device *device,
|
||||
double x, double y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_pointer_rel_event(device, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
eis_device_in_region(struct eis_device *device, double x, double y)
|
||||
{
|
||||
struct eis_region *r;
|
||||
|
||||
list_for_each(r, &device->regions, link) {
|
||||
if (eis_region_contains(r, x, y))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_abs(struct eis_device *device,
|
||||
double x, double y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not an absolute pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
if (eis_device_in_region(device, x, y))
|
||||
eis_queue_pointer_abs_event(device, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_button(struct eis_device *device,
|
||||
uint32_t button, bool is_press)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_pointer_button_event(device, button, is_press);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll(struct eis_device *device,
|
||||
double x, double y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a (absolute) pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_pointer_scroll_event(device, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll_discrete(struct eis_device *device,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a (absolute) pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_pointer_scroll_discrete_event(device, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll_stop(struct eis_device *device, bool x, bool y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a (absolute) pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_pointer_scroll_stop_event(device, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll_cancel(struct eis_device *device, bool x, bool y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) &&
|
||||
!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a (absolute) pointer", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_pointer_scroll_cancel_event(device, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_keyboard_key(struct eis_device *device,
|
||||
uint32_t key, bool is_press)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a keyboard", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_keyboard_key_event(device, key, is_press);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_touch_down(struct eis_device *device, uint32_t touchid, double x, double y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a touch device", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_touch_down_event(device, touchid, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_touch_motion(struct eis_device *device, uint32_t touchid, double x, double y)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a touch device", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_touch_motion_event(device, touchid, x, y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_touch_up(struct eis_device *device, uint32_t touchid)
|
||||
{
|
||||
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: device is not a touch device", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_touch_up_event(device, touchid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
eis_device_closed_by_client(struct eis_device *device)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -117,45 +117,6 @@ eis_device_set_client_keymap(struct eis_device *device,
|
|||
enum eis_keymap_type type,
|
||||
int keymap_fd, size_t size);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_rel(struct eis_device *device,
|
||||
double x, double y);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_abs(struct eis_device *device,
|
||||
double x, double y);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_button(struct eis_device *device,
|
||||
uint32_t button, bool state);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll(struct eis_device *device,
|
||||
double x, double y);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll_discrete(struct eis_device *device,
|
||||
int32_t x, int32_t y);
|
||||
int
|
||||
eis_device_event_pointer_scroll_stop(struct eis_device *device, bool x, bool y);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_scroll_cancel(struct eis_device *device, bool x, bool y);
|
||||
|
||||
int
|
||||
eis_device_event_keyboard_key(struct eis_device *device,
|
||||
uint32_t key, bool state);
|
||||
int
|
||||
eis_device_event_touch_down(struct eis_device *device, uint32_t touchid,
|
||||
double x, double y);
|
||||
|
||||
int
|
||||
eis_device_event_touch_motion(struct eis_device *device, uint32_t touchid,
|
||||
double x, double y);
|
||||
|
||||
int
|
||||
eis_device_event_touch_up(struct eis_device *device, uint32_t touchid);
|
||||
|
||||
void
|
||||
eis_device_closed_by_client(struct eis_device *device);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue