mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-24 05:20:05 +01:00
Add timestamps to frame events
Currently only implemented for frame events, the vague plan for the future is to merely queue the device events internally and "release" them once a frame event was received, retrofitting the timestamp to the C event struct (i.e. making ei_event_get_time() available on all device events). Meanwhile, the frame event it is.
This commit is contained in:
parent
e913462a23
commit
d99e42b808
24 changed files with 547 additions and 175 deletions
|
|
@ -66,6 +66,7 @@ src_libutil = [
|
|||
'src/util-sources.c',
|
||||
'src/util-strings.c',
|
||||
'src/util-strings.h',
|
||||
'src/util-time.h',
|
||||
]
|
||||
|
||||
lib_util = static_library('util', src_libutil)
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ message StopEmulating {
|
|||
|
||||
message Frame {
|
||||
uint32 deviceid = 1;
|
||||
uint64 timestamp = 2;
|
||||
}
|
||||
|
||||
message Property {
|
||||
|
|
|
|||
|
|
@ -348,13 +348,21 @@ ei_device_has_capability(struct ei_device *device,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
ei_device_frame_now(struct ei_device *device)
|
||||
{
|
||||
uint64_t now = ei_now(ei_device_get_context(device));
|
||||
|
||||
ei_device_frame(device, now);
|
||||
}
|
||||
|
||||
static void
|
||||
_flush_frame(struct ei_device *device, const char *func)
|
||||
{
|
||||
if (device->send_frame_event) {
|
||||
log_bug_client(ei_device_get_context(device),
|
||||
"%s: missing call to ei_device_frame()\n", func);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame_now(device);
|
||||
}
|
||||
}
|
||||
#define ei_device_flush_frame(d_) _flush_frame(d_, __func__)
|
||||
|
|
@ -617,7 +625,7 @@ ei_touch_destroy(struct ei_touch *touch)
|
|||
ei_touch_up(touch);
|
||||
/* Enforce a frame, otherwise we're just pending. If the client
|
||||
* doesn't want this, it needs to ei_touch_up() */
|
||||
ei_device_frame(touch->device);
|
||||
ei_device_frame_now(touch->device);
|
||||
ei_device_unref(touch->device);
|
||||
}
|
||||
|
||||
|
|
@ -723,12 +731,12 @@ ei_touch_up(struct ei_touch *touch)
|
|||
}
|
||||
|
||||
_public_ void
|
||||
ei_device_frame(struct ei_device *device)
|
||||
ei_device_frame(struct ei_device *device, uint64_t time)
|
||||
{
|
||||
if (device->state != EI_DEVICE_STATE_EMULATING)
|
||||
return;
|
||||
|
||||
ei_send_frame(device);
|
||||
ei_send_frame(device, time);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -770,12 +778,12 @@ ei_device_event_stop_emulating(struct ei_device *device)
|
|||
}
|
||||
|
||||
int
|
||||
ei_device_event_frame(struct ei_device *device)
|
||||
ei_device_event_frame(struct ei_device *device, uint64_t time)
|
||||
{
|
||||
if (device->state != EI_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
ei_queue_frame_event(device);
|
||||
ei_queue_frame_event(device, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -422,3 +422,11 @@ ei_event_touch_get_y(struct ei_event *event)
|
|||
|
||||
return event->touch.y;
|
||||
}
|
||||
|
||||
_public_ uint64_t
|
||||
ei_event_get_time(struct ei_event *event)
|
||||
{
|
||||
require_event_type(event, 0, EI_EVENT_FRAME);
|
||||
|
||||
return event->timestamp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ struct ei_event {
|
|||
struct ei_seat *seat; /* NULL if device is non-NULL */
|
||||
struct ei_device *device;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
union {
|
||||
struct ei_xkb_modifiers modifiers;
|
||||
struct {
|
||||
|
|
@ -274,7 +276,7 @@ int
|
|||
ei_send_stop_emulating(struct ei_device *device);
|
||||
|
||||
int
|
||||
ei_send_frame(struct ei_device *device);
|
||||
ei_send_frame(struct ei_device *device, uint64_t time);
|
||||
|
||||
void
|
||||
ei_queue_device_removed_event(struct ei_device *device);
|
||||
|
|
@ -292,7 +294,7 @@ void
|
|||
ei_queue_device_stop_emulating_event(struct ei_device *device);
|
||||
|
||||
void
|
||||
ei_queue_frame_event(struct ei_device *device);
|
||||
ei_queue_frame_event(struct ei_device *device, uint64_t time);
|
||||
|
||||
void
|
||||
ei_queue_pointer_rel_event(struct ei_device *device, double x, double y);
|
||||
|
|
@ -342,7 +344,7 @@ void
|
|||
ei_device_removed_by_server(struct ei_device *device);
|
||||
|
||||
int
|
||||
ei_device_event_frame(struct ei_device *device);
|
||||
ei_device_event_frame(struct ei_device *device, uint64_t time);
|
||||
|
||||
void
|
||||
ei_device_event_start_emulating(struct ei_device *device);
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ ei_proto_handle_message(struct ei *ei,
|
|||
proto->touch_up->touchid);
|
||||
break;
|
||||
case SERVER_MESSAGE__MSG_FRAME:
|
||||
rc = call(frame, ei, proto->frame->deviceid);
|
||||
rc = call(frame, ei, proto->frame->deviceid, proto->frame->timestamp);
|
||||
break;
|
||||
default:
|
||||
rc = -EBADMSG;
|
||||
|
|
@ -515,11 +515,12 @@ ei_proto_send_touch_up(struct ei_device *device, uint32_t tid)
|
|||
}
|
||||
|
||||
static int
|
||||
ei_proto_send_frame(struct ei_device *device)
|
||||
ei_proto_send_frame(struct ei_device *device, uint64_t time)
|
||||
{
|
||||
prepare_msg(FRAME, Frame, frame);
|
||||
|
||||
frame.deviceid = device->id;
|
||||
frame.timestamp = time;
|
||||
|
||||
return ei_proto_send_msg(ei_device_get_context(device), &msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ struct ei_proto_interface {
|
|||
int (*touch_motion)(struct ei *ei, uint32_t deviceid,
|
||||
uint32_t tid, double x, double y);
|
||||
int (*touch_up)(struct ei *ei, uint32_t deviceid, uint32_t tid);
|
||||
int (*frame) (struct ei *ei, uint32_t deviceid);
|
||||
int (*frame) (struct ei *ei, uint32_t deviceid, uint64_t time);
|
||||
};
|
||||
|
||||
struct ei_proto_requests {
|
||||
|
|
@ -101,7 +101,7 @@ struct ei_proto_requests {
|
|||
int (*touch_motion)(struct ei_device *device,
|
||||
uint32_t tid, double x, double y);
|
||||
int (*touch_up)(struct ei_device *device, uint32_t tid);
|
||||
int (*frame)(struct ei_device *device);
|
||||
int (*frame)(struct ei_device *device, uint64_t time);
|
||||
int (*property)(struct ei *ei,
|
||||
const char *name, const char *value,
|
||||
uint32_t permissions);
|
||||
|
|
|
|||
32
src/libei.c
32
src/libei.c
|
|
@ -28,15 +28,16 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "util-io.h"
|
||||
#include "util-macros.h"
|
||||
#include "util-object.h"
|
||||
#include "util-sources.h"
|
||||
#include "util-strings.h"
|
||||
#include "util-time.h"
|
||||
|
||||
#include "libei.h"
|
||||
#include "libei-private.h"
|
||||
|
|
@ -226,7 +227,7 @@ queue_event(struct ei *ei, struct ei_event *event)
|
|||
default:
|
||||
if (device) {
|
||||
if (device->queue_frame_event)
|
||||
ei_queue_frame_event(device);
|
||||
ei_queue_frame_event(device, ei_now(ei));
|
||||
device->queue_frame_event = false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -378,11 +379,12 @@ queue_property_event(struct ei *ei, const char *name,
|
|||
}
|
||||
|
||||
void
|
||||
ei_queue_frame_event(struct ei_device *device)
|
||||
ei_queue_frame_event(struct ei_device *device, uint64_t time)
|
||||
{
|
||||
struct ei_event *e = ei_event_new_for_device(device);
|
||||
|
||||
e->type = EI_EVENT_FRAME;
|
||||
e->timestamp = time;
|
||||
|
||||
queue_event(ei_device_get_context(device), e);
|
||||
}
|
||||
|
|
@ -872,7 +874,7 @@ ei_send_seat_bind(struct ei_seat *seat, uint32_t capabilities)
|
|||
}
|
||||
|
||||
int
|
||||
ei_send_frame(struct ei_device *device)
|
||||
ei_send_frame(struct ei_device *device, uint64_t time)
|
||||
{
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
|
||||
|
|
@ -884,7 +886,7 @@ ei_send_frame(struct ei_device *device)
|
|||
|
||||
device->send_frame_event = false;
|
||||
|
||||
int rc = ei->requests->frame(device);
|
||||
int rc = ei->requests->frame(device, time);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
return rc;
|
||||
|
|
@ -1131,14 +1133,14 @@ handle_msg_stop_emulating(struct ei *ei, uint32_t deviceid)
|
|||
}
|
||||
|
||||
static int
|
||||
handle_msg_frame(struct ei *ei, uint32_t deviceid)
|
||||
handle_msg_frame(struct ei *ei, uint32_t deviceid, uint64_t time)
|
||||
{
|
||||
DISCONNECT_IF_SENDER_CONTEXT(ei);
|
||||
|
||||
struct ei_device *device = ei_find_device(ei, deviceid);
|
||||
|
||||
if (device)
|
||||
return ei_device_event_frame(device);
|
||||
return ei_device_event_frame(device, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1427,6 +1429,22 @@ ei_configure_name(struct ei *ei, const char *name)
|
|||
ei->name = xstrdup(name);
|
||||
}
|
||||
|
||||
_public_ uint64_t
|
||||
ei_now(struct ei *ei)
|
||||
{
|
||||
uint64_t ts = 0;
|
||||
int rc = now(&ts);
|
||||
|
||||
if (rc < 0) {
|
||||
/* We should probably disconnect here but the chances of this
|
||||
* happening are so slim it's not worth worrying about. Plus,
|
||||
* if this fails we're likely to be inside eis_device_frame()
|
||||
* so we should flush a frame event before disconnecting and... */
|
||||
log_error(ei, "clock_gettime failed: %s\n", strerror(-rc));
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
#ifdef _enable_tests_
|
||||
#include "util-munit.h"
|
||||
|
||||
|
|
|
|||
25
src/libei.h
25
src/libei.h
|
|
@ -762,6 +762,12 @@ struct ei_device *
|
|||
ei_event_get_device(struct ei_event *event);
|
||||
|
||||
/**
|
||||
* Return the time for the event of type @ref EI_EVENT_FRAME in microseconds.
|
||||
*
|
||||
* @note: This function is currently only implemented for events of type @ref
|
||||
* EI_EVENT_FRAME. In the future, it may become available to other event types
|
||||
* too.
|
||||
*
|
||||
* @return the event time in microseconds
|
||||
*/
|
||||
uint64_t
|
||||
|
|
@ -1153,9 +1159,16 @@ ei_device_stop_emulating(struct ei_device *device);
|
|||
* Generate a frame event to group the current set of events
|
||||
* into a logical hardware event. This function **must** be called after any
|
||||
* other event has been generated.
|
||||
*
|
||||
* The given timestamp applies to all events in the current frame.
|
||||
* The timestamp must be in microseconds of CLOCK_MONOTONIC, use the return
|
||||
* value of ei_now() to get a compatible timestamp.
|
||||
*
|
||||
* @note libei does not prevent a caller from passing in a future time but it
|
||||
* is strongly recommended that this is avoided by the caller.
|
||||
*/
|
||||
void
|
||||
ei_device_frame(struct ei_device *device);
|
||||
ei_device_frame(struct ei_device *device, uint64_t time);
|
||||
|
||||
/**
|
||||
* Generate a relative motion event on a device with
|
||||
|
|
@ -1564,6 +1577,16 @@ ei_event_touch_get_x(struct ei_event *event);
|
|||
double
|
||||
ei_event_touch_get_y(struct ei_event *event);
|
||||
|
||||
/**
|
||||
* @returns a timestamp in microseconds for the current time to pass into
|
||||
* ei_device_frame().
|
||||
*
|
||||
* In the current implementation, the returned timestamp is CLOCK_MONOTONIC
|
||||
* for compatibility with evdev and libinput.
|
||||
*/
|
||||
uint64_t
|
||||
ei_now(struct ei *ei);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -298,14 +298,14 @@ client_msg_stop_emulating(struct eis_client *client, uint32_t deviceid)
|
|||
}
|
||||
|
||||
static int
|
||||
client_msg_frame(struct eis_client *client, uint32_t deviceid)
|
||||
client_msg_frame(struct eis_client *client, uint32_t deviceid, uint64_t time)
|
||||
{
|
||||
DISCONNECT_IF_RECEIVER_CONTEXT(client);
|
||||
|
||||
struct eis_device *device = eis_client_find_device(client, deviceid);
|
||||
|
||||
if (device)
|
||||
return eis_device_event_frame(device);
|
||||
return eis_device_event_frame(device, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,13 +308,21 @@ eis_device_has_capability(struct eis_device *device,
|
|||
eis->requests->func_(device_, device->id, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
static void
|
||||
eis_device_frame_now(struct eis_device *device)
|
||||
{
|
||||
uint64_t now = eis_now(eis_device_get_context(device));
|
||||
|
||||
eis_device_frame(device, now);
|
||||
}
|
||||
|
||||
static void
|
||||
_flush_frame(struct eis_device *device, const char *func)
|
||||
{
|
||||
if (device->send_frame_event) {
|
||||
log_bug_client(eis_device_get_context(device),
|
||||
"%s: missing call to eis_device_frame()\n", func);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame_now(device);
|
||||
}
|
||||
}
|
||||
#define eis_device_flush_frame(d_) _flush_frame(d_, __func__)
|
||||
|
|
@ -564,7 +572,7 @@ eis_touch_destroy(struct eis_touch *touch)
|
|||
eis_touch_up(touch);
|
||||
/* Enforce a frame, otherwise we're just pending. If the client
|
||||
* doesn't want this, it needs to eis_touch_up() */
|
||||
eis_device_frame(touch->device);
|
||||
eis_device_frame_now(touch->device);
|
||||
eis_device_unref(touch->device);
|
||||
}
|
||||
|
||||
|
|
@ -654,7 +662,7 @@ eis_touch_up(struct eis_touch *touch)
|
|||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_frame(struct eis_device *device)
|
||||
eis_device_frame(struct eis_device *device, uint64_t time)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return;
|
||||
|
|
@ -665,16 +673,16 @@ eis_device_frame(struct eis_device *device)
|
|||
device->send_frame_event = false;
|
||||
|
||||
|
||||
handle_request_noargs(device, frame);
|
||||
handle_request(device, frame, time);
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_event_frame(struct eis_device *device)
|
||||
eis_device_event_frame(struct eis_device *device, uint64_t time)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return -EINVAL;
|
||||
|
||||
eis_queue_frame_event(device);
|
||||
eis_queue_frame_event(device, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,14 @@ check_event_type(struct eis_event *event,
|
|||
if (!check_event_type(event_, __func__, __VA_ARGS__, -1)) \
|
||||
return retval_; \
|
||||
|
||||
_public_ uint64_t
|
||||
eis_event_get_time(struct eis_event *event)
|
||||
{
|
||||
require_event_type(event, 0, EIS_EVENT_FRAME);
|
||||
|
||||
return event->timestamp;
|
||||
}
|
||||
|
||||
_public_ bool
|
||||
eis_event_seat_has_capability(struct eis_event *event, enum eis_device_capability cap)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ struct eis_event {
|
|||
struct eis_seat *seat;
|
||||
struct eis_device *device;
|
||||
|
||||
uint64_t timestamp;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t capabilities;
|
||||
|
|
@ -286,7 +288,7 @@ eis_device_set_client_keymap(struct eis_device *device,
|
|||
enum eis_keymap_type type,
|
||||
int keymap_fd, size_t size);
|
||||
int
|
||||
eis_device_event_frame(struct eis_device *device);
|
||||
eis_device_event_frame(struct eis_device *device, uint64_t time);
|
||||
|
||||
int
|
||||
eis_device_event_pointer_rel(struct eis_device *device,
|
||||
|
|
@ -371,7 +373,7 @@ void
|
|||
eis_queue_device_closed_event(struct eis_device *device);
|
||||
|
||||
void
|
||||
eis_queue_frame_event(struct eis_device *device);
|
||||
eis_queue_frame_event(struct eis_device *device, uint64_t time);
|
||||
|
||||
void
|
||||
eis_queue_device_start_emulating_event(struct eis_device *device);
|
||||
|
|
|
|||
|
|
@ -440,11 +440,12 @@ eis_proto_send_touch_up(struct eis_device *device, uint32_t deviceid, uint32_t t
|
|||
}
|
||||
|
||||
static int
|
||||
eis_proto_send_frame(struct eis_device *device, uint32_t deviceid)
|
||||
eis_proto_send_frame(struct eis_device *device, uint32_t deviceid, uint64_t time)
|
||||
{
|
||||
prepare_msg(FRAME, Frame, frame);
|
||||
|
||||
frame.deviceid = device->id;
|
||||
frame.timestamp = time;
|
||||
|
||||
return eis_proto_send_msg(eis_device_get_client(device), &msg);
|
||||
}
|
||||
|
|
@ -613,7 +614,7 @@ eis_proto_handle_message(struct eis_client *client,
|
|||
proto->touch_up->touchid);
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_FRAME:
|
||||
rc = call(frame, client, proto->frame->deviceid);
|
||||
rc = call(frame, client, proto->frame->deviceid, proto->frame->timestamp);
|
||||
break;
|
||||
default:
|
||||
rc = -EBADMSG;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ struct eis_proto_interface {
|
|||
int (*touch_motion)(struct eis_client *client, uint32_t deviceid,
|
||||
uint32_t tid, double x, double y);
|
||||
int (*touch_up)(struct eis_client *client, uint32_t deviceid, uint32_t tid);
|
||||
int (*frame) (struct eis_client *client, uint32_t deviceid);
|
||||
int (*frame) (struct eis_client *client, uint32_t deviceid, uint64_t time);
|
||||
};
|
||||
|
||||
struct eis_proto_requests {
|
||||
|
|
@ -97,7 +97,7 @@ struct eis_proto_requests {
|
|||
int (*touch_motion)(struct eis_device *device, uint32_t deviceid,
|
||||
uint32_t tid, double x, double y);
|
||||
int (*touch_up)(struct eis_device *device, uint32_t deviceid, uint32_t tid);
|
||||
int (*frame) (struct eis_device *device, uint32_t deviceid);
|
||||
int (*frame) (struct eis_device *device, uint32_t deviceid, uint64_t time);
|
||||
};
|
||||
|
||||
int
|
||||
|
|
|
|||
22
src/libeis.c
22
src/libeis.c
|
|
@ -33,6 +33,7 @@
|
|||
#include "util-object.h"
|
||||
#include "util-sources.h"
|
||||
#include "util-strings.h"
|
||||
#include "util-time.h"
|
||||
|
||||
#include "libeis.h"
|
||||
#include "libeis-proto.h"
|
||||
|
|
@ -164,7 +165,7 @@ eis_queue_event(struct eis_event *event)
|
|||
default:
|
||||
if (device) {
|
||||
if (device->queue_frame_event)
|
||||
eis_queue_frame_event(device);
|
||||
eis_queue_frame_event(device, eis_now(eis));
|
||||
device->queue_frame_event = false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -222,10 +223,11 @@ eis_queue_device_closed_event(struct eis_device *device)
|
|||
}
|
||||
|
||||
void
|
||||
eis_queue_frame_event(struct eis_device *device)
|
||||
eis_queue_frame_event(struct eis_device *device, uint64_t time)
|
||||
{
|
||||
struct eis_event *e = eis_event_new_for_device(device);
|
||||
e->type = EIS_EVENT_FRAME;
|
||||
e->timestamp = time;
|
||||
eis_queue_event(e);
|
||||
}
|
||||
|
||||
|
|
@ -392,3 +394,19 @@ eis_add_client(struct eis *eis, struct eis_client *client)
|
|||
{
|
||||
list_append(&eis->clients, &client->link);
|
||||
}
|
||||
|
||||
_public_ uint64_t
|
||||
eis_now(struct eis *eis)
|
||||
{
|
||||
uint64_t ts = 0;
|
||||
int rc = now(&ts);
|
||||
|
||||
if (rc < 0) {
|
||||
/* We should probably disconnect here but the chances of this
|
||||
* happening are so slim it's not worth worrying about. Plus,
|
||||
* if this fails we're likely to be inside ei_device_frame()
|
||||
* so we should flush a frame event before disconnecting and... */
|
||||
log_error(eis, "clock_gettime failed: %s\n", strerror(-rc));
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
|
|
|||
24
src/libeis.h
24
src/libeis.h
|
|
@ -953,7 +953,7 @@ eis_device_stop_emulating(struct eis_device *device);
|
|||
|
||||
/** see @ref ei_device_frame */
|
||||
void
|
||||
eis_device_frame(struct eis_device *device);
|
||||
eis_device_frame(struct eis_device *device, uint64_t time);
|
||||
|
||||
/** see @ref ei_device_pointer_motion */
|
||||
void
|
||||
|
|
@ -1044,6 +1044,18 @@ eis_event_seat_has_capability(struct eis_event *event, enum eis_device_capabilit
|
|||
struct eis_device *
|
||||
eis_event_get_device(struct eis_event *event);
|
||||
|
||||
/**
|
||||
* Return the time for the event of type @ref EIS_EVENT_FRAME in microseconds.
|
||||
*
|
||||
* @note: This function is currently only implemented for events of type @ref
|
||||
* EIS_EVENT_FRAME. In the future, it may become available to other event types
|
||||
* too.
|
||||
*
|
||||
* @return the event time in microseconds
|
||||
*/
|
||||
uint64_t
|
||||
eis_event_get_time(struct eis_event *event);
|
||||
|
||||
/**
|
||||
* For an event of type @ref EIS_EVENT_POINTER_MOTION return the relative x
|
||||
* movement in logical pixels or mm, depending on the device type.
|
||||
|
|
@ -1177,6 +1189,16 @@ eis_event_touch_get_x(struct eis_event *event);
|
|||
double
|
||||
eis_event_touch_get_y(struct eis_event *event);
|
||||
|
||||
/**
|
||||
* @returns a timestamp for the current time to pass into
|
||||
* eis_device_frame().
|
||||
*
|
||||
* In the current implementation, the returned timestamp is CLOCK_MONOTONIC
|
||||
* for compatibility with evdev and libinput.
|
||||
*/
|
||||
uint64_t
|
||||
eis_now(struct eis *ei);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
79
src/util-time.h
Normal file
79
src/util-time.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Merely for code readability, e.g. timeout = us(100); */
|
||||
static inline uint64_t
|
||||
us(uint64_t us)
|
||||
{
|
||||
return us;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
us2ms(uint64_t us)
|
||||
{
|
||||
return us * 1000;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ns2us(uint64_t ns)
|
||||
{
|
||||
return us(ns / 1000);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ms2us(uint64_t ms)
|
||||
{
|
||||
return us(ms * 1000);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
s2us(uint64_t s)
|
||||
{
|
||||
return ms2us(s * 1000);
|
||||
}
|
||||
|
||||
static inline int
|
||||
now(uint64_t *now_out)
|
||||
{
|
||||
struct timespec ts = { 0, 0 };
|
||||
|
||||
assert(now_out != NULL);
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
|
||||
*now_out = s2us(ts.tv_sec) + ns2us(ts.tv_nsec);
|
||||
return 0;
|
||||
} else {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
#include "util-logger.h"
|
||||
#include "util-object.h"
|
||||
#include "util-strings.h"
|
||||
#include "util-time.h"
|
||||
|
||||
DEFINE_TRISTATE(yes, no, unset);
|
||||
|
||||
|
|
@ -64,6 +65,8 @@ struct peck {
|
|||
struct ei_device *ei_abs;
|
||||
struct ei_device *ei_touch;
|
||||
|
||||
uint64_t now;
|
||||
|
||||
struct eis_client *eis_client;
|
||||
|
||||
uint32_t indent;
|
||||
|
|
@ -212,6 +215,34 @@ peck_ei_get_default_touch(struct peck *peck)
|
|||
return peck->ei_touch;
|
||||
};
|
||||
|
||||
/* Ensures that device frames in tests always have an ascending and fixed
|
||||
* interval. We start with 30 * interval in the past, every event then goes
|
||||
* forward by 10ms.
|
||||
*
|
||||
* Tests that have more than 30 events will run into the future with their
|
||||
* timestamps, shouldn't be an issue for the test suite though.
|
||||
*/
|
||||
uint64_t
|
||||
peck_ei_now(struct peck *peck)
|
||||
{
|
||||
const uint32_t interval = ms2us(10);
|
||||
const uint32_t past_offset = interval * 30;
|
||||
|
||||
peck->now = peck->now == 0 ? ei_now(peck->ei) - past_offset : peck->now + interval;
|
||||
|
||||
return peck->now;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
peck_eis_now(struct peck *peck)
|
||||
{
|
||||
const uint32_t interval = ms2us(10);
|
||||
const uint32_t past_offset = interval * 30;
|
||||
|
||||
peck->now = peck->now == 0 ? eis_now(peck->eis) - past_offset : peck->now + interval;
|
||||
|
||||
return peck->now;
|
||||
}
|
||||
static void
|
||||
peck_ei_log_handler(struct ei *ei,
|
||||
enum ei_log_priority priority,
|
||||
|
|
@ -655,6 +686,7 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
struct eis *eis = peck->eis;
|
||||
bool had_event = false;
|
||||
bool need_frame = false;
|
||||
static uint64_t last_timestamp;
|
||||
|
||||
log_debug(peck, "EIS Dispatch, line %d\n", lineno);
|
||||
peck_indent(peck);
|
||||
|
|
@ -747,6 +779,16 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
peck_eis_device_remove(peck, eis_event_get_device(e));
|
||||
break;
|
||||
case EIS_EVENT_FRAME: {
|
||||
uint64_t timestamp = eis_event_get_time(e);
|
||||
uint64_t ts_now = 0;
|
||||
|
||||
munit_assert_int(now(&ts_now), ==, 0);
|
||||
munit_assert_int64(last_timestamp, <, timestamp);
|
||||
munit_assert_int64(last_timestamp, <=, ts_now);
|
||||
last_timestamp = timestamp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
@ -194,6 +195,12 @@ peck_ei_get_default_pointer_absolute(struct peck *peck);
|
|||
struct ei_device *
|
||||
peck_ei_get_default_touch(struct peck *peck);
|
||||
|
||||
uint64_t
|
||||
peck_ei_now(struct peck *peck);
|
||||
|
||||
uint64_t
|
||||
peck_eis_now(struct peck *peck);
|
||||
|
||||
/**
|
||||
* Dispatch all events according to the currently defined behavior.
|
||||
* When this function returns false, the connection is in a "stable" state
|
||||
|
|
|
|||
|
|
@ -283,9 +283,9 @@ MUNIT_TEST(test_ei_device_keyboard_key)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_keyboard(peck);
|
||||
ei_device_keyboard_key(device, KEY_Q, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_keyboard_key(device, KEY_Q, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -317,11 +317,11 @@ MUNIT_TEST(test_ei_device_pointer_rel)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_pointer_motion(device, 1, 2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_motion(device, 0.3, 1.4);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_motion(device, 100, 200);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -498,7 +498,7 @@ MUNIT_TEST(test_ei_device_pointer_abs)
|
|||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ei_device_pointer_motion_absolute(device, 1 * i , 2 + i);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -522,9 +522,9 @@ MUNIT_TEST(test_ei_device_pointer_abs)
|
|||
|
||||
/* outside of pointer range, expect to be discarded */
|
||||
ei_device_pointer_motion_absolute(device, maxx + 1, maxy/2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_motion_absolute(device, maxx/2 , maxy + 1);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -567,9 +567,9 @@ MUNIT_TEST(test_ei_device_pointer_scroll)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_pointer_scroll(device, 1.1, 2.2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_discrete(device, 3, 4);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -601,26 +601,26 @@ MUNIT_TEST(test_ei_device_pointer_scroll_stop)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_pointer_scroll(device, 1.1, 2.2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_stop(device, true, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_stop(device, false, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* This should not generate an event */
|
||||
ei_device_pointer_scroll_stop(device, true, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* But scrolling again will re-enable stopping */
|
||||
ei_device_pointer_scroll(device, 3.3, 4.4);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_stop(device, true, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_device_pointer_scroll(device, 3.3, 4.4);
|
||||
/* This one is a client bug and shouldn't trigger an event */
|
||||
ei_device_pointer_scroll_stop(device, false, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -670,26 +670,26 @@ MUNIT_TEST(test_ei_device_pointer_scroll_cancel)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_pointer_scroll(device, 1.1, 2.2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_cancel(device, true, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_cancel(device, false, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* This should not generate an event */
|
||||
ei_device_pointer_scroll_cancel(device, true, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* But scrolling again will re-enable stopping */
|
||||
ei_device_pointer_scroll(device, 3.3, 4.4);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_cancel(device, true, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_device_pointer_scroll(device, 3.3, 4.4);
|
||||
/* This one is a client bug and shouldn't trigger an event */
|
||||
ei_device_pointer_scroll_cancel(device, false, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -740,17 +740,17 @@ MUNIT_TEST(test_ei_device_pointer_scroll_stop_cancel)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_pointer_scroll(device, 1.1, 2.2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_stop(device, true, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_cancel(device, true, false);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_pointer_scroll_cancel(device, false, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* This should not generate an event */
|
||||
ei_device_pointer_scroll_stop(device, true, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -802,11 +802,11 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
|
||||
_unref_(ei_touch) *t = ei_device_touch_new(device);
|
||||
ei_touch_down(t, 1, 2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t, 200, 500);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -828,19 +828,19 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
_unref_(ei_touch) *t = ei_device_touch_new(device);
|
||||
/* outside clip range, expect touch to be dropped */
|
||||
ei_touch_down(t, maxx + 1, maxy/2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t, maxx + 1, maxy/3);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* outside clip range, expect touch to be dropped */
|
||||
ei_touch_down(t, maxx/2, maxy + 1);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t, maxx/3, maxy + 1);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -852,12 +852,12 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
with_client(peck) {
|
||||
_unref_(ei_touch) *t = ei_device_touch_new(device);
|
||||
ei_touch_down(t, 100, 200);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
/* outside allowed range, generates a touch up */
|
||||
ei_touch_motion(t, maxx + 1, 200);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -871,7 +871,7 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
with_client(peck) {
|
||||
_unref_(ei_touch) *t = ei_device_touch_new(device);
|
||||
ei_touch_down(t, 100, 100);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
/* client forgets to touch up, touch_unref takes care of it */
|
||||
}
|
||||
|
||||
|
|
@ -890,14 +890,14 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
/* touch never set down */
|
||||
_unref_(ei_touch) *t2 = ei_device_touch_new(device);
|
||||
ei_touch_up(t2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* touch never set down */
|
||||
_unref_(ei_touch) *t3 = ei_device_touch_new(device);
|
||||
ei_touch_motion(t3, 100, 200);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t3);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -909,15 +909,15 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
/* touch re-used */
|
||||
_unref_(ei_touch) *t = ei_device_touch_new(device);
|
||||
ei_touch_down(t, 100, 200);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_down(t, 200, 300);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t, 300, 400);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -932,15 +932,15 @@ MUNIT_TEST(test_ei_device_touch)
|
|||
/* double-down, double-up */
|
||||
_unref_(ei_touch) *t = ei_device_touch_new(device);
|
||||
ei_touch_down(t, 100, 200);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_down(t, 200, 300); /* ignored */
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t, 300, 400);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_up(t); /* ignored */
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -972,14 +972,14 @@ MUNIT_TEST(test_ei_device_multitouch)
|
|||
_unref_(ei_touch) *t1 = ei_device_touch_new(device);
|
||||
_unref_(ei_touch) *t2 = ei_device_touch_new(device);
|
||||
ei_touch_down(t1, 1, 2);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t1, 2, 3);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_touch_down(t2, 3, 4);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_touch_motion(t2, 4, 5);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_touch_up(t2);
|
||||
ei_touch_up(t1);
|
||||
|
|
@ -1153,6 +1153,53 @@ MUNIT_TEST(test_ei_keyboard_modifiers)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_ei_frame_timestamp)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
uint64_t ts1 = 0, ts2 = 0;
|
||||
|
||||
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_RESUME_DEVICE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
ts1 = peck_ei_now(peck);
|
||||
struct ei_device *device = peck_ei_get_default_keyboard(peck);
|
||||
ei_device_keyboard_key(device, KEY_Q, true);
|
||||
ei_device_frame(device, ts1);
|
||||
|
||||
ts2 = peck_ei_now(peck);
|
||||
ei_device_keyboard_key(device, KEY_Q, false);
|
||||
ei_device_frame(device, ts2);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *kbd1 =
|
||||
peck_eis_next_event(eis, EIS_EVENT_KEYBOARD_KEY);
|
||||
_unref_(eis_event) *frame1 =
|
||||
peck_eis_next_event(eis, EIS_EVENT_FRAME);
|
||||
_unref_(eis_event) *kbd2 =
|
||||
peck_eis_next_event(eis, EIS_EVENT_KEYBOARD_KEY);
|
||||
_unref_(eis_event) *frame2 =
|
||||
peck_eis_next_event(eis, EIS_EVENT_FRAME);
|
||||
|
||||
uint64_t timestamp = eis_event_get_time(frame1);
|
||||
munit_assert_uint64(timestamp, ==, ts1);
|
||||
|
||||
timestamp = eis_event_get_time(frame2);
|
||||
munit_assert_uint64(timestamp, ==, ts2);
|
||||
|
||||
peck_assert_no_eis_events(eis);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_ei_no_empty_frames)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
|
@ -1166,10 +1213,10 @@ MUNIT_TEST(test_ei_no_empty_frames)
|
|||
|
||||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_keyboard(peck);
|
||||
ei_device_frame(device); /* Expect to be filtered */
|
||||
ei_device_frame(device, peck_ei_now(peck)); /* Expect to be filtered */
|
||||
ei_device_keyboard_key(device, KEY_Q, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device); /* Expect to be filtered */
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_frame(device, peck_ei_now(peck)); /* Expect to be filtered */
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1317,9 +1364,9 @@ MUNIT_TEST(test_passive_ei_device_keyboard_key)
|
|||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_keyboard(peck);
|
||||
eis_device_keyboard_key(device, KEY_Q, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_keyboard_key(device, KEY_Q, false);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1364,11 +1411,11 @@ MUNIT_TEST(test_passive_ei_device_pointer_rel)
|
|||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
eis_device_pointer_motion(device, 1, 2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_motion(device, 0.3, 1.4);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_motion(device, 100, 200);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1421,7 +1468,7 @@ MUNIT_TEST(test_passive_ei_device_pointer_abs)
|
|||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
eis_device_pointer_motion_absolute(device, 1 * i , 2 + i);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1445,9 +1492,9 @@ MUNIT_TEST(test_passive_ei_device_pointer_abs)
|
|||
|
||||
/* outside of pointer range, expect to be discarded */
|
||||
eis_device_pointer_motion_absolute(device, maxx + 1, maxy/2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_motion_absolute(device, maxx/2 , maxy + 1);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1500,9 +1547,9 @@ MUNIT_TEST(test_passive_ei_device_pointer_scroll)
|
|||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
eis_device_pointer_scroll(device, 1.1, 2.2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_discrete(device, 3, 4);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1547,26 +1594,26 @@ MUNIT_TEST(test_passive_ei_device_pointer_scroll_stop)
|
|||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
eis_device_pointer_scroll(device, 1.1, 2.2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_stop(device, true, false);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_stop(device, false, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
/* This should not generate an event */
|
||||
eis_device_pointer_scroll_stop(device, true, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
/* But scrolling again will re-enable stopping */
|
||||
eis_device_pointer_scroll(device, 3.3, 4.4);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_stop(device, true, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
eis_device_pointer_scroll(device, 3.3, 4.4);
|
||||
/* This one is a client bug and shouldn't trigger an event */
|
||||
eis_device_pointer_scroll_stop(device, false, false);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1629,26 +1676,26 @@ MUNIT_TEST(test_passive_ei_device_pointer_scroll_cancel)
|
|||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
eis_device_pointer_scroll(device, 1.1, 2.2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_cancel(device, true, false);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_cancel(device, false, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
/* This should not generate an event */
|
||||
eis_device_pointer_scroll_cancel(device, true, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
/* But scrolling again will re-enable stopping */
|
||||
eis_device_pointer_scroll(device, 3.3, 4.4);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_cancel(device, true, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
eis_device_pointer_scroll(device, 3.3, 4.4);
|
||||
/* This one is a client bug and shouldn't trigger an event */
|
||||
eis_device_pointer_scroll_cancel(device, false, false);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1712,21 +1759,21 @@ MUNIT_TEST(test_passive_ei_device_pointer_scroll_stop_cancel)
|
|||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
eis_device_pointer_scroll(device, 1.1, 2.2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
peck_mark(peck);
|
||||
eis_device_pointer_scroll_stop(device, true, false);
|
||||
peck_mark(peck);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_cancel(device, true, false);
|
||||
peck_mark(peck);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_device_pointer_scroll_cancel(device, false, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
peck_mark(peck);
|
||||
|
||||
/* This should not generate an event */
|
||||
eis_device_pointer_scroll_stop(device, true, true);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1793,11 +1840,11 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
|
||||
_unref_(eis_touch) *t = eis_device_touch_new(device);
|
||||
eis_touch_down(t, 1, 2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t, 200, 500);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1818,19 +1865,19 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
_unref_(eis_touch) *t = eis_device_touch_new(device);
|
||||
/* outside clip range, expect touch to be dropped */
|
||||
eis_touch_down(t, maxx + 1, maxy/2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t, maxx + 1, maxy/3);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
/* outside clip range, expect touch to be dropped */
|
||||
eis_touch_down(t, maxx/2, maxy + 1);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t, maxx/3, maxy + 1);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1842,12 +1889,12 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
with_server(peck) {
|
||||
_unref_(eis_touch) *t = eis_device_touch_new(device);
|
||||
eis_touch_down(t, 100, 200);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
/* outside allowed range, generates a touch up */
|
||||
eis_touch_motion(t, maxx + 1, 200);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1861,7 +1908,7 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
with_server(peck) {
|
||||
_unref_(eis_touch) *t = eis_device_touch_new(device);
|
||||
eis_touch_down(t, 100, 100);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
/* client forgets to touch up, touch_unref takes care of it */
|
||||
}
|
||||
|
||||
|
|
@ -1880,14 +1927,14 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
/* touch never set down */
|
||||
_unref_(eis_touch) *t2 = eis_device_touch_new(device);
|
||||
eis_touch_up(t2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
/* touch never set down */
|
||||
_unref_(eis_touch) *t3 = eis_device_touch_new(device);
|
||||
eis_touch_motion(t3, 100, 200);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t3);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1899,15 +1946,15 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
/* touch re-used */
|
||||
_unref_(eis_touch) *t = eis_device_touch_new(device);
|
||||
eis_touch_down(t, 100, 200);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_down(t, 200, 300);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t, 300, 400);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1922,15 +1969,15 @@ MUNIT_TEST(test_passive_ei_device_touch)
|
|||
/* double-down, double-up */
|
||||
_unref_(eis_touch) *t = eis_device_touch_new(device);
|
||||
eis_touch_down(t, 100, 200);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_down(t, 200, 300); /* ignored */
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t, 300, 400);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_up(t); /* ignored */
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
|
@ -1963,18 +2010,18 @@ MUNIT_TEST(test_passive_ei_device_multitouch)
|
|||
_unref_(eis_touch) *t2 = eis_device_touch_new(device);
|
||||
eis_device_start_emulating(device);
|
||||
eis_touch_down(t1, 1, 2);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t1, 2, 3);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
eis_touch_down(t2, 3, 4);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
eis_touch_motion(t2, 4, 5);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
eis_touch_up(t2);
|
||||
eis_touch_up(t1);
|
||||
eis_device_frame(device);
|
||||
eis_device_frame(device, peck_eis_now(peck));
|
||||
|
||||
eis_device_stop_emulating(device);
|
||||
}
|
||||
|
|
@ -2011,6 +2058,60 @@ MUNIT_TEST(test_passive_ei_device_multitouch)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_passive_ei_frame_timestamp)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context(PECK_EI_RECEIVER);
|
||||
uint64_t ts1 = 0, ts2 = 0;
|
||||
|
||||
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_RESUME_DEVICE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_keyboard(peck);
|
||||
eis_device_start_emulating(device);
|
||||
|
||||
ts1 = peck_eis_now(peck);
|
||||
eis_device_keyboard_key(device, KEY_Q, true);
|
||||
eis_device_frame(device, ts1);
|
||||
|
||||
ts2 = peck_eis_now(peck);
|
||||
eis_device_keyboard_key(device, KEY_Q, false);
|
||||
eis_device_frame(device, ts2);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
_unref_(ei_event) *start =
|
||||
peck_ei_next_event(ei, EI_EVENT_DEVICE_START_EMULATING);
|
||||
_unref_(ei_event) *kbd1 =
|
||||
peck_ei_next_event(ei, EI_EVENT_KEYBOARD_KEY);
|
||||
_unref_(ei_event) *frame1 =
|
||||
peck_ei_next_event(ei, EI_EVENT_FRAME);
|
||||
_unref_(ei_event) *kbd2 =
|
||||
peck_ei_next_event(ei, EI_EVENT_KEYBOARD_KEY);
|
||||
_unref_(ei_event) *frame2 =
|
||||
peck_ei_next_event(ei, EI_EVENT_FRAME);
|
||||
|
||||
uint64_t timestamp = ei_event_get_time(frame1);
|
||||
munit_assert_uint64(timestamp, ==, ts1);
|
||||
|
||||
timestamp = ei_event_get_time(frame2);
|
||||
munit_assert_uint64(timestamp, ==, ts2);
|
||||
|
||||
peck_assert_no_ei_events(ei);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
|
||||
MUNIT_TEST(test_passive_ei_flush_frame)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context(PECK_EI_RECEIVER);
|
||||
|
|
|
|||
|
|
@ -921,7 +921,7 @@ MUNIT_TEST(test_xdotool_rel_motion)
|
|||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_pointer_motion(device, -1, 10);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_close(device);
|
||||
ei_unref(ei);
|
||||
peck_drop_ei(peck);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "src/util-memfile.h"
|
||||
#include "src/util-color.h"
|
||||
#include "src/util-strings.h"
|
||||
#include "src/util-time.h"
|
||||
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_device);
|
||||
|
|
@ -445,29 +446,38 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (!receiver) {
|
||||
uint64_t now = ei_now(ei);
|
||||
uint32_t interval = us2ms(10); /* pretend events are 10ms apart */
|
||||
|
||||
if (have_ptr) {
|
||||
colorprint("sending motion event\n");
|
||||
ei_device_pointer_motion(ptr, -1, 1);
|
||||
/* BTN_LEFT */
|
||||
colorprint("sending button event\n");
|
||||
ei_device_pointer_button(ptr, BTN_LEFT, true);
|
||||
ei_device_frame(ptr);
|
||||
ei_device_frame(ptr, now);
|
||||
now += interval;
|
||||
ei_device_pointer_button(ptr, BTN_LEFT, false);
|
||||
ei_device_frame(ptr);
|
||||
ei_device_frame(ptr, now);
|
||||
now += interval;
|
||||
colorprint("sending scroll events\n");
|
||||
ei_device_pointer_scroll(ptr, 1, 1);
|
||||
ei_device_frame(ptr);
|
||||
ei_device_frame(ptr, now);
|
||||
now += interval;
|
||||
ei_device_pointer_scroll_discrete(ptr, 1, 1);
|
||||
ei_device_frame(ptr);
|
||||
ei_device_frame(ptr, now);
|
||||
now += interval;
|
||||
}
|
||||
|
||||
if (have_kbd) {
|
||||
static int key = 0;
|
||||
colorprint("sending key event\n");
|
||||
ei_device_keyboard_key(kbd, KEY_Q + key, true); /* KEY_Q */
|
||||
ei_device_frame(kbd);
|
||||
ei_device_frame(kbd, now);
|
||||
now += interval;
|
||||
ei_device_keyboard_key(kbd, KEY_Q + key, false); /* KEY_Q */
|
||||
ei_device_frame(kbd);
|
||||
ei_device_frame(kbd, now);
|
||||
now += interval;
|
||||
key = (key + 1) % 6;
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +485,8 @@ int main(int argc, char **argv)
|
|||
static int x, y;
|
||||
colorprint("sending abs event\n");
|
||||
ei_device_pointer_motion_absolute(abs, 150 + ++x, 150 - ++y);
|
||||
ei_device_frame(abs);
|
||||
ei_device_frame(abs, now);
|
||||
now += interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "src/util-mem.h"
|
||||
#include "src/util-memfile.h"
|
||||
#include "src/util-strings.h"
|
||||
#include "src/util-time.h"
|
||||
|
||||
#include "eis-demo-server.h"
|
||||
|
||||
|
|
@ -575,6 +576,9 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
struct eis_demo_client *democlient;
|
||||
uint64_t now = eis_now(eis);
|
||||
const int interval = ms2us(12); /* events are 12ms apart */
|
||||
|
||||
list_for_each(democlient, &server.clients, link) {
|
||||
if (eis_client_is_sender(democlient->client))
|
||||
continue;
|
||||
|
|
@ -588,23 +592,29 @@ int main(int argc, char **argv)
|
|||
/* BTN_LEFT */
|
||||
colorprint("sending button event\n");
|
||||
eis_device_pointer_button(ptr, BTN_LEFT, true);
|
||||
eis_device_frame(ptr);
|
||||
eis_device_frame(ptr, now);
|
||||
now += interval;
|
||||
eis_device_pointer_button(ptr, BTN_LEFT, false);
|
||||
eis_device_frame(ptr);
|
||||
eis_device_frame(ptr, now);
|
||||
now += interval;
|
||||
colorprint("sending scroll events\n");
|
||||
eis_device_pointer_scroll(ptr, 1, 1);
|
||||
eis_device_frame(ptr);
|
||||
eis_device_frame(ptr, now);
|
||||
now += interval;
|
||||
eis_device_pointer_scroll_discrete(ptr, 1, 1);
|
||||
eis_device_frame(ptr);
|
||||
eis_device_frame(ptr, now);
|
||||
now += interval;
|
||||
}
|
||||
|
||||
if (kbd) {
|
||||
static int key = 0;
|
||||
colorprint("sending key event\n");
|
||||
eis_device_keyboard_key(kbd, KEY_Q + key, true); /* KEY_Q */
|
||||
eis_device_frame(kbd);
|
||||
eis_device_frame(kbd, now);
|
||||
now += interval;
|
||||
eis_device_keyboard_key(kbd, KEY_Q + key, false); /* KEY_Q */
|
||||
eis_device_frame(kbd);
|
||||
eis_device_frame(kbd, now);
|
||||
now += interval;
|
||||
key = (key + 1) % 6;
|
||||
}
|
||||
|
||||
|
|
@ -612,7 +622,8 @@ int main(int argc, char **argv)
|
|||
static int x, y;
|
||||
colorprint("sending abs event\n");
|
||||
eis_device_pointer_motion_absolute(abs, 150 + ++x, 150 - ++y);
|
||||
eis_device_frame(abs);
|
||||
eis_device_frame(abs, now);
|
||||
now += interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue