Implement device suspend/resume with starting state of "suspended"

This was already spelled out in the documentation but just not yet
implemented. New starting state for any device added by EIS is "suspended",
the server needs to explicitly resume it before events are accepted.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-08-19 13:39:32 +10:00
parent f8fa944262
commit c4601b7196
17 changed files with 430 additions and 24 deletions

View file

@ -18,9 +18,10 @@ syntax = "proto3";
* 3. - client sends "AddDevice"
* 3.a - server replies with "DeviceAdded" or
* 3.b - server replies with "DeviceRemoved"
* 4. - client sends "PointerRelative" or any other event
* 5. - client sends "RemoveDevice"
* 6. - client sends "Disconnect" and closes its end of the socket
* 4. - server sends "DeviceResumed"
* 5. - client sends "PointerRelative" or any other event
* 6. - client sends "RemoveDevice"
* 7. - client sends "Disconnect" and closes its end of the socket
*
* The server may send Disconnect at any time.
* The server may send Removed for a device at any time after that device's
@ -139,12 +140,22 @@ message DeviceRemoved {
uint32 deviceid = 1;
}
message DeviceResumed {
uint32 deviceid = 1;
}
message DeviceSuspended {
uint32 deviceid = 1;
}
message ServerMessage {
oneof msg {
Connected connected = 2;
Disconnected disconnected = 3;
DeviceAdded device_added = 4;
DeviceRemoved device_removed = 5;
DeviceResumed device_resumed = 6;
DeviceSuspended device_suspended = 7;
}
}

View file

