mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-20 15:00:06 +01:00
ei: add ei_ping() and the matching EI_EVENT_PONG
This wraps around ei_connection.sync to allow a C API user to add synchronization points. Closes #69 Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
This commit is contained in:
parent
2cc5e56e28
commit
a278c7b371
13 changed files with 408 additions and 5 deletions
|
|
@ -44,11 +44,8 @@ ei_connection_destroy(struct ei_connection *connection)
|
||||||
struct ei *ei = ei_connection_get_context(connection);
|
struct ei *ei = ei_connection_get_context(connection);
|
||||||
ei_unregister_object(ei, &connection->proto_object);
|
ei_unregister_object(ei, &connection->proto_object);
|
||||||
|
|
||||||
struct ei_callback *cb;
|
/* should be a noop */
|
||||||
list_for_each_safe(cb, &connection->pending_callbacks, link) {
|
ei_connection_remove_pending_callbacks(connection);
|
||||||
list_remove(&cb->link);
|
|
||||||
ei_callback_unref(cb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJECT_IMPLEMENT_REF(ei_connection);
|
OBJECT_IMPLEMENT_REF(ei_connection);
|
||||||
|
|
@ -101,6 +98,17 @@ ei_connection_new(struct ei *ei, object_id_t id, uint32_t version)
|
||||||
return connection; /* ref owned by caller */
|
return connection; /* ref owned by caller */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ei_connection_remove_pending_callbacks(struct ei_connection *connection)
|
||||||
|
{
|
||||||
|
struct ei_callback *cb;
|
||||||
|
list_for_each_safe(cb, &connection->pending_callbacks, link) {
|
||||||
|
list_remove(&cb->link);
|
||||||
|
ei_connection_sync_callback_unref(cb->user_data);
|
||||||
|
ei_callback_unref(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ei_connection_sync_callback_destroy(struct ei_connection_sync_callback *callback)
|
ei_connection_sync_callback_destroy(struct ei_connection_sync_callback *callback)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,9 @@ OBJECT_DECLARE_UNREF(ei_connection);
|
||||||
struct ei_connection *
|
struct ei_connection *
|
||||||
ei_connection_new(struct ei *ei, object_id_t id, uint32_t version);
|
ei_connection_new(struct ei *ei, object_id_t id, uint32_t version);
|
||||||
|
|
||||||
|
void
|
||||||
|
ei_connection_remove_pending_callbacks(struct ei_connection *connection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the ei_callback.done event is received after
|
* Called when the ei_callback.done event is received after
|
||||||
* an ei_connection_sync() request.
|
* an ei_connection_sync() request.
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ ei_event_type_to_string(enum ei_event_type type)
|
||||||
CASE_RETURN_STRING(EI_EVENT_DEVICE_PAUSED);
|
CASE_RETURN_STRING(EI_EVENT_DEVICE_PAUSED);
|
||||||
CASE_RETURN_STRING(EI_EVENT_DEVICE_RESUMED);
|
CASE_RETURN_STRING(EI_EVENT_DEVICE_RESUMED);
|
||||||
CASE_RETURN_STRING(EI_EVENT_KEYBOARD_MODIFIERS);
|
CASE_RETURN_STRING(EI_EVENT_KEYBOARD_MODIFIERS);
|
||||||
|
CASE_RETURN_STRING(EI_EVENT_PONG);
|
||||||
CASE_RETURN_STRING(EI_EVENT_FRAME);
|
CASE_RETURN_STRING(EI_EVENT_FRAME);
|
||||||
CASE_RETURN_STRING(EI_EVENT_DEVICE_START_EMULATING);
|
CASE_RETURN_STRING(EI_EVENT_DEVICE_START_EMULATING);
|
||||||
CASE_RETURN_STRING(EI_EVENT_DEVICE_STOP_EMULATING);
|
CASE_RETURN_STRING(EI_EVENT_DEVICE_STOP_EMULATING);
|
||||||
|
|
@ -96,6 +97,9 @@ ei_event_destroy(struct ei_event *event)
|
||||||
case EI_EVENT_TOUCH_UP:
|
case EI_EVENT_TOUCH_UP:
|
||||||
case EI_EVENT_TOUCH_MOTION:
|
case EI_EVENT_TOUCH_MOTION:
|
||||||
break;
|
break;
|
||||||
|
case EI_EVENT_PONG:
|
||||||
|
ei_ping_unref(event->pong.ping);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ei_device_unref(event->device);
|
ei_device_unref(event->device);
|
||||||
ei_seat_unref(event->seat);
|
ei_seat_unref(event->seat);
|
||||||
|
|
@ -204,6 +208,14 @@ ei_event_keyboard_get_xkb_group(struct ei_event *event)
|
||||||
return event->modifiers.group;
|
return event->modifiers.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ struct ei_ping *
|
||||||
|
ei_event_pong_get_ping(struct ei_event *event)
|
||||||
|
{
|
||||||
|
require_event_type(event, NULL, EI_EVENT_PONG);
|
||||||
|
|
||||||
|
return event->pong.ping;
|
||||||
|
}
|
||||||
|
|
||||||
_public_ double
|
_public_ double
|
||||||
ei_event_pointer_get_dx(struct ei_event *event)
|
ei_event_pointer_get_dx(struct ei_event *event)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,9 @@ struct ei_event {
|
||||||
struct {
|
struct {
|
||||||
uint32_t sequence;
|
uint32_t sequence;
|
||||||
} start_emulating;
|
} start_emulating;
|
||||||
|
struct {
|
||||||
|
struct ei_ping *ping;
|
||||||
|
} pong;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
124
src/libei-ping.c
Normal file
124
src/libei-ping.c
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
/*
|
||||||
|
* Copyright © 2024 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 <stdio.h>
|
||||||
|
|
||||||
|
#include "util-mem.h"
|
||||||
|
#include "util-macros.h"
|
||||||
|
#include "util-object.h"
|
||||||
|
#include "util-list.h"
|
||||||
|
#include "brei-shared.h"
|
||||||
|
|
||||||
|
#include "libei-private.h"
|
||||||
|
#include "libei-connection.h"
|
||||||
|
|
||||||
|
struct ei_ping {
|
||||||
|
struct object object;
|
||||||
|
uint64_t id;
|
||||||
|
void *user_data;
|
||||||
|
|
||||||
|
struct ei *context;
|
||||||
|
bool is_pending;
|
||||||
|
bool is_done;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ei_ping_destroy(struct ei_ping *ping)
|
||||||
|
{
|
||||||
|
if (!ping->is_pending)
|
||||||
|
ei_unref(ping->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
OBJECT_IMPLEMENT_CREATE(ei_ping);
|
||||||
|
|
||||||
|
_public_
|
||||||
|
OBJECT_IMPLEMENT_REF(ei_ping);
|
||||||
|
_public_
|
||||||
|
OBJECT_IMPLEMENT_UNREF_CLEANUP(ei_ping);
|
||||||
|
_public_
|
||||||
|
OBJECT_IMPLEMENT_GETTER(ei_ping, id, uint64_t);
|
||||||
|
_public_
|
||||||
|
OBJECT_IMPLEMENT_GETTER(ei_ping, user_data, void*);
|
||||||
|
_public_
|
||||||
|
OBJECT_IMPLEMENT_SETTER(ei_ping, user_data, void*);
|
||||||
|
static
|
||||||
|
OBJECT_IMPLEMENT_GETTER(ei_ping, context, struct ei*);
|
||||||
|
|
||||||
|
_public_ struct ei_ping *
|
||||||
|
ei_new_ping(struct ei *ei)
|
||||||
|
{
|
||||||
|
static uint64_t id = 0;
|
||||||
|
|
||||||
|
struct ei_ping *ping = ei_ping_create(NULL);
|
||||||
|
ping->id = ++id;
|
||||||
|
/* Ref our context while it's pending (i.e. only the caller has the ref).
|
||||||
|
* Once it's pending we no longer need the ref.
|
||||||
|
*/
|
||||||
|
ping->context = ei_ref(ei);
|
||||||
|
ping->is_pending = false;
|
||||||
|
ping->is_done = false;
|
||||||
|
|
||||||
|
return ping;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_pong(struct ei_connection_sync_callback *callback)
|
||||||
|
{
|
||||||
|
struct ei_ping *ping = ei_connection_sync_callback_get_user_data(callback);
|
||||||
|
ping->is_done = true;
|
||||||
|
|
||||||
|
struct ei *ei = ei_connection_sync_callback_get_context(callback);
|
||||||
|
ei_queue_pong_event(ei, ping);
|
||||||
|
/* ei_ping ref is removed in on_destroy */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_destroy(struct ei_connection_sync_callback *callback)
|
||||||
|
{
|
||||||
|
/* This is only called if we never received a pong */
|
||||||
|
_unref_(ei_ping) *ping = ei_connection_sync_callback_get_user_data(callback);
|
||||||
|
|
||||||
|
/* We never got a pong because we got disconnected. Queue a fake pong event */
|
||||||
|
if (!ping->is_done) {
|
||||||
|
struct ei *ei = ei_connection_sync_callback_get_context(callback);
|
||||||
|
ei_queue_pong_event(ei, ping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_public_ void
|
||||||
|
ei_ping(struct ei_ping *ping)
|
||||||
|
{
|
||||||
|
struct ei *ei = ei_ping_get_context(ping);
|
||||||
|
|
||||||
|
ei_unref(ping->context);
|
||||||
|
ping->context = ei;
|
||||||
|
ping->is_pending = true;
|
||||||
|
|
||||||
|
_unref_(ei_connection_sync_callback) *cb = ei_connection_sync_callback_new(ei,
|
||||||
|
on_pong,
|
||||||
|
on_destroy,
|
||||||
|
ei_ping_ref(ping));
|
||||||
|
ei_connection_sync(ei->connection, cb);
|
||||||
|
}
|
||||||
|
|
@ -168,6 +168,9 @@ ei_queue_connect_event(struct ei *ei);
|
||||||
void
|
void
|
||||||
ei_queue_disconnect_event(struct ei *ei);
|
ei_queue_disconnect_event(struct ei *ei);
|
||||||
|
|
||||||
|
void
|
||||||
|
ei_queue_pong_event(struct ei *ei, struct ei_ping *ping);
|
||||||
|
|
||||||
void
|
void
|
||||||
ei_queue_device_removed_event(struct ei_device *device);
|
ei_queue_device_removed_event(struct ei_device *device);
|
||||||
|
|
||||||
|
|
|
||||||
11
src/libei.c
11
src/libei.c
|
|
@ -326,6 +326,16 @@ ei_queue_disconnect_event(struct ei *ei)
|
||||||
queue_event(ei, e);
|
queue_event(ei, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ei_queue_pong_event(struct ei *ei, struct ei_ping *ping)
|
||||||
|
{
|
||||||
|
struct ei_event *e = ei_event_new(ei);
|
||||||
|
e->type = EI_EVENT_PONG;
|
||||||
|
e->pong.ping = ei_ping_ref(ping);
|
||||||
|
|
||||||
|
queue_event(ei, e);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ei_queue_seat_added_event(struct ei_seat *seat)
|
ei_queue_seat_added_event(struct ei_seat *seat)
|
||||||
{
|
{
|
||||||
|
|
@ -613,6 +623,7 @@ ei_disconnect(struct ei *ei)
|
||||||
|
|
||||||
if (state != EI_STATE_NEW) {
|
if (state != EI_STATE_NEW) {
|
||||||
ei_connection_request_disconnect(ei->connection);
|
ei_connection_request_disconnect(ei->connection);
|
||||||
|
ei_connection_remove_pending_callbacks(ei->connection);
|
||||||
}
|
}
|
||||||
ei_queue_disconnect_event(ei);
|
ei_queue_disconnect_event(ei);
|
||||||
ei->state = EI_STATE_DISCONNECTED;
|
ei->state = EI_STATE_DISCONNECTED;
|
||||||
|
|
|
||||||
120
src/libei.h
120
src/libei.h
|
|
@ -215,6 +215,16 @@ struct ei_region;
|
||||||
*/
|
*/
|
||||||
struct ei_touch;
|
struct ei_touch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct ei_ping
|
||||||
|
*
|
||||||
|
* A callback struct returned by ei_new_ping() to handle
|
||||||
|
* roundtrips to the EIS implementation.
|
||||||
|
*
|
||||||
|
* @see ei_new_ping
|
||||||
|
*/
|
||||||
|
struct ei_ping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum ei_device_type
|
* @enum ei_device_type
|
||||||
* @ingroup libei-device
|
* @ingroup libei-device
|
||||||
|
|
@ -412,6 +422,15 @@ enum ei_event_type {
|
||||||
*/
|
*/
|
||||||
EI_EVENT_KEYBOARD_MODIFIERS,
|
EI_EVENT_KEYBOARD_MODIFIERS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returned in response to ei_ping().
|
||||||
|
*
|
||||||
|
* Note that in the ei protocol, the matching client request is called `sync`
|
||||||
|
* but for consistency in the libeis/libei API the C API uses
|
||||||
|
* ei_ping() with `EI_EVENT_PONG` as return.
|
||||||
|
*/
|
||||||
|
EI_EVENT_PONG = 90,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Hardware" frame event. This event **must** be sent by the server
|
* "Hardware" frame event. This event **must** be sent by the server
|
||||||
* and notifies the client that the previous set of events belong to
|
* and notifies the client that the previous set of events belong to
|
||||||
|
|
@ -807,6 +826,95 @@ ei_setup_backend_socket(struct ei *ei, const char *socketpath);
|
||||||
int
|
int
|
||||||
ei_get_fd(struct ei *ei);
|
ei_get_fd(struct ei *ei);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ei_ping object to trigger a round trip to the EIS implementation.
|
||||||
|
* See ei_ping() for details.
|
||||||
|
*
|
||||||
|
* The returned @ref ei_ping is refcounted, use ei_ping_unref() to
|
||||||
|
* drop the reference.
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
struct ei_ping *
|
||||||
|
ei_new_ping(struct ei *ei);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a unique, increasing id for this struct. This ID is assigned at
|
||||||
|
* struct creation and constant for the lifetime of the struct. The ID
|
||||||
|
* does not exist at the protocol level.
|
||||||
|
*
|
||||||
|
* This is a convenience API to make it easier to put this struct into
|
||||||
|
* e.g. a hashtable without having to use the pointer value itself.
|
||||||
|
*
|
||||||
|
* The ID increases by an unspecified amount.
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
uint64_t
|
||||||
|
ei_ping_get_id(struct ei_ping *ping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the refcount of this struct by one. Use ei_ping_unref() to decrease
|
||||||
|
* the refcount.
|
||||||
|
*
|
||||||
|
* @return the argument passed into the function
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
struct ei_ping *
|
||||||
|
ei_ping_ref(struct ei_ping *ei_ping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrease the refcount of this struct by one. When the refcount reaches
|
||||||
|
* zero, the context disconnects from the server and all allocated resources
|
||||||
|
* are released.
|
||||||
|
*
|
||||||
|
* @return always NULL
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
struct ei_ping *
|
||||||
|
ei_ping_unref(struct ei_ping *ei_ping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a custom data pointer for this struct. libei will not look at or
|
||||||
|
* modify the pointer. Use ei_ping_get_user_data() to retrieve a previously set
|
||||||
|
* user data.
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_ping_set_user_data(struct ei_ping *ei_ping, void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the custom data pointer for this struct. libei will not look at or
|
||||||
|
* modify the pointer. Use ei_ping_set_user_data() to change the user data.
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
ei_ping_get_user_data(struct ei_ping *ei_ping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issue a roundtrip request to the EIS implementation, resulting in
|
||||||
|
* an @ref EI_EVENT_PONG event when this roundtrip has been processed. Client
|
||||||
|
* requests are processed in-order by the EIS implementation so this
|
||||||
|
* function can be used as synchronization point between requests.
|
||||||
|
*
|
||||||
|
* If the client is disconnected before the roundtrip is complete,
|
||||||
|
* libei will emulate a @ref EI_EVENT_PONG event before @ref
|
||||||
|
* EI_EVENT_DISCONNECT.
|
||||||
|
*
|
||||||
|
* Note that in the ei protocol, the client request is `ei_connection.sync`
|
||||||
|
* followed by `ei_callback.done`. For consistency with the
|
||||||
|
* libeis API the C API uses ei_ping() with and @ref EI_EVENT_PONG as return
|
||||||
|
* event.
|
||||||
|
*
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_ping(struct ei_ping *ping);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main event dispatching function. Reads events of the file descriptors
|
* Main event dispatching function. Reads events of the file descriptors
|
||||||
* and processes them internally. Use ei_get_event() to retrieve the
|
* and processes them internally. Use ei_get_event() to retrieve the
|
||||||
|
|
@ -1819,6 +1927,18 @@ ei_touch_get_device(struct ei_touch *touch);
|
||||||
struct ei_seat *
|
struct ei_seat *
|
||||||
ei_event_get_seat(struct ei_event *event);
|
ei_event_get_seat(struct ei_event *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the associated @ref ei_ping struct with this event.
|
||||||
|
*
|
||||||
|
* For events of type other than @ref EI_EVENT_PONG this function
|
||||||
|
* returns NULL.
|
||||||
|
*
|
||||||
|
* This does not increase the refcount of the ei_pong. Use ei_pong_ref()
|
||||||
|
* to keep a reference beyond the immediate scope.
|
||||||
|
*/
|
||||||
|
struct ei_ping *
|
||||||
|
ei_event_pong_get_ping(struct ei_event *event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup libei-receiver
|
* @ingroup libei-receiver
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ if build_libei
|
||||||
'libei-keyboard.c',
|
'libei-keyboard.c',
|
||||||
'libei-log.c',
|
'libei-log.c',
|
||||||
'libei-pingpong.c',
|
'libei-pingpong.c',
|
||||||
|
'libei-ping.c',
|
||||||
'libei-pointer-absolute.c',
|
'libei-pointer-absolute.c',
|
||||||
'libei-pointer.c',
|
'libei-pointer.c',
|
||||||
'libei-region.c',
|
'libei-region.c',
|
||||||
|
|
|
||||||
|
|
@ -1067,6 +1067,8 @@ _peck_dispatch_ei(struct peck *peck, int lineno)
|
||||||
if (flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_PAUSED))
|
if (flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_PAUSED))
|
||||||
process_event = tristate_yes;
|
process_event = tristate_yes;
|
||||||
break;
|
break;
|
||||||
|
case EI_EVENT_PONG:
|
||||||
|
break;
|
||||||
case EI_EVENT_FRAME:
|
case EI_EVENT_FRAME:
|
||||||
/* Ensure we only expect frames when we expect them */
|
/* Ensure we only expect frames when we expect them */
|
||||||
munit_assert_true(need_frame);
|
munit_assert_true(need_frame);
|
||||||
|
|
@ -1381,6 +1383,7 @@ peck_ei_event_type_name(enum ei_event_type type)
|
||||||
CASE_STRING(DEVICE_PAUSED);
|
CASE_STRING(DEVICE_PAUSED);
|
||||||
CASE_STRING(DEVICE_RESUMED);
|
CASE_STRING(DEVICE_RESUMED);
|
||||||
CASE_STRING(KEYBOARD_MODIFIERS);
|
CASE_STRING(KEYBOARD_MODIFIERS);
|
||||||
|
CASE_STRING(PONG);
|
||||||
CASE_STRING(FRAME);
|
CASE_STRING(FRAME);
|
||||||
CASE_STRING(DEVICE_START_EMULATING);
|
CASE_STRING(DEVICE_START_EMULATING);
|
||||||
CASE_STRING(DEVICE_STOP_EMULATING);
|
CASE_STRING(DEVICE_STOP_EMULATING);
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ DEFINE_UNREF_CLEANUP_FUNC(ei_touch);
|
||||||
DEFINE_UNREF_CLEANUP_FUNC(ei_keymap);
|
DEFINE_UNREF_CLEANUP_FUNC(ei_keymap);
|
||||||
DEFINE_UNREF_CLEANUP_FUNC(ei_seat);
|
DEFINE_UNREF_CLEANUP_FUNC(ei_seat);
|
||||||
DEFINE_UNREF_CLEANUP_FUNC(ei_region);
|
DEFINE_UNREF_CLEANUP_FUNC(ei_region);
|
||||||
|
DEFINE_UNREF_CLEANUP_FUNC(ei_ping);
|
||||||
|
|
||||||
DEFINE_UNREF_CLEANUP_FUNC(eis);
|
DEFINE_UNREF_CLEANUP_FUNC(eis);
|
||||||
DEFINE_UNREF_CLEANUP_FUNC(eis_client);
|
DEFINE_UNREF_CLEANUP_FUNC(eis_client);
|
||||||
|
|
|
||||||
102
test/test-ei.c
102
test/test-ei.c
|
|
@ -797,3 +797,105 @@ MUNIT_TEST(test_ei_invalid_object_ids)
|
||||||
|
|
||||||
return MUNIT_OK;
|
return MUNIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MUNIT_TEST(test_ei_ping)
|
||||||
|
{
|
||||||
|
_unref_(peck) *peck = peck_new();
|
||||||
|
_unref_(ei_ping) *ping = NULL;
|
||||||
|
int userdata = 123;
|
||||||
|
|
||||||
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
|
||||||
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||||
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||||
|
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
|
||||||
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
|
||||||
|
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSTART);
|
||||||
|
|
||||||
|
peck_dispatch_until_stable(peck);
|
||||||
|
|
||||||
|
with_client(peck) {
|
||||||
|
peck_drain_ei(ei);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a ping object without having our own ref, object
|
||||||
|
* is kept alive until the returned pong event is destroyed */
|
||||||
|
with_client(peck) {
|
||||||
|
_unref_(ei_ping) *ping = ei_new_ping(ei);
|
||||||
|
ei_ping_set_user_data(ping, &userdata);
|
||||||
|
ei_ping(ping);
|
||||||
|
}
|
||||||
|
|
||||||
|
peck_dispatch_until_stable(peck);
|
||||||
|
|
||||||
|
with_client(peck) {
|
||||||
|
_unref_(ei_event) *e = peck_ei_next_event(ei, EI_EVENT_PONG);
|
||||||
|
struct ei_ping *pong = ei_event_pong_get_ping(e);
|
||||||
|
munit_assert_not_null(pong);
|
||||||
|
munit_assert_ptr_equal(ei_ping_get_user_data(pong), &userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
peck_dispatch_until_stable(peck);
|
||||||
|
|
||||||
|
/* Create a ping object this time keeping our own ref, object
|
||||||
|
* is kept alive until the returned pong event is destroyed */
|
||||||
|
with_client(peck) {
|
||||||
|
ping = ei_new_ping(ei);
|
||||||
|
ei_ping_set_user_data(ping, &userdata);
|
||||||
|
ei_ping(ping);
|
||||||
|
/* Keep the ref */
|
||||||
|
}
|
||||||
|
|
||||||
|
peck_dispatch_until_stable(peck);
|
||||||
|
|
||||||
|
with_client(peck) {
|
||||||
|
_unref_(ei_event) *e = peck_ei_next_event(ei, EI_EVENT_PONG);
|
||||||
|
struct ei_ping *pong = ei_event_pong_get_ping(e);
|
||||||
|
munit_assert_ptr_equal(pong, ping);
|
||||||
|
munit_assert_int64(ei_ping_get_id(pong), ==, ei_ping_get_id(ping));
|
||||||
|
munit_assert_ptr_equal(ei_ping_get_user_data(pong), &userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unref after the event above, in case that blows things up */
|
||||||
|
ping = ei_ping_unref(ping);
|
||||||
|
|
||||||
|
peck_mark(peck);
|
||||||
|
|
||||||
|
/* Send two pings, one we keep the ref to, one floating, then disconnect
|
||||||
|
* immediately */
|
||||||
|
with_client(peck) {
|
||||||
|
ping = ei_new_ping(ei);
|
||||||
|
ei_ping(ping);
|
||||||
|
|
||||||
|
_unref_(ei_ping) *floating = ei_new_ping(ei);
|
||||||
|
ei_ping(floating);
|
||||||
|
}
|
||||||
|
|
||||||
|
with_server(peck) {
|
||||||
|
struct eis_client *client = peck_eis_get_default_client(peck);
|
||||||
|
eis_client_disconnect(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
peck_dispatch_until_stable(peck);
|
||||||
|
|
||||||
|
with_client(peck) {
|
||||||
|
struct ei_event *e;
|
||||||
|
while ((e = ei_peek_event(ei))) {
|
||||||
|
bool found = ei_event_get_type(e) == EI_EVENT_PONG;
|
||||||
|
ei_event_unref(e);
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
_unref_(ei_event) *ev = ei_get_event(ei);
|
||||||
|
}
|
||||||
|
|
||||||
|
_unref_(ei_event) *e1 = peck_ei_next_event(ei, EI_EVENT_PONG);
|
||||||
|
struct ei_ping *pong = ei_event_pong_get_ping(e1);
|
||||||
|
munit_assert_ptr_equal(pong, ping);
|
||||||
|
|
||||||
|
_unref_(ei_event) *e2 = peck_ei_next_event(ei, EI_EVENT_PONG);
|
||||||
|
pong = ei_event_pong_get_ping(e2);
|
||||||
|
munit_assert_ptr_not_equal(pong, ping);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MUNIT_OK;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
@ -286,6 +287,14 @@ print_modifiers_event(struct ei_event *event)
|
||||||
printf(" locked: \"0x%x\"\n", ei_event_keyboard_get_xkb_mods_locked(event));
|
printf(" locked: \"0x%x\"\n", ei_event_keyboard_get_xkb_mods_locked(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_pong_event(struct ei_event *event)
|
||||||
|
{
|
||||||
|
struct ei_ping *ping = ei_event_pong_get_ping(event);
|
||||||
|
|
||||||
|
printf(" id: %#" PRIx64 "\n", ei_ping_get_id(ping));
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -443,6 +452,9 @@ int main(int argc, char **argv)
|
||||||
case EI_EVENT_KEYBOARD_MODIFIERS:
|
case EI_EVENT_KEYBOARD_MODIFIERS:
|
||||||
print_modifiers_event(e);
|
print_modifiers_event(e);
|
||||||
break;
|
break;
|
||||||
|
case EI_EVENT_PONG:
|
||||||
|
print_pong_event(e);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue