xwayland: Add a new input device used for pointer warping/locking

Generating relative and absolute movement events from the same input
device is problematic, because an absolute pointer device doesn't
expect to see any relative motion events. To be able to generate
relative pointer motion events including unaccelerated deltas, create a
secondary pointer device 'xwayland-relative-pointer', and use that for
emitting relative motion events.

Signed-off-by: Krzysztof Sobiecki <sobkas@gmail.com>
Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
This commit is contained in:
Krzysztof Sobiecki 2016-09-13 22:23:49 +08:00 committed by Adam Jackson
parent 011ada724a
commit 42e8902395
2 changed files with 72 additions and 0 deletions

View File

@ -134,6 +134,56 @@ xwl_pointer_proc(DeviceIntPtr device, int what)
#undef NAXES
}
static int
xwl_pointer_proc_relative(DeviceIntPtr device, int what)
{
#define NAXES 2
Atom axes_labels[NAXES] = { 0 };
switch (what) {
case DEVICE_INIT:
device->public.on = FALSE;
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
/*
* We'll never send buttons, but XGetPointerMapping might in certain
* situations make the client think we have no buttons.
*/
if (!init_pointer_buttons(device))
return BadValue;
if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
GetMotionHistorySize(), Relative))
return BadValue;
/* Valuators */
InitValuatorAxisStruct(device, 0, axes_labels[0],
NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
InitValuatorAxisStruct(device, 1, axes_labels[1],
NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
return BadValue;
return Success;
case DEVICE_ON:
device->public.on = TRUE;
return Success;
case DEVICE_OFF:
case DEVICE_CLOSE:
device->public.on = FALSE;
return Success;
}
return BadMatch;
#undef NAXES
}
static void
xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
{
@ -803,6 +853,25 @@ release_pointer(struct xwl_seat *xwl_seat)
DisableDevice(xwl_seat->pointer, TRUE);
}
static void
init_relative_pointer(struct xwl_seat *xwl_seat)
{
if (xwl_seat->relative_pointer == NULL) {
xwl_seat->relative_pointer =
add_device(xwl_seat, "xwayland-relative-pointer",
xwl_pointer_proc_relative);
ActivateDevice(xwl_seat->relative_pointer, TRUE);
}
EnableDevice(xwl_seat->relative_pointer, TRUE);
}
static void
release_relative_pointer(struct xwl_seat *xwl_seat)
{
if (xwl_seat->relative_pointer)
DisableDevice(xwl_seat->relative_pointer, TRUE);
}
static void
init_keyboard(struct xwl_seat *xwl_seat)
{
@ -869,8 +938,10 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
if (caps & WL_SEAT_CAPABILITY_POINTER && xwl_seat->wl_pointer == NULL) {
init_pointer(xwl_seat);
init_relative_pointer(xwl_seat);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->wl_pointer) {
release_pointer(xwl_seat);
release_relative_pointer(xwl_seat);
}
if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->wl_keyboard == NULL) {

View File

@ -120,6 +120,7 @@ struct xwl_touch {
struct xwl_seat {
DeviceIntPtr pointer;
DeviceIntPtr relative_pointer;
DeviceIntPtr keyboard;
DeviceIntPtr touch;
struct xwl_screen *xwl_screen;