@ -156,10 +156,22 @@ ei_device_remove(struct ei_device *device)
ei_remove_device(device);
}
void
ei_device_resumed(struct ei_device *device)
{
device->state = EI_DEVICE_STATE_RESUMED;
}
void
ei_device_suspended(struct ei_device *device)
{
device->state = EI_DEVICE_STATE_SUSPENDED;
}
void
ei_device_added(struct ei_device *device)
{
device->state = EI_DEVICE_STATE_ADDED;
ei_device_suspended(device);
}
void
@ -214,7 +226,7 @@ ei_device_pointer_motion(struct ei_device *device,
if (!ei_device_has_capability(device, EI_DEVICE_CAP_POINTER))
return;
if (device->state != EI_DEVICE_STATE_ADDED)
if (device->state != EI_DEVICE_STATE_RESUMED)
return;
ei_pointer_rel(device, x, y);
@ -227,7 +239,7 @@ ei_device_pointer_button(struct ei_device *device,
if (!ei_device_has_capability(device, EI_DEVICE_CAP_POINTER))
return;
if (device->state != EI_DEVICE_STATE_ADDED)
if (device->state != EI_DEVICE_STATE_RESUMED)
return;
ei_pointer_button(device, button, is_press);
@ -240,7 +252,7 @@ ei_device_keyboard_key(struct ei_device *device,
if (!ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD))
return;
if (device->state != EI_DEVICE_STATE_ADDED)
if (device->state != EI_DEVICE_STATE_RESUMED)
return;
ei_keyboard_key(device, key, is_press);

View file

@ -60,7 +60,8 @@ struct ei {
enum ei_device_state {
EI_DEVICE_STATE_NEW,
EI_DEVICE_STATE_CONNECTING,
EI_DEVICE_STATE_ADDED,
EI_DEVICE_STATE_SUSPENDED,
EI_DEVICE_STATE_RESUMED,
EI_DEVICE_STATE_REMOVED,
};
@ -120,6 +121,12 @@ ei_keyboard_key(struct ei_device *device,
void
ei_device_added(struct ei_device *device);
void
ei_device_suspended(struct ei_device *device);
void
ei_device_resumed(struct ei_device *device);
void
ei_device_set_capabilities(struct ei_device *device,
uint32_t capabilities);

View file

@ -92,6 +92,24 @@ ei_proto_parse_message(const char *msgdata, size_t msglen, size_t *consumed)
};
}
break;
case SERVER_MESSAGE__MSG_DEVICE_RESUMED:
{
DeviceResumed *r = proto->device_resumed;
*msg = (struct message) {
.type = MESSAGE_DEVICE_RESUMED,
.resumed.deviceid = r->deviceid,
};
}
break;
case SERVER_MESSAGE__MSG_DEVICE_SUSPENDED:
{
DeviceSuspended *r = proto->device_suspended;
*msg = (struct message) {
.type = MESSAGE_DEVICE_SUSPENDED,
.suspended.deviceid = r->deviceid,
};
}
break;
default:
success = false;
break;

View file

@ -36,6 +36,8 @@ enum message_type {
MESSAGE_DISCONNECTED,
MESSAGE_DEVICE_ADDED,
MESSAGE_DEVICE_REMOVED,
MESSAGE_DEVICE_RESUMED,
MESSAGE_DEVICE_SUSPENDED,
};
struct message {
@ -54,6 +56,12 @@ struct message {
struct message_device_removed {
uint32_t deviceid;
} removed;
struct message_device_resumed {
uint32_t deviceid;
} resumed;
struct message_device_suspended {
uint32_t deviceid;
} suspended;
};
};

View file

@ -48,9 +48,11 @@ ei_event_destroy(struct ei_event *event)
case EI_EVENT_DISCONNECT:
case EI_EVENT_DEVICE_ADDED:
case EI_EVENT_DEVICE_REMOVED:
case EI_EVENT_DEVICE_SUSPENDED:
case EI_EVENT_DEVICE_RESUMED:
break;
default:
abort(); /* not yet implemented */
assert(!"destroy not implemented for this type");
}
ei_device_unref(event->device);
}
@ -179,6 +181,30 @@ ei_queue_removed_event(struct ei_device *device)
ei_queue_event(ei, e);
}
static void
ei_queue_suspended_event(struct ei_device *device)
{
struct ei *ei= ei_device_get_context(device);
struct ei_event *e = ei_event_create(&ei->object);
e->type = EI_EVENT_DEVICE_SUSPENDED;
e->device = ei_device_ref(device);
ei_queue_event(ei, e);
}
static void
ei_queue_resumed_event(struct ei_device *device)
{
struct ei *ei= ei_device_get_context(device);
struct ei_event *e = ei_event_create(&ei->object);
e->type = EI_EVENT_DEVICE_RESUMED;
e->device = ei_device_ref(device);
ei_queue_event(ei, e);
}
static int
connection_send_connect(struct ei *ei)
{
@ -349,9 +375,44 @@ ei_removed(struct ei *ei, uint32_t deviceid)
}
}
return -0;
return 0;
}
static int
ei_resumed(struct ei *ei, uint32_t deviceid)
{
struct ei_device *d;
log_debug(ei, "Resumed device %d\n", deviceid);
list_for_each(d, &ei->devices, link) {
if (d->id == deviceid) {
ei_device_resumed(d);
ei_queue_resumed_event(d);
break;
}
}
return 0;
}
static int
ei_suspended(struct ei *ei, uint32_t deviceid)
{
struct ei_device *d;
log_debug(ei, "Suspended device %d\n", deviceid);
list_for_each(d, &ei->devices, link) {
if (d->id == deviceid) {
ei_device_suspended(d);
ei_queue_suspended_event(d);
break;
}
}
return 0;
}
int
ei_pointer_rel(struct ei_device *device, double x, double y)
@ -415,6 +476,8 @@ connection_new_handle_msg(struct ei *ei, struct message *msg)
case MESSAGE_DISCONNECTED:
case MESSAGE_DEVICE_ADDED:
case MESSAGE_DEVICE_REMOVED:
case MESSAGE_DEVICE_RESUMED:
case MESSAGE_DEVICE_SUSPENDED:
rc = -EPROTO;
break;
}
@ -437,6 +500,8 @@ connection_connecting_handle_msg(struct ei *ei, struct message *msg)
break;
case MESSAGE_DEVICE_ADDED:
case MESSAGE_DEVICE_REMOVED:
case MESSAGE_DEVICE_RESUMED:
case MESSAGE_DEVICE_SUSPENDED:
rc = -EPROTO;
break;
}
@ -462,6 +527,12 @@ connection_connected_handle_msg(struct ei *ei, struct message *msg)
case MESSAGE_DEVICE_REMOVED:
rc = ei_removed(ei, msg->removed.deviceid);
break;
case MESSAGE_DEVICE_RESUMED:
rc = ei_resumed(ei, msg->resumed.deviceid);
break;
case MESSAGE_DEVICE_SUSPENDED:
rc = ei_suspended(ei, msg->resumed.deviceid);
break;
}
return rc;

View file

@ -94,6 +94,18 @@ client_send_device_removed(struct eis_client *client, struct eis_device *device)
return eis_proto_send_device_removed(client, device);
}
static int
client_send_device_suspended(struct eis_client *client, struct eis_device *device)
{
return eis_proto_send_device_suspended(client, device);
}
static int
client_send_device_resumed(struct eis_client *client, struct eis_device *device)
{
return eis_proto_send_device_resumed(client, device);
}
_public_ void
eis_client_connect(struct eis_client *client)
{
@ -481,3 +493,15 @@ eis_client_disconnect_device(struct eis_client *client, struct eis_device *devic
list_remove(&device->link);
eis_device_unref(device);
}
void
eis_client_suspend_device(struct eis_client *client, struct eis_device *device)
{
client_send_device_suspended(client, device);
}
void
eis_client_resume_device(struct eis_client *client, struct eis_device *device)
{
client_send_device_resumed(client, device);
}

View file

@ -138,7 +138,7 @@ eis_device_pointer_rel(struct eis_device *device,
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER))
return -EINVAL;
if (device->state != EIS_DEVICE_STATE_ACCEPTED)
if (device->state != EIS_DEVICE_STATE_RESUMED)
return -EINVAL;
eis_queue_pointer_rel_event(device, x, y);
@ -153,7 +153,7 @@ eis_device_pointer_button(struct eis_device *device,
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER))
return -EINVAL;
if (device->state != EIS_DEVICE_STATE_ACCEPTED)
if (device->state != EIS_DEVICE_STATE_RESUMED)
return -EINVAL;
eis_queue_pointer_button_event(device, button, is_press);
@ -168,7 +168,7 @@ eis_device_keyboard_key(struct eis_device *device,
if (!eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD))
return -EINVAL;
if (device->state != EIS_DEVICE_STATE_ACCEPTED)
if (device->state != EIS_DEVICE_STATE_RESUMED)
return -EINVAL;
eis_queue_keyboard_key_event(device, key, is_press);
@ -182,7 +182,7 @@ eis_device_connect(struct eis_device *device)
if (device->state != EIS_DEVICE_STATE_NEW)
return;
device->state = EIS_DEVICE_STATE_ACCEPTED;
device->state = EIS_DEVICE_STATE_SUSPENDED;
eis_client_connect_device(eis_device_get_client(device), device);
}
@ -195,3 +195,23 @@ eis_device_disconnect(struct eis_device *device)
device->state = EIS_DEVICE_STATE_REMOVED;
eis_client_disconnect_device(eis_device_get_client(device), device);
}
_public_ void
eis_device_suspend(struct eis_device *device)
{
if (device->state != EIS_DEVICE_STATE_RESUMED)
return;
device->state = EIS_DEVICE_STATE_SUSPENDED;
eis_client_suspend_device(eis_device_get_client(device), device);
}
_public_ void
eis_device_resume(struct eis_device *device)
{
if (device->state != EIS_DEVICE_STATE_SUSPENDED)
return;
device->state = EIS_DEVICE_STATE_RESUMED;
eis_client_resume_device(eis_device_get_client(device), device);
}

View file

@ -75,7 +75,8 @@ struct eis_client {
enum eis_device_state {
EIS_DEVICE_STATE_NEW,
EIS_DEVICE_STATE_ACCEPTED,
EIS_DEVICE_STATE_SUSPENDED,
EIS_DEVICE_STATE_RESUMED,
EIS_DEVICE_STATE_REMOVED,
};
@ -136,6 +137,13 @@ void
eis_client_disconnect_device(struct eis_client *client,
struct eis_device *device);
void
eis_client_resume_device(struct eis_client *client,
struct eis_device *device);
void
eis_client_suspend_device(struct eis_client *client,
struct eis_device *device);
struct eis_device *
eis_device_new(struct eis_client *client,
uint32_t id,

View file

@ -65,6 +65,8 @@ log_wire_message(struct eis *eis, const ServerMessage *msg)
MSG_STRING_CASE(DISCONNECTED);
MSG_STRING_CASE(DEVICE_ADDED);
MSG_STRING_CASE(DEVICE_REMOVED);
MSG_STRING_CASE(DEVICE_RESUMED);
MSG_STRING_CASE(DEVICE_SUSPENDED);
break;
default:
assert(!"Unimplemented message type");
@ -144,6 +146,34 @@ eis_proto_send_device_removed(struct eis_client *client, struct eis_device *devi
return eis_proto_send_msg(client, &msg);
}
int
eis_proto_send_device_suspended(struct eis_client *client, struct eis_device *device)
{
ServerMessage msg = SERVER_MESSAGE__INIT;
DeviceSuspended suspended = DEVICE_SUSPENDED__INIT;
suspended.deviceid = device->id;
msg.device_suspended = &suspended;
msg.msg_case = SERVER_MESSAGE__MSG_DEVICE_SUSPENDED;
return eis_proto_send_msg(client, &msg);
}
int
eis_proto_send_device_resumed(struct eis_client *client, struct eis_device *device)
{
ServerMessage msg = SERVER_MESSAGE__INIT;
DeviceResumed resumed = DEVICE_RESUMED__INIT;
resumed.deviceid = device->id;
msg.device_resumed = &resumed;
msg.msg_case = SERVER_MESSAGE__MSG_DEVICE_RESUMED;
return eis_proto_send_msg(client, &msg);
}
struct message *
eis_proto_parse_message(const char *msgdata, size_t msglen, size_t *consumed)
{

View file

@ -107,5 +107,13 @@ int
eis_proto_send_device_removed(struct eis_client *client,
struct eis_device *device);
int
eis_proto_send_device_suspended(struct eis_client *client,
struct eis_device *device);
int
eis_proto_send_device_resumed(struct eis_client *client,
struct eis_device *device);
struct message *
eis_proto_parse_message(const char *data, size_t len, size_t *consumed);

View file

@ -79,7 +79,7 @@ peck_new(void)
rc = ei_setup_backend_fd(ei, sv[0]);
munit_assert_int(rc, ==, 0);
peck->ei = ei;
peck->ei_behavior = bit(PECK_EI_BEHAVIOR_AUTOCONNNECT);
flag_set(peck->ei_behavior, PECK_EI_BEHAVIOR_AUTOCONNNECT);
struct eis *eis = eis_new(NULL);
rc = eis_setup_backend_fd(eis);
@ -105,6 +105,7 @@ peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior)
case PECK_EIS_BEHAVIOR_ACCEPT_ALL:
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_DEVICE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
break;
case PECK_EIS_BEHAVIOR_REJECT_ALL:
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_CLIENT);
@ -143,6 +144,14 @@ peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior)
case PECK_EIS_BEHAVIOR_HANDLE_DEVICE:
flag_set(peck->eis_behavior, behavior);
break;
case PECK_EIS_BEHAVIOR_RESUME_DEVICE:
flag_clear(peck->eis_behavior, PECK_EIS_BEHAVIOR_SUSPEND_DEVICE);
flag_set(peck->eis_behavior, behavior);
break;
case PECK_EIS_BEHAVIOR_SUSPEND_DEVICE:
flag_clear(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
flag_set(peck->eis_behavior, behavior);
break;
}
}
@ -166,6 +175,10 @@ peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior)
case PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH:
flag_set(peck->ei_behavior, behavior);
break;
case PECK_EI_BEHAVIOR_HANDLE_RESUMED:
case PECK_EI_BEHAVIOR_HANDLE_SUSPENDED:
flag_set(peck->ei_behavior, behavior);
break;
}
}
@ -173,6 +186,7 @@ static inline void
peck_handle_eis_connect(struct peck *peck, struct eis_event *e)
{
struct eis_client *client = eis_event_get_client(e);
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT)) {
log_debug(peck, "EIS accepting client: %s\n", eis_client_get_name(client));
eis_client_connect(client);
@ -182,7 +196,7 @@ peck_handle_eis_connect(struct peck *peck, struct eis_event *e)
}
}
static inline void
static inline bool
peck_handle_eis_added(struct peck *peck, struct eis_event *e)
{
struct eis_device *device = eis_event_get_device(e);
@ -212,9 +226,11 @@ peck_handle_eis_added(struct peck *peck, struct eis_event *e)
if (!mask) {
log_debug(peck, "EIS refusing device\n");
eis_device_disconnect(eis_event_get_device(e));
return false;
} else {
log_debug(peck, "EIS adding device\n");
eis_device_connect(eis_event_get_device(e));
return true;
}
}
@ -276,7 +292,9 @@ peck_dispatch_eis(struct peck *peck)
eis_client_disconnect(eis_event_get_client(e));
break;
case EIS_EVENT_DEVICE_ADDED:
peck_handle_eis_added(peck, e);
if (peck_handle_eis_added(peck, e) &&
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
eis_device_resume(eis_event_get_device(e));
break;
case EIS_EVENT_DEVICE_REMOVED:
log_debug(peck, "EIS removing device\n");
@ -334,6 +352,15 @@ peck_dispatch_ei(struct peck *peck)
break;
case EI_EVENT_DEVICE_ADDED:
process_event = peck_check_ei_added(peck, e);
break;
case EI_EVENT_DEVICE_RESUMED:
if (flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_RESUMED))
process_event = tristate_yes;
break;
case EI_EVENT_DEVICE_SUSPENDED:
if (flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_SUSPENDED))
process_event = tristate_yes;
break;
default:
break;
}
@ -358,6 +385,8 @@ peck_dispatch_ei(struct peck *peck)
/* Nothing to do here */
break;
case EI_EVENT_DEVICE_ADDED:
case EI_EVENT_DEVICE_RESUMED:
case EI_EVENT_DEVICE_SUSPENDED:
/* Nothing to do here */
break;
default:

View file

@ -39,12 +39,12 @@
*/
enum peck_eis_behavior {
/**
* Behavior of EIS is implemented in the test case. This is the
* default.
* Behavior of EIS is implemented in the test case.
*/
PECK_EIS_BEHAVIOR_NONE,
/**
* Accept all client connection requests and device additions.
* Accept all client connection requests and device additions
* **and** resume any device immediately after add.
*/
PECK_EIS_BEHAVIOR_ACCEPT_ALL,
/**
@ -76,6 +76,9 @@ enum peck_eis_behavior {
PECK_EIS_BEHAVIOR_ACCEPT_TOUCH,
PECK_EIS_BEHAVIOR_DROP_TOUCH,
PECK_EIS_BEHAVIOR_RESUME_DEVICE,
PECK_EIS_BEHAVIOR_SUSPEND_DEVICE,
};
enum peck_ei_behavior {
@ -86,6 +89,9 @@ enum peck_ei_behavior {
PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER,
PECK_EI_BEHAVIOR_HANDLE_ADDED_KEYBOARD,
PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH,
PECK_EI_BEHAVIOR_HANDLE_RESUMED,
PECK_EI_BEHAVIOR_HANDLE_SUSPENDED,
};
struct peck;

View file

@ -196,6 +196,8 @@ MUNIT_TEST(test_ei_disconnect_after_remove_before_received)
with_client(peck) {
_cleanup_ei_event_ struct ei_event *added =
peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED);
_cleanup_ei_event_ struct ei_event *resumed =
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
ei_device_remove(device);
}
@ -249,6 +251,8 @@ MUNIT_TEST(test_ei_disconnect_after_remove_after_received)
with_client(peck) {
_cleanup_ei_event_ struct ei_event *added =
peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED);
_cleanup_ei_event_ struct ei_event *resumed =
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
ei_device_remove(device);
}

View file

@ -109,6 +109,147 @@ MUNIT_TEST(eistest_ranges)
return MUNIT_OK;
}
MUNIT_TEST(eistest_device_resume_suspend_twice)
{
_cleanup_peck_ struct peck *peck = peck_new();
_cleanup_eis_device_ struct eis_device *device = NULL;
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_dispatch_until_stable(peck);
with_client(peck) {
_cleanup_ei_device_ struct ei_device *d = ei_device_new(ei);
ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER);
ei_device_add(d);
}
peck_dispatch_until_stable(peck);
with_server(peck) {
_cleanup_eis_event_ struct eis_event *added =
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
device = eis_device_ref(eis_event_get_device(added));
eis_device_connect(device);
/* Resuming multiple times should only trigger one event */
eis_device_resume(device);
eis_device_resume(device); /* noop */
eis_device_resume(device); /* noop */
}
peck_dispatch_until_stable(peck);
with_client(peck) {
_cleanup_ei_event_ struct ei_event *added =
peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED);
_cleanup_ei_event_ struct ei_event *resumed =
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
peck_assert_no_ei_events(ei);
}
/* Suspending multiple times should only trigger one event */
with_server(peck) {
eis_device_suspend(device);
eis_device_suspend(device); /* noop */
eis_device_suspend(device); /* noop */
}
peck_dispatch_until_stable(peck);
with_client(peck) {
_cleanup_ei_event_ struct ei_event *suspended =
peck_ei_next_event(ei, EI_EVENT_DEVICE_SUSPENDED);
peck_assert_no_ei_events(ei);
}
return MUNIT_OK;
}
MUNIT_TEST(eistest_device_ignore_suspended)
{
_cleanup_peck_ struct peck *peck = peck_new();
_cleanup_eis_device_ struct eis_device *device = NULL;
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_dispatch_until_stable(peck);
with_client(peck) {
_cleanup_ei_device_ struct ei_device *d = ei_device_new(ei);
ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER);
ei_device_add(d);
}
peck_dispatch_until_stable(peck);
with_server(peck) {
_cleanup_eis_event_ struct eis_event *added =
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
device = eis_device_ref(eis_event_get_device(added));
eis_device_connect(device);
}
peck_dispatch_until_stable(peck);
with_client(peck) {
_cleanup_ei_event_ struct ei_event *added =
peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED);
struct ei_device *device = ei_event_get_device(added);
peck_assert_no_ei_events(ei);
ei_device_pointer_motion(device, 1, 1);
}
for (size_t i = 0; i < 3; i++) {
/* Device is suspended */
with_server(peck) {
peck_assert_no_eis_events(eis);
eis_device_resume(device);
}
peck_dispatch_until_stable(peck);
/* Device is resumed */
with_client(peck) {
_cleanup_ei_event_ struct ei_event *resumed =
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
struct ei_device *device = ei_event_get_device(resumed);
peck_assert_no_ei_events(ei);
ei_device_pointer_motion(device, 1, 1);
}
peck_dispatch_until_stable(peck);
/* Device is resumed */
with_server(peck) {
_cleanup_eis_event_ struct eis_event *rel =
peck_eis_next_event(eis, EIS_EVENT_POINTER_MOTION);
peck_assert_no_eis_events(eis);
eis_device_suspend(device);
}
peck_dispatch_until_stable(peck);
/* Device is suspended */
with_client(peck) {
_cleanup_ei_event_ struct ei_event *suspended =
peck_ei_next_event(ei, EI_EVENT_DEVICE_SUSPENDED);
struct ei_device *device = ei_event_get_device(suspended);
peck_assert_no_ei_events(ei);
ei_device_pointer_motion(device, 1, 1);
}
}
return MUNIT_OK;
}
int
main(int argc, char **argv)
{

View file

@ -91,14 +91,22 @@ int main(int argc, char **argv)
break;
}
case EI_EVENT_DEVICE_ADDED:
{
printf("client: our device was accepted\n");
printf("client: our device was accepted, waiting for resume\n");
break;
case EI_EVENT_DEVICE_RESUMED:
printf("client: our device was resumed\n");
if (ei_event_get_device(e) == ptr)
have_ptr = true;
if (ei_event_get_device(e) == kbd)
have_kbd = true;
break;
}
case EI_EVENT_DEVICE_SUSPENDED:
printf("client: our device was suspended\n");
if (ei_event_get_device(e) == ptr)
have_ptr = false;
if (ei_event_get_device(e) == kbd)
have_kbd = false;
break;
case EI_EVENT_DEVICE_REMOVED:
{
printf("client: our device was removed\n");

View file

@ -117,6 +117,7 @@ int main(int argc, char **argv)
eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH) ? " touch" : "");
/* insert sophisticated device checks here */
eis_device_connect(device);
eis_device_resume(device);
break;
}
case EIS_EVENT_DEVICE_REMOVED: