Commit Graph

23 Commits

Author SHA1 Message Date
Peter Hutterer
db8e73141c Change creating subdevices to something more generic
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-01-05 11:16:19 +10:00
Peter Hutterer
ad8483b913 Drain the fd after opening
Make sure we don't send any events that may have been enqueued before we
initialized ourselves. Specifically, if we're using systemd-logind the fd
remains open when we disable/enable the device, allowing events to queue up on
the fd. These events are then replayed once the device is re-opened.

This is not the case when VT-switching, in that case logind closes the fd for
us.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
2015-12-17 11:23:28 +10:00
Peter Hutterer
1f43f3921f Split mixed pointer/keyboard devices into two separate X devices
The server struggles with devices that are both, the protocol (especially XI2)
requires a fairly strict separation of pointer vs keyboard devices. Though the
server has a couple of hacks to route events correctly, mixed
devices still experience bugs like [1].

Instead of advertising the device as a single mixed device, split the device
into two X devices, one with only a pointer/touch component, one with only a
keyboard component. This ensures that the device is effectively attached to
both the VCP and the VCK, something the XI2 protocol doesn't really allow.

This patch drops the keyboard capability on a mixed device, duplicates the
input options and attributes and queues a NewInputDeviceRequest call. The new
device only has the keyboard capability but is otherwise unchanged. The
wacom driver has used this approach for years.

The WorkProc is necessary to avoid inconsistent state, the server doesn't
handle a NewInputDeviceRequest during PreInit well.

The approach:
During pre-init we create a struct xf86libinput_device with the
libinput_device and a unique ID. The child device has that ID added to the
options and will look for the other device during its pre-init. The two
devices then share the xf86libinput_device struct.

We only have a single epollfd for all devices  and the server calls read_input
on the first device in the list with the epollfd as pInfo->fd. That shared
struct is used as the userdata on the libinput_device we get back from the
event, and each device is in the xorg_list device_list of that shared struct.
We loop through those to find the ones with the right capabilities and
post the event through that device.

Since devices can be enabled and disabled independently, the rest of the code
makes sure that we only ever add the device to libinput when the first shared
device is enabled, and remove it accordingly.

The server uses pInfo->major/minor to detect if another device is using the
same path for a logind-controlled fd. If so, it reuses that device's
pInfo->fd and sets the "fd" option to that value. That pInfo->fd is the
libinput epollfd though, not the actual device fd.

This doesn't matter for us, since we manage the fds largely ourselves and the
pInfo->fd we use is the epollfd anyway. On unplug however, the udev code
triggers a device removal for all devices, including the duplicated ones. When
we disable device, we restore the pInfo->fd from the "fd" option so that the
server can request logind to close the fd.

That only works if the "fd" option is correct, otherwise the server asks
logind to close the epollfd and everyone is unhappy.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=49950

https://bugs.freedesktop.org/show_bug.cgi?id=92896

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-11-23 07:26:46 +10:00
Peter Hutterer
83dfd31ec8 Revert "Split mixed pointer/keyboard devices into two separate X devices"
When using logind, this causes the server to hang when a split device is
unplugged. The reason is mostly in the server, when open the device by
requesting the logind fd, the server loops through the device list to check if
any other device has the same major/minor (see systemd_logind_take_fd()) and
returns the pInfo->fd for that device instead of requesting the fd again from
logind.

For libinput devices, the pInfo->fd is the epollfd, not the actual device, so
our second device gets the epollfd assigned. When the devices are removed, we
keep the device fd open and release the epollfd through logind.

This reverts commit c943739a2b.
2015-11-20 10:51:38 +10:00
Peter Hutterer
c943739a2b Split mixed pointer/keyboard devices into two separate X devices
The server struggles with devices that are both, the protocol (especially XI2)
requires a fairly strict separation of pointer vs keyboard devices. Though the
server has a couple of hacks to route events correctly, mixed
devices still experience bugs like [1].

Instead of advertising the device as a single mixed device, split the device
into two X devices, one with only a pointer/touch component, one with only a
keyboard component. This ensures that the device is effectively attached to
both the VCP and the VCK, something the XI2 protocol doesn't really allow.

This patch drops the keyboard capability on a mixed device, duplicates the
input options and attributes and queues a NewInputDeviceRequest call. The new
device only has the keyboard capability but is otherwise unchanged. The
wacom driver has used this approach for years.

The WorkProc is necessary to avoid inconsistent state, the server doesn't
handle a NewInputDeviceRequest during PreInit well.

The approach:
During pre-init we create a struct xf86libinput_device with the
libinput_device and a unique ID. The child device has that ID added to the
options and will look for the other device during its pre-init. The two
devices then share the xf86libinput_device struct.

We only have a single epollfd for all devices  and the server calls read_input
on the first device in the list with the epollfd as pInfo->fd. That shared
struct is used as the userdata on the libinput_device we get back from the
event, and each device is in the xorg_list device_list of that shared struct.
We loop through those to find the ones with the right capabilities and
post the event through that device.

Since devices can be enabled and disabled independently, the rest of the code
makes sure that we only ever add the device to libinput when the first shared
device is enabled, and remove it accordingly.

[1] https://bugs.freedesktop.org/show_bug.cgi?id=49950

https://bugs.freedesktop.org/show_bug.cgi?id=92896

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-11-20 08:45:40 +10:00
Peter Hutterer
a72e96538a Add a helper function for the driver context initialization
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-11-18 07:00:29 +10:00
Peter Hutterer
b1a9bea607 Copy the device capabilities to the X driver struct
And use those copied caps instead of the direct device capability calls.

No functional changes at this point, this is preparation work for selectively
disabling capabilities on a device.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-11-18 07:00:29 +10:00
Peter Hutterer
a6aad69a97 Split type_name detection out into a helper function
No functional changes

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-11-18 07:00:29 +10:00
Peter Hutterer
6fa5f30129 Unref the libinput context on pre_init failure
A device that fails pre_init has a ref to the libinput context but may not
have a pInfo->private. For those devices we never call libinput_unref() and
the libinput struct never gets freed.

Thus if at least one device didn't pass pre_init, we never cleaned up after
ourselves.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-11-18 07:00:01 +10:00
Peter Hutterer
c53dde1a50 Don't fail DEVICE_CLOSE
We're not doing anything here, so no reason to fail.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-11-13 14:33:02 +10:00
Peter Hutterer
d7331f6e34 Remove unused server_fds list
Obsolete as of 353c52f2be

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-11-13 14:32:31 +10:00
Peter Hutterer
fb56f6d7a5 Set the device to NULL after unref
No real effect in the current code, but it adds a bit of safety.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-11-13 10:02:16 +10:00
Peter Hutterer
c8861d2a2f Plug two memory leaks
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-11-12 10:17:39 +10:00
Peter Hutterer
0163482e22 Add property support for the accel profiles
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-10-26 10:00:57 +10:00
Peter Hutterer
6abd341279 Fix invalid pointer passed to the properties
Takes a void*, not a void**

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-09-03 17:42:20 +10:00
Peter Hutterer
19b42f242d Move the read-only properties into the same condition
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-09-03 17:33:40 +10:00
Peter Hutterer
9563334dda Use xf86OpenSerial instead of a direct open() call
This will transparently handle server-side fds for us.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Martin Pieuchot <mpi@openbsd.org>
2015-08-17 09:18:01 +10:00
Peter Hutterer
353c52f2be Revamp server fd opening
The server already stores the server-fd in the options, so we only need to run
through the list of current devices, find a match and extract that fd from the
options. Less magic in our driver and it gives us a pInfo handle in
open_restricted which we'll can use for xf86OpenSerial().

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Martin Pieuchot <mpi@openbsd.org>
2015-08-17 09:16:42 +10:00
Peter Hutterer
f139f14249 Add an option to disable horizontal scrolling
libinput always has horizontal scrolling enabled and punts the decision when
to scroll horizontally to the toolkit/widget. This is the better approach, but
while we have a stack that's not ready for that, and in the X case likely
never will be fully ready provide an option to disable horizontal scrolling.

This option doesn't really disable horizontal scrolling, it merely discards
any horizontal scroll delta. libinput will still think it's scrolling.

https://bugs.freedesktop.org/show_bug.cgi?id=91589

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-08-13 07:53:19 +10:00
Peter Hutterer
e3a888c3ab Add drag lock support
First, why is this here and not in libinput: drag lock should be implemented
in the compositor (not in libinput) so it can provide feedback when it
activates and grouped in with other accessibility features. That will work for
Wayland but in X the compositor cannot filter button events - only the server
and the drivers can.

This patch adds mostly the same functionality that evdev provides with two
options on how it works:
* a single button number configures the given button to lock the next button
  pressed in a logically down state until a press+ release of that same button
  again
* a set of button number pairs configures each button with the to-be-locked
  logical button, i.e. a pair of "1 3" will hold 3 logically down after a
  button 1 press

The property and the xorg.conf options take the same configuration as the
evdev driver (though the property has a different prefix, libinput instead of
Evdev).

The behavior difference to evdev is in how releases are handled, evdev sends
the release on the second button press event, this implementation sends the
release on the second release event.

https://bugs.freedesktop.org/show_bug.cgi?id=85577

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-08-13 07:52:48 +10:00
Martin Pieuchot
cd61ddb040 Remove unneeded header, epoll(7) interface is not directly used.
Signed-off-by: Martin Pieuchot <mpi@openbsd.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-08-12 10:16:11 +10:00
Martin Pieuchot
a199880057 Rename a local variable to not shadow the BSD strmode(3) function.
Signed-off-by: Martin Pieuchot <mpi@openbsd.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-08-12 10:16:01 +10:00
Peter Hutterer
fe58cff48b Rename main source file to x86libinput.c
To avoid conflict and confusion with libinput's sources. This was originally
triggered by needing a header file for the driver which cannot be named
libinput.h. That need went away after other refacturing, but we might as well
rename it now, sooner or later we'll need a xf86libinput.h file.

Can't do much about the libinput-properties header though, not worth breaking
other projects and it's namespaced into /usr/include/xorg anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-08-11 15:05:29 +10:00