Compare commits

...

122 commits

Author SHA1 Message Date
Giulio P
be44b6e6a8 doc: fix typo
Remove a repetition of words in the comments on
libevdev_set_event_value()

Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/131>
2025-12-07 02:31:20 +00:00
Peter Hutterer
139b58e135 libevdev 1.13.6
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2025-12-01 15:12:22 +10:00
Peter Hutterer
c6bf238c4e include: sync event codes with kernel 6.18
Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/129>
2025-12-01 14:49:50 +10:00
Peter Hutterer
f3a9c2038d libevdev 1.13.5
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2025-10-20 14:49:38 +10:00
Marcos Alano
9289c9826c Sync headers with kernel 6.17
Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/126>
2025-09-28 20:34:21 -03:00
Peter Hutterer
a30a461e82 util: change the bit to shift to ULL
libevdev/libevdev-util.h:45:45: runtime error: left shift of 1 by 63 places cannot be represented in type 'long long'

Fixes: #32
Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/127>
2025-08-13 21:23:10 +10:00
Peter Hutterer
d093b4752a include: sync event codes with kernel 6.16
Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/125>
2025-07-29 09:07:13 +10:00
Peter Hutterer
ac0056961c libevdev 1.13.4 2025-03-25 09:27:07 +10:00
andeston
d06abb81e5 Always push changed mt events when syncing
If the start and end of a touch are dropped, the slot, according to the
kernel, may have a different state. We should inform the client of these
changes even if the slot is not currently active.

For most axes this doesn't matter too much as we expect them to change
during an active touch anyway so we don't expect the kernel's caching to
be a problem. However where the ABS_MT_TOOL_TYPE changed during a sync
we need to inform the client of the new tool type so that future
touchese won't be erroneously treated as e.g. palms.

For a full reproducer see the test case but it comes down to:
- touch down with MT_TOOL_PALM, make sure libevdev reads the state
- change that slot to MT_TOOL_FINGER, trigger a sync
- ensure that libevdev pushes out that tool type change even if the
  slot is not currently active

Co-authored-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/124>
2025-01-06 13:21:29 +10:00
Peter Hutterer
cfd803566c CI: update to latest ci-templates
This allows for using @users.noreply addresses and still pass
ci-fairy checks.

Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/123>
2025-01-06 12:57:50 +10:00
Peter Hutterer
1a8324aeb8 Drop the signed-off-by requirement
We've had this for roughly 10y now and it's value is dubious. Most of
xorg no longer requires, mesa accepts but doesn't require it, most of GNOME
doesn't accept it and neither does systemd.

Let's drop the requirement.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Part-of: <https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/123>
2025-01-06 12:51:05 +10:00
Peter Hutterer
72fa564092 gitlab CI: bump to latest fedoras and ubuntu
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-11-25 10:34:30 +10:00
Peter Hutterer
2342d8c9ee libevdev 1.13.3
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-09-03 12:16:11 +10:00
Peter Hutterer
54c083378e include: sync event codes with kernel 6.10
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-07-15 15:57:02 +10:00
Peter Hutterer
5501633d51 libevdev 1.13.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-05-31 15:16:54 +10:00
Peter Hutterer
080d1d097a include: sync event codes with kernel 6.9
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-05-14 15:23:31 +10:00
Peter Hutterer
414757317d gitlab CI: don't run MR pipelines in forks
Commit originally by Simon Ser in wayland/wayland-protocols!305.

Currently our CI setup has a downside: for each push on a merge
request, two pipelines are triggered. The first is triggered in
the context of the forked repository, and the second is triggered
in the context of the MR in the parent repository.

Replace the workflow rules with the ones in the official docs [1],
so that a branch pipeline isn't triggered when a MR exists for that
branch.

[1]: https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-04-30 08:46:00 +10:00
Peter Hutterer
fb5402020f meson.build: remove superfluous double doxygen check
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 16:11:08 +10:00
Peter Hutterer
de6ae19483 meson.build: specify the include directory correctly
If libevdev is used as subproject header lookup for libevdev.h fails
because our build directory isn't correctly set as one of the include
directories.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 16:11:08 +10:00
Peter Hutterer
82560ca9d7 meson.build: declare the file list as such
Not much of an effect but where libevdev is used as subproject those
files are now correctly accessible.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 16:11:08 +10:00
Peter Hutterer
1ee2399ba8 meson.build: allow disabling building the various tools
A bit of a niche case but this helps with embedding libevdev as static
library when the tools don't matter.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 16:11:08 +10:00
Peter Hutterer
d852e59dd0 gitlab CI: rebuild the images
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 16:04:50 +10:00
Peter Hutterer
8d8a3d8fc7 gitlab CI: drop Ubuntu 22.10
Repos are 404

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 16:04:44 +10:00
Peter Hutterer
cd9bea914c gitlab CI: drop unnecessary B2C_VERSION
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 15:52:50 +10:00
Peter Hutterer
179fc4d370 gitlab CI: update to the same b2c image libinput uses
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 15:26:57 +10:00
Peter Hutterer
703999edec gitlab CI: remove the jobs for the scheduled forced rebuild
This scheduled pipeline no long runs, so let's drop this job.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 15:15:01 +10:00
Peter Hutterer
5db8e66bd3 gitlab CI: update to latest Fedoras
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 15:15:01 +10:00
Peter Hutterer
2e0a0cd271 gitlab CI: update to latest template and use the ci-fairy image
Makes life easier because we don't have to deal with the pip complaints.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2024-03-21 15:10:00 +10:00
Peter Hutterer
97d0e4d151 CI: add a comment to the meson build helper
We now have an upstream for it so we can sync changes between projects.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-30 15:18:28 +10:00
Peter Hutterer
d21d826b63 CI: bump to new fedoras and ubuntus
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-08 14:45:10 +10:00
Peter Hutterer
d399abca1a tools/publish-doc: enable pushing docs for specific tags
Historically, I copied the docs on the server directly after pushing latest,
but (especially with meson) it's a lot easier to just build that specific tag
locally and rsync it to the correct target directory.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-07 23:48:44 +00:00
Peter Hutterer
d7139f1314 tools/publish-doc: build the docs with meson before synching
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-07 23:48:44 +00:00
Peter Hutterer
1cc8c6d491 doc: update the ioctl list with missing ioctls
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-08 09:35:37 +10:00
Peter Hutterer
f201583026 doc: remove duplicate doc entry for EVIOCSKEYCODE
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-08 09:18:57 +10:00
Peter Hutterer
4582559b66 libevdev 1.13.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-05-05 10:45:30 +10:00
Peter Hutterer
fb3741e0cd include: sync event codes with kernel 6.2
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-04-20 08:58:13 +10:00
Enric Balletbo i Serra
bb4404dd91 test: Get the print mode from the CK_VERBOSITY environment variable
On a test run it only prints the summary and one message per failed
test. While having this behaviour by default is nice it might be
interesting in some case to have more information print. Make the print
mode configurable from the environment variable CK_VERBOSITY, which can
have the values "silent", "minimal", "normal" or "verbose" so we can have
different outputs.

    $ sudo CK_VERBOSITY=verbose ./test-libevdev
    Running suite(s): libevdev init tests
     libevdev_has_event tests
     libevdev event tests
     100%: Checks: 79, Failures: 0, Errors: 0
     test-libevdev-init.c:23:P:test_new_device:test_new_device:0: Passed
     test-libevdev-init.c:28:P:test_free_device:test_free_device:0: Passed
     [ ... ]

Note that the default print mode doesn't change after this patch.

Signed-off-by: Enric Balletbo i Serra <eballetbo@redhat.com>
2023-04-19 16:40:14 +02:00
Peter Hutterer
db0d4271ed gitlab CI: add new workflow rules
Required for pipelines to run after some infrastructure changes, see
https://gitlab.freedesktop.org/freedesktop/freedesktop/-/issues/438

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-03-15 10:21:43 +10:00
Peter Hutterer
689d1eb01c gitlab CI: bump to latest fedoras
The F37 update was delayed by https://github.com/systemd/systemd/pull/25941 which
is now available in F37 as of v251.11

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-02-15 08:31:58 +10:00
Benjamin Tissoires
2eb0bb4be4 CI: bump b2c and kernel
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2023-02-08 11:31:02 +01:00
Alyssa Ross
d8c491f57e
Include all include files in dist tarballs
Otherwise, the distribution tarballs will be generated based on what's
in libevdev_la_SOURCES, which only includes the headers for the
operating system the maintainer happens to be running "make dist"
from.  As a result of this, e.g. the 1.13.0 tarball only includes the
headers for Linux, making the tarball unbuildable for FreeBSD.

"meson dist" was already doing the right thing.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
2023-01-13 21:43:04 +00:00
Peter Hutterer
54f4c054ea gitlab CI: sync the meson-build.sh script with libinput
Pulls in the three libinput commits up to 31ecda70087

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-10 08:56:52 +10:00
Peter Hutterer
b2e12fe926 gitlab CI: use b2c instead of qemu
This is copied from libinput's CI but as one large change rather than
cherry-picking the process on how to get here. meson-build.sh is synched
with libinput's version - it is a more generic version anyway.

With this change we no longer require separate images for the qemu runs,
our default image is qemu-capable and can be run in qemu via
boot2container (b2c).

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 10:32:01 +10:00
Peter Hutterer
50ac79078e gitlab CI: pass the --no-suite to meson builds
Only use the LIBEVDEV_SKIP_ROOT_TESTS env var in autotools where we need
it, in meson we can use meson to control which tests we (don't) want to
run.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 10:30:47 +10:00
Peter Hutterer
37f71a8493 gitlab CI: drop the ninja dist for every job
Unlike autotools distcheck which ensures we didn't forget to add
anything to the makefiles, ninja dist just zips up the git repo.

It does run the tests though but without suite selection which is a
problem for us here.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 10:26:39 +10:00
Peter Hutterer
6be54f75c8 gitlab CI: skip the right tests in the tarball jobs
Use the new needs-uinput suite specifier for the meson build job, and
use --no-tests for ninja dist in the autotools build job.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 10:26:39 +10:00
Peter Hutterer
427af9d248 meson.build: add the tests that need uinput into a needs-uinput suite
This way we can skip it all by meson test --no-suite=needs-uinput

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 10:25:02 +10:00
Peter Hutterer
6d0d778e59 gitlab CI: replace the meson-build.sh with the libinput one
The libinput one is more generic and expressive, taking arguments and
whatnot.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 09:25:46 +10:00
Peter Hutterer
ac3d44ee7a gitlab CI: drop MESON_SKIP_TEST variables
In the no-check:meson job, the ninja arg was "dist" so the test would be
run as part of that anyway (and skipped, since we didn't have check).

In the no-doxygen-check:meson job, the ninja arg was zero so the test
would be skipped but since we don't have check we might as well just
run it as empty test suite.

And the same applies to the scan-build job, running the test shouldn't
hurt here.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 09:18:17 +10:00
Peter Hutterer
46ed9e53e4 gitlab CI: drop the custom meson to junit conversion script
And always collect test logs, makes it easier to debug when things fail
to go wrong

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-05 09:01:38 +10:00
Peter Hutterer
1e9fb4fe02 test: drop the valgrind make check wrappers from autotools
We have meson with a proper test suite setup and this currently breaks
the CI due to some Arch issues with glibc debuginfo packages. Let's just
drop this so we don't run valgrind unconditionally.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-04 15:51:58 +10:00
Peter Hutterer
1489287bf1 gitlab CI: bump to newer Ubuntus
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-04 15:25:06 +10:00
Peter Hutterer
136efe0399 gitlab CI: bump to a newer version of the templates
Required by the debian sid containers, otherwise we fail because of a
missing /etc/apt/sources.list file.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-04 15:20:33 +10:00
Peter Hutterer
f45bc03d9f gitlab CI: do not retry the qemu runs
See libinput commit fb4f4131a112201c86c510179cfc939fcfa8aece by Benjamin
Tissoires

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-04 14:46:28 +10:00
Peter Hutterer
4f66455160 gitlab CI: change an explicit Fedora to {{distro}}
See libinput commit 0d602e12a4b66d5b5f27d2a9fd9899d43cf128fe by Benjamin
Tissoires

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-04 14:43:18 +10:00
Peter Hutterer
09fd1f4e66 gitlab CI: prettify the include of templates
Identical to libinput commit c8c825289f1b7575ee10b849c04f5caa60483a7e by
Benjamin Tissoires.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-01-04 14:41:33 +10:00
illiliti
7820dc8b08 meson: Use proper type for bool object
Fix invalid bool usage which violates official meson specification and thus
breaks muon, an implementation of meson written in C.

Signed-off-by: illiliti <illiliti@protonmail.com>
2022-10-20 23:13:06 +03:00
Zixian Liu
df826a3c54 Correct document 2022-08-16 09:00:08 +00:00
Douglas R. Reno
011946d446 configure.ac: Update the bug report URL.
While I was running the tests for libevdev on a
system, I had a test failure, and it told me to report it to
bugs.freedesktop.org.

This project uses GitLab now, so update the URL.

Signed-off-by: Douglas R. Reno <renodr@linuxfromscratch.org>
2022-08-08 22:26:36 +00:00
Peter Hutterer
ff4276398c libevdev 1.13.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-08-02 11:21:12 +10:00
Peter Hutterer
1da836d0a9 include: sync event codes with kernel 5.19
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-08-02 11:09:51 +10:00
Peter Hutterer
b6c9dfd9d7 meson: drop the uinput.h header listing
This is a noop, meson gets its compile dependencies from the compiler,
listing it here makes no difference.

Same is true for listing the other two linux/input/*.h headers as
sources.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-12 09:50:08 +00:00
Peter Hutterer
0afed6479d meson.build: drop the use of join_paths
Replace with the slash notation supported since 0.49

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-12 09:50:08 +00:00
Peter Hutterer
c6c4d33474 meson.build: use project_source_root() instead of source_root()
The latter is deprecated, so let's bump the meson version requirement
and use the newer, shiny feature.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-12 09:50:08 +00:00
Peter Hutterer
c9781f00f3 uinput: use named initializers for the event struct
With the 64 bit timestamps, the struct layout changes into a flatter
version, so let's use the input_event_(u)sec helpers to transparently
handle this.

Fixes #25

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-11 15:32:59 +10:00
Peter Hutterer
0c7e1d2f67 Fix a few whitespace/coding style issues
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-11 15:31:45 +10:00
Peter Hutterer
2d49be8303 Fix a compiler warning
[1/16] Compiling C object libevdev.so.2.3.0.p/libevdev_libevdev.c.o
../libevdev/libevdev.c:665:40: warning: argument 2 of type ‘struct slot_change_state[dev->num_slots]’ declared as a variable length array [-Wvla-parameter]
  665 |               struct slot_change_state changes_out[dev->num_slots])
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
../libevdev/libevdev.c:47:52: note: previously declared as a pointer ‘struct slot_change_state *’
   47 |                          struct slot_change_state *changes_out);
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-11 15:31:45 +10:00
Peter Hutterer
c2eaaa171e meson: up the timeout to 10s per test
Fixes #26

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-07-11 15:28:23 +10:00
Peter Hutterer
de2daf8d36 meson.build: install the mouse-dpi-tool man page
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-03-25 14:37:28 +10:00
Peter Hutterer
8ced382eb8 libevdev 1.12.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-03-25 14:32:48 +10:00
Peter Hutterer
f3c3b0a233 include: sync key codes with kernel 5.17
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-03-22 12:34:08 +10:00
Peter Hutterer
7c43e86944 gitlab CI: update to current distribution versions, drop Centos
No big point building for Centos 7 anywmore, and Centos 8 is now Centos
Stream only which needs fixing in the CI templates first.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-02-02 00:29:35 +00:00
Stephen Kitt
066d9caf55
Add a manpage for mouse-dpi-tool
Signed-off-by: Stephen Kitt <steve@sk2.org>
2021-11-15 08:58:11 +01:00
Peter Hutterer
69403a63ed libevdev 1.12.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-11-09 09:52:06 +10:00
Peter Hutterer
d03f9b6616 tools: add a helper tool to list all currently known codes
A non-installed tool to make it easy to check if newly added codes are
indeed supported correctly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-11-09 09:46:16 +10:00
Peter Hutterer
fdba5a41dd include: sync event codes with kernel 5.15
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-11-09 08:54:21 +10:00
José Expósito
889fc01c81 doc: fix initialization and setup error
Remove an unnecessary and unmatched curly bracket from the demo code.

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-09-04 13:30:17 +02:00
José Expósito
8a4f45df5b doc: fix uinput device creation warnings
The example code for creating uinput devices produces the following
warnings:

warning: unused variable ‘ev’ [-Wunused-variable]
   | struct input_event ev[2];
   |                    ^~
warning: unused variable ‘new_fd’ [-Wunused-variable]
   | int fd, new_fd, uifd;
   |         ^~~~~~
warning: ‘err’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   |     return err;
   |            ^~~

Signed-off-by: José Expósito <jose.exposito89@gmail.com>
2021-09-04 13:21:42 +02:00
Ulrich Ölmann
9b918d316a doc: fix typos
Signed-off-by: Ulrich Ölmann <u.oelmann@pengutronix.de>
2021-08-17 18:33:58 +02:00
Ulrich Ölmann
5fc81553f5 doc: fix uinput example code
Signed-off-by: Ulrich Ölmann <u.oelmann@pengutronix.de>
2021-08-17 15:09:26 +02:00
Peter Hutterer
a6970e1cec gitlab CI: update to latest ci-templates
We can ditch the custom localhost usages and instead use the vmctl and
ssh-config aliases.

Signed-off-by:	Peter Hutterer <peter.hutterer@who-t.net>
2021-07-26 10:23:39 +10:00
Simeon Schaub
662c84d80e
build: properly link against rt
This is especially relevant for cross-compilation, since libevdev uses
`clock_gettime`.
This came up in https://github.com/JuliaPackaging/Yggdrasil/pull/3201.

Signed-off-by: Simeon Schaub <simeondavidschaub99@gmail.com>
2021-06-21 02:56:52 +02:00
Peter Hutterer
bb1cd0dd57 gitlab CI: bump to Fedora 34 and Ubuntu 21.04
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-05-19 10:37:21 +10:00
Peter Hutterer
a53c6d1154 gitlab CI: make the tarball distro selection automatic
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-05-19 10:36:58 +10:00
Peter Hutterer
4e5babd7a1 gitlab CI: make the qemu selection automatic
Generate the snippet for whichever is the last version in the list for the
want_qemu tag.

And move the want_qemu tag up so it's more obvious in the config file.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-05-19 10:36:53 +10:00
Richard Purdie
8d70f44989 make-event-names: Fix determinism issue
The order of dict values is not deterministic in python leading to differing 
header file generation which results in differing build output for the same
configuration. Sort to remove this inconsistency and make the output 
reproducible.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Reviewed-by: Filipe Laíns <lains@archlinux.org>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-02-22 07:06:46 +10:00
Peter Hutterer
8855f1ac59 libevdev 1.11.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-02-01 15:51:10 +10:00
Peter Hutterer
60d4f1b2ae Change to the (always intended) MIT license
Due to what must've been a copy/paste error many years ago, the license text
for libevdev wasn't actually the MIT license. Let's rectify this, it was
always MIT intended anyway.

To make this more obvious and reduce the chance of copy/paste mistakes, use
the SPDX license identifier in the various source files. The two installed
public header files have the full license text.

All contributors with copyrightable contributions have ACKed the license
change to MIT, either in the MR directly [1] or privately in reply to an
email.

[1] https://gitlab.freedesktop.org/libevdev/libevdev/-/merge_requests/69

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Alexander Dahl <ada@thorsis.com>
Acked-by: Andreas Pokorny <andreas.pokorny@canonical.com>
Acked-by: Armin K <krejzi@email.com>
Acked-by: Benjamin Tissoires <btissoir@redhat.com>
Acked-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Deepa Dinamani <deepa.kernel@gmail.com>
Acked-by: Emmanuele Bassi <ebassi@gnome.org>
Acked-by: Gaetan Nadon <memsize@videotron.ca>
Acked-by: George Thomas <georgefsthomas@gmail.com>
Acked-by: Michael Forney <mforney@mforney.org>
Acked-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
Acked-by: Niclas Zeising <zeising@daemonic.se>
Acked-by: Owen W. Taylor <otaylor@fishsoup.net>
Acked-by: Peter Seiderer <ps.report@gmx.net>
Acked-by: Ran Benita <ran234@gmail.com>
Acked-by: Rosen Penev <rosenp@gmail.com>
Acked-by: Scott Jann <sjann@knight-rider.org>
Acked-by: Thilo Schulz <thilo@tjps.eu>
Acked-by: polyphemus <rolfmorel@gmail.com>
2021-01-25 13:46:55 +10:00
Peter Hutterer
7eae5e322c libevdev 1.10.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-01-11 13:07:47 +10:00
Peter Hutterer
70881516f2 doc: fix conflicting documentation for libevdev_get_event_value()
Yes, the value we return is from the currently active slot, but there are a
few niche cases where the active slot changes from what the client may think
it is. So let's call it undefined like the other half of the documentation
already does.

Fixes #20

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-01-08 09:58:16 +10:00
Peter Hutterer
510bde8f47 gitlab CI: use Fedora 33 and Ubuntu 20.10
This requires latest CI templates for the mkosi changes. Since the start_vm.sh
script is now gone, switch to using vmctl instead.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-01-04 11:49:42 +10:00
Peter Hutterer
7f53bcfab3 gitlab CI: make the custom build reference automated
We still require Fedora for the various jobs with custom autotools/meson
configurations. But we might as well make it dependent on the config file
entries only than hardcoding it.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2021-01-04 10:59:25 +10:00
Peter Hutterer
896d087a0e include: sync event codes with kernel 5.10
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-12-14 00:17:15 +00:00
Shuo Wang
74dc7ff245 CODING_STYLE.md: fix a typo
Signed-off-by: Shuo Wang <wangshuo47@huawei.com>
2020-11-03 14:42:25 +08:00
Peter Hutterer
e6f3141eb6 libevdev 1.10.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-10-26 09:07:01 +10:00
Peter Hutterer
a37d76b49b README: drop an obsolete paragraph
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-10-26 09:06:09 +10:00
Peter Hutterer
869fda7810 libevdev 1.10rc2 2020-10-20 09:34:05 +10:00
Scott Jann
4226c7801b Add libevdev_disable_property
On some devices, a kernel input property has been set in error and we need the
ability to disable that property.

Signed-off-by: Scott Jann <sjann@knight-rider.org>
2020-10-19 14:47:07 +10:00
Nayan Deshmukh
8e94375bc6 Add link to Rust bindings
Signed-off-by: Nayan Deshmukh <nayan26deshmukh@gmail.com>
2020-10-10 03:58:22 +00:00
Peter Hutterer
df677d954c libevdev 1.10rc1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-10-06 10:19:50 +10:00
Peter Hutterer
f6c0a048c5 tools: add a man page for the touchpad-edge-detector tool
Requires some .gitignore pattern removal too and an autotools fix to actually
dist the man pages.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-10-06 09:56:33 +10:00
Peter Hutterer
da2eea1dcb meson.build: install the libevdev-tweak-device man page
This got lost in meson conversion

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-10-06 09:44:45 +10:00
Niclas Zeising
6ea230bc72 tools: Remove signalfd.h include again
Remove the includsion of sys/signalfd.h again, it hasn't been needed
since cca90938 and was accidentally re-added, probably as a mismerge,
in a40e014e.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-09-19 12:13:12 +02:00
Peter Hutterer
44b5c9bd9f include: sync event codes with kernel 5.8
And fix the script to sync the headers up so it syncs event codes for both bsd
and linux, but only syncs input.h for linux.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-09-11 12:13:13 +10:00
Peter Hutterer
b40675c701 doc: fix doxyen complaints after fd6c9b8ca0
Fixes fd6c9b8ca0

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-09-11 12:13:04 +10:00
Peter Hutterer
cb5d56ab80 gitlab ci: run the qemu jobs on F32
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-09-11 11:04:27 +10:00
Peter Hutterer
ed71864c4c gitlab CI: update to use F32
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-09-11 10:38:54 +10:00
Rosen Penev
fb6a84a52a
[clang-tidy] do not use else after return
Found with readability-else-after-return

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-08-27 00:42:20 -07:00
Rosen Penev
a40e014eca
libevdev: sort includes alphabetically
Found with clang-tidy's llvm-include-order

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-08-27 00:29:54 -07:00
Rosen Penev
cd8bde522f libevdev: remove pointless return in void function
Found with clang-tidy's readability-redundant-control-flow

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-08-27 07:15:28 +00:00
Rosen Penev
fd6c9b8ca0 libevdev: fix inconsistent declarations
Found with clang-tidy's readability-inconsistent-declaration-parameter-name

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-08-27 07:15:28 +00:00
Niclas Zeising
1f54f82f70 Document FreeBSD quirks
Document FreeBSD quirks related to syspath.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
4194023122 tests: Add FreeBSD specific tests
Add two FreeBSD specific tests:
test_uinput_check_devnode_bsd checks that libevdev_uinput_get_devnode()
returns something sensible.  This is modelled on the Linux test
test_uinput_check_syspath_name, but uses devnode instead of syspath, since
reeBSD doesn't have sysfs.
test_uinput_check_syspath_bsd checks that libevdev_uinput_get_syspath()
always returns NULL.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
0af8c4054d tests: Disable attach debugger on FreeBSD
Disable attaching a debugger on FreeBSD, since FreeBSD lacks support for
PTRACE_ATTACH.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
8026722f86 tests: disable force feedback events on FreeBSD
FreeBSD does not support force feedack events.  Disable the test for
this event when running on FreeBSD.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
800946a673 tests: Use CLOCK_MONOTONIC_FAST on FreeBSD
FreeBSD does not have CLOCK_MONOTONIC_RAW, instead use
CLOCK_MONOTONIC_FAST.  This test checks that libevdev_set_clock_id()
fails when called with CLOCK_MONOTONIC_[RAW,FAST].

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
83e446225d uinput: Implement FreeBSD fetch_syspath_and_devnode()
Implement a FreeBSD version of fetch_syspath_and_devnode().
FreeBSD does not have sysfs, so instead fetch the device node directly
as as this matches with what is returned by the UI_GET_SYSNAME ioctl().
Since there is no sysfs, libevdev_uinput.syspath will always be set to NULL.

If the ioctl fail, return -1 from fetch_syspath_and_devnode(), since
there is no other way to figure out the device node path.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
153d8d0a5a uinput: Move SYS_INPUT_DIR to where it is used
Move the definition of SYS_INPUT_DIR to where it is used, instead of at
the top of the file, to make it easier to find.
Undefine it at the end of usage to avoid accidental uses.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
1bf2b41d3f tools: use basename(argv[0]) for program name
Use baename(argv[0]) to get the program name (for usage), instead of
using program_invocation_short_name, which only exists on Linux, not
FreeBSD.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
cca9093887 tools: Remove signalfd() use
Remove signalfd() use from the mouse-dpi-tool and touchpad-edge-detector
tools, in favor of using plain old signals.
FreeBSD does not have signalfd() without pulling in external libraries,
and with this change these tools can be compiled on FreeBSD.
Instead of providing two implementations, one using signalfd() and one
using signal(), just use the signal() implementation everywhere as it is
more portable.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
7ce82709aa Add FreeBSD compatible input.h and uinput.h
Add FreeBSD compatible input.h and uinput.h files.
This is done by moving the linux files to include/linux/linux, adding
the freebsd versions in include/linux/freebsd, and then changing
include/linux/[u]input.h to pull in the right one depending on which OS
we are compiling on.
Make sure that the build infrastructure in meson.build and
autoconf.ac/Makefile.am uses the correct files when building and as
dependency for targets, and ensure that make-event-names.py get the
correct files as arguments.

A similar change has been done in libinput in
61f3e3854458c556a01fb05d7abb22733fd2b7c1

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-14 17:50:56 +02:00
Niclas Zeising
db01b2d606 Don't hardcode /bin/bash
Don't hardcode /bin/bash, use /usr/bin/env bash instead, since not all
platforms install bash as /bin/bash.
FreeBSD, as an example, installs bash in /usr/local/bin/bash by default.

Signed-off-by: Niclas Zeising <zeising@daemonic.se>
2020-08-13 13:11:33 +02:00
59 changed files with 3880 additions and 2258 deletions

2
.gitignore vendored
View file

@ -31,8 +31,6 @@ mkinstalldirs
stamp-h?
# Edit Compile Debug Document Distribute
*~
*.[0-9]
*.[0-9]x
*.bak
*.bin
core

View file

@ -4,33 +4,18 @@
# #
########################################
.templates_sha: &template_sha ca99d9418390fb5faaa7f2407b94c733d7ec6a37 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
.templates_sha: &template_sha e195d80f35b45cc73668be3767b923fd76c70ed5 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
include:
# Alpine container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/alpine.yml'
# Arch container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/arch.yml'
# Centos container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/centos.yml'
# Debian container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/debian.yml'
# Fedora container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/fedora.yml'
# Ubuntu container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/ubuntu.yml'
file:
- '/templates/alpine.yml'
- '/templates/arch.yml'
- '/templates/debian.yml'
- '/templates/fedora.yml'
- '/templates/ubuntu.yml'
- '/templates/ci-fairy.yml'
stages:
- prep # rebuild the container images if there is a change
@ -42,10 +27,16 @@ stages:
- container_clean # clean up unused container images
- merge-check # check for a merge request
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
variables:
# The upstrem repository we will check for images
FDO_UPSTREAM_REPO: libevdev/libevdev
LIBEVDEV_SKIP_ROOT_TESTS: 1
GIT_DEPTH: 1
MESON_BUILDDIR: 'build dir'
@ -55,9 +46,9 @@ variables:
- _build/test/test-suite.log
- $MESON_BUILDDIR/meson-logs/
expire_in: 1 week
when: on_failure
when: always
reports:
junit: $MESON_BUILDDIR/junit-*.xml
junit: $MESON_BUILDDIR/*junit*.xml
.autotools_build:
extends:
@ -70,71 +61,57 @@ variables:
- make check
- if ! [[ -z "$MAKE_ARGS" ]]; then make $MAKE_ARGS; fi
- popd > /dev/null
variables:
LIBEVDEV_SKIP_ROOT_TESTS: 1
.meson_build:
extends:
- .default_artifacts
script:
- .gitlab-ci/meson-build.sh
- .gitlab-ci/meson-build.sh --run-test
variables:
MESON_TEST_ARGS: '--no-suite=needs-uinput'
.fedora:30:
.fedora:40:
extends: .fdo.distribution-image@fedora
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_VERSION: '30'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: '40'
.fedora:31:
.fedora:41:
extends: .fdo.distribution-image@fedora
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_VERSION: '31'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: '41'
.ubuntu:20.04:
.ubuntu:24.10:
extends: .fdo.distribution-image@ubuntu
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_VERSION: '20.04'
.ubuntu:19.10:
extends: .fdo.distribution-image@ubuntu
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_VERSION: '19.10'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: '24.10'
.debian:stable:
extends: .fdo.distribution-image@debian
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: 'stable'
.debian:sid:
extends: .fdo.distribution-image@debian
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: 'sid'
.centos:7:
extends: .fdo.distribution-image@centos
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_VERSION: '7'
.centos:8:
extends: .fdo.distribution-image@centos
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_VERSION: '8'
.arch:rolling:
extends: .fdo.distribution-image@arch
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: 'rolling'
.alpine:latest:
extends: .fdo.distribution-image@alpine
variables:
FDO_DISTRIBUTION_TAG: '2020-03-17.0'
FDO_DISTRIBUTION_TAG: '2024-11-25.0'
FDO_DISTRIBUTION_VERSION: 'latest'
@ -150,14 +127,11 @@ variables:
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
#
check-ci-script:
image: golang:alpine
extends:
- .fdo.ci-fairy
stage: prep
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
- ci-fairy generate-template
- git diff --exit-code && exit 0 || true
- ci-fairy generate-template --verify && exit 0 || true
- echo "Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify"
- exit 1
@ -166,13 +140,13 @@ check-ci-script:
#
check-commit:
image: golang:alpine
extends:
- .fdo.ci-fairy
stage: prep
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
- ci-fairy check-commits --signed-off-by --junit-xml=results.xml
- ci-fairy -vv check-commits --junit-xml=results.xml && exit 0 || true
- echo "Error checking the commit message format. Please verify"
- exit 1
except:
- master@libevdev/libevdev
variables:
@ -186,11 +160,9 @@ check-commit:
#
check-merge-request:
image: golang:alpine
extends:
- .fdo.ci-fairy
stage: merge-check
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
@ -198,11 +170,13 @@ check-merge-request:
reports:
junit: results.xml
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
.fedora.packages:
variables:
FDO_DISTRIBUTION_PACKAGES: 'git gcc gcc-c++ meson automake autoconf libtool make pkgconfig python3 check-devel valgrind binutils doxygen xz clang-analyzer'
FDO_DISTRIBUTION_PACKAGES: 'git gcc gcc-c++ meson automake autoconf libtool make pkgconfig python3 check-devel valgrind binutils doxygen xz clang-analyzer systemd-udev qemu-img qemu-system-x86-core qemu-system-aarch64-core jq python3-click python3-rich'
.ubuntu.packages:
variables:
@ -212,153 +186,48 @@ check-merge-request:
variables:
FDO_DISTRIBUTION_PACKAGES: 'git gcc g++ meson automake autoconf libtool make pkg-config python3 check valgrind binutils doxygen xz-utils'
.centos.packages:
variables:
FDO_DISTRIBUTION_PACKAGES: 'git gcc gcc-c++ automake autoconf libtool make pkgconfig python3 check-devel valgrind binutils xz'
.arch.packages:
variables:
FDO_DISTRIBUTION_PACKAGES: 'git gcc meson automake autoconf libtool make pkgconfig python3 check valgrind binutils doxygen'
FDO_DISTRIBUTION_PACKAGES: 'git gc meson automake autoconf libtool make pkgconfig python3 check valgrind binutils doxygen'
.alpine.packages:
variables:
FDO_DISTRIBUTION_PACKAGES: 'git gcc g++ meson automake autoconf libtool make pkgconfig python3 check-dev valgrind binutils doxygen xz linux-headers'
# Pulls in the qemu container from upstream or rebuilds it if missing
.fedora:30@qemu-prep:
extends:
- .fedora:30
- .fedora.packages
- .fdo.qemu-build@fedora
stage: prep
tags:
- kvm
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_TAG: qemu-2020-03-17.0
allow_failure: true
# Always rebuilds the container
.fedora:30@qemu-forced-rebuild:
extends:
- .fedora:30@qemu-prep
variables:
FDO_FORCE_REBUILD: 1
only:
- schedules
# Pulls in the qemu container from upstream or rebuilds it if missing
.fedora:31@qemu-prep:
extends:
- .fedora:31
- .fedora.packages
- .fdo.qemu-build@fedora
stage: prep
tags:
- kvm
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_TAG: qemu-2020-03-17.0
allow_failure: true
# Always rebuilds the container
.fedora:31@qemu-forced-rebuild:
extends:
- .fedora:31@qemu-prep
variables:
FDO_FORCE_REBUILD: 1
only:
- schedules
# This is the actual job
fedora:31@qemu-prep:
extends: .fedora:31@qemu-prep
fedora:31@qemu-forced-rebuild:
extends: .fedora:31@qemu-forced-rebuild
# Pulls in the container from upstream or rebuilds it if missing
fedora:30@container-prep:
fedora:40@container-prep:
extends:
- .fedora:30
- .fedora:40
- .fedora.packages
- .fdo.container-build@fedora
stage: prep
variables:
GIT_STRATEGY: none
# Always rebuilds the container
fedora:30@container-forced-rebuild:
extends:
- fedora:30@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
fedora:31@container-prep:
fedora:41@container-prep:
extends:
- .fedora:31
- .fedora:41
- .fedora.packages
- .fdo.container-build@fedora
stage: prep
variables:
GIT_STRATEGY: none
# Always rebuilds the container
fedora:31@container-forced-rebuild:
extends:
- fedora:31@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
ubuntu:20.04@container-prep:
ubuntu:24.10@container-prep:
extends:
- .ubuntu:20.04
- .ubuntu:24.10
- .ubuntu.packages
- .fdo.container-build@ubuntu
stage: prep
variables:
GIT_STRATEGY: none
# Always rebuilds the container
ubuntu:20.04@container-forced-rebuild:
extends:
- ubuntu:20.04@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
ubuntu:19.10@container-prep:
extends:
- .ubuntu:19.10
- .ubuntu.packages
- .fdo.container-build@ubuntu
stage: prep
variables:
GIT_STRATEGY: none
# Always rebuilds the container
ubuntu:19.10@container-forced-rebuild:
extends:
- ubuntu:19.10@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
debian:stable@container-prep:
@ -370,15 +239,6 @@ debian:stable@container-prep:
variables:
GIT_STRATEGY: none
# Always rebuilds the container
debian:stable@container-forced-rebuild:
extends:
- debian:stable@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
debian:sid@container-prep:
@ -390,55 +250,6 @@ debian:sid@container-prep:
variables:
GIT_STRATEGY: none
# Always rebuilds the container
debian:sid@container-forced-rebuild:
extends:
- debian:sid@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
centos:7@container-prep:
extends:
- .centos:7
- .centos.packages
- .fdo.container-build@centos
stage: prep
variables:
GIT_STRATEGY: none
# Always rebuilds the container
centos:7@container-forced-rebuild:
extends:
- centos:7@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
centos:8@container-prep:
extends:
- .centos:8
- .centos.packages
- .fdo.container-build@centos
stage: prep
variables:
GIT_STRATEGY: none
# Always rebuilds the container
centos:8@container-forced-rebuild:
extends:
- centos:8@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
arch:rolling@container-prep:
@ -450,15 +261,6 @@ arch:rolling@container-prep:
variables:
GIT_STRATEGY: none
# Always rebuilds the container
arch:rolling@container-forced-rebuild:
extends:
- arch:rolling@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
# Pulls in the container from upstream or rebuilds it if missing
alpine:latest@container-prep:
@ -470,15 +272,6 @@ alpine:latest@container-prep:
variables:
GIT_STRATEGY: none
# Always rebuilds the container
alpine:latest@container-forced-rebuild:
extends:
- alpine:latest@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
#################################################################
# #
@ -492,11 +285,9 @@ alpine:latest@container-forced-rebuild:
# the registry and will remove any that are not tagged with the provided
# $container_image:$tag
.container-clean:
extends:
- .fdo.ci-fairy
stage: container_clean
image: golang:alpine
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
# Go to your Profile, Settings, Access Tokens
# Create a personal token with 'api' scope, copy the value.
@ -511,33 +302,26 @@ alpine:latest@container-forced-rebuild:
only:
- schedules
### fedora 30
fedora:30@container-clean:
### fedora 40
fedora:40@container-clean:
extends:
- .fedora:30
- .fedora:40
- .container-clean
needs: ["fedora:30@container-prep"]
needs: ["fedora:40@container-prep"]
### fedora 31
fedora:31@container-clean:
### fedora 41
fedora:41@container-clean:
extends:
- .fedora:31
- .fedora:41
- .container-clean
needs: ["fedora:31@container-prep"]
needs: ["fedora:41@container-prep"]
### ubuntu 20.04
ubuntu:20.04@container-clean:
### ubuntu 24.10
ubuntu:24.10@container-clean:
extends:
- .ubuntu:20.04
- .ubuntu:24.10
- .container-clean
needs: ["ubuntu:20.04@container-prep"]
### ubuntu 19.10
ubuntu:19.10@container-clean:
extends:
- .ubuntu:19.10
- .container-clean
needs: ["ubuntu:19.10@container-prep"]
needs: ["ubuntu:24.10@container-prep"]
### debian stable
debian:stable@container-clean:
@ -553,20 +337,6 @@ debian:sid@container-clean:
- .container-clean
needs: ["debian:sid@container-prep"]
### centos 7
centos:7@container-clean:
extends:
- .centos:7
- .container-clean
needs: ["centos:7@container-prep"]
### centos 8
centos:8@container-clean:
extends:
- .centos:8
- .container-clean
needs: ["centos:8@container-prep"]
### arch rolling
arch:rolling@container-clean:
extends:
@ -601,68 +371,51 @@ alpine:latest@container-clean:
- .meson_build
stage: build
dependencies: []
variables:
NINJA_ARGS: "dist"
fedora:30@autotools-build:
fedora:40@autotools-build:
extends:
- .fedora:30
- .fedora:40
- .autotools-build@template
stage: autotools
needs: ['fedora:30@container-prep']
needs: ['fedora:40@container-prep']
fedora:30@meson-build:
fedora:40@meson-build:
extends:
- .fedora:30
- .fedora:40
- .meson-build@template
stage: meson
needs: ['fedora:30@container-prep']
needs: ['fedora:40@container-prep']
fedora:31@autotools-build:
fedora:41@autotools-build:
extends:
- .fedora:31
- .fedora:41
- .autotools-build@template
stage: autotools
needs: ['fedora:31@container-prep']
needs: ['fedora:41@container-prep']
fedora:31@meson-build:
fedora:41@meson-build:
extends:
- .fedora:31
- .fedora:41
- .meson-build@template
stage: meson
needs: ['fedora:31@container-prep']
needs: ['fedora:41@container-prep']
ubuntu:20.04@autotools-build:
ubuntu:24.10@autotools-build:
extends:
- .ubuntu:20.04
- .ubuntu:24.10
- .autotools-build@template
stage: autotools
needs: ['ubuntu:20.04@container-prep']
needs: ['ubuntu:24.10@container-prep']
ubuntu:20.04@meson-build:
ubuntu:24.10@meson-build:
extends:
- .ubuntu:20.04
- .ubuntu:24.10
- .meson-build@template
stage: meson
needs: ['ubuntu:20.04@container-prep']
ubuntu:19.10@autotools-build:
extends:
- .ubuntu:19.10
- .autotools-build@template
stage: autotools
needs: ['ubuntu:19.10@container-prep']
ubuntu:19.10@meson-build:
extends:
- .ubuntu:19.10
- .meson-build@template
stage: meson
needs: ['ubuntu:19.10@container-prep']
needs: ['ubuntu:24.10@container-prep']
debian:stable@autotools-build:
@ -695,28 +448,6 @@ debian:sid@meson-build:
needs: ['debian:sid@container-prep']
centos:7@autotools-build:
extends:
- .centos:7
- .autotools-build@template
stage: autotools
variables:
MAKE_ARGS: '' # disable distcheck, requires doxygen
needs: ['centos:7@container-prep']
centos:8@autotools-build:
extends:
- .centos:8
- .autotools-build@template
stage: autotools
variables:
MAKE_ARGS: '' # disable distcheck, requires doxygen
needs: ['centos:8@container-prep']
arch:rolling@autotools-build:
extends:
- .arch:rolling
@ -753,10 +484,10 @@ alpine:latest@meson-build:
# because they're supposed to fail equally on all
.fedora-custom-build@autotools-template:
extends:
- .fedora:31
- .fedora:40
- .autotools-build@template
stage: build
needs: ['fedora:31@container-prep']
needs: ['fedora:40@container-prep']
no-valgrind:autotools:
extends: .fedora-custom-build@autotools-template
@ -795,10 +526,10 @@ enable-gcov:autotools:
.fedora-custom-build@meson-template:
extends:
- .fedora:31
- .fedora:40
- .meson-build@template
stage: build
needs: ['fedora:31@container-prep']
needs: ['fedora:40@container-prep']
no-valgrind:meson:
extends: .fedora-custom-build@meson-template
@ -811,7 +542,6 @@ no-check:meson:
- dnf remove -y check check-devel
variables:
MESON_ARGS: -Dtests=disabled
SKIP_MESON_TEST: 1
# doxygen is required for dist
no-doxygen:meson:
@ -830,7 +560,6 @@ no-doxygen-check-valgrind:meson:
variables:
MESON_ARGS: -Dtests=disabled -Ddocumentation=disabled
NINJA_ARGS: ''
SKIP_MESON_TEST: 1
enable-gcov:meson:
extends: .fedora-custom-build@meson-template
@ -841,7 +570,6 @@ scan-build:meson:
extends: .fedora-custom-build@meson-template
variables:
NINJA_ARGS: 'scan-build'
SKIP_MESON_TEST: 1
static-build:meson:
extends: .fedora-custom-build@meson-template
@ -852,7 +580,7 @@ static-build:meson:
soname:
extends:
- .fedora:31
- .fedora:40
stage: build
script:
- ./autogen.sh --prefix=$PWD/prefix-autotools/
@ -861,7 +589,7 @@ soname:
- meson "$MESON_BUILDDIR" --prefix=$PWD/prefix-meson/
- ninja -C "$MESON_BUILDDIR" install
- ls -l $PWD/prefix-meson/lib64/libevdev.so.2.3.0
needs: ['fedora:31@container-prep']
needs: ['fedora:40@container-prep']
#################################################################
# #
@ -871,74 +599,54 @@ soname:
.check_tainted: &check_tainted |
# make sure the kernel is not tainted
if [[ "$(ssh localhost -p 5555 cat /proc/sys/kernel/tainted)" -gt 0 ]];
if [[ "$(/app/vmctl exec cat /proc/sys/kernel/tainted)" -gt 0 ]];
then
echo tainted kernel ;
exit 1 ;
fi
.qemu@fedora:31:
# build on the host, then run a systemd service to execute the test suite
# inside the qemu VM handled by b2c
.build-in-b2c@template:
extends:
- .fedora:31
stage: VM
image: $CI_REGISTRY_IMAGE/$FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION:qemu-$FDO_DISTRIBUTION_TAG
- .default_artifacts
tags:
- kvm
variables:
MESON_BUILDDIR: build_dir
B2C_KERNEL: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.5/bzImage
B2C_IMAGE: $FDO_DISTRIBUTION_IMAGE
B2C_COMMAND: .gitlab-ci/start-in-systemd.sh
script:
# start our vm, no args required
- /app/start_vm.sh
# first build in the host container
- .gitlab-ci/meson-build.sh --skip-test
- *check_tainted
# pull b2c
- curl -L -o /app/boot2container https://gitlab.freedesktop.org/gfx-ci/boot2container/-/raw/2ff65156ba67fa8a0c309a4fc16c5df1a88a3844/vm2c.py
- chmod +x /app/boot2container
- "scp -P 5555 -r $PWD localhost:"
- echo "CI_JOB_ID=\"$CI_JOB_ID\"" > sshenv
- echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
- echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
- echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS\"" >> sshenv
- echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
- "scp -P 5555 sshenv localhost:~/$CI_PROJECT_NAME/.meson_environment"
- ssh localhost -p 5555 "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
# no matter the results of the tests, we want to fetch the logs
- scp -P 5555 -r localhost:$CI_PROJECT_NAME/"$MESON_BUILDDIR" .
- *check_tainted
- ssh localhost -p 5555 halt || true
- sleep 2
- pkill qemu || true
- if [[ ! -e .success ]] ;
then
exit 1 ;
fi
artifacts:
name: "qemu-meson-logs-$CI_JOB_NAME"
when: always
expire_in: 1 week
paths:
- $MESON_BUILDDIR/meson-logs
- console.out
reports:
junit: $MESON_BUILDDIR/junit-*.xml
retry:
max: 2
when: script_failure
needs: ['fedora:31@qemu-prep']
# runs the test suite only
- /app/boot2container
qemu:meson:
extends: .qemu@fedora:31
stage: VM
extends:
- .fdo.distribution-image@fedora
- .fedora:41
- .build-in-b2c@template
needs:
- "fedora:41@container-prep"
qemu:meson:valgrind:
extends: .qemu@fedora:31
extends:
- qemu:meson
variables:
MESON_TEST_ARGS: '--setup=valgrind'
meson-from-tarball:
extends:
- .fedora:31
- .fedora:41
stage: tarballs
script:
- export INSTALLDIR="$PWD/_inst"
@ -946,26 +654,26 @@ meson-from-tarball:
- pushd _build > /dev/null
- ../autogen.sh --disable-silent-rules $CONFIGURE_FLAGS
- make
- make distcheck
- make dist
- popd > /dev/null
- mkdir -p _tarball_dir
- tar xf _build/libevdev-*.tar.xz -C _tarball_dir
- pushd _tarball_dir/libevdev-*/ > /dev/null
- meson "$MESON_BUILDDIR" --prefix="$INSTALLDIR"
- ninja -C "$MESON_BUILDDIR" test
- meson test -C "$MESON_BUILDDIR" --no-suite="needs-uinput"
- ninja -C "$MESON_BUILDDIR" install
- popd > /dev/null
- ls -lR $INSTALLDIR
needs: ['fedora:31@container-prep']
needs: ['fedora:41@container-prep']
autotools-from-tarball:
extends:
- .fedora:31
- .fedora:41
stage: tarballs
script:
- export INSTALLDIR="$PWD/_inst"
- meson "$MESON_BUILDDIR"
- ninja -C "$MESON_BUILDDIR" dist
- meson dist -C "$MESON_BUILDDIR" --no-tests
- mkdir -p _tarball_dir
- tar xf "$MESON_BUILDDIR"/meson-dist/libevdev-*.xz -C _tarball_dir
- pushd _tarball_dir/libevdev-*/ > /dev/null
@ -978,4 +686,7 @@ autotools-from-tarball:
- popd > /dev/null
- popd > /dev/null
- ls -lR $INSTALLDIR
needs: ['fedora:31@container-prep']
variables:
LIBEVDEV_SKIP_ROOT_TESTS: 1
needs: ['fedora:41@container-prep']

View file

@ -6,15 +6,16 @@
# #
########################################
.templates_sha: &template_sha ca99d9418390fb5faaa7f2407b94c733d7ec6a37 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
.templates_sha: &template_sha e195d80f35b45cc73668be3767b923fd76c70ed5 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
include:
{% for distribution in distributions|map(attribute='name')|unique()|sort() %}
# {{ distribution.capitalize() }} container builder template
- project: 'freedesktop/ci-templates'
ref: *template_sha
file: '/templates/{{distribution}}.yml'
file:
{% for distribution in distributions|map(attribute='name')|unique()|sort() %}
- '/templates/{{distribution}}.yml'
{% endfor %}
- '/templates/ci-fairy.yml'
stages:
- prep # rebuild the container images if there is a change
@ -26,10 +27,16 @@ stages:
- container_clean # clean up unused container images
- merge-check # check for a merge request
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
variables:
# The upstrem repository we will check for images
FDO_UPSTREAM_REPO: libevdev/libevdev
LIBEVDEV_SKIP_ROOT_TESTS: 1
GIT_DEPTH: 1
MESON_BUILDDIR: 'build dir'
@ -39,9 +46,9 @@ variables:
- _build/test/test-suite.log
- $MESON_BUILDDIR/meson-logs/
expire_in: 1 week
when: on_failure
when: always
reports:
junit: $MESON_BUILDDIR/junit-*.xml
junit: $MESON_BUILDDIR/*junit*.xml
.autotools_build:
extends:
@ -54,12 +61,16 @@ variables:
- make check
- if ! [[ -z "$MAKE_ARGS" ]]; then make $MAKE_ARGS; fi
- popd > /dev/null
variables:
LIBEVDEV_SKIP_ROOT_TESTS: 1
.meson_build:
extends:
- .default_artifacts
script:
- .gitlab-ci/meson-build.sh
- .gitlab-ci/meson-build.sh --run-test
variables:
MESON_TEST_ARGS: '--no-suite=needs-uinput'
{# Generate templates for every distribution/version combination we want, any
job can then just extends: .name:version and the images will sort
@ -87,14 +98,11 @@ variables:
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
#
check-ci-script:
image: golang:alpine
extends:
- .fdo.ci-fairy
stage: prep
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
- ci-fairy generate-template
- git diff --exit-code && exit 0 || true
- ci-fairy generate-template --verify && exit 0 || true
- echo "Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify"
- exit 1
@ -103,13 +111,13 @@ check-ci-script:
#
check-commit:
image: golang:alpine
extends:
- .fdo.ci-fairy
stage: prep
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
- ci-fairy check-commits --signed-off-by --junit-xml=results.xml
- ci-fairy -vv check-commits --junit-xml=results.xml && exit 0 || true
- echo "Error checking the commit message format. Please verify"
- exit 1
except:
- master@libevdev/libevdev
variables:
@ -123,11 +131,9 @@ check-commit:
#
check-merge-request:
image: golang:alpine
extends:
- .fdo.ci-fairy
stage: merge-check
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
artifacts:
@ -135,6 +141,8 @@ check-merge-request:
reports:
junit: results.xml
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
{% for distro in distributions %}
@ -144,43 +152,6 @@ check-merge-request:
{% endfor %}
{% for distro in distributions %}
{% if distro.want_qemu %}
{% for version in distro.versions %}
# Pulls in the qemu container from upstream or rebuilds it if missing
.{{ distro.name }}:{{ version }}@qemu-prep:
extends:
- .{{ distro.name }}:{{ version }}
- .{{ distro.name}}.packages
- .fdo.qemu-build@fedora
stage: prep
tags:
- kvm
variables:
GIT_STRATEGY: none
FDO_DISTRIBUTION_TAG: qemu-{{ distro.tag }}
allow_failure: true
# Always rebuilds the container
.{{ distro.name }}:{{ version }}@qemu-forced-rebuild:
extends:
- .{{ distro.name }}:{{ version }}@qemu-prep
variables:
FDO_FORCE_REBUILD: 1
only:
- schedules
{% endfor %}
{% endif %}
{% endfor %}
# This is the actual job
fedora:31@qemu-prep:
extends: .fedora:31@qemu-prep
fedora:31@qemu-forced-rebuild:
extends: .fedora:31@qemu-forced-rebuild
{% for distro in distributions %}
{% for version in distro.versions %}
@ -194,15 +165,6 @@ fedora:31@qemu-forced-rebuild:
variables:
GIT_STRATEGY: none
# Always rebuilds the container
{{ distro.name }}:{{ version }}@container-forced-rebuild:
extends:
- {{ distro.name }}:{{ version }}@container-prep
only:
- schedules
variables:
FDO_FORCE_REBUILD: 1
{% endfor %}
{% endfor %}
@ -218,11 +180,9 @@ fedora:31@qemu-forced-rebuild:
# the registry and will remove any that are not tagged with the provided
# $container_image:$tag
.container-clean:
extends:
- .fdo.ci-fairy
stage: container_clean
image: golang:alpine
before_script:
- apk add python3 py-pip git
- pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
script:
# Go to your Profile, Settings, Access Tokens
# Create a personal token with 'api' scope, copy the value.
@ -268,8 +228,6 @@ fedora:31@qemu-forced-rebuild:
- .meson_build
stage: build
dependencies: []
variables:
NINJA_ARGS: "dist"
{% for distro in distributions %}
{% for version in distro.versions %}
@ -311,12 +269,13 @@ fedora:31@qemu-forced-rebuild:
#
# We only run the build option combinations on one image
# because they're supposed to fail equally on all
{% set custom_build_distro = distributions|selectattr("name", "equalto", "fedora")|first() %}
.fedora-custom-build@autotools-template:
extends:
- .fedora:31
- .{{custom_build_distro.name}}:{{custom_build_distro.versions|first()}}
- .autotools-build@template
stage: build
needs: ['fedora:31@container-prep']
needs: ['{{custom_build_distro.name}}:{{custom_build_distro.versions|first()}}@container-prep']
no-valgrind:autotools:
extends: .fedora-custom-build@autotools-template
@ -355,10 +314,10 @@ enable-gcov:autotools:
.fedora-custom-build@meson-template:
extends:
- .fedora:31
- .{{custom_build_distro.name}}:{{custom_build_distro.versions|first()}}
- .meson-build@template
stage: build
needs: ['fedora:31@container-prep']
needs: ['{{custom_build_distro.name}}:{{custom_build_distro.versions|first()}}@container-prep']
no-valgrind:meson:
extends: .fedora-custom-build@meson-template
@ -371,7 +330,6 @@ no-check:meson:
- dnf remove -y check check-devel
variables:
MESON_ARGS: -Dtests=disabled
SKIP_MESON_TEST: 1
# doxygen is required for dist
no-doxygen:meson:
@ -390,7 +348,6 @@ no-doxygen-check-valgrind:meson:
variables:
MESON_ARGS: -Dtests=disabled -Ddocumentation=disabled
NINJA_ARGS: ''
SKIP_MESON_TEST: 1
enable-gcov:meson:
extends: .fedora-custom-build@meson-template
@ -401,7 +358,6 @@ scan-build:meson:
extends: .fedora-custom-build@meson-template
variables:
NINJA_ARGS: 'scan-build'
SKIP_MESON_TEST: 1
static-build:meson:
extends: .fedora-custom-build@meson-template
@ -412,7 +368,7 @@ static-build:meson:
soname:
extends:
- .fedora:31
- .{{custom_build_distro.name}}:{{custom_build_distro.versions|first()}}
stage: build
script:
- ./autogen.sh --prefix=$PWD/prefix-autotools/
@ -421,7 +377,7 @@ soname:
- meson "$MESON_BUILDDIR" --prefix=$PWD/prefix-meson/
- ninja -C "$MESON_BUILDDIR" install
- ls -l $PWD/prefix-meson/lib64/libevdev.so.2.3.0
needs: ['fedora:31@container-prep']
needs: ['{{custom_build_distro.name}}:{{custom_build_distro.versions|first()}}@container-prep']
#################################################################
# #
@ -431,74 +387,59 @@ soname:
.check_tainted: &check_tainted |
# make sure the kernel is not tainted
if [[ "$(ssh localhost -p 5555 cat /proc/sys/kernel/tainted)" -gt 0 ]];
if [[ "$(/app/vmctl exec cat /proc/sys/kernel/tainted)" -gt 0 ]];
then
echo tainted kernel ;
exit 1 ;
fi
.qemu@fedora:31:
# build on the host, then run a systemd service to execute the test suite
# inside the qemu VM handled by b2c
.build-in-b2c@template:
extends:
- .fedora:31
stage: VM
image: $CI_REGISTRY_IMAGE/$FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION:qemu-$FDO_DISTRIBUTION_TAG
- .default_artifacts
tags:
- kvm
variables:
MESON_BUILDDIR: build_dir
B2C_KERNEL: {{ b2c.kernel }}
B2C_IMAGE: $FDO_DISTRIBUTION_IMAGE
B2C_COMMAND: .gitlab-ci/start-in-systemd.sh
script:
# start our vm, no args required
- /app/start_vm.sh
# first build in the host container
- .gitlab-ci/meson-build.sh --skip-test
- *check_tainted
# pull b2c
- curl -L -o /app/boot2container https://gitlab.freedesktop.org/gfx-ci/boot2container/-/raw/{{b2c.version}}/vm2c.py
- chmod +x /app/boot2container
- "scp -P 5555 -r $PWD localhost:"
- echo "CI_JOB_ID=\"$CI_JOB_ID\"" > sshenv
- echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
- echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
- echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS\"" >> sshenv
- echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
- "scp -P 5555 sshenv localhost:~/$CI_PROJECT_NAME/.meson_environment"
- ssh localhost -p 5555 "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
# no matter the results of the tests, we want to fetch the logs
- scp -P 5555 -r localhost:$CI_PROJECT_NAME/"$MESON_BUILDDIR" .
- *check_tainted
- ssh localhost -p 5555 halt || true
- sleep 2
- pkill qemu || true
- if [[ ! -e .success ]] ;
then
exit 1 ;
fi
artifacts:
name: "qemu-meson-logs-$CI_JOB_NAME"
when: always
expire_in: 1 week
paths:
- $MESON_BUILDDIR/meson-logs
- console.out
reports:
junit: $MESON_BUILDDIR/junit-*.xml
retry:
max: 2
when: script_failure
needs: ['fedora:31@qemu-prep']
# runs the test suite only
- /app/boot2container
{% for distro in distributions if distro.use_for_qemu_tests %}
{% set version = "{}".format(distro.versions|last()) %}
qemu:meson:
extends: .qemu@fedora:31
stage: VM
extends:
- .fdo.distribution-image@{{distro.name}}
- .{{distro.name}}:{{version}}
- .build-in-b2c@template
needs:
- "{{distro.name}}:{{version}}@container-prep"
qemu:meson:valgrind:
extends: .qemu@fedora:31
extends:
- qemu:meson
variables:
MESON_TEST_ARGS: '--setup=valgrind'
{% endfor %}
{% for distro in distributions if distro.use_for_tarball_tests %}
{% set version = "{}".format(distro.versions|last()) %}
meson-from-tarball:
extends:
- .fedora:31
- .{{distro.name}}:{{version}}
stage: tarballs
script:
- export INSTALLDIR="$PWD/_inst"
@ -506,26 +447,26 @@ meson-from-tarball:
- pushd _build > /dev/null
- ../autogen.sh --disable-silent-rules $CONFIGURE_FLAGS
- make
- make distcheck
- make dist
- popd > /dev/null
- mkdir -p _tarball_dir
- tar xf _build/libevdev-*.tar.xz -C _tarball_dir
- pushd _tarball_dir/libevdev-*/ > /dev/null
- meson "$MESON_BUILDDIR" --prefix="$INSTALLDIR"
- ninja -C "$MESON_BUILDDIR" test
- meson test -C "$MESON_BUILDDIR" --no-suite="needs-uinput"
- ninja -C "$MESON_BUILDDIR" install
- popd > /dev/null
- ls -lR $INSTALLDIR
needs: ['fedora:31@container-prep']
needs: ['{{distro.name}}:{{version}}@container-prep']
autotools-from-tarball:
extends:
- .fedora:31
- .{{distro.name}}:{{version}}
stage: tarballs
script:
- export INSTALLDIR="$PWD/_inst"
- meson "$MESON_BUILDDIR"
- ninja -C "$MESON_BUILDDIR" dist
- meson dist -C "$MESON_BUILDDIR" --no-tests
- mkdir -p _tarball_dir
- tar xf "$MESON_BUILDDIR"/meson-dist/libevdev-*.xz -C _tarball_dir
- pushd _tarball_dir/libevdev-*/ > /dev/null
@ -538,4 +479,8 @@ autotools-from-tarball:
- popd > /dev/null
- popd > /dev/null
- ls -lR $INSTALLDIR
needs: ['fedora:31@container-prep']
variables:
LIBEVDEV_SKIP_ROOT_TESTS: 1
needs: ['{{distro.name}}:{{version}}@container-prep']
{% endfor %}

View file

@ -3,14 +3,17 @@
#
# We're happy to rebuild all containers when one changes.
.default_tag: &default_tag '2020-03-17.0'
.default_tag: &default_tag '2024-11-25.0'
distributions:
- name: fedora
tag: *default_tag
use_for_tarball_tests: true
# only one distro for qemu tests
use_for_qemu_tests: true
versions:
- '30'
- '31'
- '40'
- '41'
packages:
- git
- gcc
@ -28,12 +31,18 @@ distributions:
- doxygen
- xz
- clang-analyzer
want_qemu: true
# below packages are for the qemu runs, so optional
- systemd-udev
- qemu-img
- qemu-system-x86-core
- qemu-system-aarch64-core
- jq
- python3-click
- python3-rich
- name: ubuntu
tag: *default_tag
versions:
- '20.04'
- '19.10'
- '24.10'
packages:
- git
- gcc
@ -71,37 +80,13 @@ distributions:
- binutils
- doxygen
- xz-utils
- name: centos
tag: *default_tag
versions:
- '7'
- '8'
packages:
- git
- gcc
- gcc-c++
- automake
- autoconf
- libtool
- make
- pkgconfig
- python3
- check-devel
- valgrind
- binutils
- xz
build:
meson: False
extra_variables:
# note: the variable value includes the comment because we want that in the gitlab-ci file
MAKE_ARGS: "'' # disable distcheck, requires doxygen"
- name: arch
tag: *default_tag
versions:
- 'rolling'
packages:
- git
- gcc
- gc
- meson
- automake
- autoconf
@ -134,3 +119,7 @@ distributions:
- doxygen
- xz
- linux-headers
b2c:
version: 2ff65156ba67fa8a0c309a4fc16c5df1a88a3844
kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.5/bzImage

View file

@ -1,9 +1,43 @@
#!/bin/bash
#!/usr/bin/env bash
#
# This script is sourced from here:
# https://gitlab.freedesktop.org/whot/meson-helper
#
# SPDX-License-Identifier: MIT
set -x
if [[ -f .meson_environment ]]; then
. .meson_environment
fi
# If test args are set, we assume we want to run the tests
MESON_RUN_TEST="$MESON_TEST_ARGS"
while [[ $# -gt 0 ]]; do
case $1 in
--skip-setup)
shift
MESON_SKIP_SETUP="1"
;;
--skip-build)
shift
MESON_SKIP_BUILD="1"
;;
--skip-test)
shift
MESON_RUN_TEST=""
;;
--run-test)
shift
MESON_RUN_TEST="1"
;;
*)
echo "Unknow commandline argument $1"
exit 1
;;
esac
done
if [[ -z "$MESON_BUILDDIR" ]]; then
echo "\$MESON_BUILDDIR undefined."
exit 1
@ -13,43 +47,42 @@ fi
# run and debug locally.
if [[ -z "$CI_JOB_ID" ]] || [[ -z "$CI_JOB_NAME" ]]; then
echo "Missing \$CI_JOB_ID or \$CI_JOB_NAME".
CI_PROJECT_NAME=$(basename "$PWD")
CI_JOB_ID=$(date +%s)
CI_JOB_NAME='libevdev-job-local'
CI_JOB_NAME="$CI_PROJECT_NAME-job-local"
echo "Simulating gitlab environment: "
echo " CI_JOB_ID=$CI_JOB_ID"
echo " CI_JOB_NAME=$CI_JOB_NAME"
fi
if [[ -n "$FDO_CI_CONCURRENT" ]]; then
jobcount="-j$FDO_CI_CONCURRENT"
export MESON_TESTTHREADS="$FDO_CI_CONCURRENT"
fi
echo "*************************************************"
echo "builddir: $MESON_BUILDDIR"
echo "meson args: $MESON_ARGS"
echo "ninja args: $NINJA_ARGS"
echo "meson test args: $MESON_TEST_ARGS"
echo "job count: ${jobcount-0}"
echo "*************************************************"
set -e
rm -rf "$MESON_BUILDDIR"
meson "$MESON_BUILDDIR" $MESON_ARGS
if [[ -z "$MESON_SKIP_SETUP" ]]; then
rm -rf "$MESON_BUILDDIR"
meson setup "$MESON_BUILDDIR" $MESON_ARGS
fi
meson configure "$MESON_BUILDDIR"
ninja -C "$MESON_BUILDDIR" $NINJA_ARGS
if [[ ! -z "$SKIP_MESON_TEST" ]]; then
echo "Skipping meson test"
exit 0
if [[ -z "$MESON_SKIP_BUILD" ]]; then
if [[ -n "$NINJA_ARGS" ]]; then
ninja_args="--ninja-args $NINJA_ARGS"
fi
meson compile -v -C "$MESON_BUILDDIR" $jobcount $ninja_args
fi
# we still want to generate the reports, even if meson test fails
set +e
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
exit_code=$?
set -e
# We need the glob for the testlog so that it picks up those suffixed by a
# suite (e.g. testlog-valgrind.json)
./.gitlab-ci/meson-junit-report.py \
--output="$MESON_BUILDDIR/junit-$CI_JOB_NAME-report.xml" \
"$MESON_BUILDDIR"/meson-logs/testlog*.json; \
exit $exit_code
if [[ -n "$MESON_RUN_TEST" ]]; then
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
fi

View file

@ -1,128 +0,0 @@
#!/usr/bin/env python3
#
# meson-junit-report.py: Turns a Meson test log into a JUnit report
#
# Copyright 2019 GNOME Foundation
#
# SPDX-License-Identifier: LGPL-2.1-or-later
import argparse
import datetime
import json
import os
import sys
import xml.etree.ElementTree as ET
default_name = os.getenv('CI_PROJECT_NAME', 'unknown')
default_job_id = os.getenv('CI_JOB_ID', 'Unknown')
default_branch = os.getenv('CI_COMMIT_REF_NAME', 'master')
aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
aparser.add_argument('--project-name', metavar='NAME',
help='The project name (default: $CI_PROJECT_NAME)',
default=default_name)
aparser.add_argument('--job-id', metavar='ID',
help='The job ID for the report (default: $CI_JOB_ID)',
default=default_job_id)
aparser.add_argument('--branch', metavar='NAME',
help='Branch of the project being tested',
default=default_branch)
aparser.add_argument('--output', metavar='FILE',
help='The output file, stdout by default',
type=argparse.FileType('w', encoding='UTF-8'),
default=sys.stdout)
aparser.add_argument('infile', metavar='FILE',
help='The input testlog.json, stdin by default',
type=argparse.FileType('r', encoding='UTF-8'),
default=sys.stdin)
args = aparser.parse_args()
outfile = args.output
testsuites = ET.Element('testsuites')
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
testsuites.set('package', args.project_name)
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
suites = {}
for line in args.infile:
data = json.loads(line)
(full_suite, unit_name) = data['name'].split(' / ')
(project_name, suite_name) = full_suite.split(':')
duration = data['duration']
return_code = data['returncode']
log = data['stdout']
unit = {
'suite': suite_name,
'name': unit_name,
'duration': duration,
'returncode': return_code,
'stdout': log,
}
units = suites.setdefault(suite_name, [])
units.append(unit)
for name, units in suites.items():
print('Processing suite {} (units: {})'.format(name, len(units)))
def if_failed(unit):
if not if_skipped(unit) and unit['returncode'] != 0:
return True
return False
def if_skipped(unit):
if unit['returncode'] == 77:
return True
return False
def if_succeded(unit):
if unit['returncode'] == 0:
return True
return False
successes = list(filter(if_succeded, units))
failures = list(filter(if_failed, units))
skips = list(filter(if_skipped, units))
print(' - {}: {} pass, {} fail, {} skipped'.format(name, len(successes), len(failures), len(skips)))
testsuite = ET.SubElement(testsuites, 'testsuite')
testsuite.set('name', '{}/{}'.format(args.project_name, name))
testsuite.set('tests', str(len(units)))
testsuite.set('errors', str(len(failures)))
testsuite.set('skipped', str(len(skips)))
testsuite.set('failures', str(len(failures)))
for unit in successes:
testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration']))
for unit in skips:
testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration']))
skip = ET.SubElement(testcase, 'skipped')
for unit in failures:
testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration']))
failure = ET.SubElement(testcase, 'failure')
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
failure.set('name', unit['name'])
failure.set('type', 'error')
failure.text = unit['stdout']
output = ET.tostring(testsuites, encoding='unicode')
outfile.write(output)

69
.gitlab-ci/start-in-systemd.sh Executable file
View file

@ -0,0 +1,69 @@
#!/usr/bin/env bash
set -x
systemd_target=basic.target
post_command="/usr/bin/systemctl exit \$EXIT_STATUS"
while [[ $# -gt 0 ]]; do
case $1 in
--debug-mode)
shift
systemd_target=multi-user.target
post_command="echo you can now log in as root (no password) and then turn off by running \'/usr/bin/systemctl exit \$EXIT_STATUS\'"
;;
*)
echo "Unknow commandline argument $1"
exit 1
;;
esac
done
WORKDIR=${FDO_DISTRIBUTION_WORKINGDIR:-$PWD}
B2C_WORKDIR=${FDO_B2C_WORKDIR:-/app}
# remove root password for debugging
sed -i 's/root:!locked::/root:::/' /etc/shadow
# create a libevdev test suite service
cat <<EOF > /etc/systemd/system/libevdev-testsuite.service
[Unit]
Description=libevdev test suite
After=$systemd_target
[Service]
Type=simple
StandardOutput=journal+console
EnvironmentFile=$B2C_WORKDIR/.b2c_env
WorkingDirectory=$WORKDIR
ExecStart=$WORKDIR/.gitlab-ci/meson-build.sh --skip-setup --skip-build --run-test
# exit the container on termination
ExecStopPost=$post_command
[Install]
WantedBy=default.target
EOF
cat /etc/systemd/system/libevdev-testsuite.service
# enable the service
systemctl enable libevdev-testsuite.service
# disable some services we don't need in the CI
systemctl mask network-online.target
systemctl mask network-pre.target
systemctl mask timers.target
systemctl mask dnf-makecache.timer
systemctl mask systemd-logind.service
systemctl mask rpmdb-migrate.service
systemctl mask systemd-network-generator.service
systemctl mask cryptsetup-pre.target
systemctl mask cryptsetup.target
#change default target
systemctl set-default $systemd_target
# start the system
exec /usr/sbin/init

View file

@ -141,7 +141,7 @@ A [good commit message](http://who-t.blogspot.com/2009/12/on-commit-messages.htm
answer three questions:
- Why is it necessary? It may fix a bug, it may add a feature, it may
improve performance, reliabilty, stability, or just be a change for the
improve performance, reliability, stability, or just be a change for the
sake of correctness.
- How does it address the issue? For short obvious patches this part can be
omitted, but it should be a high level description of what the approach

35
COPYING
View file

@ -1,23 +1,26 @@
SPDX-License-Identifier: MIT
Copyright © 2013 Red Hat, Inc.
Copyright © 2013 David Herrmann <dh.herrmann@gmail.com>
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.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
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.
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
The following license is from a Linux kernel header file and there is no GPL
code this package links to.

View file

@ -7,9 +7,6 @@ interface to the callers, thus avoiding erroneous ioctls, etc.
https://gitlab.freedesktop.org/libevdev/libevdev.git
The eventual goal is that libevdev wraps all ioctls available to evdev
devices, thus making direct access unnecessary.
Go here for the API documentation:
http://www.freedesktop.org/software/libevdev/doc/latest/

View file

@ -1,29 +1,14 @@
# SPDX-License-Identifier: MIT
#
# Copyright © 2013 Red Hat, Inc.
#
# 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.
AC_PREREQ([2.62])
# change meson version too
AC_INIT([libevdev],
[1.9.1],
[https://bugs.freedesktop.org/enter_bug.cgi?product=libevdev],
[1.13.6],
[https://gitlab.freedesktop.org/libevdev/libevdev/issues/],
[libevdev],
[http://freedesktop.org/wiki/Software/libevdev/])
@ -61,16 +46,22 @@ if test "x$lt_cv_prog_gnu_ld" = "xyes"; then
fi
AC_SUBST([GNU_LD_FLAGS], $with_ldflags)
case "${host_os}" in
freebsd*)
AC_SUBST([OS], [freebsd])
;;
*)
AC_SUBST([OS], [linux])
;;
esac
AC_CHECK_LIB([m], [round])
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(CHECK, [check >= 0.9.9], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
if test "x$HAVE_CHECK" = "xyes"; then
AC_PATH_PROG(VALGRIND, [valgrind])
else
if test "x$HAVE_CHECK" != "xyes"; then
AC_MSG_WARN([check not found - skipping building unit tests])
fi
AM_CONDITIONAL(HAVE_VALGRIND, [test "x$VALGRIND" != "x"])
AM_CONDITIONAL(ENABLE_RUNTIME_TESTS, [test "x$HAVE_CHECK" = "xyes"])
AM_CONDITIONAL(ENABLE_STATIC_LINK_TEST, [test "x$enable_static" = "xyes"])

View file

@ -27,6 +27,7 @@
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
#define INPUT_PROP_MAX 0x1f
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
@ -278,7 +279,8 @@
#define KEY_PAUSECD 201
#define KEY_PROG3 202
#define KEY_PROG4 203
#define KEY_DASHBOARD 204 /* AL Dashboard */
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
#define KEY_SUSPEND 205
#define KEY_CLOSE 206 /* AC Close */
#define KEY_PLAY 207
@ -515,6 +517,10 @@
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
#define KEY_IMAGES 0x1ba /* AL Image Browser */
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
#define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1
@ -542,6 +548,7 @@
#define KEY_FN_F 0x1e2
#define KEY_FN_S 0x1e3
#define KEY_FN_B 0x1e4
#define KEY_FN_RIGHT_SHIFT 0x1e5
#define KEY_BRL_DOT1 0x1f1
#define KEY_BRL_DOT2 0x1f2
@ -595,8 +602,14 @@
#define BTN_DPAD_LEFT 0x222
#define BTN_DPAD_RIGHT 0x223
#define BTN_GRIPL 0x224
#define BTN_GRIPR 0x225
#define BTN_GRIPL2 0x226
#define BTN_GRIPR2 0x227
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
@ -607,10 +620,29 @@
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
/*
* Keycodes for hotkeys toggling the electronic privacy screen found on some
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
* screen itself then the state should be reported through drm connecter props:
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
* Except when implementing the drm connecter properties API is not possible
* because e.g. the firmware does not allow querying the presence and/or status
* of the eprivacy screen at boot.
*/
#define KEY_EPRIVACY_SCREEN_ON 0x252
#define KEY_EPRIVACY_SCREEN_OFF 0x253
#define KEY_KBDINPUTASSIST_PREV 0x260
#define KEY_KBDINPUTASSIST_NEXT 0x261
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
@ -655,6 +687,27 @@
/* Select an area of screen to be copied */
#define KEY_SELECTIVE_SCREENSHOT 0x27a
/* Move the focus to the next or previous user controllable element within a UI container */
#define KEY_NEXT_ELEMENT 0x27b
#define KEY_PREVIOUS_ELEMENT 0x27c
/* Toggle Autopilot engagement */
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
/* Shortcut Keys */
#define KEY_MARK_WAYPOINT 0x27e
#define KEY_SOS 0x27f
#define KEY_NAV_CHART 0x280
#define KEY_FISHING_CHART 0x281
#define KEY_SINGLE_RANGE_RADAR 0x282
#define KEY_DUAL_RANGE_RADAR 0x283
#define KEY_RADAR_OVERLAY 0x284
#define KEY_TRADITIONAL_SONAR 0x285
#define KEY_CLEARVU_SONAR 0x286
#define KEY_SIDEVU_SONAR 0x287
#define KEY_NAV_INFO 0x288
#define KEY_BRIGHTNESS_MENU 0x289
/*
* Some keyboards have keys which do not have a defined meaning, these keys
* are intended to be programmed / bound to macros by the user. For most
@ -730,6 +783,9 @@
#define KEY_KBD_LCD_MENU4 0x2bb
#define KEY_KBD_LCD_MENU5 0x2bc
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
#define KEY_PERFORMANCE 0x2bd
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
@ -834,6 +890,7 @@
#define ABS_TOOL_WIDTH 0x1c
#define ABS_VOLUME 0x20
#define ABS_PROFILE 0x21
#define ABS_MISC 0x28
@ -888,7 +945,9 @@
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
#define SW_MAX 0x0f
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
#define SW_MAX 0x11
#define SW_CNT (SW_MAX+1)
/*

View file

@ -0,0 +1,513 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef _UAPI_INPUT_H
#define _UAPI_INPUT_H
#ifndef __KERNEL__
#include <sys/time.h>
#include <sys/ioccom.h>
#include <sys/types.h>
#endif
#include "input-event-codes.h"
/*
* The event structure itself
* Note that __USE_TIME_BITS64 is defined by libc based on
* application's request to use 64 bit time_t.
*/
struct input_event {
#if 1 /* (__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL__) */
struct timeval time;
#define input_event_sec time.tv_sec
#define input_event_usec time.tv_usec
#else
__kernel_ulong_t __sec;
#if defined(__sparc__) && defined(__arch64__)
unsigned int __usec;
unsigned int __pad;
#else
__kernel_ulong_t __usec;
#endif
#define input_event_sec __sec
#define input_event_usec __usec
#endif
uint16_t type;
uint16_t code;
int32_t value;
};
/*
* Protocol version.
*/
#define EV_VERSION 0x010001
/*
* IOCTLs (0x00 - 0x7f)
*/
struct input_id {
uint16_t bustype;
uint16_t vendor;
uint16_t product;
uint16_t version;
};
/**
* struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
* @value: latest reported value for the axis.
* @minimum: specifies minimum value for the axis.
* @maximum: specifies maximum value for the axis.
* @fuzz: specifies fuzz value that is used to filter noise from
* the event stream.
* @flat: values that are within this value will be discarded by
* joydev interface and reported as 0 instead.
* @resolution: specifies resolution for the values reported for
* the axis.
*
* Note that input core does not clamp reported values to the
* [minimum, maximum] limits, such task is left to userspace.
*
* The default resolution for main axes (ABS_X, ABS_Y, ABS_Z)
* is reported in units per millimeter (units/mm), resolution
* for rotational axes (ABS_RX, ABS_RY, ABS_RZ) is reported
* in units per radian.
* When INPUT_PROP_ACCELEROMETER is set the resolution changes.
* The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in
* in units per g (units/g) and in units per degree per second
* (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ).
*/
struct input_absinfo {
int32_t value;
int32_t minimum;
int32_t maximum;
int32_t fuzz;
int32_t flat;
int32_t resolution;
};
/**
* struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls
* @scancode: scancode represented in machine-endian form.
* @len: length of the scancode that resides in @scancode buffer.
* @index: index in the keymap, may be used instead of scancode
* @flags: allows to specify how kernel should handle the request. For
* example, setting INPUT_KEYMAP_BY_INDEX flag indicates that kernel
* should perform lookup in keymap by @index instead of @scancode
* @keycode: key code assigned to this scancode
*
* The structure is used to retrieve and modify keymap data. Users have
* option of performing lookup either by @scancode itself or by @index
* in keymap entry. EVIOCGKEYCODE will also return scancode or index
* (depending on which element was used to perform lookup).
*/
struct input_keymap_entry {
#define INPUT_KEYMAP_BY_INDEX (1 << 0)
uint8_t flags;
uint8_t len;
uint16_t index;
uint32_t keycode;
uint8_t scancode[32];
};
struct input_mask {
uint32_t type;
uint32_t codes_size;
uint64_t codes_ptr;
};
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
#define EVIOCGKEYCODE _IOWR('E', 0x04, unsigned int[2]) /* get keycode */
#define EVIOCGKEYCODE_V2 _IOWR('E', 0x04, struct input_keymap_entry)
#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
#define EVIOCGNAME(len) _IOC(IOC_OUT, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(IOC_OUT, 'E', 0x07, len) /* get physical location */
#define EVIOCGUNIQ(len) _IOC(IOC_OUT, 'E', 0x08, len) /* get unique identifier */
#define EVIOCGPROP(len) _IOC(IOC_OUT, 'E', 0x09, len) /* get device properties */
/**
* EVIOCGMTSLOTS(len) - get MT slot values
* @len: size of the data buffer in bytes
*
* The ioctl buffer argument should be binary equivalent to
*
* struct input_mt_request_layout {
* uint32_t code;
* int32_t values[num_slots];
* };
*
* where num_slots is the (arbitrary) number of MT slots to extract.
*
* The ioctl size argument (len) is the size of the buffer, which
* should satisfy len = (num_slots + 1) * sizeof(int32_t). If len is
* too small to fit all available slots, the first num_slots are
* returned.
*
* Before the call, code is set to the wanted ABS_MT event type. On
* return, values[] is filled with the slot values for the specified
* ABS_MT code.
*
* If the request code is not an ABS_MT value, -EINVAL is returned.
*/
#define EVIOCGMTSLOTS(len) _IOC(IOC_INOUT, 'E', 0x0a, len)
#define EVIOCGKEY(len) _IOC(IOC_OUT, 'E', 0x18, len) /* get global key state */
#define EVIOCGLED(len) _IOC(IOC_OUT, 'E', 0x19, len) /* get all LEDs */
#define EVIOCGSND(len) _IOC(IOC_OUT, 'E', 0x1a, len) /* get all sounds status */
#define EVIOCGSW(len) _IOC(IOC_OUT, 'E', 0x1b, len) /* get all switch states */
#define EVIOCGBIT(ev,len) _IOC(IOC_OUT, 'E', 0x20 + (ev), len) /* get event bits */
#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
#define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */
#define EVIOCRMFF _IOWINT('E', 0x81) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOWINT('E', 0x90) /* Grab/Release device */
#define EVIOCREVOKE _IOWINT('E', 0x91) /* Revoke device access */
/**
* EVIOCGMASK - Retrieve current event mask
*
* This ioctl allows user to retrieve the current event mask for specific
* event type. The argument must be of type "struct input_mask" and
* specifies the event type to query, the address of the receive buffer and
* the size of the receive buffer.
*
* The event mask is a per-client mask that specifies which events are
* forwarded to the client. Each event code is represented by a single bit
* in the event mask. If the bit is set, the event is passed to the client
* normally. Otherwise, the event is filtered and will never be queued on
* the client's receive buffer.
*
* Event masks do not affect global state of the input device. They only
* affect the file descriptor they are applied to.
*
* The default event mask for a client has all bits set, i.e. all events
* are forwarded to the client. If the kernel is queried for an unknown
* event type or if the receive buffer is larger than the number of
* event codes known to the kernel, the kernel returns all zeroes for those
* codes.
*
* At maximum, codes_size bytes are copied.
*
* This ioctl may fail with ENODEV in case the file is revoked, EFAULT
* if the receive-buffer points to invalid memory, or EINVAL if the kernel
* does not implement the ioctl.
*/
#define EVIOCGMASK _IOW('E', 0x92, struct input_mask) /* Get event-masks */
/**
* EVIOCSMASK - Set event mask
*
* This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the
* current event mask, this changes the client's event mask for a specific
* type. See EVIOCGMASK for a description of event-masks and the
* argument-type.
*
* This ioctl provides full forward compatibility. If the passed event type
* is unknown to the kernel, or if the number of event codes specified in
* the mask is bigger than what is known to the kernel, the ioctl is still
* accepted and applied. However, any unknown codes are left untouched and
* stay cleared. That means, the kernel always filters unknown codes
* regardless of what the client requests. If the new mask doesn't cover
* all known event-codes, all remaining codes are automatically cleared and
* thus filtered.
*
* This ioctl may fail with ENODEV in case the file is revoked. EFAULT is
* returned if the receive-buffer points to invalid memory. EINVAL is returned
* if the kernel does not implement the ioctl.
*/
#define EVIOCSMASK _IOW('E', 0x93, struct input_mask) /* Set event-masks */
#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
/*
* IDs.
*/
#define ID_BUS 0
#define ID_VENDOR 1
#define ID_PRODUCT 2
#define ID_VERSION 3
#define BUS_PCI 0x01
#define BUS_ISAPNP 0x02
#define BUS_USB 0x03
#define BUS_HIL 0x04
#define BUS_BLUETOOTH 0x05
#define BUS_VIRTUAL 0x06
#define BUS_ISA 0x10
#define BUS_I8042 0x11
#define BUS_XTKBD 0x12
#define BUS_RS232 0x13
#define BUS_GAMEPORT 0x14
#define BUS_PARPORT 0x15
#define BUS_AMIGA 0x16
#define BUS_ADB 0x17
#define BUS_I2C 0x18
#define BUS_HOST 0x19
#define BUS_GSC 0x1A
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C
#define BUS_RMI 0x1D
#define BUS_CEC 0x1E
#define BUS_INTEL_ISHTP 0x1F
/*
* MT_TOOL types
*/
#define MT_TOOL_FINGER 0x00
#define MT_TOOL_PEN 0x01
#define MT_TOOL_PALM 0x02
#define MT_TOOL_DIAL 0x0a
#define MT_TOOL_MAX 0x0f
/*
* Values describing the status of a force-feedback effect
*/
#define FF_STATUS_STOPPED 0x00
#define FF_STATUS_PLAYING 0x01
#define FF_STATUS_MAX 0x01
/*
* Structures used in ioctls to upload effects to a device
* They are pieces of a bigger structure (called ff_effect)
*/
/*
* All duration values are expressed in ms. Values above 32767 ms (0x7fff)
* should not be used and have unspecified results.
*/
/**
* struct ff_replay - defines scheduling of the force-feedback effect
* @length: duration of the effect
* @delay: delay before effect should start playing
*/
struct ff_replay {
uint16_t length;
uint16_t delay;
};
/**
* struct ff_trigger - defines what triggers the force-feedback effect
* @button: number of the button triggering the effect
* @interval: controls how soon the effect can be re-triggered
*/
struct ff_trigger {
uint16_t button;
uint16_t interval;
};
/**
* struct ff_envelope - generic force-feedback effect envelope
* @attack_length: duration of the attack (ms)
* @attack_level: level at the beginning of the attack
* @fade_length: duration of fade (ms)
* @fade_level: level at the end of fade
*
* The @attack_level and @fade_level are absolute values; when applying
* envelope force-feedback core will convert to positive/negative
* value based on polarity of the default level of the effect.
* Valid range for the attack and fade levels is 0x0000 - 0x7fff
*/
struct ff_envelope {
uint16_t attack_length;
uint16_t attack_level;
uint16_t fade_length;
uint16_t fade_level;
};
/**
* struct ff_constant_effect - defines parameters of a constant force-feedback effect
* @level: strength of the effect; may be negative
* @envelope: envelope data
*/
struct ff_constant_effect {
int16_t level;
struct ff_envelope envelope;
};
/**
* struct ff_ramp_effect - defines parameters of a ramp force-feedback effect
* @start_level: beginning strength of the effect; may be negative
* @end_level: final strength of the effect; may be negative
* @envelope: envelope data
*/
struct ff_ramp_effect {
int16_t start_level;
int16_t end_level;
struct ff_envelope envelope;
};
/**
* struct ff_condition_effect - defines a spring or friction force-feedback effect
* @right_saturation: maximum level when joystick moved all way to the right
* @left_saturation: same for the left side
* @right_coeff: controls how fast the force grows when the joystick moves
* to the right
* @left_coeff: same for the left side
* @deadband: size of the dead zone, where no force is produced
* @center: position of the dead zone
*/
struct ff_condition_effect {
uint16_t right_saturation;
uint16_t left_saturation;
int16_t right_coeff;
int16_t left_coeff;
uint16_t deadband;
int16_t center;
};
/**
* struct ff_periodic_effect - defines parameters of a periodic force-feedback effect
* @waveform: kind of the effect (wave)
* @period: period of the wave (ms)
* @magnitude: peak value
* @offset: mean value of the wave (roughly)
* @phase: 'horizontal' shift
* @envelope: envelope data
* @custom_len: number of samples (FF_CUSTOM only)
* @custom_data: buffer of samples (FF_CUSTOM only)
*
* Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
* FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
* for the time being as no driver supports it yet.
*
* Note: the data pointed by custom_data is copied by the driver.
* You can therefore dispose of the memory after the upload/update.
*/
struct ff_periodic_effect {
uint16_t waveform;
uint16_t period;
int16_t magnitude;
int16_t offset;
uint16_t phase;
struct ff_envelope envelope;
uint32_t custom_len;
int16_t *custom_data;
};
/**
* struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
* @strong_magnitude: magnitude of the heavy motor
* @weak_magnitude: magnitude of the light one
*
* Some rumble pads have two motors of different weight. Strong_magnitude
* represents the magnitude of the vibration generated by the heavy one.
*/
struct ff_rumble_effect {
uint16_t strong_magnitude;
uint16_t weak_magnitude;
};
/**
* struct ff_effect - defines force feedback effect
* @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
* FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
* @id: an unique id assigned to an effect
* @direction: direction of the effect
* @trigger: trigger conditions (struct ff_trigger)
* @replay: scheduling of the effect (struct ff_replay)
* @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
* ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
* defining effect parameters
*
* This structure is sent through ioctl from the application to the driver.
* To create a new effect application should set its @id to -1; the kernel
* will return assigned @id which can later be used to update or delete
* this effect.
*
* Direction of the effect is encoded as follows:
* 0 deg -> 0x0000 (down)
* 90 deg -> 0x4000 (left)
* 180 deg -> 0x8000 (up)
* 270 deg -> 0xC000 (right)
*/
struct ff_effect {
uint16_t type;
int16_t id;
uint16_t direction;
struct ff_trigger trigger;
struct ff_replay replay;
union {
struct ff_constant_effect constant;
struct ff_ramp_effect ramp;
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2]; /* One for each axis */
struct ff_rumble_effect rumble;
} u;
};
/*
* Force feedback effect types
*/
#define FF_RUMBLE 0x50
#define FF_PERIODIC 0x51
#define FF_CONSTANT 0x52
#define FF_SPRING 0x53
#define FF_FRICTION 0x54
#define FF_DAMPER 0x55
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
#define FF_EFFECT_MIN FF_RUMBLE
#define FF_EFFECT_MAX FF_RAMP
/*
* Force feedback periodic effect types
*/
#define FF_SQUARE 0x58
#define FF_TRIANGLE 0x59
#define FF_SINE 0x5a
#define FF_SAW_UP 0x5b
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM 0x5d
#define FF_WAVEFORM_MIN FF_SQUARE
#define FF_WAVEFORM_MAX FF_CUSTOM
/*
* Set ff device properties
*/
#define FF_GAIN 0x60
#define FF_AUTOCENTER 0x61
/*
* ff->playback(effect_id = FF_GAIN) is the first effect_id to
* cause a collision with another ff method, in this case ff->set_gain().
* Therefore the greatest safe value for effect_id is FF_GAIN - 1,
* and thus the total number of effects should never exceed FF_GAIN.
*/
#define FF_MAX_EFFECTS FF_GAIN
#define FF_MAX 0x7f
#define FF_CNT (FF_MAX+1)
#endif /* _UAPI_INPUT_H */

View file

@ -0,0 +1,232 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* User level driver support for input subsystem
*
* Heavily based on evdev.c by Vojtech Pavlik
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
*
* Changes/Revisions:
* 0.5 08/13/2015 (David Herrmann <dh.herrmann@gmail.com> &
* Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - add UI_DEV_SETUP ioctl
* - add UI_ABS_SETUP ioctl
* - add UI_GET_VERSION ioctl
* 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - add UI_GET_SYSNAME ioctl
* 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
* - update ff support for the changes in kernel interface
* - add UINPUT_VERSION
* 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
* - added force feedback support
* - added UI_SET_PHYS
* 0.1 20/06/2002
* - first public version
*/
#ifndef _UAPI__UINPUT_H_
#define _UAPI__UINPUT_H_
#include <sys/types.h>
#include <linux/input.h>
#define UINPUT_VERSION 5
#define UINPUT_MAX_NAME_SIZE 80
struct uinput_ff_upload {
uint32_t request_id;
int32_t retval;
struct ff_effect effect;
struct ff_effect old;
};
struct uinput_ff_erase {
uint32_t request_id;
int32_t retval;
uint32_t effect_id;
};
/* ioctl */
#define UINPUT_IOCTL_BASE 'U'
#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
struct uinput_setup {
struct input_id id;
char name[UINPUT_MAX_NAME_SIZE];
uint32_t ff_effects_max;
};
/**
* UI_DEV_SETUP - Set device parameters for setup
*
* This ioctl sets parameters for the input device to be created. It
* supersedes the old "struct uinput_user_dev" method, which wrote this data
* via write(). To actually set the absolute axes UI_ABS_SETUP should be
* used.
*
* The ioctl takes a "struct uinput_setup" object as argument. The fields of
* this object are as follows:
* id: See the description of "struct input_id". This field is
* copied unchanged into the new device.
* name: This is used unchanged as name for the new device.
* ff_effects_max: This limits the maximum numbers of force-feedback effects.
* See below for a description of FF with uinput.
*
* This ioctl can be called multiple times and will overwrite previous values.
* If this ioctl fails with -EINVAL, it is recommended to use the old
* "uinput_user_dev" method via write() as a fallback, in case you run on an
* old kernel that does not support this ioctl.
*
* This ioctl may fail with -EINVAL if it is not supported or if you passed
* incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
* passed uinput_setup object cannot be read/written.
* If this call fails, partial data may have already been applied to the
* internal device.
*/
#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup)
struct uinput_abs_setup {
uint16_t code; /* axis code */
/* uint16_t filler; */
struct input_absinfo absinfo;
};
/**
* UI_ABS_SETUP - Set absolute axis information for the device to setup
*
* This ioctl sets one absolute axis information for the input device to be
* created. It supersedes the old "struct uinput_user_dev" method, which wrote
* part of this data and the content of UI_DEV_SETUP via write().
*
* The ioctl takes a "struct uinput_abs_setup" object as argument. The fields
* of this object are as follows:
* code: The corresponding input code associated with this axis
* (ABS_X, ABS_Y, etc...)
* absinfo: See "struct input_absinfo" for a description of this field.
* This field is copied unchanged into the kernel for the
* specified axis. If the axis is not enabled via
* UI_SET_ABSBIT, this ioctl will enable it.
*
* This ioctl can be called multiple times and will overwrite previous values.
* If this ioctl fails with -EINVAL, it is recommended to use the old
* "uinput_user_dev" method via write() as a fallback, in case you run on an
* old kernel that does not support this ioctl.
*
* This ioctl may fail with -EINVAL if it is not supported or if you passed
* incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
* passed uinput_setup object cannot be read/written.
* If this call fails, partial data may have already been applied to the
* internal device.
*/
#define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup)
#define UI_SET_EVBIT _IOWINT(UINPUT_IOCTL_BASE, 100)
#define UI_SET_KEYBIT _IOWINT(UINPUT_IOCTL_BASE, 101)
#define UI_SET_RELBIT _IOWINT(UINPUT_IOCTL_BASE, 102)
#define UI_SET_ABSBIT _IOWINT(UINPUT_IOCTL_BASE, 103)
#define UI_SET_MSCBIT _IOWINT(UINPUT_IOCTL_BASE, 104)
#define UI_SET_LEDBIT _IOWINT(UINPUT_IOCTL_BASE, 105)
#define UI_SET_SNDBIT _IOWINT(UINPUT_IOCTL_BASE, 106)
#define UI_SET_FFBIT _IOWINT(UINPUT_IOCTL_BASE, 107)
#define UI_SET_PHYS _IO(UINPUT_IOCTL_BASE, 108)
#define UI_SET_SWBIT _IOWINT(UINPUT_IOCTL_BASE, 109)
#define UI_SET_PROPBIT _IOWINT(UINPUT_IOCTL_BASE, 110)
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
/**
* UI_GET_SYSNAME - get the sysfs name of the created uinput device
*
* @return the sysfs name of the created virtual input device.
* The complete sysfs path is then /sys/devices/virtual/input/--NAME--
* Usually, it is in the form "inputN"
*/
#define UI_GET_SYSNAME(len) _IOC(IOC_OUT, UINPUT_IOCTL_BASE, 44, len)
/**
* UI_GET_VERSION - Return version of uinput protocol
*
* This writes uinput protocol version implemented by the kernel into
* the integer pointed to by the ioctl argument. The protocol version
* is hard-coded in the kernel and is independent of the uinput device.
*/
#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 45, unsigned int)
/*
* To write a force-feedback-capable driver, the upload_effect
* and erase_effect callbacks in input_dev must be implemented.
* The uinput driver will generate a fake input event when one of
* these callbacks are invoked. The userspace code then uses
* ioctls to retrieve additional parameters and send the return code.
* The callback blocks until this return code is sent.
*
* The described callback mechanism is only used if ff_effects_max
* is set.
*
* To implement upload_effect():
* 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_upload struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
* uinput_ff_upload struct. It will be filled in with the
* ff_effects passed to upload_effect().
* 4. Perform the effect upload, and place a return code back into
the uinput_ff_upload struct.
* 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
* uinput_ff_upload_effect struct. This will complete execution
* of our upload_effect() handler.
*
* To implement erase_effect():
* 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_erase struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
* uinput_ff_erase struct. It will be filled in with the
* effect ID passed to erase_effect().
* 4. Perform the effect erasure, and place a return code back
* into the uinput_ff_erase struct.
* 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
* uinput_ff_erase_effect struct. This will complete execution
* of our erase_effect() handler.
*/
/*
* This is the new event type, used only by uinput.
* 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
* is the unique request ID. This number was picked
* arbitrarily, above EV_MAX (since the input system
* never sees it) but in the range of a 16-bit int.
*/
#define EV_UINPUT 0x0101
#define UI_FF_UPLOAD 1
#define UI_FF_ERASE 2
struct uinput_user_dev {
char name[UINPUT_MAX_NAME_SIZE];
struct input_id id;
uint32_t ff_effects_max;
int32_t absmax[ABS_CNT];
int32_t absmin[ABS_CNT];
int32_t absfuzz[ABS_CNT];
int32_t absflat[ABS_CNT];
};
#endif /* _UAPI__UINPUT_H_ */

View file

@ -1,512 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef _INPUT_H
#define _INPUT_H
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/types.h>
#include "input-event-codes.h"
/*
* The event structure itself
* Note that __USE_TIME_BITS64 is defined by libc based on
* application's request to use 64 bit time_t.
*/
struct input_event {
#if (__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL__)
struct timeval time;
#define input_event_sec time.tv_sec
#define input_event_usec time.tv_usec
#else
__kernel_ulong_t __sec;
#if defined(__sparc__) && defined(__arch64__)
unsigned int __usec;
unsigned int __pad;
#else
__kernel_ulong_t __usec;
#ifdef __linux__
#include "linux/input.h"
#elif __FreeBSD__
#include "freebsd/input.h"
#endif
#define input_event_sec __sec
#define input_event_usec __usec
#endif
__u16 type;
__u16 code;
__s32 value;
};
/*
* Protocol version.
*/
#define EV_VERSION 0x010001
/*
* IOCTLs (0x00 - 0x7f)
*/
struct input_id {
__u16 bustype;
__u16 vendor;
__u16 product;
__u16 version;
};
/**
* struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
* @value: latest reported value for the axis.
* @minimum: specifies minimum value for the axis.
* @maximum: specifies maximum value for the axis.
* @fuzz: specifies fuzz value that is used to filter noise from
* the event stream.
* @flat: values that are within this value will be discarded by
* joydev interface and reported as 0 instead.
* @resolution: specifies resolution for the values reported for
* the axis.
*
* Note that input core does not clamp reported values to the
* [minimum, maximum] limits, such task is left to userspace.
*
* The default resolution for main axes (ABS_X, ABS_Y, ABS_Z)
* is reported in units per millimeter (units/mm), resolution
* for rotational axes (ABS_RX, ABS_RY, ABS_RZ) is reported
* in units per radian.
* When INPUT_PROP_ACCELEROMETER is set the resolution changes.
* The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in
* in units per g (units/g) and in units per degree per second
* (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ).
*/
struct input_absinfo {
__s32 value;
__s32 minimum;
__s32 maximum;
__s32 fuzz;
__s32 flat;
__s32 resolution;
};
/**
* struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls
* @scancode: scancode represented in machine-endian form.
* @len: length of the scancode that resides in @scancode buffer.
* @index: index in the keymap, may be used instead of scancode
* @flags: allows to specify how kernel should handle the request. For
* example, setting INPUT_KEYMAP_BY_INDEX flag indicates that kernel
* should perform lookup in keymap by @index instead of @scancode
* @keycode: key code assigned to this scancode
*
* The structure is used to retrieve and modify keymap data. Users have
* option of performing lookup either by @scancode itself or by @index
* in keymap entry. EVIOCGKEYCODE will also return scancode or index
* (depending on which element was used to perform lookup).
*/
struct input_keymap_entry {
#define INPUT_KEYMAP_BY_INDEX (1 << 0)
__u8 flags;
__u8 len;
__u16 index;
__u32 keycode;
__u8 scancode[32];
};
struct input_mask {
__u32 type;
__u32 codes_size;
__u64 codes_ptr;
};
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */
/**
* EVIOCGMTSLOTS(len) - get MT slot values
* @len: size of the data buffer in bytes
*
* The ioctl buffer argument should be binary equivalent to
*
* struct input_mt_request_layout {
* __u32 code;
* __s32 values[num_slots];
* };
*
* where num_slots is the (arbitrary) number of MT slots to extract.
*
* The ioctl size argument (len) is the size of the buffer, which
* should satisfy len = (num_slots + 1) * sizeof(__s32). If len is
* too small to fit all available slots, the first num_slots are
* returned.
*
* Before the call, code is set to the wanted ABS_MT event type. On
* return, values[] is filled with the slot values for the specified
* ABS_MT code.
*
* If the request code is not an ABS_MT value, -EINVAL is returned.
*/
#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */
#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len) /* get event bits */
#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
#define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */
#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
#define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */
/**
* EVIOCGMASK - Retrieve current event mask
*
* This ioctl allows user to retrieve the current event mask for specific
* event type. The argument must be of type "struct input_mask" and
* specifies the event type to query, the address of the receive buffer and
* the size of the receive buffer.
*
* The event mask is a per-client mask that specifies which events are
* forwarded to the client. Each event code is represented by a single bit
* in the event mask. If the bit is set, the event is passed to the client
* normally. Otherwise, the event is filtered and will never be queued on
* the client's receive buffer.
*
* Event masks do not affect global state of the input device. They only
* affect the file descriptor they are applied to.
*
* The default event mask for a client has all bits set, i.e. all events
* are forwarded to the client. If the kernel is queried for an unknown
* event type or if the receive buffer is larger than the number of
* event codes known to the kernel, the kernel returns all zeroes for those
* codes.
*
* At maximum, codes_size bytes are copied.
*
* This ioctl may fail with ENODEV in case the file is revoked, EFAULT
* if the receive-buffer points to invalid memory, or EINVAL if the kernel
* does not implement the ioctl.
*/
#define EVIOCGMASK _IOR('E', 0x92, struct input_mask) /* Get event-masks */
/**
* EVIOCSMASK - Set event mask
*
* This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the
* current event mask, this changes the client's event mask for a specific
* type. See EVIOCGMASK for a description of event-masks and the
* argument-type.
*
* This ioctl provides full forward compatibility. If the passed event type
* is unknown to the kernel, or if the number of event codes specified in
* the mask is bigger than what is known to the kernel, the ioctl is still
* accepted and applied. However, any unknown codes are left untouched and
* stay cleared. That means, the kernel always filters unknown codes
* regardless of what the client requests. If the new mask doesn't cover
* all known event-codes, all remaining codes are automatically cleared and
* thus filtered.
*
* This ioctl may fail with ENODEV in case the file is revoked. EFAULT is
* returned if the receive-buffer points to invalid memory. EINVAL is returned
* if the kernel does not implement the ioctl.
*/
#define EVIOCSMASK _IOW('E', 0x93, struct input_mask) /* Set event-masks */
#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
/*
* IDs.
*/
#define ID_BUS 0
#define ID_VENDOR 1
#define ID_PRODUCT 2
#define ID_VERSION 3
#define BUS_PCI 0x01
#define BUS_ISAPNP 0x02
#define BUS_USB 0x03
#define BUS_HIL 0x04
#define BUS_BLUETOOTH 0x05
#define BUS_VIRTUAL 0x06
#define BUS_ISA 0x10
#define BUS_I8042 0x11
#define BUS_XTKBD 0x12
#define BUS_RS232 0x13
#define BUS_GAMEPORT 0x14
#define BUS_PARPORT 0x15
#define BUS_AMIGA 0x16
#define BUS_ADB 0x17
#define BUS_I2C 0x18
#define BUS_HOST 0x19
#define BUS_GSC 0x1A
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C
#define BUS_RMI 0x1D
#define BUS_CEC 0x1E
#define BUS_INTEL_ISHTP 0x1F
/*
* MT_TOOL types
*/
#define MT_TOOL_FINGER 0x00
#define MT_TOOL_PEN 0x01
#define MT_TOOL_PALM 0x02
#define MT_TOOL_DIAL 0x0a
#define MT_TOOL_MAX 0x0f
/*
* Values describing the status of a force-feedback effect
*/
#define FF_STATUS_STOPPED 0x00
#define FF_STATUS_PLAYING 0x01
#define FF_STATUS_MAX 0x01
/*
* Structures used in ioctls to upload effects to a device
* They are pieces of a bigger structure (called ff_effect)
*/
/*
* All duration values are expressed in ms. Values above 32767 ms (0x7fff)
* should not be used and have unspecified results.
*/
/**
* struct ff_replay - defines scheduling of the force-feedback effect
* @length: duration of the effect
* @delay: delay before effect should start playing
*/
struct ff_replay {
__u16 length;
__u16 delay;
};
/**
* struct ff_trigger - defines what triggers the force-feedback effect
* @button: number of the button triggering the effect
* @interval: controls how soon the effect can be re-triggered
*/
struct ff_trigger {
__u16 button;
__u16 interval;
};
/**
* struct ff_envelope - generic force-feedback effect envelope
* @attack_length: duration of the attack (ms)
* @attack_level: level at the beginning of the attack
* @fade_length: duration of fade (ms)
* @fade_level: level at the end of fade
*
* The @attack_level and @fade_level are absolute values; when applying
* envelope force-feedback core will convert to positive/negative
* value based on polarity of the default level of the effect.
* Valid range for the attack and fade levels is 0x0000 - 0x7fff
*/
struct ff_envelope {
__u16 attack_length;
__u16 attack_level;
__u16 fade_length;
__u16 fade_level;
};
/**
* struct ff_constant_effect - defines parameters of a constant force-feedback effect
* @level: strength of the effect; may be negative
* @envelope: envelope data
*/
struct ff_constant_effect {
__s16 level;
struct ff_envelope envelope;
};
/**
* struct ff_ramp_effect - defines parameters of a ramp force-feedback effect
* @start_level: beginning strength of the effect; may be negative
* @end_level: final strength of the effect; may be negative
* @envelope: envelope data
*/
struct ff_ramp_effect {
__s16 start_level;
__s16 end_level;
struct ff_envelope envelope;
};
/**
* struct ff_condition_effect - defines a spring or friction force-feedback effect
* @right_saturation: maximum level when joystick moved all way to the right
* @left_saturation: same for the left side
* @right_coeff: controls how fast the force grows when the joystick moves
* to the right
* @left_coeff: same for the left side
* @deadband: size of the dead zone, where no force is produced
* @center: position of the dead zone
*/
struct ff_condition_effect {
__u16 right_saturation;
__u16 left_saturation;
__s16 right_coeff;
__s16 left_coeff;
__u16 deadband;
__s16 center;
};
/**
* struct ff_periodic_effect - defines parameters of a periodic force-feedback effect
* @waveform: kind of the effect (wave)
* @period: period of the wave (ms)
* @magnitude: peak value
* @offset: mean value of the wave (roughly)
* @phase: 'horizontal' shift
* @envelope: envelope data
* @custom_len: number of samples (FF_CUSTOM only)
* @custom_data: buffer of samples (FF_CUSTOM only)
*
* Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
* FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
* for the time being as no driver supports it yet.
*
* Note: the data pointed by custom_data is copied by the driver.
* You can therefore dispose of the memory after the upload/update.
*/
struct ff_periodic_effect {
__u16 waveform;
__u16 period;
__s16 magnitude;
__s16 offset;
__u16 phase;
struct ff_envelope envelope;
__u32 custom_len;
__s16 *custom_data;
};
/**
* struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
* @strong_magnitude: magnitude of the heavy motor
* @weak_magnitude: magnitude of the light one
*
* Some rumble pads have two motors of different weight. Strong_magnitude
* represents the magnitude of the vibration generated by the heavy one.
*/
struct ff_rumble_effect {
__u16 strong_magnitude;
__u16 weak_magnitude;
};
/**
* struct ff_effect - defines force feedback effect
* @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
* FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
* @id: an unique id assigned to an effect
* @direction: direction of the effect
* @trigger: trigger conditions (struct ff_trigger)
* @replay: scheduling of the effect (struct ff_replay)
* @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
* ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
* defining effect parameters
*
* This structure is sent through ioctl from the application to the driver.
* To create a new effect application should set its @id to -1; the kernel
* will return assigned @id which can later be used to update or delete
* this effect.
*
* Direction of the effect is encoded as follows:
* 0 deg -> 0x0000 (down)
* 90 deg -> 0x4000 (left)
* 180 deg -> 0x8000 (up)
* 270 deg -> 0xC000 (right)
*/
struct ff_effect {
__u16 type;
__s16 id;
__u16 direction;
struct ff_trigger trigger;
struct ff_replay replay;
union {
struct ff_constant_effect constant;
struct ff_ramp_effect ramp;
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2]; /* One for each axis */
struct ff_rumble_effect rumble;
} u;
};
/*
* Force feedback effect types
*/
#define FF_RUMBLE 0x50
#define FF_PERIODIC 0x51
#define FF_CONSTANT 0x52
#define FF_SPRING 0x53
#define FF_FRICTION 0x54
#define FF_DAMPER 0x55
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
#define FF_EFFECT_MIN FF_RUMBLE
#define FF_EFFECT_MAX FF_RAMP
/*
* Force feedback periodic effect types
*/
#define FF_SQUARE 0x58
#define FF_TRIANGLE 0x59
#define FF_SINE 0x5a
#define FF_SAW_UP 0x5b
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM 0x5d
#define FF_WAVEFORM_MIN FF_SQUARE
#define FF_WAVEFORM_MAX FF_CUSTOM
/*
* Set ff device properties
*/
#define FF_GAIN 0x60
#define FF_AUTOCENTER 0x61
/*
* ff->playback(effect_id = FF_GAIN) is the first effect_id to
* cause a collision with another ff method, in this case ff->set_gain().
* Therefore the greatest safe value for effect_id is FF_GAIN - 1,
* and thus the total number of effects should never exceed FF_GAIN.
*/
#define FF_MAX_EFFECTS FF_GAIN
#define FF_MAX 0x7f
#define FF_CNT (FF_MAX+1)
#endif /* _INPUT_H */

File diff suppressed because it is too large Load diff

539
include/linux/linux/input.h Normal file
View file

@ -0,0 +1,539 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Copyright (c) 1999-2002 Vojtech Pavlik
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef _UAPI_INPUT_H
#define _UAPI_INPUT_H
#ifndef __KERNEL__
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/types.h>
#endif
#include "input-event-codes.h"
/*
* The event structure itself
* Note that __USE_TIME_BITS64 is defined by libc based on
* application's request to use 64 bit time_t.
*/
struct input_event {
#if (__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL__)
struct timeval time;
#define input_event_sec time.tv_sec
#define input_event_usec time.tv_usec
#else
__kernel_ulong_t __sec;
#if defined(__sparc__) && defined(__arch64__)
unsigned int __usec;
unsigned int __pad;
#else
__kernel_ulong_t __usec;
#endif
#define input_event_sec __sec
#define input_event_usec __usec
#endif
__u16 type;
__u16 code;
__s32 value;
};
/*
* Protocol version.
*/
#define EV_VERSION 0x010001
/*
* IOCTLs (0x00 - 0x7f)
*/
struct input_id {
__u16 bustype;
__u16 vendor;
__u16 product;
__u16 version;
};
/**
* struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls
* @value: latest reported value for the axis.
* @minimum: specifies minimum value for the axis.
* @maximum: specifies maximum value for the axis.
* @fuzz: specifies fuzz value that is used to filter noise from
* the event stream.
* @flat: values that are within this value will be discarded by
* joydev interface and reported as 0 instead.
* @resolution: specifies resolution for the values reported for
* the axis.
*
* Note that input core does not clamp reported values to the
* [minimum, maximum] limits, such task is left to userspace.
*
* The default resolution for main axes (ABS_X, ABS_Y, ABS_Z,
* ABS_MT_POSITION_X, ABS_MT_POSITION_Y) is reported in units
* per millimeter (units/mm), resolution for rotational axes
* (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian.
* The resolution for the size axes (ABS_MT_TOUCH_MAJOR,
* ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MAJOR, ABS_MT_WIDTH_MINOR)
* is reported in units per millimeter (units/mm).
* When INPUT_PROP_ACCELEROMETER is set the resolution changes.
* The main axes (ABS_X, ABS_Y, ABS_Z) are then reported in
* units per g (units/g) and in units per degree per second
* (units/deg/s) for rotational axes (ABS_RX, ABS_RY, ABS_RZ).
*/
struct input_absinfo {
__s32 value;
__s32 minimum;
__s32 maximum;
__s32 fuzz;
__s32 flat;
__s32 resolution;
};
/**
* struct input_keymap_entry - used by EVIOCGKEYCODE/EVIOCSKEYCODE ioctls
* @scancode: scancode represented in machine-endian form.
* @len: length of the scancode that resides in @scancode buffer.
* @index: index in the keymap, may be used instead of scancode
* @flags: allows to specify how kernel should handle the request. For
* example, setting INPUT_KEYMAP_BY_INDEX flag indicates that kernel
* should perform lookup in keymap by @index instead of @scancode
* @keycode: key code assigned to this scancode
*
* The structure is used to retrieve and modify keymap data. Users have
* option of performing lookup either by @scancode itself or by @index
* in keymap entry. EVIOCGKEYCODE will also return scancode or index
* (depending on which element was used to perform lookup).
*/
struct input_keymap_entry {
#define INPUT_KEYMAP_BY_INDEX (1 << 0)
__u8 flags;
__u8 len;
__u16 index;
__u32 keycode;
__u8 scancode[32];
};
struct input_mask {
__u32 type;
__u32 codes_size;
__u64 codes_ptr;
};
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len) /* get device properties */
/**
* EVIOCGMTSLOTS(len) - get MT slot values
* @len: size of the data buffer in bytes
*
* The ioctl buffer argument should be binary equivalent to
*
* struct input_mt_request_layout {
* __u32 code;
* __s32 values[num_slots];
* };
*
* where num_slots is the (arbitrary) number of MT slots to extract.
*
* The ioctl size argument (len) is the size of the buffer, which
* should satisfy len = (num_slots + 1) * sizeof(__s32). If len is
* too small to fit all available slots, the first num_slots are
* returned.
*
* Before the call, code is set to the wanted ABS_MT event type. On
* return, values[] is filled with the slot values for the specified
* ABS_MT code.
*
* If the request code is not an ABS_MT value, -EINVAL is returned.
*/
#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global key state */
#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len) /* get event bits */
#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
#define EVIOCSFF _IOW('E', 0x80, struct ff_effect) /* send a force effect to a force feedback device */
#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
#define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */
/**
* EVIOCGMASK - Retrieve current event mask
*
* This ioctl allows user to retrieve the current event mask for specific
* event type. The argument must be of type "struct input_mask" and
* specifies the event type to query, the address of the receive buffer and
* the size of the receive buffer.
*
* The event mask is a per-client mask that specifies which events are
* forwarded to the client. Each event code is represented by a single bit
* in the event mask. If the bit is set, the event is passed to the client
* normally. Otherwise, the event is filtered and will never be queued on
* the client's receive buffer.
*
* Event masks do not affect global state of the input device. They only
* affect the file descriptor they are applied to.
*
* The default event mask for a client has all bits set, i.e. all events
* are forwarded to the client. If the kernel is queried for an unknown
* event type or if the receive buffer is larger than the number of
* event codes known to the kernel, the kernel returns all zeroes for those
* codes.
*
* At maximum, codes_size bytes are copied.
*
* This ioctl may fail with ENODEV in case the file is revoked, EFAULT
* if the receive-buffer points to invalid memory, or EINVAL if the kernel
* does not implement the ioctl.
*/
#define EVIOCGMASK _IOR('E', 0x92, struct input_mask) /* Get event-masks */
/**
* EVIOCSMASK - Set event mask
*
* This ioctl is the counterpart to EVIOCGMASK. Instead of receiving the
* current event mask, this changes the client's event mask for a specific
* type. See EVIOCGMASK for a description of event-masks and the
* argument-type.
*
* This ioctl provides full forward compatibility. If the passed event type
* is unknown to the kernel, or if the number of event codes specified in
* the mask is bigger than what is known to the kernel, the ioctl is still
* accepted and applied. However, any unknown codes are left untouched and
* stay cleared. That means, the kernel always filters unknown codes
* regardless of what the client requests. If the new mask doesn't cover
* all known event-codes, all remaining codes are automatically cleared and
* thus filtered.
*
* This ioctl may fail with ENODEV in case the file is revoked. EFAULT is
* returned if the receive-buffer points to invalid memory. EINVAL is returned
* if the kernel does not implement the ioctl.
*/
#define EVIOCSMASK _IOW('E', 0x93, struct input_mask) /* Set event-masks */
#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */
/*
* IDs.
*/
#define ID_BUS 0
#define ID_VENDOR 1
#define ID_PRODUCT 2
#define ID_VERSION 3
#define BUS_PCI 0x01
#define BUS_ISAPNP 0x02
#define BUS_USB 0x03
#define BUS_HIL 0x04
#define BUS_BLUETOOTH 0x05
#define BUS_VIRTUAL 0x06
#define BUS_ISA 0x10
#define BUS_I8042 0x11
#define BUS_XTKBD 0x12
#define BUS_RS232 0x13
#define BUS_GAMEPORT 0x14
#define BUS_PARPORT 0x15
#define BUS_AMIGA 0x16
#define BUS_ADB 0x17
#define BUS_I2C 0x18
#define BUS_HOST 0x19
#define BUS_GSC 0x1A
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C
#define BUS_RMI 0x1D
#define BUS_CEC 0x1E
#define BUS_INTEL_ISHTP 0x1F
#define BUS_AMD_SFH 0x20
#define BUS_SDW 0x21
/*
* MT_TOOL types
*/
#define MT_TOOL_FINGER 0x00
#define MT_TOOL_PEN 0x01
#define MT_TOOL_PALM 0x02
#define MT_TOOL_DIAL 0x0a
#define MT_TOOL_MAX 0x0f
/*
* Values describing the status of a force-feedback effect
*/
#define FF_STATUS_STOPPED 0x00
#define FF_STATUS_PLAYING 0x01
#define FF_STATUS_MAX 0x01
/*
* Structures used in ioctls to upload effects to a device
* They are pieces of a bigger structure (called ff_effect)
*/
/*
* All duration values are expressed in ms. Values above 32767 ms (0x7fff)
* should not be used and have unspecified results.
*/
/**
* struct ff_replay - defines scheduling of the force-feedback effect
* @length: duration of the effect
* @delay: delay before effect should start playing
*/
struct ff_replay {
__u16 length;
__u16 delay;
};
/**
* struct ff_trigger - defines what triggers the force-feedback effect
* @button: number of the button triggering the effect
* @interval: controls how soon the effect can be re-triggered
*/
struct ff_trigger {
__u16 button;
__u16 interval;
};
/**
* struct ff_envelope - generic force-feedback effect envelope
* @attack_length: duration of the attack (ms)
* @attack_level: level at the beginning of the attack
* @fade_length: duration of fade (ms)
* @fade_level: level at the end of fade
*
* The @attack_level and @fade_level are absolute values; when applying
* envelope force-feedback core will convert to positive/negative
* value based on polarity of the default level of the effect.
* Valid range for the attack and fade levels is 0x0000 - 0x7fff
*/
struct ff_envelope {
__u16 attack_length;
__u16 attack_level;
__u16 fade_length;
__u16 fade_level;
};
/**
* struct ff_constant_effect - defines parameters of a constant force-feedback effect
* @level: strength of the effect; may be negative
* @envelope: envelope data
*/
struct ff_constant_effect {
__s16 level;
struct ff_envelope envelope;
};
/**
* struct ff_ramp_effect - defines parameters of a ramp force-feedback effect
* @start_level: beginning strength of the effect; may be negative
* @end_level: final strength of the effect; may be negative
* @envelope: envelope data
*/
struct ff_ramp_effect {
__s16 start_level;
__s16 end_level;
struct ff_envelope envelope;
};
/**
* struct ff_condition_effect - defines a spring or friction force-feedback effect
* @right_saturation: maximum level when joystick moved all way to the right
* @left_saturation: same for the left side
* @right_coeff: controls how fast the force grows when the joystick moves
* to the right
* @left_coeff: same for the left side
* @deadband: size of the dead zone, where no force is produced
* @center: position of the dead zone
*/
struct ff_condition_effect {
__u16 right_saturation;
__u16 left_saturation;
__s16 right_coeff;
__s16 left_coeff;
__u16 deadband;
__s16 center;
};
/**
* struct ff_periodic_effect - defines parameters of a periodic force-feedback effect
* @waveform: kind of the effect (wave)
* @period: period of the wave (ms)
* @magnitude: peak value
* @offset: mean value of the wave (roughly)
* @phase: 'horizontal' shift
* @envelope: envelope data
* @custom_len: number of samples (FF_CUSTOM only)
* @custom_data: buffer of samples (FF_CUSTOM only)
*
* Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
* FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
* for the time being as no driver supports it yet.
*
* Note: the data pointed by custom_data is copied by the driver.
* You can therefore dispose of the memory after the upload/update.
*/
struct ff_periodic_effect {
__u16 waveform;
__u16 period;
__s16 magnitude;
__s16 offset;
__u16 phase;
struct ff_envelope envelope;
__u32 custom_len;
__s16 *custom_data;
};
/**
* struct ff_rumble_effect - defines parameters of a periodic force-feedback effect
* @strong_magnitude: magnitude of the heavy motor
* @weak_magnitude: magnitude of the light one
*
* Some rumble pads have two motors of different weight. Strong_magnitude
* represents the magnitude of the vibration generated by the heavy one.
*/
struct ff_rumble_effect {
__u16 strong_magnitude;
__u16 weak_magnitude;
};
/**
* struct ff_haptic_effect
* @hid_usage: hid_usage according to Haptics page (WAVEFORM_CLICK, etc.)
* @vendor_id: the waveform vendor ID if hid_usage is in the vendor-defined range
* @vendor_waveform_page: the vendor waveform page if hid_usage is in the vendor-defined range
* @intensity: strength of the effect as percentage
* @repeat_count: number of times to retrigger effect
* @retrigger_period: time before effect is retriggered (in ms)
*/
struct ff_haptic_effect {
__u16 hid_usage;
__u16 vendor_id;
__u8 vendor_waveform_page;
__u16 intensity;
__u16 repeat_count;
__u16 retrigger_period;
};
/**
* struct ff_effect - defines force feedback effect
* @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
* FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
* @id: an unique id assigned to an effect
* @direction: direction of the effect
* @trigger: trigger conditions (struct ff_trigger)
* @replay: scheduling of the effect (struct ff_replay)
* @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
* ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
* defining effect parameters
*
* This structure is sent through ioctl from the application to the driver.
* To create a new effect application should set its @id to -1; the kernel
* will return assigned @id which can later be used to update or delete
* this effect.
*
* Direction of the effect is encoded as follows:
* 0 deg -> 0x0000 (down)
* 90 deg -> 0x4000 (left)
* 180 deg -> 0x8000 (up)
* 270 deg -> 0xC000 (right)
*/
struct ff_effect {
__u16 type;
__s16 id;
__u16 direction;
struct ff_trigger trigger;
struct ff_replay replay;
union {
struct ff_constant_effect constant;
struct ff_ramp_effect ramp;
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2]; /* One for each axis */
struct ff_rumble_effect rumble;
struct ff_haptic_effect haptic;
} u;
};
/*
* Force feedback effect types
*/
#define FF_HAPTIC 0x4f
#define FF_RUMBLE 0x50
#define FF_PERIODIC 0x51
#define FF_CONSTANT 0x52
#define FF_SPRING 0x53
#define FF_FRICTION 0x54
#define FF_DAMPER 0x55
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
#define FF_EFFECT_MIN FF_HAPTIC
#define FF_EFFECT_MAX FF_RAMP
/*
* Force feedback periodic effect types
*/
#define FF_SQUARE 0x58
#define FF_TRIANGLE 0x59
#define FF_SINE 0x5a
#define FF_SAW_UP 0x5b
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM 0x5d
#define FF_WAVEFORM_MIN FF_SQUARE
#define FF_WAVEFORM_MAX FF_CUSTOM
/*
* Set ff device properties
*/
#define FF_GAIN 0x60
#define FF_AUTOCENTER 0x61
/*
* ff->playback(effect_id = FF_GAIN) is the first effect_id to
* cause a collision with another ff method, in this case ff->set_gain().
* Therefore the greatest safe value for effect_id is FF_GAIN - 1,
* and thus the total number of effects should never exceed FF_GAIN.
*/
#define FF_MAX_EFFECTS FF_GAIN
#define FF_MAX 0x7f
#define FF_CNT (FF_MAX+1)
#endif /* _UAPI_INPUT_H */

View file

@ -0,0 +1,231 @@
/*
* User level driver support for input subsystem
*
* Heavily based on evdev.c by Vojtech Pavlik
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
*
* Changes/Revisions:
* 0.5 08/13/2015 (David Herrmann <dh.herrmann@gmail.com> &
* Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - add UI_DEV_SETUP ioctl
* - add UI_ABS_SETUP ioctl
* - add UI_GET_VERSION ioctl
* 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - add UI_GET_SYSNAME ioctl
* 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
* - update ff support for the changes in kernel interface
* - add UINPUT_VERSION
* 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
* - added force feedback support
* - added UI_SET_PHYS
* 0.1 20/06/2002
* - first public version
*/
#ifndef __UINPUT_H_
#define __UINPUT_H_
#include <linux/types.h>
#include <linux/input.h>
#define UINPUT_VERSION 5
#define UINPUT_MAX_NAME_SIZE 80
struct uinput_ff_upload {
__u32 request_id;
__s32 retval;
struct ff_effect effect;
struct ff_effect old;
};
struct uinput_ff_erase {
__u32 request_id;
__s32 retval;
__u32 effect_id;
};
/* ioctl */
#define UINPUT_IOCTL_BASE 'U'
#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
struct uinput_setup {
struct input_id id;
char name[UINPUT_MAX_NAME_SIZE];
__u32 ff_effects_max;
};
/**
* UI_DEV_SETUP - Set device parameters for setup
*
* This ioctl sets parameters for the input device to be created. It
* supersedes the old "struct uinput_user_dev" method, which wrote this data
* via write(). To actually set the absolute axes UI_ABS_SETUP should be
* used.
*
* The ioctl takes a "struct uinput_setup" object as argument. The fields of
* this object are as follows:
* id: See the description of "struct input_id". This field is
* copied unchanged into the new device.
* name: This is used unchanged as name for the new device.
* ff_effects_max: This limits the maximum numbers of force-feedback effects.
* See below for a description of FF with uinput.
*
* This ioctl can be called multiple times and will overwrite previous values.
* If this ioctl fails with -EINVAL, it is recommended to use the old
* "uinput_user_dev" method via write() as a fallback, in case you run on an
* old kernel that does not support this ioctl.
*
* This ioctl may fail with -EINVAL if it is not supported or if you passed
* incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
* passed uinput_setup object cannot be read/written.
* If this call fails, partial data may have already been applied to the
* internal device.
*/
#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup)
struct uinput_abs_setup {
__u16 code; /* axis code */
/* __u16 filler; */
struct input_absinfo absinfo;
};
/**
* UI_ABS_SETUP - Set absolute axis information for the device to setup
*
* This ioctl sets one absolute axis information for the input device to be
* created. It supersedes the old "struct uinput_user_dev" method, which wrote
* part of this data and the content of UI_DEV_SETUP via write().
*
* The ioctl takes a "struct uinput_abs_setup" object as argument. The fields
* of this object are as follows:
* code: The corresponding input code associated with this axis
* (ABS_X, ABS_Y, etc...)
* absinfo: See "struct input_absinfo" for a description of this field.
* This field is copied unchanged into the kernel for the
* specified axis. If the axis is not enabled via
* UI_SET_ABSBIT, this ioctl will enable it.
*
* This ioctl can be called multiple times and will overwrite previous values.
* If this ioctl fails with -EINVAL, it is recommended to use the old
* "uinput_user_dev" method via write() as a fallback, in case you run on an
* old kernel that does not support this ioctl.
*
* This ioctl may fail with -EINVAL if it is not supported or if you passed
* incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
* passed uinput_setup object cannot be read/written.
* If this call fails, partial data may have already been applied to the
* internal device.
*/
#define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup)
#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
/**
* UI_GET_SYSNAME - get the sysfs name of the created uinput device
*
* @return the sysfs name of the created virtual input device.
* The complete sysfs path is then /sys/devices/virtual/input/--NAME--
* Usually, it is in the form "inputN"
*/
#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len)
/**
* UI_GET_VERSION - Return version of uinput protocol
*
* This writes uinput protocol version implemented by the kernel into
* the integer pointed to by the ioctl argument. The protocol version
* is hard-coded in the kernel and is independent of the uinput device.
*/
#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 45, unsigned int)
/*
* To write a force-feedback-capable driver, the upload_effect
* and erase_effect callbacks in input_dev must be implemented.
* The uinput driver will generate a fake input event when one of
* these callbacks are invoked. The userspace code then uses
* ioctls to retrieve additional parameters and send the return code.
* The callback blocks until this return code is sent.
*
* The described callback mechanism is only used if ff_effects_max
* is set.
*
* To implement upload_effect():
* 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_upload struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
* uinput_ff_upload struct. It will be filled in with the
* ff_effects passed to upload_effect().
* 4. Perform the effect upload, and place a return code back into
the uinput_ff_upload struct.
* 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
* uinput_ff_upload_effect struct. This will complete execution
* of our upload_effect() handler.
*
* To implement erase_effect():
* 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_erase struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
* uinput_ff_erase struct. It will be filled in with the
* effect ID passed to erase_effect().
* 4. Perform the effect erasure, and place a return code back
* into the uinput_ff_erase struct.
* 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
* uinput_ff_erase_effect struct. This will complete execution
* of our erase_effect() handler.
*/
/*
* This is the new event type, used only by uinput.
* 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
* is the unique request ID. This number was picked
* arbitrarily, above EV_MAX (since the input system
* never sees it) but in the range of a 16-bit int.
*/
#define EV_UINPUT 0x0101
#define UI_FF_UPLOAD 1
#define UI_FF_ERASE 2
struct uinput_user_dev {
char name[UINPUT_MAX_NAME_SIZE];
struct input_id id;
__u32 ff_effects_max;
__s32 absmax[ABS_CNT];
__s32 absmin[ABS_CNT];
__s32 absfuzz[ABS_CNT];
__s32 absflat[ABS_CNT];
};
#endif /* __UINPUT_H_ */

View file

@ -1,231 +1,5 @@
/*
* User level driver support for input subsystem
*
* Heavily based on evdev.c by Vojtech Pavlik
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
*
* Changes/Revisions:
* 0.5 08/13/2015 (David Herrmann <dh.herrmann@gmail.com> &
* Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - add UI_DEV_SETUP ioctl
* - add UI_ABS_SETUP ioctl
* - add UI_GET_VERSION ioctl
* 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>)
* - add UI_GET_SYSNAME ioctl
* 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
* - update ff support for the changes in kernel interface
* - add UINPUT_VERSION
* 0.2 16/10/2004 (Micah Dowty <micah@navi.cx>)
* - added force feedback support
* - added UI_SET_PHYS
* 0.1 20/06/2002
* - first public version
*/
#ifndef __UINPUT_H_
#define __UINPUT_H_
#include <linux/types.h>
#include <linux/input.h>
#define UINPUT_VERSION 5
#define UINPUT_MAX_NAME_SIZE 80
struct uinput_ff_upload {
__u32 request_id;
__s32 retval;
struct ff_effect effect;
struct ff_effect old;
};
struct uinput_ff_erase {
__u32 request_id;
__s32 retval;
__u32 effect_id;
};
/* ioctl */
#define UINPUT_IOCTL_BASE 'U'
#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
struct uinput_setup {
struct input_id id;
char name[UINPUT_MAX_NAME_SIZE];
__u32 ff_effects_max;
};
/**
* UI_DEV_SETUP - Set device parameters for setup
*
* This ioctl sets parameters for the input device to be created. It
* supersedes the old "struct uinput_user_dev" method, which wrote this data
* via write(). To actually set the absolute axes UI_ABS_SETUP should be
* used.
*
* The ioctl takes a "struct uinput_setup" object as argument. The fields of
* this object are as follows:
* id: See the description of "struct input_id". This field is
* copied unchanged into the new device.
* name: This is used unchanged as name for the new device.
* ff_effects_max: This limits the maximum numbers of force-feedback effects.
* See below for a description of FF with uinput.
*
* This ioctl can be called multiple times and will overwrite previous values.
* If this ioctl fails with -EINVAL, it is recommended to use the old
* "uinput_user_dev" method via write() as a fallback, in case you run on an
* old kernel that does not support this ioctl.
*
* This ioctl may fail with -EINVAL if it is not supported or if you passed
* incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
* passed uinput_setup object cannot be read/written.
* If this call fails, partial data may have already been applied to the
* internal device.
*/
#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup)
struct uinput_abs_setup {
__u16 code; /* axis code */
/* __u16 filler; */
struct input_absinfo absinfo;
};
/**
* UI_ABS_SETUP - Set absolute axis information for the device to setup
*
* This ioctl sets one absolute axis information for the input device to be
* created. It supersedes the old "struct uinput_user_dev" method, which wrote
* part of this data and the content of UI_DEV_SETUP via write().
*
* The ioctl takes a "struct uinput_abs_setup" object as argument. The fields
* of this object are as follows:
* code: The corresponding input code associated with this axis
* (ABS_X, ABS_Y, etc...)
* absinfo: See "struct input_absinfo" for a description of this field.
* This field is copied unchanged into the kernel for the
* specified axis. If the axis is not enabled via
* UI_SET_ABSBIT, this ioctl will enable it.
*
* This ioctl can be called multiple times and will overwrite previous values.
* If this ioctl fails with -EINVAL, it is recommended to use the old
* "uinput_user_dev" method via write() as a fallback, in case you run on an
* old kernel that does not support this ioctl.
*
* This ioctl may fail with -EINVAL if it is not supported or if you passed
* incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the
* passed uinput_setup object cannot be read/written.
* If this call fails, partial data may have already been applied to the
* internal device.
*/
#define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup)
#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
/**
* UI_GET_SYSNAME - get the sysfs name of the created uinput device
*
* @return the sysfs name of the created virtual input device.
* The complete sysfs path is then /sys/devices/virtual/input/--NAME--
* Usually, it is in the form "inputN"
*/
#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len)
/**
* UI_GET_VERSION - Return version of uinput protocol
*
* This writes uinput protocol version implemented by the kernel into
* the integer pointed to by the ioctl argument. The protocol version
* is hard-coded in the kernel and is independent of the uinput device.
*/
#define UI_GET_VERSION _IOR(UINPUT_IOCTL_BASE, 45, unsigned int)
/*
* To write a force-feedback-capable driver, the upload_effect
* and erase_effect callbacks in input_dev must be implemented.
* The uinput driver will generate a fake input event when one of
* these callbacks are invoked. The userspace code then uses
* ioctls to retrieve additional parameters and send the return code.
* The callback blocks until this return code is sent.
*
* The described callback mechanism is only used if ff_effects_max
* is set.
*
* To implement upload_effect():
* 1. Wait for an event with type == EV_UINPUT and code == UI_FF_UPLOAD.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_upload struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_UPLOAD ioctl, giving it the
* uinput_ff_upload struct. It will be filled in with the
* ff_effects passed to upload_effect().
* 4. Perform the effect upload, and place a return code back into
the uinput_ff_upload struct.
* 5. Issue a UI_END_FF_UPLOAD ioctl, also giving it the
* uinput_ff_upload_effect struct. This will complete execution
* of our upload_effect() handler.
*
* To implement erase_effect():
* 1. Wait for an event with type == EV_UINPUT and code == UI_FF_ERASE.
* A request ID will be given in 'value'.
* 2. Allocate a uinput_ff_erase struct, fill in request_id with
* the 'value' from the EV_UINPUT event.
* 3. Issue a UI_BEGIN_FF_ERASE ioctl, giving it the
* uinput_ff_erase struct. It will be filled in with the
* effect ID passed to erase_effect().
* 4. Perform the effect erasure, and place a return code back
* into the uinput_ff_erase struct.
* 5. Issue a UI_END_FF_ERASE ioctl, also giving it the
* uinput_ff_erase_effect struct. This will complete execution
* of our erase_effect() handler.
*/
/*
* This is the new event type, used only by uinput.
* 'code' is UI_FF_UPLOAD or UI_FF_ERASE, and 'value'
* is the unique request ID. This number was picked
* arbitrarily, above EV_MAX (since the input system
* never sees it) but in the range of a 16-bit int.
*/
#define EV_UINPUT 0x0101
#define UI_FF_UPLOAD 1
#define UI_FF_ERASE 2
struct uinput_user_dev {
char name[UINPUT_MAX_NAME_SIZE];
struct input_id id;
__u32 ff_effects_max;
__s32 absmax[ABS_CNT];
__s32 absmin[ABS_CNT];
__s32 absfuzz[ABS_CNT];
__s32 absflat[ABS_CNT];
};
#endif /* __UINPUT_H_ */
#ifdef __linux__
#include "linux/uinput.h"
#elif __FreeBSD__
#include "freebsd/uinput.h"
#endif

View file

@ -12,9 +12,11 @@ libevdev_la_SOURCES = \
libevdev-uinput-int.h \
libevdev.c \
libevdev-names.c \
../include/linux/input-event-codes.h \
../include/linux/input.h \
../include/linux/uinput.h
../include/linux/uinput.h \
../include/linux/@OS@/input-event-codes.h \
../include/linux/@OS@/input.h \
../include/linux/@OS@/uinput.h
libevdev_la_LDFLAGS = \
$(AM_LDFLAGS) \
@ -28,10 +30,10 @@ libevdevincludedir = $(includedir)/libevdev-1.0/libevdev
libevdevinclude_HEADERS = libevdev.h libevdev-uinput.h
event-names.h: Makefile make-event-names.py
$(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/input.h $(top_srcdir)/include/linux/input-event-codes.h > $@
$(PYTHON) $(srcdir)/make-event-names.py $(top_srcdir)/include/linux/@OS@/input.h $(top_srcdir)/include/linux/@OS@/input-event-codes.h > $@
EXTRA_DIST = make-event-names.py libevdev.sym
EXTRA_DIST = make-event-names.py libevdev.sym ../include
CLEANFILES = event-names.h
BUILT_SOURCES = event-names.h

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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.
*/
#ifndef LIBEVDEV_INT_H

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 David Herrmann <dh.herrmann@gmail.com>
*
* 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 "config.h"
@ -26,9 +9,10 @@
#include <string.h>
#include <strings.h>
#include "libevdev.h"
#include "libevdev-int.h"
#include "libevdev-util.h"
#include "libevdev.h"
#include "event-names.h"
struct name_lookup {

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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.
*/
struct libevdev_uinput {

View file

@ -1,44 +1,25 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/uinput.h>
#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <linux/uinput.h>
#include <unistd.h>
#include "libevdev.h"
#include "libevdev-int.h"
#include "libevdev-uinput.h"
#include "libevdev-uinput-int.h"
#include "libevdev-uinput.h"
#include "libevdev-util.h"
#define SYS_INPUT_DIR "/sys/devices/virtual/input/"
#include "libevdev.h"
#ifndef UINPUT_IOCTL_BASE
#define UINPUT_IOCTL_BASE 'U'
@ -182,6 +163,35 @@ libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
return uinput_dev->fd;
}
#ifdef __FreeBSD__
/*
* FreeBSD does not have anything similar to sysfs.
* Set libevdev_uinput->syspath to NULL unconditionally.
* Look up the device nodes directly instead of via sysfs, as this matches what
* is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.
*/
static int
fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
{
#define DEV_INPUT_DIR "/dev/input/"
int rc;
char buf[sizeof(DEV_INPUT_DIR) + 64] = DEV_INPUT_DIR;
rc = ioctl(uinput_dev->fd,
UI_GET_SYSNAME(sizeof(buf) - strlen(DEV_INPUT_DIR)),
&buf[strlen(DEV_INPUT_DIR)]);
if (rc == -1)
return -1;
uinput_dev->syspath = NULL;
uinput_dev->devnode = strdup(buf);
return 0;
#undef DEV_INPUT_DIR
}
#else /* !__FreeBSD__ */
static int is_event_device(const struct dirent *dent) {
return strncmp("event", dent->d_name, 5) == 0;
}
@ -217,6 +227,7 @@ static int is_input_device(const struct dirent *dent) {
static int
fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
{
#define SYS_INPUT_DIR "/sys/devices/virtual/input/"
struct dirent **namelist;
int ndev, i;
int rc;
@ -270,18 +281,19 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
/* FIXME: could descend into bit comparison here */
log_info(NULL, "multiple identical devices found. syspath is unreliable\n");
break;
} else {
rc = snprintf(buf, sizeof(buf), "%s%s",
SYS_INPUT_DIR,
namelist[i]->d_name);
if (rc < 0 || (size_t)rc >= sizeof(buf)) {
log_error(NULL, "Invalid syspath, syspath is unreliable\n");
break;
}
uinput_dev->syspath = strdup(buf);
uinput_dev->devnode = fetch_device_node(buf);
}
rc = snprintf(buf, sizeof(buf), "%s%s",
SYS_INPUT_DIR,
namelist[i]->d_name);
if (rc < 0 || (size_t)rc >= sizeof(buf)) {
log_error(NULL, "Invalid syspath, syspath is unreliable\n");
break;
}
uinput_dev->syspath = strdup(buf);
uinput_dev->devnode = fetch_device_node(buf);
}
}
@ -290,7 +302,9 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
free(namelist);
return uinput_dev->devnode ? 0 : -1;
#undef SYS_INPUT_DIR
}
#endif /* __FreeBSD__*/
static int
uinput_create_write(const struct libevdev *dev, int fd)
@ -454,7 +468,13 @@ libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
unsigned int code,
int value)
{
struct input_event ev = { {0,0}, type, code, value };
struct input_event ev = {
.input_event_sec = 0,
.input_event_usec = 0,
.type = type,
.code = code,
.value = value
};
int fd = libevdev_uinput_get_fd(uinput_dev);
int rc, max;

View file

@ -1,23 +1,25 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef LIBEVDEV_UINPUT_H
@ -40,14 +42,13 @@ struct libevdev_uinput;
*
* @code
* int err;
* int fd, new_fd, uifd;
* int fd, uifd;
* struct libevdev *dev;
* struct libevdev_uinput *uidev;
* struct input_event ev[2];
*
* fd = open("/dev/input/event0", O_RDONLY);
* if (fd < 0)
* return err;
* return -errno;
*
* err = libevdev_new_from_fd(fd, &dev);
* if (err != 0)
@ -65,7 +66,7 @@ struct libevdev_uinput;
* err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1);
* if (err != 0)
* return err;
* libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
* err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0);
* if (err != 0)
* return err;
*
@ -107,7 +108,7 @@ struct libevdev_uinput;
*/
enum libevdev_uinput_open_mode {
/* intentionally -2 to avoid to avoid code like the below from accidentally working:
/* intentionally -2 to avoid code like below from accidentally working:
fd = open("/dev/uinput", O_RDWR); // fails, fd is -1
libevdev_uinput_create_from_device(dev, fd, &uidev); // may hide the error */
LIBEVDEV_UINPUT_OPEN_MANAGED = -2 /**< let libevdev open and close @c /dev/uinput */
@ -138,6 +139,9 @@ enum libevdev_uinput_open_mode {
* REP_PERIOD will default to the kernel defaults, not to the ones set in the
* source device.
*
* @note On FreeBSD, if the UI_GET_SYSNAME ioctl() fails, there is no other way
* to get a device, and the function call will fail.
*
* @param dev The device to duplicate
* @param uinput_fd @ref LIBEVDEV_UINPUT_OPEN_MANAGED or a file descriptor to @c /dev/uinput,
* @param[out] uinput_dev The newly created libevdev device.
@ -183,7 +187,7 @@ int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
* @ingroup uinput
*
* Return the syspath representing this uinput device. If the UI_GET_SYSNAME
* ioctl not available, libevdev makes an educated guess.
* ioctl is not available, libevdev makes an educated guess.
* The UI_GET_SYSNAME ioctl is available since Linux 3.15.
*
* The syspath returned is the one of the input node itself
@ -192,8 +196,11 @@ int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev);
*
* @note This function may return NULL if UI_GET_SYSNAME is not available.
* In that case, libevdev uses ctime and the device name to guess devices.
* To avoid false positives, wait at least wait at least 1.5s between
* creating devices that have the same name.
* To avoid false positives, wait at least 1.5s between creating devices that
* have the same name.
*
* @note FreeBSD does not have sysfs, on FreeBSD this function always returns
* NULL.
*
* @param uinput_dev A previously created uinput device.
* @return The syspath for this device, including the preceding /sys
@ -212,6 +219,11 @@ const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
*
* @note This function may return NULL. libevdev may have to guess the
* syspath and the device node. See libevdev_uinput_get_syspath() for details.
*
* @note On FreeBSD, this function can not return NULL. libudev uses the
* UI_GET_SYSNAME ioctl to get the device node on this platform and if that
* fails, the call to libevdev_uinput_create_from_device() fails.
*
* @param uinput_dev A previously created uinput device.
* @return The device node for this device, in the form of /dev/input/eventN
*

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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.
*/
#ifndef _UTIL_H_
@ -59,19 +42,19 @@ startswith(const char *str, size_t len, const char *prefix, size_t plen)
static inline int
bit_is_set(const unsigned long *array, int bit)
{
return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
return !!(array[bit / LONG_BITS] & (1ULL << (bit % LONG_BITS)));
}
static inline void
set_bit(unsigned long *array, int bit)
{
array[bit / LONG_BITS] |= (1LL << (bit % LONG_BITS));
array[bit / LONG_BITS] |= (1ULL << (bit % LONG_BITS));
}
static inline void
clear_bit(unsigned long *array, int bit)
{
array[bit / LONG_BITS] &= ~(1LL << (bit % LONG_BITS));
array[bit / LONG_BITS] &= ~(1ULL << (bit % LONG_BITS));
}
static inline void

View file

@ -1,39 +1,23 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
#include <errno.h>
#include <limits.h>
#include <poll.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include "libevdev.h"
#include "libevdev-int.h"
#include "libevdev-util.h"
#include "libevdev.h"
#include "event-names.h"
#define MAXEVENTS 64
@ -60,7 +44,8 @@ struct slot_change_state {
};
static int sync_mt_state(struct libevdev *dev,
struct slot_change_state *changes_out);
struct slot_change_state changes_out[dev->num_slots]);
static int
update_key_state(struct libevdev *dev, const struct input_event *e);
@ -316,8 +301,7 @@ _libevdev_log_priority(const struct libevdev *dev)
{
if (dev && dev->log.device_handler)
return dev->log.priority;
else
return libevdev_get_log_priority();
return libevdev_get_log_priority();
}
LIBEVDEV_EXPORT int
@ -397,7 +381,9 @@ libevdev_set_fd(struct libevdev* dev, int fd)
if (dev->initialized) {
log_bug(dev, "device already initialized.\n");
return -EBADF;
} else if (fd < 0) {
}
if (fd < 0) {
return -EBADF;
}
@ -819,23 +805,34 @@ push_mt_sync_events(struct libevdev *dev,
int rc;
for (int slot = 0; slot < dev->num_slots; slot++) {
/* stopped touches were already terminated in
* terminate_slots */
if (changes[slot].state == TOUCH_STOPPED ||
!bit_is_set(changes[slot].axes, ABS_MT_SLOT))
continue;
bool have_slot_event = false;
queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot);
last_reported_slot = slot;
if (!bit_is_set(changes[slot].axes, ABS_MT_SLOT))
continue;
for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) {
if (axis == ABS_MT_SLOT ||
!libevdev_has_event_code(dev, EV_ABS, axis))
continue;
if (bit_is_set(changes[slot].axes, axis))
if (bit_is_set(changes[slot].axes, axis)) {
/* We already sent the tracking id -1 in
* terminate_slots so don't do that again. There
* may be other axes like ABS_MT_TOOL_TYPE that
* need to be synced despite no touch being active */
if (axis == ABS_MT_TRACKING_ID &&
*slot_value(dev, slot, axis) == -1)
continue;
if (!have_slot_event) {
queue_push_event(dev, EV_ABS, ABS_MT_SLOT, slot);
last_reported_slot = slot;
have_slot_event = true;
}
queue_push_event(dev, EV_ABS, axis,
*slot_value(dev, slot, axis));
}
}
}
@ -869,11 +866,13 @@ read_more_events(struct libevdev *dev)
next = queue_next_element(dev);
len = read(dev->fd, next, free_elem * sizeof(struct input_event));
if (len < 0) {
if (len < 0)
return -errno;
} else if (len > 0 && len % sizeof(struct input_event) != 0) {
if (len > 0 && len % sizeof(struct input_event) != 0)
return -EINVAL;
} else if (len > 0) {
if (len > 0) {
int nev = len/sizeof(struct input_event);
queue_set_num_elements(dev, queue_num_elements(dev) + nev);
}
@ -923,7 +922,8 @@ sync_state(struct libevdev *dev)
bool want_mt_sync = false;
int last_reported_slot = 0;
struct slot_change_state changes[dev->num_slots > 0 ? dev->num_slots : 1];
memset(changes, 0, sizeof(changes));
memset(changes, 0, sizeof(changes));
/* see section "Discarding events before synchronizing" in
* libevdev/libevdev.h */
@ -996,10 +996,11 @@ update_mt_state(struct libevdev *dev, const struct input_event *e)
}
return 0;
} else if (dev->current_slot == -1) {
return 1;
}
if (dev->current_slot == -1)
return 1;
*slot_value(dev, dev->current_slot, e->code) = e->value;
return 0;
@ -1103,7 +1104,9 @@ sanitize_event(const struct libevdev *dev,
N to -1 or from -1 to N. Never from -1 to -1, or N to M. Very
unlikely to ever happen from a real device.
*/
} else if (unlikely(sync_state == SYNC_NONE &&
}
if (unlikely(sync_state == SYNC_NONE &&
dev->num_slots > -1 &&
libevdev_event_is_code(ev, EV_ABS, ABS_MT_TRACKING_ID) &&
((ev->value == -1 &&
@ -1131,10 +1134,11 @@ libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event
if (!dev->initialized) {
log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0) {
return -EBADF;
}
if (dev->fd < 0)
return -EBADF;
if ((flags & valid_flags) == 0) {
log_bug(dev, "invalid flags %#x.\n", flags);
return -EINVAL;
@ -1223,10 +1227,11 @@ libevdev_has_event_pending(struct libevdev *dev)
if (!dev->initialized) {
log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0) {
return -EBADF;
}
if (dev->fd < 0)
return -EBADF;
if (queue_num_elements(dev) != 0)
return 1;
@ -1309,6 +1314,16 @@ libevdev_enable_property(struct libevdev *dev, unsigned int prop)
return 0;
}
LIBEVDEV_EXPORT int
libevdev_disable_property(struct libevdev *dev, unsigned int prop)
{
if (prop > INPUT_PROP_MAX)
return -1;
clear_bit(dev->props, prop);
return 0;
}
LIBEVDEV_EXPORT int
libevdev_has_event_type(const struct libevdev *dev, unsigned int type)
{
@ -1405,9 +1420,9 @@ libevdev_fetch_event_value(const struct libevdev *dev, unsigned int type, unsign
libevdev_has_event_code(dev, type, code)) {
*value = libevdev_get_event_value(dev, type, code);
return 1;
} else {
return 0;
}
return 0;
}
LIBEVDEV_EXPORT int
@ -1457,9 +1472,9 @@ libevdev_fetch_slot_value(const struct libevdev *dev, unsigned int slot, unsigne
slot < (unsigned int)dev->num_slots) {
*value = libevdev_get_slot_value(dev, slot, code);
return 1;
} else {
return 0;
}
return 0;
}
LIBEVDEV_EXPORT int
@ -1646,10 +1661,11 @@ libevdev_kernel_set_abs_info(struct libevdev *dev, unsigned int code, const stru
if (!dev->initialized) {
log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0) {
return -EBADF;
}
if (dev->fd < 0)
return -EBADF;
if (code > ABS_MAX)
return -EINVAL;
@ -1670,10 +1686,11 @@ libevdev_grab(struct libevdev *dev, enum libevdev_grab_mode grab)
if (!dev->initialized) {
log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0) {
return -EBADF;
}
if (dev->fd < 0)
return -EBADF;
if (grab != LIBEVDEV_GRAB && grab != LIBEVDEV_UNGRAB) {
log_bug(dev, "invalid grab parameter %#x\n", grab);
return -EINVAL;
@ -1799,10 +1816,11 @@ libevdev_kernel_set_led_values(struct libevdev *dev, ...)
if (!dev->initialized) {
log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0) {
return -EBADF;
}
if (dev->fd < 0)
return -EBADF;
memset(ev, 0, sizeof(ev));
va_start(args, dev);
@ -1856,9 +1874,10 @@ libevdev_set_clock_id(struct libevdev *dev, int clockid)
if (!dev->initialized) {
log_bug(dev, "device not initialized. call libevdev_set_fd() first\n");
return -EBADF;
} else if (dev->fd < 0) {
return -EBADF;
}
if (dev->fd < 0)
return -EBADF;
return ioctl(dev->fd, EVIOCSCLOCKID, &clockid) ? -errno : 0;
}

View file

@ -1,23 +1,26 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* 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.
*/
#ifndef LIBEVDEV_H
@ -160,12 +163,13 @@ extern "C" {
* License information
* ===================
* libevdev is licensed under the
* [X11 license](http://cgit.freedesktop.org/libevdev/tree/COPYING).
* [MIT license](http://cgit.freedesktop.org/libevdev/tree/COPYING).
*
* Bindings
* ===================
* - Python: https://gitlab.freedesktop.org/libevdev/python-libevdev
* - Haskell: http://hackage.haskell.org/package/evdev
* - Rust: https://crates.io/crates/evdev-rs
*
* Reporting bugs
* ==============
@ -496,11 +500,11 @@ extern "C" {
* <dd>supported, see libevdev_enable_event_code()</dd>
* <dt>EVIOCGKEYCODE:</dt>
* <dd>currently not supported</dd>
* <dt>EVIOCGKEYCODE:</dt>
* <dd>currently not supported</dd>
* <dt>EVIOCSKEYCODE:</dt>
* <dd>currently not supported</dd>
* <dt>EVIOCSKEYCODE:</dt>
* <dt>EVIOCGKEYCODE_V2:</dt>
* <dd>currently not supported</dd>
* <dt>EVIOCSKEYCODE_V2:</dt>
* <dd>currently not supported</dd>
* <dt>EVIOCGNAME:</dt>
* <dd>supported, see libevdev_get_name()</dd>
@ -540,6 +544,10 @@ extern "C" {
* <dt>EVIOCREVOKE:</dt>
* <dd>currently not supported, see
* http://lists.freedesktop.org/archives/input-tools/2014-January/000688.html</dd>
* <dt>EVIOCGMASK:</dt>
* <dd>currently not supported</dd>
* <dt>EVIOCSMASK:</dt>
* <dd>currently not supported</dd>
* </dl>
*
*/
@ -630,7 +638,7 @@ extern "C" {
* return ENOMEM;
*
* err = libevdev_set_fd(dev, fd);
* if (err < 0) {
* if (err < 0)
* printf("Failed (errno %d): %s\n", -err, strerror(-err));
*
* libevdev_free(dev);
@ -1387,6 +1395,16 @@ int libevdev_has_property(const struct libevdev *dev, unsigned int prop);
*/
int libevdev_enable_property(struct libevdev *dev, unsigned int prop);
/**
* @ingroup kernel
*
* @param dev The evdev device
* @param prop The input property to disable, one of INPUT_PROP_...
*
* @return 0 on success or -1 on failure
*/
int libevdev_disable_property(struct libevdev *dev, unsigned int prop);
/**
* @ingroup bits
*
@ -1504,8 +1522,7 @@ const struct input_absinfo* libevdev_get_abs_info(const struct libevdev *dev, un
* the event.
*
* If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_*
* event code is the value of the currently active slot. You should use
* libevdev_get_slot_value() instead.
* event code is undefined. Use libevdev_get_slot_value() instead.
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param type The event type for the code to query (EV_SYN, EV_REL, etc.)
@ -1546,8 +1563,7 @@ int libevdev_get_event_value(const struct libevdev *dev, unsigned int type, unsi
*
* @return 0 on success, or -1 on failure.
* @retval -1
* - the device does not have the event type or
* - code enabled, or the code is outside the, or
* - the device does not have the event type or code enabled, or
* - the code is outside the allowed limits for the given type, or
* - the type cannot be set, or
* - the value is not permitted for the given code.
@ -1704,9 +1720,9 @@ int libevdev_get_current_slot(const struct libevdev *dev);
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param code One of ABS_X, ABS_Y, ...
* @param min The new minimum for this axis
* @param val The new minimum for this axis
*/
void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int min);
void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int val);
/**
* @ingroup kernel
@ -1717,9 +1733,9 @@ void libevdev_set_abs_minimum(struct libevdev *dev, unsigned int code, int min);
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param code One of ABS_X, ABS_Y, ...
* @param max The new maxium for this axis
* @param val The new maxium for this axis
*/
void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int max);
void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int val);
/**
* @ingroup kernel
@ -1730,9 +1746,9 @@ void libevdev_set_abs_maximum(struct libevdev *dev, unsigned int code, int max);
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param code One of ABS_X, ABS_Y, ...
* @param fuzz The new fuzz for this axis
* @param val The new fuzz for this axis
*/
void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int fuzz);
void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int val);
/**
* @ingroup kernel
@ -1743,9 +1759,9 @@ void libevdev_set_abs_fuzz(struct libevdev *dev, unsigned int code, int fuzz);
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param code One of ABS_X, ABS_Y, ...
* @param flat The new flat for this axis
* @param val The new flat for this axis
*/
void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int flat);
void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int val);
/**
* @ingroup kernel
@ -1756,9 +1772,9 @@ void libevdev_set_abs_flat(struct libevdev *dev, unsigned int code, int flat);
*
* @param dev The evdev device, already initialized with libevdev_set_fd()
* @param code One of ABS_X, ABS_Y, ...
* @param resolution The new axis resolution
* @param val The new axis resolution
*/
void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int resolution);
void libevdev_set_abs_resolution(struct libevdev *dev, unsigned int code, int val);
/**
* @ingroup kernel

View file

@ -1,23 +1,6 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (c) 2013 David Herrmann <dh.herrmann@gmail.com>
*
* 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.
*/
LIBEVDEV_1 {
@ -131,3 +114,10 @@ global:
local:
*;
} LIBEVDEV_1_6;
LIBEVDEV_1_10 {
global:
libevdev_disable_property;
local:
*;
} LIBEVDEV_1_7;

View file

@ -70,10 +70,10 @@ def print_bits(bits, prefix):
if not hasattr(bits, prefix):
return
print("static const char * const %s_map[%s_MAX + 1] = {" % (prefix, prefix.upper()))
for val, name in list(getattr(bits, prefix).items()):
for val, name in sorted(list(getattr(bits, prefix).items())):
print(" [%s] = \"%s\"," % (name, name))
if prefix == "key":
for val, name in list(getattr(bits, "btn").items()):
for val, name in sorted(list(getattr(bits, "btn").items())):
print(" [%s] = \"%s\"," % (name, name))
print("};")
print("")
@ -118,7 +118,7 @@ def print_lookup(bits, prefix):
if not hasattr(bits, prefix):
return
names = list(getattr(bits, prefix).items())
names = sorted(list(getattr(bits, prefix).items()))
if prefix == "btn":
names = names + btn_additional

View file

@ -1,13 +1,14 @@
project('libevdev', 'c',
version: '1.9.1', # change autotools version too
version: '1.13.6', # change autotools version too
license: 'MIT/Expat',
default_options: [ 'c_std=gnu99', 'warning_level=2' ],
meson_version: '>= 0.47.0')
meson_version: '>= 0.56.0')
libevdev_version = meson.project_version().split('.')
dir_src = join_paths(meson.source_root(), 'libevdev')
dir_src_test = join_paths(meson.source_root(), 'test')
dir_root = meson.project_source_root()
dir_src = dir_root / 'libevdev'
dir_src_test = dir_root / 'test'
# Include directories
includes_include = include_directories('include')
@ -37,11 +38,12 @@ config_h.set('_GNU_SOURCE', '1')
# Dependencies
pkgconfig = import('pkgconfig')
dep_lm = cc.find_library('m')
dep_rt = cc.find_library('rt')
input_h = dir_root / 'include' / 'linux' / host_machine.system() / 'input.h'
input_event_codes_h = dir_root / 'include' / 'linux' / host_machine.system() / 'input-event-codes.h'
# event-names.h
input_h = join_paths(meson.source_root(), 'include', 'linux', 'input.h')
input_event_codes_h = join_paths(meson.source_root(), 'include', 'linux', 'input-event-codes.h')
make_event_names = find_program('libevdev/make-event-names.py')
event_names_h = configure_file(input: 'libevdev/libevdev.h',
output: 'event-names.h',
@ -53,8 +55,7 @@ event_names_h = configure_file(input: 'libevdev/libevdev.h',
install_headers('libevdev/libevdev.h',
'libevdev/libevdev-uinput.h',
subdir: 'libevdev-1.0/libevdev')
src_libevdev = [
event_names_h,
src_libevdev = [event_names_h] + files(
'libevdev/libevdev.h',
'libevdev/libevdev-int.h',
'libevdev/libevdev-util.h',
@ -63,24 +64,25 @@ src_libevdev = [
'libevdev/libevdev-uinput-int.h',
'libevdev/libevdev.c',
'libevdev/libevdev-names.c',
'include/linux/input-event-codes.h',
'include/linux/input.h',
'include/linux/uinput.h'
]
'include/linux/uinput.h',
)
mapfile = join_paths(dir_src, 'libevdev.sym')
mapfile = dir_src / 'libevdev.sym'
version_flag = '-Wl,--version-script,@0@'.format(mapfile)
lib_libevdev = library('evdev',
src_libevdev,
include_directories: [includes_include],
dependencies: [],
dependencies: [dep_rt],
version: libevdev_so_version,
link_args: version_flag,
link_depends: mapfile,
install: true
)
dep_libevdev = declare_dependency(link_with: lib_libevdev)
inc_libevdev = include_directories('.')
dep_libevdev = declare_dependency(link_with: lib_libevdev,
include_directories: [inc_libevdev])
pkgconfig.generate(
filebase: 'libevdev',
@ -100,27 +102,36 @@ install_man(manpage)
# tools
executable('libevdev-events',
sources: ['tools/libevdev-events.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: false)
executable('touchpad-edge-detector',
sources: ['tools/touchpad-edge-detector.c'],
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_lm],
install: true)
executable('mouse-dpi-tool',
sources: ['tools/mouse-dpi-tool.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: true)
executable('libevdev-tweak-device',
sources: ['tools/libevdev-tweak-device.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: true)
if not get_option('tools').disabled()
executable('libevdev-events',
sources: ['tools/libevdev-events.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: false)
executable('libevdev-list-codes',
sources: ['tools/libevdev-list-codes.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: false)
executable('touchpad-edge-detector',
sources: ['tools/touchpad-edge-detector.c'],
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_lm],
install: true)
executable('mouse-dpi-tool',
sources: ['tools/mouse-dpi-tool.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: true)
executable('libevdev-tweak-device',
sources: ['tools/libevdev-tweak-device.c'],
include_directories: [includes_include],
dependencies: dep_libevdev,
install: true)
install_man('tools/libevdev-tweak-device.1',
'tools/touchpad-edge-detector.1',
'tools/mouse-dpi-tool.1')
endif
# tests
dep_check = dependency('check', version: '>= 0.9.9',
@ -154,7 +165,7 @@ if dep_check.found()
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_check],
install: false)
test('test-event-codes', test_event_codes, suite: 'library')
test('test-event-codes', test_event_codes, suite: ['library', 'needs-uinput'])
test_internals = executable('test-internals',
sources: src_common + [
@ -163,7 +174,7 @@ if dep_check.found()
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_check],
install: false)
test('test-internals', test_internals, suite: 'library')
test('test-internals', test_internals, suite: ['library', 'needs-uinput'])
test_uinput = executable('test-uinput',
sources: src_common + [
@ -172,7 +183,7 @@ if dep_check.found()
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_check],
install: false)
test('test-uinput', test_uinput, suite: 'library')
test('test-uinput', test_uinput, suite: ['library', 'needs-uinput'])
test_libevdev = executable('test-libevdev',
sources: src_common + [
@ -183,7 +194,7 @@ if dep_check.found()
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_check],
install: false)
test('test-libevdev', test_libevdev, suite: 'library')
test('test-libevdev', test_libevdev, suite: ['library', 'needs-uinput'], env: ['CK_DEFAULT_TIMEOUT=10'])
test_kernel = executable('test-kernel',
sources: src_common + [
@ -192,7 +203,7 @@ if dep_check.found()
include_directories: [includes_include],
dependencies: [dep_libevdev, dep_check],
install: false)
test('test-kernel', test_kernel, suite: 'kernel')
test('test-kernel', test_kernel, suite: ['kernel', 'needs-uinput'])
valgrind = find_program('valgrind', required: false)
@ -201,14 +212,14 @@ if dep_check.found()
valgrind_env.set('CK_TIMEOUT_MULTIPLIER', '10')
valgrind_env.set('CK_FORK', 'no')
valgrind_env.set('RUNNING_ON_VALGRIND', '1')
valgrind_suppressions_file = join_paths(dir_src_test, 'valgrind.suppressions')
valgrind_suppressions_file = dir_src_test / 'valgrind.suppressions'
add_test_setup('valgrind',
exe_wrapper: [ valgrind,
'--leak-check=full',
'--gen-suppressions=all',
'--error-exitcode=3',
'--suppressions=' + valgrind_suppressions_file ],
env: valgrind_env,
env: valgrind_env,
timeout_multiplier: 100)
else
message('valgrind not found, disabling valgrind test suite')
@ -222,12 +233,10 @@ endif
doxygen = find_program('doxygen', required: get_option('documentation'))
if doxygen.found()
doxygen = find_program('doxygen')
src_doxygen = files(
# source files
join_paths(dir_src, 'libevdev.h'),
join_paths(dir_src, 'libevdev-uinput.h'),
dir_src / 'libevdev.h',
dir_src / 'libevdev-uinput.h',
# style files
'doc/style/bootstrap.css',
'doc/style/customdoxygen.css',
@ -253,8 +262,8 @@ if doxygen.found()
doc_config.set('PACKAGE_NAME', meson.project_name())
doc_config.set('PACKAGE_VERSION', meson.project_version())
doc_config.set('builddir', meson.current_build_dir())
doc_config.set('top_srcdir', meson.source_root())
doc_config.set('srcdir', join_paths(meson.source_root(), 'doc'))
doc_config.set('top_srcdir', dir_root)
doc_config.set('srcdir', dir_root / 'doc')
doxyfile = configure_file(input: 'doc/libevdev.doxygen.in',
output: 'libevdev.doxygen',

View file

@ -2,11 +2,15 @@ option('tests',
type: 'feature',
value: 'enabled',
description: 'Build the tests')
option('tools',
type: 'feature',
value: 'enabled',
description: 'Build the tools')
option('documentation',
type: 'feature',
value: 'enabled',
description: 'Build the documentation')
option('coverity',
type: 'boolean',
value: 'false',
value: false,
description: 'Enable coverity build fixes, see meson.build for details')

View file

@ -89,24 +89,11 @@ test_kernel_SOURCES = \
test_kernel_CFLAGS = -I$(top_srcdir)
test_kernel_LDADD = $(CHECK_LIBS) $(top_builddir)/libevdev/libevdev.la
if HAVE_VALGRIND
VALGRIND_FLAGS=--leak-check=full \
--quiet \
--error-exitcode=3 \
--suppressions=$(srcdir)/valgrind.suppressions
valgrind:
$(MAKE) check-TESTS CK_TIMEOUT_MULTIPLIER=10 LOG_COMPILER="$(VALGRIND)" LOG_FLAGS="$(VALGRIND_FLAGS)"
check_local_deps += valgrind
endif
if GCOV_ENABLED
CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda
gcov-report: generate-gcov-report.sh check-TESTS
gcov-report: generate-gcov-report.sh
$(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/libevdev $(builddir)
gcov: gcov-report

View file

@ -1,4 +1,6 @@
#!/bin/bash -e
#!/usr/bin/env bash
set -e
if [[ $# -lt 2 ]]; then
echo "Usage: ./generate-gcov-report.sh <rel-target-dir> <srcdir> [<srcdir> ... ]"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 David Herrmann <dh.herrmann@gmail.com>
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
@ -175,7 +158,7 @@ START_TEST(test_code_sw_name)
ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_RFKILL_ALL), "SW_RFKILL_ALL");
ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_LINEIN_INSERT), "SW_LINEIN_INSERT");
ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_PEN_INSERTED), "SW_PEN_INSERTED");
ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_MAX), "SW_PEN_INSERTED");
ck_assert_str_eq(libevdev_event_code_get_name(EV_SW, SW_MAX), "SW_USB_INSERT");
}
END_TEST

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2014 Red Hat, Inc.
*
* 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 "config.h"

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
@ -634,12 +617,12 @@ START_TEST(test_syn_delta_sw)
EV_SYN, SYN_DROPPED,
EV_SW, SW_HEADPHONE_INSERT,
EV_SW, SW_MICROPHONE_INSERT,
EV_SW, SW_MAX,
EV_SW, SW_MACHINE_COVER, /* Replace with SW_MAX once runners are on 6.16 */
-1);
uinput_device_event(uidev, EV_SW, SW_HEADPHONE_INSERT, 1);
uinput_device_event(uidev, EV_SW, SW_MICROPHONE_INSERT, 1);
uinput_device_event(uidev, EV_SW, SW_MAX, 1);
uinput_device_event(uidev, EV_SW, SW_MACHINE_COVER, 1);
uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
@ -652,7 +635,7 @@ START_TEST(test_syn_delta_sw)
assert_event(&ev, EV_SW, SW_MICROPHONE_INSERT, 1);
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
assert_event(&ev, EV_SW, SW_MAX, 1);
assert_event(&ev, EV_SW, SW_MACHINE_COVER, 1);
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
assert_event(&ev, EV_SYN, SYN_REPORT, 0);
@ -661,7 +644,7 @@ START_TEST(test_syn_delta_sw)
ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_HEADPHONE_INSERT), 1);
ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MICROPHONE_INSERT), 1);
ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MAX), 1);
ck_assert_int_eq(libevdev_get_event_value(dev, EV_SW, SW_MACHINE_COVER), 1);
uinput_device_free(uidev);
libevdev_free(dev);
@ -1025,6 +1008,206 @@ START_TEST(test_syn_delta_tracking_ids_btntool)
}
END_TEST
START_TEST(test_syn_delta_mt_tool_type)
{
struct uinput_device* uidev;
struct libevdev *dev;
int rc;
struct input_event ev;
int i;
const int num_slots = 15;
int slot = -1;
unsigned long terminated[NLONGS(num_slots)];
struct input_absinfo abs[7] = {
{ .value = ABS_X, .maximum = 1000 },
{ .value = ABS_Y, .maximum = 1000 },
{ .value = ABS_MT_POSITION_X, .maximum = 1000 },
{ .value = ABS_MT_POSITION_Y, .maximum = 1000 },
{ .value = ABS_MT_TOOL_TYPE, .maximum = MT_TOOL_PALM },
{ .value = ABS_MT_SLOT, .maximum = num_slots },
{ .value = ABS_MT_TRACKING_ID, .minimum = -1, .maximum = 0xff },
};
test_create_abs_device(&uidev, &dev,
ARRAY_LENGTH(abs), abs,
EV_SYN, SYN_REPORT,
-1);
for (i = num_slots; i >= 0; i--) {
int tool_type = MT_TOOL_FINGER;
switch (i) {
case 0:
case 1:
case 2:
case 3:
tool_type = MT_TOOL_FINGER;
break;
case 4:
case 5:
case 6:
case 7:
tool_type = MT_TOOL_PALM;
break;
}
uinput_device_event_multiple(uidev,
EV_ABS, ABS_MT_SLOT, i,
EV_ABS, ABS_MT_TRACKING_ID, i,
EV_ABS, ABS_X, 100 + i,
EV_ABS, ABS_Y, 500 + i,
EV_ABS, ABS_MT_POSITION_X, 100 + i,
EV_ABS, ABS_MT_POSITION_Y, 500 + i,
EV_ABS, ABS_MT_TOOL_TYPE, tool_type,
EV_SYN, SYN_REPORT, 0,
-1, -1);
do {
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
ck_assert_int_ne(rc, LIBEVDEV_READ_STATUS_SYNC);
} while (rc >= 0);
}
/* we have a bunch of touches now, and libevdev knows it. Change all
* touches */
for (i = num_slots; i >= 0; i--) {
uinput_device_event(uidev, EV_ABS, ABS_MT_SLOT, i);
switch (i) {
/* Slot 0 is a finger and stays a finger */
case 0:
/* Slot 4 is a palm and stays a palm */
case 4:
uinput_device_event_multiple(uidev,
EV_ABS, ABS_X, 200 + i,
EV_ABS, ABS_Y, 700 + i,
EV_ABS, ABS_MT_POSITION_X, 200 + i,
EV_ABS, ABS_MT_POSITION_Y, 700 + i,
-1, -1);
break;
/* Slot 1 is a finger and changes active touch to palm */
case 1:
uinput_device_event(uidev, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
break;
/* Slot 2 is a finger and terminates */
case 2:
/* Slot 6 is a palm and terminates */
case 6:
uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
break;
/* Slot 3 is a finger and restarts as finger */
case 3:
/* Slot 5 is a palm and restarts as finger */
case 5:
uinput_device_event_multiple(uidev,
EV_ABS, ABS_MT_TRACKING_ID, num_slots + i,
EV_ABS, ABS_X, 200 + i,
EV_ABS, ABS_Y, 700 + i,
EV_ABS, ABS_MT_POSITION_X, 200 + i,
EV_ABS, ABS_MT_POSITION_Y, 700 + i,
EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER,
-1, -1);
break;
/* Slot 7 is a palm and restarts and terminates again as finger */
case 7:
uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
uinput_device_event_multiple(uidev,
EV_ABS, ABS_MT_TRACKING_ID, num_slots + i,
EV_ABS, ABS_X, 200 + i,
EV_ABS, ABS_Y, 700 + i,
EV_ABS, ABS_MT_POSITION_X, 200 + i,
EV_ABS, ABS_MT_POSITION_Y, 700 + i,
EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER,
-1, -1);
uinput_device_event(uidev, EV_ABS, ABS_MT_TRACKING_ID, -1);
uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
break;
}
uinput_device_event(uidev, EV_SYN, SYN_REPORT, 0);
}
/* Force sync */
rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
ck_assert_int_eq(rc, LIBEVDEV_READ_STATUS_SYNC);
/* now check for the right tracking IDs */
memset(terminated, 0, sizeof(terminated));
slot = -1;
while ((rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev)) != -EAGAIN) {
if (libevdev_event_is_code(&ev, EV_SYN, SYN_REPORT))
continue;
if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_SLOT)) {
slot = ev.value;
continue;
}
if (libevdev_event_is_code(&ev, EV_ABS, ABS_X) ||
libevdev_event_is_code(&ev, EV_ABS, ABS_Y))
continue;
ck_assert_int_ne(slot, -1);
if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_TRACKING_ID)) {
switch (slot) {
case 0:
case 1:
case 4:
ck_abort_msg("No ABS_MT_TRACKING_ID expected for this slot");
break;
case 2:
case 6:
case 7:
ck_assert_int_eq(ev.value, -1);
break;
case 3:
case 5:
if (!bit_is_set(terminated, slot)) {
ck_assert_int_eq(ev.value, -1);
set_bit(terminated, slot);
} else {
ck_assert_int_eq(ev.value, num_slots + slot);
}
break;
}
continue;
}
if (libevdev_event_is_code(&ev, EV_ABS, ABS_MT_TOOL_TYPE)) {
switch (slot) {
case 0:
case 2:
case 3:
case 4:
case 6:
ck_abort_msg("No ABS_MT_TOOL_TYPE expected for this slot");
break;
case 1:
ck_assert_int_eq(ev.value, MT_TOOL_PALM);
break;
case 5:
case 7:
ck_assert_int_eq(ev.value, MT_TOOL_FINGER);
break;
}
continue;
}
switch(ev.code) {
case ABS_MT_POSITION_X:
ck_assert_int_eq(ev.value, 200 + slot);
break;
case ABS_MT_POSITION_Y:
ck_assert_int_eq(ev.value, 700 + slot);
break;
default:
ck_abort();
}
}
uinput_device_free(uidev);
libevdev_free(dev);
}
END_TEST
START_TEST(test_syn_delta_late_sync)
{
struct uinput_device* uidev;
@ -2077,6 +2260,7 @@ TEST_SUITE_ROOT_PRIVILEGES(libevdev_events)
add_test(s, test_syn_delta_late_sync);
add_test(s, test_syn_delta_tracking_ids);
add_test(s, test_syn_delta_tracking_ids_btntool);
add_test(s, test_syn_delta_mt_tool_type);
add_test(s, test_skipped_sync);
add_test(s, test_incomplete_sync);

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
@ -117,6 +100,14 @@ START_TEST(test_event_codes)
continue;
}
#ifdef __FreeBSD__
/* Force feedback events are not supported by FreeBSD */
if (*evbit == EV_FF) {
evbit++;
continue;
}
#endif
max = libevdev_event_type_get_max(*evbit);
for (code = 1; code < max; code += 10) {
@ -125,10 +116,11 @@ START_TEST(test_event_codes)
test_create_abs_device(&uidev, &dev,
1, &abs,
-1);
} else
} else {
test_create_device(&uidev, &dev,
*evbit, code,
-1);
}
ck_assert_msg(libevdev_has_event_type(dev, *evbit), "for event type %d\n", *evbit);
ck_assert_msg(libevdev_has_event_code(dev, *evbit, code), "for type %d code %d", *evbit, code);
@ -305,6 +297,13 @@ START_TEST(test_set_input_props)
ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 0);
ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 1);
/* Test disabling the properties too */
ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_MAX + 1), -1);
ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_DIRECT), 0);
ck_assert_int_eq(libevdev_disable_property(dev, INPUT_PROP_BUTTONPAD), 0);
ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_DIRECT), 0);
ck_assert_int_eq(libevdev_has_property(dev, INPUT_PROP_BUTTONPAD), 0);
uinput_device_free(uidev);
libevdev_free(dev);
}

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
@ -559,6 +542,7 @@ START_TEST(test_set_clock_id)
{
struct uinput_device* uidev;
struct libevdev *dev;
int clockid;
int rc;
test_create_device(&uidev, &dev,
@ -577,7 +561,13 @@ START_TEST(test_set_clock_id)
rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC);
ck_assert_int_eq(rc, 0);
rc = libevdev_set_clock_id(dev, CLOCK_MONOTONIC_RAW);
#ifdef __FreeBSD__
clockid = CLOCK_MONOTONIC_FAST;
#else
clockid = CLOCK_MONOTONIC_RAW;
#endif
rc = libevdev_set_clock_id(dev, clockid);
ck_assert_int_eq(rc, -EINVAL);
uinput_device_free(uidev);

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
@ -38,8 +21,13 @@
static int
is_debugger_attached(void)
{
int rc = 1;
/*
* FreeBSD does not support PTRACE_ATTACH, disable attaching a debugger
* on FreeBSD by skipping the rest of the function and just return 1.
*/
#ifndef __FreeBSD__
int status;
int rc;
int pid = fork();
if (pid == -1)
@ -52,14 +40,14 @@ is_debugger_attached(void)
ptrace(PTRACE_CONT, NULL, NULL);
ptrace(PTRACE_DETACH, ppid, NULL, NULL);
rc = 0;
} else
rc = 1;
}
_exit(rc);
} else {
waitpid(pid, &status, 0);
rc = WEXITSTATUS(status);
}
#endif /* !__FreeBSD__ */
return rc;
}
@ -120,7 +108,7 @@ int main(void)
srunner_add_suite(sr, t->setup());
}
srunner_run_all(sr, CK_NORMAL);
srunner_run_all(sr, CK_ENV);
failed = srunner_ntests_failed(sr);
srunner_free(sr);

View file

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# Hack to check for leaking symbols in the static library.
# See https://bugs.freedesktop.org/show_bug.cgi?id=82785

View file

@ -1,23 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
@ -164,6 +147,93 @@ START_TEST(test_uinput_create_device_from_fd)
}
END_TEST
#ifdef __FreeBSD__
START_TEST(test_uinput_check_devnode_bsd)
{
struct libevdev *dev;
struct libevdev_uinput *uidev, *uidev2;
const char *devnode, *devnode2;
int fd, fd2;
int rc;
dev = libevdev_new();
ck_assert(dev != NULL);
libevdev_set_name(dev, TEST_DEVICE_NAME);
libevdev_enable_event_type(dev, EV_SYN);
libevdev_enable_event_type(dev, EV_REL);
libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
fd = open(UINPUT_NODE, O_RDWR);
ck_assert_int_gt(fd, -1);
fd2 = open(UINPUT_NODE, O_RDWR);
ck_assert_int_gt(fd2, -1);
rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
ck_assert_int_eq(rc, 0);
/* create a second one */
libevdev_set_name(dev, TEST_DEVICE_NAME " 2");
rc = libevdev_uinput_create_from_device(dev, fd2, &uidev2);
ck_assert_int_eq(rc, 0);
devnode = libevdev_uinput_get_devnode(uidev);
ck_assert(devnode != NULL);
/* get syspath twice returns same pointer */
devnode2 = libevdev_uinput_get_devnode(uidev);
ck_assert(devnode == devnode2);
/* second dev has different devnode */
devnode2 = libevdev_uinput_get_devnode(uidev2);
ck_assert(strcmp(devnode, devnode2) != 0);
libevdev_uinput_destroy(uidev2);
libevdev_uinput_destroy(uidev);
close(fd2);
close(fd);
libevdev_free(dev);
}
END_TEST
START_TEST(test_uinput_check_syspath_bsd)
{
struct libevdev *dev;
struct libevdev_uinput *uidev;
const char *syspath;
int fd;
int rc;
dev = libevdev_new();
ck_assert(dev != NULL);
libevdev_set_name(dev, TEST_DEVICE_NAME);
libevdev_enable_event_type(dev, EV_SYN);
libevdev_enable_event_type(dev, EV_REL);
libevdev_enable_event_code(dev, EV_REL, REL_X, NULL);
libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL);
fd = open(UINPUT_NODE, O_RDWR);
ck_assert_int_gt(fd, -1);
rc = libevdev_uinput_create_from_device(dev, fd, &uidev);
ck_assert_int_eq(rc, 0);
syspath = libevdev_uinput_get_syspath(uidev);
/* FreeBSD should always return NULL for libevdev_unput_get_syspath() */
ck_assert(syspath == NULL);
libevdev_uinput_destroy(uidev);
close(fd);
libevdev_free(dev);
}
END_TEST
#else /* !__FreeBSD__ */
START_TEST(test_uinput_check_syspath_time)
{
struct libevdev *dev;
@ -269,6 +339,8 @@ START_TEST(test_uinput_check_syspath_name)
}
END_TEST
#endif /* __FreeBSD __ */
START_TEST(test_uinput_events)
{
struct libevdev *dev;
@ -375,8 +447,13 @@ TEST_SUITE_ROOT_PRIVILEGES(uinput_suite)
add_test(s, test_uinput_create_device);
add_test(s, test_uinput_create_device_invalid);
add_test(s, test_uinput_create_device_from_fd);
#ifdef __FreeBSD__
add_test(s, test_uinput_check_devnode_bsd);
add_test(s, test_uinput_check_syspath_bsd);
#else
add_test(s, test_uinput_check_syspath_time);
add_test(s, test_uinput_check_syspath_name);
#endif
add_test(s, test_uinput_events);

View file

@ -1,4 +1,4 @@
noinst_PROGRAMS = libevdev-events
noinst_PROGRAMS = libevdev-events libevdev-list-codes
bin_PROGRAMS = \
touchpad-edge-detector \
mouse-dpi-tool \
@ -10,6 +10,9 @@ libevdev_ldadd = $(top_builddir)/libevdev/libevdev.la
libevdev_events_SOURCES = libevdev-events.c
libevdev_events_LDADD = $(libevdev_ldadd)
libevdev_list_codes_SOURCES = libevdev-list-codes.c
libevdev_list_codes_LDADD = $(libevdev_ldadd)
touchpad_edge_detector_SOURCES = touchpad-edge-detector.c
touchpad_edge_detector_LDADD = $(libevdev_ldadd)
@ -18,4 +21,9 @@ mouse_dpi_tool_LDADD = $(libevdev_ldadd)
libevdev_tweak_device_SOURCES = libevdev-tweak-device.c
libevdev_tweak_device_LDADD = $(libevdev_ldadd)
libevdev_tweak_device_MANS = libevdev-tweak-device.1
dist_man_MANS = \
libevdev-tweak-device.1 \
mouse-dpi-tool.1 \
touchpad-edge-detector.1 \
$(NULL)

View file

@ -1,35 +1,18 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2013 Red Hat, Inc.
*
* 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 "config.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <linux/input.h>
#include <sys/types.h>
#include "libevdev/libevdev.h"

View file

@ -0,0 +1,47 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2021 Red Hat, Inc.
*/
/* Lists all event types and codes currently known by libevdev. */
#include "config.h"
#include <stdio.h>
#include <linux/input.h>
#include "libevdev/libevdev.h"
static void
list_event_codes(unsigned int type, unsigned int max)
{
const char *typestr = libevdev_event_type_get_name(type);
if (!typestr)
return;
printf("- %s:\n", typestr);
for (unsigned int code = 0; code <= max; code++) {
const char *str = libevdev_event_code_get_name(type, code);
if (!str)
continue;
printf(" %d: %s\n", code, str);
}
}
int
main (int argc, char **argv)
{
printf("codes:\n");
for (unsigned int type = 0; type <= EV_MAX; type++) {
int max = libevdev_event_type_get_max(type);
if (max == -1)
continue;
list_event_codes(type, (unsigned int)max);
}
return 0;
}

View file

@ -1,45 +1,29 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2014 Red Hat, Inc.
*
* 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 "config.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <libgen.h>
#include <limits.h>
#include <linux/input.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <linux/input.h>
#include <sys/types.h>
#include <unistd.h>
#include "libevdev/libevdev.h"
static void
usage(void)
usage(const char *progname)
{
printf("%s --abs <axis> [--min min] [--max max] [--res res] [--fuzz fuzz] [--flat flat] /dev/input/eventXYZ\n"
"\tChange the absinfo struct for the named axis\n"
@ -47,9 +31,9 @@ usage(void)
"\tChange the x/y resolution on the given device\n"
"%s --led <led> --on|--off /dev/input/eventXYZ\n"
"\tEnable or disable the named LED\n",
program_invocation_short_name,
program_invocation_short_name,
program_invocation_short_name);
progname,
progname,
progname);
}
enum mode {
@ -415,7 +399,7 @@ main(int argc, char **argv)
rc = EXIT_SUCCESS;
/* fallthrough */
case MODE_NONE:
usage();
usage(basename(argv[0]));
goto out;
case MODE_ABS:
rc = parse_options_abs(argc, argv, &changes, &axis,
@ -439,7 +423,7 @@ main(int argc, char **argv)
if (optind >= argc) {
rc = EXIT_FAILURE;
usage();
usage(basename(argv[0]));
goto out;
}

18
tools/mouse-dpi-tool.1 Normal file
View file

@ -0,0 +1,18 @@
.TH MOUSE-DPI-TOOL "1"
.SH NAME
mouse-dpi-tool \- mouse resolution estimation tool
.SH SYNOPSIS
.BR mouse-dpi-tool " <\fIevdev device\fP>"
.SH DESCRIPTION
.B mouse-dpi-tool
reads relative events (mouse movement events) and calculates the
distance covered and maximum frequency of the incoming events.
Combined with a measurement of the actual distance physically covered,
this allows the mouse's resolution to be estimated.
.PP
Some mouse devices provide dynamic frequencies, it is
recommended to measure multiple times to obtain the highest value.
.PP
.SH OPTIONS
.B mouse-dpi-tool
accepts no options.

View file

@ -1,37 +1,19 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2014 Red Hat, Inc.
*
* 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 Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL THE AUTHORS 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 "config.h"
#include <sys/signalfd.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -40,6 +22,8 @@
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
static int signalled = 0;
struct measurements {
int distance;
double max_frequency;
@ -50,8 +34,8 @@ struct measurements {
};
static int
usage(void) {
printf("Usage: %s /dev/input/event0\n", program_invocation_short_name);
usage(const char *progname) {
printf("Usage: %s /dev/input/event0\n", progname);
printf("\n");
printf("This tool reads relative events from the kernel and calculates\n"
"the distance covered and maximum frequency of the incoming events.\n"
@ -126,7 +110,9 @@ handle_event(struct measurements *m, const struct input_event *ev)
}
return 0;
} else if (ev->type != EV_REL)
}
if (ev->type != EV_REL)
return 0;
switch(ev->code) {
@ -138,26 +124,26 @@ handle_event(struct measurements *m, const struct input_event *ev)
return 0;
}
static void
signal_handler(__attribute__((__unused__)) int signal)
{
signalled++;
}
static int
mainloop(struct libevdev *dev, struct measurements *m) {
struct pollfd fds[2];
sigset_t mask;
struct pollfd fds;
fds[0].fd = libevdev_get_fd(dev);
fds[0].events = POLLIN;
fds.fd = libevdev_get_fd(dev);
fds.events = POLLIN;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
fds[1].events = POLLIN;
signal(SIGINT, signal_handler);
sigprocmask(SIG_BLOCK, &mask, NULL);
while (poll(fds, 2, -1)) {
while (poll(&fds, 1, -1)) {
struct input_event ev;
int rc;
if (fds[1].revents)
if (signalled)
break;
do {
@ -165,12 +151,15 @@ mainloop(struct libevdev *dev, struct measurements *m) {
if (rc == LIBEVDEV_READ_STATUS_SYNC) {
fprintf(stderr, "Error: cannot keep up\n");
return 1;
} else if (rc != -EAGAIN && rc < 0) {
}
if (rc != -EAGAIN && rc < 0) {
fprintf(stderr, "Error: %s\n", strerror(-rc));
return 1;
} else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
handle_event(m, &ev);
}
if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
handle_event(m, &ev);
} while (rc != -EAGAIN);
}
@ -261,11 +250,11 @@ main (int argc, char **argv) {
struct measurements measurements = {0};
if (argc < 2)
return usage();
return usage(basename(argv[0]));
path = argv[1];
if (path[0] == '-')
return usage();
return usage(basename(argv[0]));
fd = open(path, O_RDONLY|O_NONBLOCK);
if (fd < 0) {

View file

@ -1,7 +1,37 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
make
rsync --delete -avz doc/html/ freedesktop.org:/srv/www.freedesktop.org/www/software/libevdev/doc/latest
tag="$1"
case $tag in
-h|--help)
echo "Usage: $0 <tag>"
echo "Builds the libevdev documentation and rsyncs it to the freedesktop.org server."
echo ""
echo "Options:"
echo " tag ... the tag to build (default: master)"
exit 0
;;
1*)
# Helper so we can run it with the numerical tag only, tags
# are all prefixed with libevdev
tag="libevdev-$tag"
;;
**)
;;
esac
tag=${tag:-master}
dir=$(mktemp -d --tmpdir='' libevdev-doc.XXX)
git clone --depth 1 --branch "$tag" https://gitlab.freedesktop.org/libevdev/libevdev.git "$dir"
pushd $dir
builddir=_doc_build
rm -rf "$builddir"
meson setup "$builddir"
ninja -C "$builddir"
# Strip libevdev- prefix from the tag and replace master with latest, whichever applies
htmldir=${tag/#libevdev-/}
htmldir=${htmldir/master/latest}
rsync --delete -avz "$builddir/html/" freedesktop.org:/srv/www.freedesktop.org/www/software/libevdev/doc/${htmldir}
popd

View file

@ -21,10 +21,11 @@ if ! [ -d .git ]; then
exit 1
fi
files="linux/input.h linux/input-event-codes.h"
file="linux/input.h"
git cat-file -p "$TAG:include/uapi/$file" > "include/linux/linux/$(basename $file)"
for file in $files; do
git cat-file -p "$TAG:include/uapi/$file" > "include/$file"
done
file="linux/input-event-codes.h"
git cat-file -p "$TAG:include/uapi/$file" > "include/linux/linux/$(basename $file)"
git cat-file -p "$TAG:include/uapi/$file" > "include/linux/freebsd/$(basename $file)"

View file

@ -0,0 +1,44 @@
.TH TOUCHPAD-EDGE-DETECTOR "1"
.SH NAME
touchpad-edge-detector \- print the axis ranges for a touchpad device
.SH SYNOPSIS
.B touchpad-edge-detector [--help] \fIWxH /dev/input/eventX\fR
.SH DESCRIPTION
.PP
The
.B touchpad-edge-detector
tool reads touchpad events from the kernel and records the minimum and
maximum coordinates based on user input. This is an interactive tool, the
user must move a finger around the touchpad, attempting to trigger an
event at all edges of the touchpad.
.PP
To terminate the event collection and print a summary, press Ctrl+C. It is
recommended that the tool is run several times to guarantee a reliable
result.
.SH OPTIONS
.TP 8
.I WxH
The width and height of the touchpad in mm. For a touchpad 100mm wide and
75mm high, the argument is thus \fI100x75\fR. This is a required argument.
.TP 8
.I /dev/input/eventX
The event node of the touchpad to read events from. A list of possible event
nodes can be obtained with either one of the following commands: \fBlibinput
record\fR, \fBevemu-record\fR, or \fBevtest\fR. Alternatively the event node
for a device is listed in the \fBHandlers=\fR line \fI/proc/bus/input/devices\fR.
This is a required argument.
.TP 8
.B --help
Print a short help description
.SH NOTES
.PP
On completion, this tool prints a summary of the collected events and a
suggested udev rule. Due to rounding errors it is rare to get an exact match
for the touchpad's dimensions, but any discrepancy of more than 5mm should
be corrected with the suggested udev rule.
.PP
The udev rule should be simplified and submitted as a pull request to the
system repository at \fIhttps://github.com/systemd/systemd\fR. For further
guidance, see the file \fI/usr/lib/udev/hwdb.d/60-evdev.hwdb\fR.
.SH SEE ALSO
udev(7)

View file

@ -1,38 +1,20 @@
// SPDX-License-Identifier: MIT
/*
* Copyright © 2014 Red Hat, Inc.
*
* 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 Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL THE AUTHORS 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 "config.h"
#include <sys/signalfd.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <math.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -41,9 +23,11 @@
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
static int signalled = 0;
static int
usage(void) {
printf("Usage: %s 12x34 /dev/input/eventX\n", program_invocation_short_name);
usage(const char *progname) {
printf("Usage: %s 12x34 /dev/input/eventX\n", progname);
printf("\n");
printf("This tool reads the touchpad events from the kernel and calculates\n "
"the minimum and maximum for the x and y coordinates, respectively.\n"
@ -81,9 +65,10 @@ print_current_values(const struct dimensions *d)
static int
handle_event(struct dimensions *d, const struct input_event *ev) {
if (ev->type == EV_SYN) {
if (ev->type == EV_SYN)
return print_current_values(d);
} else if (ev->type != EV_ABS)
if (ev->type != EV_ABS)
return 0;
switch(ev->code) {
@ -102,26 +87,26 @@ handle_event(struct dimensions *d, const struct input_event *ev) {
return 0;
}
static void
signal_handler(__attribute__((__unused__)) int signal)
{
signalled++;
}
static int
mainloop(struct libevdev *dev, struct dimensions *dim) {
struct pollfd fds[2];
sigset_t mask;
struct pollfd fds;
fds[0].fd = libevdev_get_fd(dev);
fds[0].events = POLLIN;
fds.fd = libevdev_get_fd(dev);
fds.events = POLLIN;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
fds[1].fd = signalfd(-1, &mask, SFD_NONBLOCK);
fds[1].events = POLLIN;
signal(SIGINT, signal_handler);
sigprocmask(SIG_BLOCK, &mask, NULL);
while (poll(fds, 2, -1)) {
while (poll(&fds, 1, -1)) {
struct input_event ev;
int rc;
if (fds[1].revents)
if (signalled)
break;
do {
@ -129,12 +114,16 @@ mainloop(struct libevdev *dev, struct dimensions *dim) {
if (rc == LIBEVDEV_READ_STATUS_SYNC) {
fprintf(stderr, "Error: cannot keep up\n");
return 1;
} else if (rc != -EAGAIN && rc < 0) {
}
if (rc != -EAGAIN && rc < 0) {
fprintf(stderr, "Error: %s\n", strerror(-rc));
return 1;
} else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
handle_event(dim, &ev);
}
if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
handle_event(dim, &ev);
} while (rc != -EAGAIN);
}
@ -168,8 +157,6 @@ dmi_matchstr(struct libevdev *dev, char *match, size_t sz)
modalias[strlen(modalias) - 1] = '\0'; /* drop \n */
snprintf(match, sz, "name:%s:%s", libevdev_get_name(dev), modalias);
return;
}
static void
@ -235,11 +222,11 @@ int main (int argc, char **argv) {
struct size size;
if (argc < 3)
return usage();
return usage(basename(argv[0]));
if (sscanf(argv[1], "%dx%d", &size.w, &size.h) != 2 ||
size.w <= 0 || size.h <= 0)
return usage();
return usage(basename(argv[0]));
if (size.w < 30 || size.h < 30) {
fprintf(stderr,
@ -251,7 +238,7 @@ int main (int argc, char **argv) {
path = argv[2];
if (path[0] == '-')
return usage();
return usage(basename(argv[0]));
fd = open(path, O_RDONLY|O_NONBLOCK);
if (fd < 0) {