xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2020 Red Hat
|
|
|
|
|
*
|
|
|
|
|
* Permission to use, copy, modify, distribute, and sell this software
|
|
|
|
|
* and its documentation for any purpose is hereby granted without
|
|
|
|
|
* fee, provided that the above copyright notice appear in all copies
|
|
|
|
|
* and that both that copyright notice and this permission notice
|
|
|
|
|
* appear in supporting documentation, and that the name of the
|
|
|
|
|
* copyright holders not be used in advertising or publicity
|
|
|
|
|
* pertaining to distribution of the software without specific,
|
|
|
|
|
* written prior permission. The copyright holders make no
|
|
|
|
|
* representations about the suitability of this software for any
|
|
|
|
|
* purpose. It is provided "as is" without express or implied
|
|
|
|
|
* warranty.
|
|
|
|
|
*
|
|
|
|
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
|
|
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
|
|
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
|
* SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <xwayland-config.h>
|
|
|
|
|
|
2024-03-18 15:11:08 +01:00
|
|
|
#include <errno.h>
|
2024-03-07 15:41:16 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <libgen.h>
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
#include <libei.h>
|
|
|
|
|
|
2024-03-07 15:41:16 +01:00
|
|
|
#include "dix/dix_priv.h"
|
|
|
|
|
|
|
|
|
|
#include <inputstr.h>
|
|
|
|
|
#include <inpututils.h>
|
|
|
|
|
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
#ifdef XWL_HAS_EI_PORTAL
|
|
|
|
|
#include "liboeffis.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "xwayland-screen.h"
|
|
|
|
|
#include "xwayland-xtest.h"
|
|
|
|
|
|
|
|
|
|
#define debug_ei(...) DebugF("[xwayland ei] " __VA_ARGS__)
|
|
|
|
|
#define error_ei(...) ErrorF("[xwayland ei] " __VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
#define SCROLL_STEP 120 /* libei's definition of a logical scroll step */
|
|
|
|
|
|
|
|
|
|
static struct xorg_list clients_for_reuse;
|
|
|
|
|
|
|
|
|
|
static DevPrivateKeyRec xwl_ei_private_key;
|
2023-06-20 16:17:36 +02:00
|
|
|
static DevPrivateKeyRec xwl_device_data_private_key;
|
|
|
|
|
|
|
|
|
|
struct xwl_device_data {
|
|
|
|
|
DeviceSendEventsProc sendEventsProc;
|
|
|
|
|
};
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
|
|
|
|
|
struct xwl_emulated_event {
|
2023-06-20 16:17:36 +02:00
|
|
|
DeviceIntPtr dev;
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
int type;
|
|
|
|
|
int detail;
|
|
|
|
|
int flags;
|
|
|
|
|
ValuatorMask mask;
|
|
|
|
|
struct xorg_list link;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct xwl_abs_device {
|
|
|
|
|
struct xorg_list link;
|
|
|
|
|
struct ei_device *device;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct xwl_ei_client {
|
|
|
|
|
struct xorg_list link; /* in clients_for_reuse */
|
|
|
|
|
ClientPtr client; /* can be NULL if the X11 client is gone */
|
|
|
|
|
char *cmdline;
|
|
|
|
|
bool accept_pointer, accept_keyboard, accept_abs;
|
|
|
|
|
struct ei *ei;
|
|
|
|
|
int ei_fd;
|
|
|
|
|
#ifdef XWL_HAS_EI_PORTAL
|
|
|
|
|
struct oeffis *oeffis;
|
|
|
|
|
int oeffis_fd;
|
|
|
|
|
#endif
|
|
|
|
|
struct ei_seat *ei_seat;
|
|
|
|
|
struct ei_device *ei_pointer;
|
|
|
|
|
struct ei_device *ei_keyboard;
|
|
|
|
|
struct xorg_list abs_devices;
|
|
|
|
|
struct xorg_list pending_emulated_events;
|
|
|
|
|
|
|
|
|
|
OsTimerPtr disconnect_timer;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void xwl_handle_ei_event(int fd, int ready, void *data);
|
2023-06-20 16:17:36 +02:00
|
|
|
static bool xwl_dequeue_emulated_events(struct xwl_ei_client *xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
static struct xwl_device_data *
|
|
|
|
|
xwl_device_data_get(DeviceIntPtr dev)
|
|
|
|
|
{
|
|
|
|
|
return dixLookupPrivate(&dev->devPrivates, &xwl_device_data_private_key);
|
|
|
|
|
}
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
|
|
|
|
|
static struct xwl_ei_client *
|
|
|
|
|
get_xwl_ei_client(ClientPtr client)
|
|
|
|
|
{
|
|
|
|
|
return dixLookupPrivate(&client->devPrivates, &xwl_ei_private_key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2023-06-20 16:17:36 +02:00
|
|
|
xwl_queue_emulated_event(struct xwl_ei_client *xwl_ei_client, DeviceIntPtr dev,
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
int type, int detail, int flags, const ValuatorMask *mask)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_emulated_event *xwl_emulated_event;
|
|
|
|
|
|
|
|
|
|
xwl_emulated_event = calloc(1, sizeof *xwl_emulated_event);
|
|
|
|
|
if (!xwl_emulated_event) {
|
|
|
|
|
error_ei("OOM, cannot queue event\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-20 16:17:36 +02:00
|
|
|
xwl_emulated_event->dev = dev;
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
xwl_emulated_event->type = type;
|
|
|
|
|
xwl_emulated_event->detail = detail;
|
|
|
|
|
xwl_emulated_event->flags = flags;
|
|
|
|
|
valuator_mask_copy(&xwl_emulated_event->mask, mask);
|
|
|
|
|
|
|
|
|
|
xorg_list_append(&xwl_emulated_event->link,
|
|
|
|
|
&xwl_ei_client->pending_emulated_events);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_clear_emulated_events(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_emulated_event *xwl_emulated_event, *next_xwl_emulated_event;
|
|
|
|
|
|
|
|
|
|
xorg_list_for_each_entry_safe(xwl_emulated_event, next_xwl_emulated_event,
|
|
|
|
|
&xwl_ei_client->pending_emulated_events, link) {
|
|
|
|
|
xorg_list_del(&xwl_emulated_event->link);
|
|
|
|
|
free(xwl_emulated_event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
add_ei_device(struct xwl_ei_client *xwl_ei_client, struct ei_device *device)
|
|
|
|
|
{
|
|
|
|
|
bool used = true;
|
|
|
|
|
|
|
|
|
|
/* Note: pointers in libei are split across four capabilities:
|
|
|
|
|
pointer/pointer-absolute/button/scroll. We expect any decent
|
|
|
|
|
compositor to give pointers the button + scroll interfaces too,
|
|
|
|
|
if that's not the case we can look into *why* and fix this as needed.
|
|
|
|
|
Meanwhile, we ignore any device that doesn't have button + scroll
|
|
|
|
|
in addition to pointer caps.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER) &&
|
|
|
|
|
ei_device_has_capability(device, EI_DEVICE_CAP_BUTTON) &&
|
|
|
|
|
ei_device_has_capability(device, EI_DEVICE_CAP_SCROLL) &&
|
|
|
|
|
xwl_ei_client->ei_pointer == NULL) {
|
|
|
|
|
|
|
|
|
|
xwl_ei_client->ei_pointer = ei_device_ref(device);
|
|
|
|
|
used = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD) &&
|
|
|
|
|
xwl_ei_client->ei_keyboard == NULL) {
|
|
|
|
|
xwl_ei_client->ei_keyboard = ei_device_ref(device);
|
|
|
|
|
used = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
|
|
|
|
ei_device_has_capability(device, EI_DEVICE_CAP_BUTTON) &&
|
|
|
|
|
ei_device_has_capability(device, EI_DEVICE_CAP_SCROLL)) {
|
|
|
|
|
struct xwl_abs_device *abs = calloc(1, sizeof(*abs));
|
|
|
|
|
|
|
|
|
|
if (abs) {
|
|
|
|
|
xorg_list_add(&abs->link, &xwl_ei_client->abs_devices);
|
|
|
|
|
abs->device = ei_device_ref(device);
|
|
|
|
|
used = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!used)
|
|
|
|
|
ei_device_close(device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_oeffis(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
#ifdef XWL_HAS_EI_PORTAL
|
|
|
|
|
if (xwl_ei_client->oeffis) {
|
|
|
|
|
debug_ei("Removing OEFFIS fd=%d\n", xwl_ei_client->oeffis_fd);
|
|
|
|
|
if (xwl_ei_client->oeffis_fd >= 0)
|
|
|
|
|
RemoveNotifyFd(xwl_ei_client->oeffis_fd);
|
|
|
|
|
xwl_ei_client->oeffis = oeffis_unref(xwl_ei_client->oeffis);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
free_ei(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
struct ei *ei = xwl_ei_client->ei;
|
|
|
|
|
struct xwl_abs_device *abs, *tmp;
|
|
|
|
|
ClientPtr client = xwl_ei_client->client;
|
|
|
|
|
|
2023-10-10 17:37:37 +02:00
|
|
|
TimerCancel(xwl_ei_client->disconnect_timer);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
xorg_list_del(&xwl_ei_client->link);
|
|
|
|
|
|
|
|
|
|
debug_ei("Removing EI fd=%d\n", xwl_ei_client->ei_fd);
|
|
|
|
|
if (xwl_ei_client->ei_fd >= 0)
|
|
|
|
|
RemoveNotifyFd(xwl_ei_client->ei_fd);
|
|
|
|
|
ei_device_unref(xwl_ei_client->ei_pointer);
|
|
|
|
|
ei_device_unref(xwl_ei_client->ei_keyboard);
|
|
|
|
|
xorg_list_for_each_entry_safe(abs, tmp, &xwl_ei_client->abs_devices, link) {
|
|
|
|
|
xorg_list_del(&abs->link);
|
|
|
|
|
ei_device_unref(abs->device);
|
|
|
|
|
free(abs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xwl_clear_emulated_events(xwl_ei_client);
|
|
|
|
|
if (client)
|
|
|
|
|
dixSetPrivate(&client->devPrivates, &xwl_ei_private_key, NULL);
|
|
|
|
|
|
|
|
|
|
free_oeffis(xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
ei_seat_unref(xwl_ei_client->ei_seat);
|
|
|
|
|
ei_unref(ei);
|
|
|
|
|
|
|
|
|
|
free(xwl_ei_client->cmdline);
|
|
|
|
|
free(xwl_ei_client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef XWL_HAS_EI_PORTAL
|
|
|
|
|
static void
|
|
|
|
|
setup_ei_from_oeffis(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
struct oeffis *oeffis = xwl_ei_client->oeffis;
|
|
|
|
|
|
|
|
|
|
xwl_ei_client->ei_fd = oeffis_get_eis_fd(oeffis);
|
|
|
|
|
if (xwl_ei_client->ei_fd < 0) {
|
|
|
|
|
error_ei("Failed to setup EI file descriptor from oeffis\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ei_setup_backend_fd(xwl_ei_client->ei, xwl_ei_client->ei_fd);
|
|
|
|
|
SetNotifyFd(xwl_ei_client->ei_fd, xwl_handle_ei_event,
|
|
|
|
|
X_NOTIFY_READ, xwl_ei_client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_handle_oeffis_event(int fd, int ready, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_ei_client *xwl_ei_client = data;
|
|
|
|
|
struct oeffis *oeffis = xwl_ei_client->oeffis;
|
|
|
|
|
enum oeffis_event_type event_type;
|
|
|
|
|
bool done = false;
|
|
|
|
|
|
|
|
|
|
oeffis_dispatch(oeffis);
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
event_type = oeffis_get_event(oeffis);
|
|
|
|
|
switch (event_type) {
|
|
|
|
|
case OEFFIS_EVENT_NONE:
|
|
|
|
|
debug_ei("OEFFIS event none\n");
|
|
|
|
|
done = true;
|
|
|
|
|
break;
|
|
|
|
|
case OEFFIS_EVENT_CONNECTED_TO_EIS:
|
|
|
|
|
debug_ei("OEFFIS connected to EIS\n");
|
|
|
|
|
setup_ei_from_oeffis(xwl_ei_client);
|
|
|
|
|
break;
|
|
|
|
|
case OEFFIS_EVENT_DISCONNECTED:
|
|
|
|
|
debug_ei("OEFFIS disconnected: %s\n",
|
|
|
|
|
oeffis_get_error_message(oeffis));
|
2023-06-20 16:17:36 +02:00
|
|
|
xwl_dequeue_emulated_events(xwl_ei_client);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
free_ei(xwl_ei_client);
|
|
|
|
|
done = true;
|
|
|
|
|
break;
|
|
|
|
|
case OEFFIS_EVENT_CLOSED:
|
|
|
|
|
debug_ei("OEFFIS closed\n");
|
|
|
|
|
free_ei(xwl_ei_client);
|
|
|
|
|
done = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (!done);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
setup_oeffis(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
#ifdef XWL_HAS_EI_PORTAL
|
|
|
|
|
xwl_ei_client->oeffis_fd = -1;
|
|
|
|
|
xwl_ei_client->oeffis = oeffis_new(NULL);
|
|
|
|
|
if (!xwl_ei_client->oeffis)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
xwl_ei_client->oeffis_fd = oeffis_get_fd(xwl_ei_client->oeffis);
|
|
|
|
|
if (xwl_ei_client->oeffis_fd < 0) {
|
|
|
|
|
error_ei("Failed to setup OEFFIS file descriptor\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetNotifyFd(xwl_ei_client->oeffis_fd, xwl_handle_oeffis_event,
|
|
|
|
|
X_NOTIFY_READ, xwl_ei_client);
|
|
|
|
|
|
2023-12-12 11:48:30 +01:00
|
|
|
oeffis_create_session(xwl_ei_client->oeffis,
|
|
|
|
|
OEFFIS_DEVICE_KEYBOARD | OEFFIS_DEVICE_POINTER);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
#else
|
|
|
|
|
return false;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
setup_ei_from_socket(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = ei_setup_backend_socket(xwl_ei_client->ei, NULL);
|
|
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
error_ei("Setup failed: %s\n", strerror(-rc));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xwl_ei_client->ei_fd = ei_get_fd(xwl_ei_client->ei);
|
|
|
|
|
if (xwl_ei_client->ei_fd < 0) {
|
|
|
|
|
error_ei("Failed to setup EI file descriptor from socket\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetNotifyFd(xwl_ei_client->ei_fd, xwl_handle_ei_event,
|
|
|
|
|
X_NOTIFY_READ, xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct xwl_ei_client *
|
|
|
|
|
setup_ei(ClientPtr client)
|
|
|
|
|
{
|
2023-09-29 10:19:13 +02:00
|
|
|
ScreenPtr pScreen = screenInfo.screens[0];
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
struct xwl_ei_client *xwl_ei_client = NULL;
|
2023-09-29 10:19:13 +02:00
|
|
|
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
struct ei *ei = NULL;
|
|
|
|
|
char buffer[PATH_MAX];
|
|
|
|
|
const char *cmdname;
|
|
|
|
|
char *client_name = NULL;
|
2023-09-29 10:19:13 +02:00
|
|
|
bool status = false;
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
|
|
|
|
|
cmdname = GetClientCmdName(client);
|
|
|
|
|
if (cmdname) {
|
|
|
|
|
snprintf(buffer, sizeof(buffer) - 1, "%s", cmdname);
|
|
|
|
|
client_name = basename(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!client_name) {
|
|
|
|
|
error_ei("Failed to retrieve the client command line name\n");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xwl_ei_client = calloc(1, sizeof *xwl_ei_client);
|
|
|
|
|
xwl_ei_client->cmdline = xstrdup(cmdname);
|
|
|
|
|
if (!xwl_ei_client) {
|
|
|
|
|
error_ei("OOM, cannot setup EI\n");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
xorg_list_init(&xwl_ei_client->link);
|
|
|
|
|
|
|
|
|
|
ei = ei_new(NULL);
|
|
|
|
|
ei_configure_name(ei, basename(client_name));
|
|
|
|
|
|
|
|
|
|
/* We can't send events to EIS until we have a device and the device
|
|
|
|
|
* is resumed.
|
|
|
|
|
*/
|
|
|
|
|
xwl_ei_client->accept_pointer = false;
|
|
|
|
|
xwl_ei_client->accept_keyboard = false;
|
|
|
|
|
xwl_ei_client->accept_abs = false;
|
|
|
|
|
xwl_ei_client->ei = ei;
|
|
|
|
|
xwl_ei_client->ei_fd = -1;
|
|
|
|
|
xwl_ei_client->client = client;
|
|
|
|
|
xorg_list_init(&xwl_ei_client->pending_emulated_events);
|
|
|
|
|
xorg_list_init(&xwl_ei_client->abs_devices);
|
|
|
|
|
|
2023-09-29 10:19:13 +02:00
|
|
|
if (xwl_screen->enable_ei_portal)
|
|
|
|
|
status = setup_oeffis(xwl_ei_client);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
if (!status)
|
|
|
|
|
status = setup_ei_from_socket(xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
if (!status) {
|
|
|
|
|
free(xwl_ei_client);
|
|
|
|
|
xwl_ei_client = NULL;
|
|
|
|
|
ei_unref(ei);
|
|
|
|
|
error_ei("EI setup failed\n");
|
2023-09-29 18:04:49 +02:00
|
|
|
/* We failed to setup EI using either backends, give up on EI. */
|
|
|
|
|
xwayland_restore_xtest();
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
return xwl_ei_client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static CARD32
|
|
|
|
|
disconnect_timer_cb(OsTimerPtr timer, CARD32 time, void *arg)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_ei_client *xwl_ei_client = arg;
|
|
|
|
|
|
|
|
|
|
free_ei(xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_ei_start_emulating(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
static uint32_t sequence = 0;
|
|
|
|
|
struct xwl_abs_device *abs;
|
|
|
|
|
|
|
|
|
|
sequence++;
|
|
|
|
|
if (xwl_ei_client->ei_pointer)
|
|
|
|
|
ei_device_start_emulating(xwl_ei_client->ei_pointer, sequence);
|
|
|
|
|
if (xwl_ei_client->ei_keyboard)
|
|
|
|
|
ei_device_start_emulating(xwl_ei_client->ei_keyboard, sequence);
|
|
|
|
|
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
|
|
|
|
|
ei_device_start_emulating(abs->device, sequence);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_ei_stop_emulating(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_abs_device *abs;
|
|
|
|
|
|
|
|
|
|
if (xwl_ei_client->ei_pointer)
|
|
|
|
|
ei_device_stop_emulating(xwl_ei_client->ei_pointer);
|
|
|
|
|
if (xwl_ei_client->ei_keyboard)
|
|
|
|
|
ei_device_stop_emulating(xwl_ei_client->ei_keyboard);
|
|
|
|
|
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
|
|
|
|
|
ei_device_stop_emulating(abs->device);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_ei_handle_client_gone(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
ClientPtr client = xwl_ei_client->client;
|
|
|
|
|
|
|
|
|
|
/* Make this EI client struct re-usable. xdotool only exists for a
|
|
|
|
|
* fraction of a second, so let's make it re-use the same client every
|
|
|
|
|
* time - this makes it easier to e.g. pause it */
|
|
|
|
|
xorg_list_add(&xwl_ei_client->link, &clients_for_reuse);
|
|
|
|
|
|
|
|
|
|
if (xorg_list_is_empty(&xwl_ei_client->pending_emulated_events))
|
|
|
|
|
xwl_ei_stop_emulating(xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
debug_ei("Client %s is now reusable\n", xwl_ei_client->cmdline);
|
|
|
|
|
|
|
|
|
|
/* Otherwise, we keep the EI part but break up with the X11 client */
|
|
|
|
|
assert(client);
|
|
|
|
|
dixSetPrivate(&client->devPrivates, &xwl_ei_private_key, NULL);
|
|
|
|
|
xwl_ei_client->client = NULL;
|
|
|
|
|
|
|
|
|
|
/* Set a timer for 10 minutes. If the same client doesn't reconnect,
|
|
|
|
|
* free it properly */
|
|
|
|
|
xwl_ei_client->disconnect_timer =
|
|
|
|
|
TimerSet(xwl_ei_client->disconnect_timer, 0,
|
|
|
|
|
10 * 60 * 1000, disconnect_timer_cb, xwl_ei_client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_ei_state_client_callback(CallbackListPtr *pcbl, void *unused, void *data)
|
|
|
|
|
{
|
|
|
|
|
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
|
|
|
|
ClientPtr client = clientinfo->client;
|
|
|
|
|
struct xwl_ei_client *xwl_ei_client = get_xwl_ei_client(client);
|
|
|
|
|
|
|
|
|
|
switch (client->clientState) {
|
|
|
|
|
case ClientStateGone:
|
|
|
|
|
case ClientStateRetained:
|
|
|
|
|
if (xwl_ei_client)
|
|
|
|
|
xwl_ei_handle_client_gone(xwl_ei_client);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
buttonmap(unsigned int b)
|
|
|
|
|
{
|
|
|
|
|
unsigned int button;
|
|
|
|
|
|
|
|
|
|
switch (b) {
|
|
|
|
|
case 0:
|
|
|
|
|
button = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
button = 0x110; /* BTN_LEFT */
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
button = 0x112; /* BTN_MIDDLE */
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
button = 0x111; /* BTN_RIGHT */
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
button = b - 8 + 0x113; /* BTN_SIDE */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return button;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_send_abs_event_to_ei(struct xwl_ei_client *xwl_ei_client, int sx, int sy)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_abs_device *abs;
|
|
|
|
|
struct ei *ei = xwl_ei_client->ei;
|
|
|
|
|
|
|
|
|
|
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices, link) {
|
|
|
|
|
struct ei_region *r;
|
|
|
|
|
size_t idx = 0;
|
|
|
|
|
|
|
|
|
|
while ((r = ei_device_get_region(abs->device, idx++))) {
|
|
|
|
|
double x = sx, y = sy;
|
|
|
|
|
|
|
|
|
|
if (ei_region_contains(r, x, y)) {
|
|
|
|
|
ei_device_pointer_motion_absolute(abs->device, sx, sy);
|
|
|
|
|
ei_device_frame(abs->device, ei_now(ei));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
xwl_send_event_to_ei(struct xwl_ei_client *xwl_ei_client,
|
|
|
|
|
int type, int detail, int flags, const ValuatorMask *mask)
|
|
|
|
|
{
|
|
|
|
|
struct ei *ei = xwl_ei_client->ei;
|
|
|
|
|
struct ei_device *ei_device = NULL;
|
|
|
|
|
int x = 0, y = 0;
|
|
|
|
|
|
|
|
|
|
debug_ei("Sending event type %d to EIS\n", type);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case MotionNotify:
|
|
|
|
|
valuator_mask_fetch(mask, 0, &x);
|
|
|
|
|
valuator_mask_fetch(mask, 1, &y);
|
|
|
|
|
|
|
|
|
|
if (flags & POINTER_ABSOLUTE) {
|
|
|
|
|
if (!xwl_ei_client->accept_abs)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
xwl_send_abs_event_to_ei(xwl_ei_client, x, y);
|
|
|
|
|
}
|
|
|
|
|
else if (x || y) {
|
|
|
|
|
if (!xwl_ei_client->accept_pointer)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ei_device = xwl_ei_client->ei_pointer;
|
|
|
|
|
ei_device_pointer_motion(ei_device, x, y);
|
|
|
|
|
ei_device_frame(ei_device, ei_now(ei));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ButtonPress:
|
|
|
|
|
case ButtonRelease:
|
|
|
|
|
if (!xwl_ei_client->accept_pointer)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ei_device = xwl_ei_client->ei_pointer;
|
|
|
|
|
if (detail < 4 || detail > 7) {
|
|
|
|
|
ei_device_button_button(ei_device,
|
|
|
|
|
buttonmap(detail), type == ButtonPress);
|
|
|
|
|
ei_device_frame(ei_device, ei_now(ei));
|
|
|
|
|
/* Scroll only on release */
|
|
|
|
|
} else if (type == ButtonRelease) {
|
|
|
|
|
if (detail == 4) {
|
|
|
|
|
ei_device_scroll_discrete(ei_device, 0, -SCROLL_STEP);
|
|
|
|
|
} else if (detail == 5) {
|
|
|
|
|
ei_device_scroll_discrete(ei_device, 0, SCROLL_STEP);
|
|
|
|
|
} else if (detail == 6) {
|
|
|
|
|
ei_device_scroll_discrete(ei_device, -SCROLL_STEP, 0);
|
|
|
|
|
} else if (detail == 7) {
|
|
|
|
|
ei_device_scroll_discrete(ei_device, SCROLL_STEP, 0);
|
|
|
|
|
}
|
2024-05-11 07:25:48 +01:00
|
|
|
ei_device_frame(ei_device, ei_now(ei));
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case KeyPress:
|
|
|
|
|
case KeyRelease:
|
|
|
|
|
if (!xwl_ei_client->accept_keyboard)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ei_device = xwl_ei_client->ei_keyboard;
|
|
|
|
|
ei_device_keyboard_key(ei_device, detail - 8, type == KeyPress);
|
|
|
|
|
ei_device_frame(ei_device, ei_now(ei));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
error_ei("XTEST event type %d is not implemented\n", type);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct xwl_ei_client *
|
|
|
|
|
reuse_client(ClientPtr client)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_ei_client *xwl_ei_client = NULL;
|
|
|
|
|
const char *cmdname = GetClientCmdName(client);
|
|
|
|
|
|
|
|
|
|
if (!cmdname)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
debug_ei("Client maybe up for re-use: %s\n", cmdname);
|
|
|
|
|
xorg_list_for_each_entry(xwl_ei_client, &clients_for_reuse, link) {
|
|
|
|
|
debug_ei("Checking if we can re-use %s\n", xwl_ei_client->cmdline);
|
|
|
|
|
if (xwl_ei_client->cmdline &&
|
|
|
|
|
strcmp(xwl_ei_client->cmdline, cmdname) == 0) {
|
|
|
|
|
debug_ei("Re-using client for %s\n", cmdname);
|
|
|
|
|
xorg_list_del(&xwl_ei_client->link);
|
|
|
|
|
xorg_list_init(&xwl_ei_client->link);
|
|
|
|
|
TimerCancel(xwl_ei_client->disconnect_timer);
|
|
|
|
|
xwl_ei_start_emulating(xwl_ei_client);
|
|
|
|
|
return xwl_ei_client;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-20 16:17:36 +02:00
|
|
|
static void
|
|
|
|
|
xwayland_xtest_fallback(DeviceIntPtr dev,
|
|
|
|
|
int type, int detail, int flags, const ValuatorMask *mask)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_device_data *xwl_device_data = xwl_device_data_get(dev);
|
|
|
|
|
|
|
|
|
|
if (xwl_device_data->sendEventsProc != NULL) {
|
|
|
|
|
debug_ei("EI failed, using XTEST as fallback for sending events\n");
|
|
|
|
|
(xwl_device_data->sendEventsProc)(dev, type, detail, flags, mask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
static void
|
|
|
|
|
xwayland_xtest_send_events(DeviceIntPtr dev,
|
|
|
|
|
int type, int detail, int flags, const ValuatorMask *mask)
|
|
|
|
|
{
|
|
|
|
|
ClientPtr client;
|
|
|
|
|
struct xwl_ei_client *xwl_ei_client;
|
|
|
|
|
bool accept = false;
|
|
|
|
|
|
2023-12-21 11:34:26 +10:00
|
|
|
if (!IsXTestDevice(dev, NULL))
|
|
|
|
|
return;
|
|
|
|
|
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
client = GetCurrentClient();
|
|
|
|
|
xwl_ei_client = get_xwl_ei_client(client);
|
|
|
|
|
if (!xwl_ei_client) {
|
|
|
|
|
xwl_ei_client = reuse_client(client);
|
|
|
|
|
if (xwl_ei_client)
|
|
|
|
|
xwl_ei_client->client = client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!xwl_ei_client) {
|
2023-06-20 16:17:36 +02:00
|
|
|
if (!(xwl_ei_client = setup_ei(client))) {
|
|
|
|
|
xwayland_xtest_fallback(dev, type, detail, flags, mask);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
return;
|
2023-06-20 16:17:36 +02:00
|
|
|
}
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
}
|
|
|
|
|
dixSetPrivate(&client->devPrivates, &xwl_ei_private_key, xwl_ei_client);
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case MotionNotify:
|
|
|
|
|
if (flags & POINTER_ABSOLUTE)
|
|
|
|
|
accept = xwl_ei_client->accept_abs;
|
|
|
|
|
else
|
|
|
|
|
accept = xwl_ei_client->accept_pointer;
|
|
|
|
|
break;
|
|
|
|
|
case ButtonPress:
|
|
|
|
|
case ButtonRelease:
|
|
|
|
|
accept = xwl_ei_client->accept_pointer;
|
|
|
|
|
break;
|
|
|
|
|
case KeyPress:
|
|
|
|
|
case KeyRelease:
|
|
|
|
|
accept = xwl_ei_client->accept_keyboard;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (accept) {
|
|
|
|
|
xwl_send_event_to_ei(xwl_ei_client, type, detail, flags, mask);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
debug_ei("Not yet connected to EIS, queueing events\n");
|
2023-06-20 16:17:36 +02:00
|
|
|
xwl_queue_emulated_event(xwl_ei_client, dev, type, detail, flags, mask);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
xwl_dequeue_emulated_events(struct xwl_ei_client *xwl_ei_client)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_emulated_event *xwl_emulated_event, *next_xwl_emulated_event;
|
2023-06-20 16:17:36 +02:00
|
|
|
bool sent;
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
|
|
|
|
|
xorg_list_for_each_entry_safe(xwl_emulated_event, next_xwl_emulated_event,
|
|
|
|
|
&xwl_ei_client->pending_emulated_events, link) {
|
2023-06-20 16:17:36 +02:00
|
|
|
sent = xwl_send_event_to_ei(xwl_ei_client,
|
|
|
|
|
xwl_emulated_event->type,
|
|
|
|
|
xwl_emulated_event->detail,
|
|
|
|
|
xwl_emulated_event->flags,
|
|
|
|
|
&xwl_emulated_event->mask);
|
|
|
|
|
if (!sent)
|
|
|
|
|
xwayland_xtest_fallback(xwl_emulated_event->dev,
|
|
|
|
|
xwl_emulated_event->type,
|
|
|
|
|
xwl_emulated_event->detail,
|
|
|
|
|
xwl_emulated_event->flags,
|
|
|
|
|
&xwl_emulated_event->mask);
|
|
|
|
|
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
xorg_list_del(&xwl_emulated_event->link);
|
|
|
|
|
free(xwl_emulated_event);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwl_handle_ei_event(int fd, int ready, void *data)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_ei_client *xwl_ei_client = data;
|
|
|
|
|
struct ei *ei;
|
|
|
|
|
bool done = false;
|
|
|
|
|
|
|
|
|
|
ei = xwl_ei_client->ei;
|
|
|
|
|
|
|
|
|
|
ei_dispatch(ei);
|
|
|
|
|
do {
|
|
|
|
|
enum ei_event_type type;
|
|
|
|
|
struct ei_event *e = ei_get_event(ei);
|
|
|
|
|
struct ei_device *ei_device;
|
|
|
|
|
|
|
|
|
|
if (!e)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ei_device = ei_event_get_device(e);
|
|
|
|
|
type = ei_event_get_type(e);
|
|
|
|
|
switch (type) {
|
|
|
|
|
case EI_EVENT_CONNECT:
|
|
|
|
|
debug_ei("Connected\n");
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_SEAT_ADDED:
|
|
|
|
|
/* We take the first seat that comes along and
|
|
|
|
|
* add our device there */
|
|
|
|
|
if (!xwl_ei_client->ei_seat) {
|
|
|
|
|
struct ei_seat *seat = ei_event_get_seat(e);
|
|
|
|
|
|
|
|
|
|
xwl_ei_client->ei_seat = ei_seat_ref(seat);
|
|
|
|
|
debug_ei("Using seat: %s (caps: %s%s%s%s%s)\n",
|
|
|
|
|
ei_seat_get_name(seat), ei_seat_has_capability(seat,
|
|
|
|
|
EI_DEVICE_CAP_KEYBOARD) ? "k" : "",
|
|
|
|
|
ei_seat_has_capability(seat,
|
|
|
|
|
EI_DEVICE_CAP_POINTER) ? "p" : "",
|
|
|
|
|
ei_seat_has_capability(seat,
|
|
|
|
|
EI_DEVICE_CAP_POINTER_ABSOLUTE) ? "a" : "",
|
|
|
|
|
ei_seat_has_capability(seat,
|
|
|
|
|
EI_DEVICE_CAP_BUTTON) ? "b" : "",
|
|
|
|
|
ei_seat_has_capability(seat,
|
|
|
|
|
EI_DEVICE_CAP_SCROLL) ? "s" : "");
|
|
|
|
|
ei_seat_bind_capabilities(seat,
|
|
|
|
|
EI_DEVICE_CAP_POINTER,
|
|
|
|
|
EI_DEVICE_CAP_POINTER_ABSOLUTE,
|
|
|
|
|
EI_DEVICE_CAP_BUTTON,
|
|
|
|
|
EI_DEVICE_CAP_SCROLL,
|
|
|
|
|
EI_DEVICE_CAP_KEYBOARD, NULL);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_SEAT_REMOVED:
|
|
|
|
|
if (ei_event_get_seat(e) == xwl_ei_client->ei_seat) {
|
|
|
|
|
debug_ei("Seat was removed\n");
|
|
|
|
|
xwl_ei_client->ei_seat =
|
|
|
|
|
ei_seat_unref(xwl_ei_client->ei_seat);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_DEVICE_ADDED:
|
|
|
|
|
debug_ei("New device: %s\n", ei_device_get_name(ei_device));
|
|
|
|
|
add_ei_device(xwl_ei_client, ei_device);
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_DEVICE_REMOVED:
|
|
|
|
|
debug_ei("Device removed: %s\n", ei_device_get_name(ei_device));
|
|
|
|
|
{
|
|
|
|
|
struct xwl_abs_device *abs, *tmp;
|
|
|
|
|
|
|
|
|
|
xorg_list_for_each_entry_safe(abs, tmp,
|
|
|
|
|
&xwl_ei_client->abs_devices, link) {
|
|
|
|
|
if (abs->device != ei_device)
|
|
|
|
|
continue;
|
|
|
|
|
ei_device_unref(abs->device);
|
|
|
|
|
xorg_list_del(&abs->link);
|
|
|
|
|
free(abs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (xwl_ei_client->ei_pointer == ei_device)
|
|
|
|
|
xwl_ei_client->ei_pointer =
|
|
|
|
|
ei_device_unref(xwl_ei_client->ei_pointer);
|
|
|
|
|
if (xwl_ei_client->ei_keyboard == ei_device)
|
|
|
|
|
xwl_ei_client->ei_keyboard =
|
|
|
|
|
ei_device_unref(xwl_ei_client->ei_keyboard);
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_DISCONNECT:
|
|
|
|
|
debug_ei("Disconnected\n");
|
|
|
|
|
free_ei(xwl_ei_client);
|
|
|
|
|
done = true;
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_DEVICE_PAUSED:
|
|
|
|
|
debug_ei("Device paused\n");
|
|
|
|
|
if (ei_device == xwl_ei_client->ei_pointer)
|
|
|
|
|
xwl_ei_client->accept_pointer = false;
|
|
|
|
|
if (ei_device == xwl_ei_client->ei_keyboard)
|
|
|
|
|
xwl_ei_client->accept_keyboard = false;
|
|
|
|
|
{
|
|
|
|
|
struct xwl_abs_device *abs;
|
|
|
|
|
|
|
|
|
|
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices,
|
|
|
|
|
link) {
|
|
|
|
|
if (ei_device == abs->device)
|
|
|
|
|
xwl_ei_client->accept_abs = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case EI_EVENT_DEVICE_RESUMED:
|
|
|
|
|
debug_ei("Device resumed\n");
|
|
|
|
|
if (ei_device == xwl_ei_client->ei_pointer)
|
|
|
|
|
xwl_ei_client->accept_pointer = true;
|
|
|
|
|
if (ei_device == xwl_ei_client->ei_keyboard)
|
|
|
|
|
xwl_ei_client->accept_keyboard = true;
|
|
|
|
|
{
|
|
|
|
|
struct xwl_abs_device *abs;
|
|
|
|
|
|
|
|
|
|
xorg_list_for_each_entry(abs, &xwl_ei_client->abs_devices,
|
|
|
|
|
link) {
|
|
|
|
|
if (ei_device == abs->device)
|
|
|
|
|
xwl_ei_client->accept_abs = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Server has accepted our device (or resumed them),
|
|
|
|
|
* we can now start sending events */
|
|
|
|
|
/* FIXME: Maybe add a timestamp and discard old events? */
|
|
|
|
|
xwl_ei_start_emulating(xwl_ei_client);
|
|
|
|
|
xwl_dequeue_emulated_events(xwl_ei_client);
|
|
|
|
|
if (!xwl_ei_client->client &&
|
|
|
|
|
xorg_list_is_empty(&xwl_ei_client->pending_emulated_events))
|
|
|
|
|
/* All events dequeued and client has disconnected in the meantime */
|
|
|
|
|
xwl_ei_stop_emulating(xwl_ei_client);
|
|
|
|
|
break;
|
2024-07-24 10:48:51 +02:00
|
|
|
case EI_EVENT_KEYBOARD_MODIFIERS:
|
|
|
|
|
debug_ei("Ignored event %s (%d)\n", ei_event_type_to_string(type), type);
|
|
|
|
|
/* Don't care */
|
|
|
|
|
break;
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
default:
|
2024-07-24 10:52:59 +02:00
|
|
|
error_ei("Unhandled event %s (%d)\n", ei_event_type_to_string(type), type);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ei_event_unref(e);
|
|
|
|
|
} while (!done);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bool
|
|
|
|
|
xwayland_ei_init(void)
|
|
|
|
|
{
|
|
|
|
|
xorg_list_init(&clients_for_reuse);
|
|
|
|
|
|
|
|
|
|
if (!dixRegisterPrivateKey(&xwl_ei_private_key, PRIVATE_CLIENT, 0)) {
|
|
|
|
|
ErrorF("Failed to register EI private key\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!AddCallback(&ClientStateCallback, xwl_ei_state_client_callback, NULL)) {
|
|
|
|
|
ErrorF("Failed to add client state callback\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-20 16:17:36 +02:00
|
|
|
if (!dixRegisterPrivateKey(&xwl_device_data_private_key, PRIVATE_DEVICE,
|
|
|
|
|
sizeof(struct xwl_device_data))) {
|
|
|
|
|
ErrorF("Failed to register private key for XTEST override\n");
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-20 16:17:36 +02:00
|
|
|
static void
|
|
|
|
|
xwayland_override_events_proc(DeviceIntPtr dev)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_device_data *xwl_device_data = xwl_device_data_get(dev);
|
|
|
|
|
|
|
|
|
|
if (xwl_device_data->sendEventsProc != NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Save original sendEventsProc handler in case */
|
|
|
|
|
xwl_device_data->sendEventsProc = dev->sendEventsProc;
|
|
|
|
|
|
|
|
|
|
/* Set up our own sendEventsProc to forward events to EI */
|
|
|
|
|
debug_ei("Overriding XTEST for %s\n", dev->name);
|
|
|
|
|
dev->sendEventsProc = xwayland_xtest_send_events;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
xwayland_restore_events_proc(DeviceIntPtr dev)
|
|
|
|
|
{
|
|
|
|
|
struct xwl_device_data *xwl_device_data = xwl_device_data_get(dev);
|
|
|
|
|
|
|
|
|
|
if (xwl_device_data->sendEventsProc == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Restore original sendEventsProc handler */
|
|
|
|
|
debug_ei("Restoring XTEST for %s\n", dev->name);
|
|
|
|
|
dev->sendEventsProc = xwl_device_data->sendEventsProc;
|
|
|
|
|
xwl_device_data->sendEventsProc = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
void
|
|
|
|
|
xwayland_override_xtest(void)
|
|
|
|
|
{
|
|
|
|
|
DeviceIntPtr d;
|
|
|
|
|
|
|
|
|
|
nt_list_for_each_entry(d, inputInfo.devices, next) {
|
2023-12-21 11:34:26 +10:00
|
|
|
xwayland_override_events_proc(d);
|
2023-06-20 16:17:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
xwayland_restore_xtest(void)
|
|
|
|
|
{
|
|
|
|
|
DeviceIntPtr d;
|
|
|
|
|
|
|
|
|
|
nt_list_for_each_entry(d, inputInfo.devices, next) {
|
2023-12-21 11:34:26 +10:00
|
|
|
xwayland_restore_events_proc(d);
|
xwayland: Add XTEST support using EIS
This adds support for XTEST in Xwayland using EIS, the emulated input
library [1].
To differentiate between X11 clients using XTEST, initiate a EI context
for each client and use the actual client name, from its command
line.
When an X11 client first tries to use XTEST to generate emulated input
events, a new connection to libEI is initiated by Xwayland on behalf
of the X11 client.
During that connection phase, the EI server will not be accepting
events until the emulated device is actually created, meaning that any
XTEST request from the X11 client will be discarded until the EI server
is willing to accept events.
To avoid that issue, add an event queue in Xwayland per X11 client that
will keep those requests, and dequeue them as soon as the EI server is
ready, i.e. once the EI device is added.
If the X11 client disconnects from the Xserver before the EI server is
ready, or if the connection is closed by the EI server, those events are
discarded and the queue cleared from any pending events.
For 10 minutes after the client disconnects, keep the internal struct
alive. If a client with the same commandline arguments connects again,
re-use the same struct. This means we are faster with the events the
second time around but it also allows the EIS server to pause individual
clients that keep sending intermittent events and disconnect immediately
(e.g. it'd be possible to pause xdtotool while an authentication prompt
is active).
[1] https://gitlab.freedesktop.org/libinput/libei
Thanks to Jan Beich <jbeich@FreeBSD.org> for fixing the build on BSD.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
Co-authored-by: David Redondo <kde@david-redondo.de>
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2020-09-04 12:44:15 +10:00
|
|
|
}
|
|
|
|
|
}
|