tools: add active/passive mode to the demo server and client

Starting the demo client with --passive initializes a passive context,
and the server will send events to any active context.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2022-02-22 16:22:18 +10:00
parent faa9500afe
commit 420c461643
2 changed files with 160 additions and 35 deletions

View file

@ -177,6 +177,7 @@ usage(FILE *fp, const char *argv0)
" --portal Use the portal backend.\n"
" --busname Use the given busname (default: org.freedesktop.portal.Desktop)\n"
" --verbose Enable debugging output\n"
" --passive Create an passive EIS context, receiving events instead of sending them\n"
"",
argv0);
}
@ -188,6 +189,7 @@ int main(int argc, char **argv)
PORTAL,
} backend = SOCKET;
bool verbose = false;
bool passive = false;
_cleanup_free_ char *busname = xstrdup("org.freedesktop.portal.Desktop");
while (1) {
@ -196,12 +198,14 @@ int main(int argc, char **argv)
OPT_BACKEND_PORTAL,
OPT_BUSNAME,
OPT_VERBOSE,
OPT_PASSIVE,
};
static struct option long_opts[] = {
{"socket", no_argument, 0, OPT_BACKEND_SOCKET},
{"portal", no_argument, 0, OPT_BACKEND_PORTAL},
{"busname", required_argument, 0, OPT_BUSNAME},
{"verbose", no_argument, 0, OPT_VERBOSE},
{"passive", no_argument, 0, OPT_PASSIVE},
{"help", no_argument, 0, 'h'},
{.name = NULL},
};
@ -228,13 +232,20 @@ int main(int argc, char **argv)
free(busname);
busname = xstrdup(optarg);
break;
case OPT_PASSIVE:
passive = true;
break;
default:
usage(stderr, argv[0]);
return EXIT_FAILURE;
}
}
_unref_(ei) *ei = ei_new(NULL);
_unref_(ei) *ei = NULL;
if (passive)
ei = ei_new_passive(NULL);
else
ei = ei_new_active(NULL);
assert(ei);
if (verbose)
@ -332,17 +343,20 @@ int main(int argc, char **argv)
break;
case EI_EVENT_DEVICE_RESUMED:
if (ei_event_get_device(e) == ptr) {
ei_device_start_emulating(ptr);
if (!passive)
ei_device_start_emulating(ptr);
colorprint("Pointer device was resumed\n");
have_ptr = true;
}
if (ei_event_get_device(e) == kbd) {
ei_device_start_emulating(kbd);
if (!passive)
ei_device_start_emulating(kbd);
colorprint("Keyboard device was resumed\n");
have_kbd = true;
}
if (ei_event_get_device(e) == abs) {
ei_device_start_emulating(abs);
if (!passive)
ei_device_start_emulating(abs);
colorprint("Abs pointer device was resumed\n");
have_abs = true;
}
@ -366,42 +380,100 @@ int main(int argc, char **argv)
colorprint("our device was removed\n");
break;
}
case EI_EVENT_FRAME:
break;
case EI_EVENT_DEVICE_START_EMULATING:
{
struct ei_device *device = ei_event_get_device(e);
colorprint("Device %s is ready to send events\n", ei_device_get_name(device));
}
break;
case EI_EVENT_DEVICE_STOP_EMULATING:
{
struct ei_device *device = ei_event_get_device(e);
colorprint("Device %s will no longer send events\n", ei_device_get_name(device));
}
break;
case EI_EVENT_POINTER_MOTION:
{
colorprint("motion by %.2f/%.2f\n",
ei_event_pointer_get_dx(e),
ei_event_pointer_get_dy(e));
}
break;
case EI_EVENT_POINTER_MOTION_ABSOLUTE:
{
colorprint("absmotion to %.2f/%.2f\n",
ei_event_pointer_get_absolute_x(e),
ei_event_pointer_get_absolute_y(e));
}
break;
case EI_EVENT_POINTER_BUTTON:
{
colorprint("button %u (%s)\n",
ei_event_pointer_get_button(e),
ei_event_pointer_get_button_is_press(e) ? "press" : "release");
}
break;
case EI_EVENT_POINTER_SCROLL:
{
colorprint("scroll %.2f/%.2f\n",
ei_event_pointer_get_scroll_x(e),
ei_event_pointer_get_scroll_y(e));
}
break;
case EI_EVENT_POINTER_SCROLL_DISCRETE:
{
colorprint("scroll discrete %d/%d\n",
ei_event_pointer_get_scroll_discrete_x(e),
ei_event_pointer_get_scroll_discrete_y(e));
}
break;
case EI_EVENT_KEYBOARD_KEY:
{
colorprint("key %u (%s)\n",
ei_event_keyboard_get_key(e),
ei_event_keyboard_get_key_is_press(e) ? "press" : "release");
}
break;
default:
abort();
}
}
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_pointer_button(ptr, BTN_LEFT, false);
ei_device_frame(ptr);
colorprint("sending scroll events\n");
ei_device_pointer_scroll(ptr, 1, 1);
ei_device_frame(ptr);
ei_device_pointer_scroll_discrete(ptr, 1, 1);
ei_device_frame(ptr);
}
if (!passive) {
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_pointer_button(ptr, BTN_LEFT, false);
ei_device_frame(ptr);
colorprint("sending scroll events\n");
ei_device_pointer_scroll(ptr, 1, 1);
ei_device_frame(ptr);
ei_device_pointer_scroll_discrete(ptr, 1, 1);
ei_device_frame(ptr);
}
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_keyboard_key(kbd, KEY_Q + key, false); /* KEY_Q */
ei_device_frame(kbd);
key = (key + 1) % 6;
}
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_keyboard_key(kbd, KEY_Q + key, false); /* KEY_Q */
ei_device_frame(kbd);
key = (key + 1) % 6;
}
if (have_abs) {
static int x, y;
colorprint("sending abs event\n");
ei_device_pointer_motion_absolute(abs, 150 + ++x, 150 - ++y);
ei_device_frame(abs);
if (have_abs) {
static int x, y;
colorprint("sending abs event\n");
ei_device_pointer_motion_absolute(abs, 150 + ++x, 150 - ++y);
ei_device_frame(abs);
}
}
}

View file

@ -48,6 +48,7 @@
#include <signal.h>
#include <string.h>
#include <sys/mman.h>
#include <linux/input.h>
#if HAVE_LIBXKBCOMMON
#include <xkbcommon/xkbcommon.h>
@ -212,7 +213,10 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
const char *pid = eis_client_property_get(client, "ei.application.pid");
const char *cmdline = eis_client_property_get(client, "ei.application.cmdline");
const char *ctype = eis_client_property_get(client, "ei.connection.type");
colorprint("new client: %s (pid %s, '%s'), connected via %s\n", eis_client_get_name(client),
bool is_active = eis_client_is_active(client);
colorprint("new %s client: %s (pid %s, '%s'), connected via %s\n",
is_active ? "active" : "passive",
eis_client_get_name(client),
pid, cmdline, ctype);
eis_demo_client_new(server, client);
@ -256,6 +260,8 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
eis_client_get_name(client));
eis_device_add(ptr);
eis_device_resume(ptr);
if (!eis_client_is_active(client))
eis_device_start_emulating(ptr);
democlient->ptr = steal(&ptr);
@ -268,6 +274,8 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
eis_client_get_name(client));
eis_device_add(kbd);
eis_device_resume(kbd);
if (!eis_client_is_active(client))
eis_device_start_emulating(kbd);
democlient->kbd = steal(&kbd);
@ -282,6 +290,8 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
eis_client_get_name(client));
eis_device_add(abs);
eis_device_resume(abs);
if (!eis_client_is_active(client))
eis_device_start_emulating(abs);
democlient->abs = steal(&abs);
}
break;
@ -391,6 +401,7 @@ usage(FILE *fp, const char *argv0)
" --layout Use the given XKB layout (requires libxkbcommon). Default: none\n"
" --uinput Set up each device as uinput device (this requires root)\n"
" --verbose Enable debugging output\n"
" --active Make this an active EIS server, sending events instead of receiving them\n"
"",
argv0);
}
@ -496,7 +507,7 @@ int main(int argc, char **argv)
.revents = 0,
};
while (!stop && poll(&fds, 1, -1) > -1) {
while (!stop && poll(&fds, 1, 1000) > -1) {
eis_dispatch(eis);
while (true) {
@ -508,6 +519,48 @@ int main(int argc, char **argv)
if (rc != 0)
break;
}
struct eis_demo_client *democlient;
list_for_each(democlient, &server.clients, link) {
if (eis_client_is_active(democlient->client))
continue;
struct eis_device *ptr = democlient->ptr;
struct eis_device *kbd = democlient->kbd;
struct eis_device *abs = democlient->abs;
if (ptr) {
colorprint("sending motion event\n");
eis_device_pointer_motion(ptr, -1, 1);
/* BTN_LEFT */
colorprint("sending button event\n");
eis_device_pointer_button(ptr, BTN_LEFT, true);
eis_device_frame(ptr);
eis_device_pointer_button(ptr, BTN_LEFT, false);
eis_device_frame(ptr);
colorprint("sending scroll events\n");
eis_device_pointer_scroll(ptr, 1, 1);
eis_device_frame(ptr);
eis_device_pointer_scroll_discrete(ptr, 1, 1);
eis_device_frame(ptr);
}
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_keyboard_key(kbd, KEY_Q + key, false); /* KEY_Q */
eis_device_frame(kbd);
key = (key + 1) % 6;
}
if (ptr) {
static int x, y;
colorprint("sending abs event\n");
eis_device_pointer_motion_absolute(abs, 150 + ++x, 150 - ++y);
eis_device_frame(abs);
}
}
}
return 0;