forked from kiss-community/repo
2379 lines
68 KiB
Diff
2379 lines
68 KiB
Diff
|
From 98e90eaec449a67e0c4216d0aac38ee9896a6a8b Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Forney <mforney@mforney.org>
|
||
|
Date: Fri, 3 Jan 2020 17:18:10 -0800
|
||
|
Subject: [PATCH] Use forward-declarations of udev structures in headers
|
||
|
|
||
|
This way, it is possible for the libinput API to be implemented without
|
||
|
requiring udev.
|
||
|
---
|
||
|
meson.build | 7 ++-----
|
||
|
src/evdev-mt-touchpad.c | 1 +
|
||
|
src/evdev-tablet-pad-leds.c | 1 +
|
||
|
src/evdev.c | 1 +
|
||
|
src/libinput.c | 1 +
|
||
|
src/libinput.h | 4 +++-
|
||
|
src/quirks.h | 4 ++--
|
||
|
src/udev-seat.c | 1 +
|
||
|
src/udev-seat.h | 1 -
|
||
|
test/litest.h | 1 +
|
||
|
tools/libinput-debug-gui.c | 1 +
|
||
|
tools/libinput-debug-tablet.c | 1 +
|
||
|
tools/libinput-quirks.c | 1 +
|
||
|
13 files changed, 16 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git a/meson.build b/meson.build
|
||
|
index af4c87e8..e65ac51e 100644
|
||
|
--- a/meson.build
|
||
|
+++ b/meson.build
|
||
|
@@ -278,7 +278,7 @@ src_libinput_util = [
|
||
|
]
|
||
|
libinput_util = static_library('libinput-util',
|
||
|
src_libinput_util,
|
||
|
- dependencies : [dep_udev, dep_libevdev, dep_libwacom],
|
||
|
+ dependencies : [dep_libevdev, dep_libwacom],
|
||
|
include_directories : includes_include)
|
||
|
dep_libinput_util = declare_dependency(link_with : libinput_util)
|
||
|
|
||
|
@@ -296,7 +296,7 @@ src_libfilter = [
|
||
|
'src/filter-private.h'
|
||
|
]
|
||
|
libfilter = static_library('filter', src_libfilter,
|
||
|
- dependencies : [dep_udev, dep_libwacom],
|
||
|
+ dependencies : [dep_libwacom],
|
||
|
include_directories : includes_include)
|
||
|
dep_libfilter = declare_dependency(link_with : libfilter)
|
||
|
|
||
|
@@ -726,14 +726,12 @@ test('symbols-leak-test',
|
||
|
# build-test only
|
||
|
executable('test-build-pedantic',
|
||
|
'test/build-pedantic.c',
|
||
|
- dependencies : [dep_udev],
|
||
|
include_directories : [includes_src, includes_include],
|
||
|
c_args : ['-std=c99', '-pedantic', '-Werror'],
|
||
|
install : false)
|
||
|
# build-test only
|
||
|
executable('test-build-std-gnuc90',
|
||
|
'test/build-pedantic.c',
|
||
|
- dependencies : [dep_udev],
|
||
|
include_directories : [includes_src, includes_include],
|
||
|
c_args : ['-std=gnu89', '-Werror'],
|
||
|
install : false)
|
||
|
@@ -747,7 +745,6 @@ executable('test-build-linker',
|
||
|
if add_languages('cpp', required: false)
|
||
|
executable('test-build-cxx',
|
||
|
'test/build-cxx.cc',
|
||
|
- dependencies : [dep_udev],
|
||
|
include_directories : [includes_src, includes_include],
|
||
|
install : false)
|
||
|
endif
|
||
|
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
|
||
|
index 4ffc4a39..29faf59e 100644
|
||
|
--- a/src/evdev-mt-touchpad.c
|
||
|
+++ b/src/evdev-mt-touchpad.c
|
||
|
@@ -27,6 +27,7 @@
|
||
|
#include <math.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <limits.h>
|
||
|
+#include <libudev.h>
|
||
|
|
||
|
#if HAVE_LIBWACOM
|
||
|
#include <libwacom/libwacom.h>
|
||
|
diff --git a/src/evdev-tablet-pad-leds.c b/src/evdev-tablet-pad-leds.c
|
||
|
index ff21878f..70df1d06 100644
|
||
|
--- a/src/evdev-tablet-pad-leds.c
|
||
|
+++ b/src/evdev-tablet-pad-leds.c
|
||
|
@@ -23,6 +23,7 @@
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
+#include <libudev.h>
|
||
|
#include <limits.h>
|
||
|
#include <fcntl.h>
|
||
|
|
||
|
diff --git a/src/evdev.c b/src/evdev.c
|
||
|
index bf85aa24..ba889b6a 100644
|
||
|
--- a/src/evdev.c
|
||
|
+++ b/src/evdev.c
|
||
|
@@ -37,6 +37,7 @@
|
||
|
#include <mtdev-plumbing.h>
|
||
|
#include <assert.h>
|
||
|
#include <math.h>
|
||
|
+#include <libudev.h>
|
||
|
|
||
|
#include "libinput.h"
|
||
|
#include "evdev.h"
|
||
|
diff --git a/src/libinput.c b/src/libinput.c
|
||
|
index e764375b..b532f1e3 100644
|
||
|
--- a/src/libinput.c
|
||
|
+++ b/src/libinput.c
|
||
|
@@ -33,6 +33,7 @@
|
||
|
#include <sys/epoll.h>
|
||
|
#include <unistd.h>
|
||
|
#include <assert.h>
|
||
|
+#include <libudev.h>
|
||
|
|
||
|
#include "libinput.h"
|
||
|
#include "libinput-private.h"
|
||
|
diff --git a/src/libinput.h b/src/libinput.h
|
||
|
index 5a19f79d..f5ae835d 100644
|
||
|
--- a/src/libinput.h
|
||
|
+++ b/src/libinput.h
|
||
|
@@ -32,12 +32,14 @@ extern "C" {
|
||
|
#include <stdlib.h>
|
||
|
#include <stdint.h>
|
||
|
#include <stdarg.h>
|
||
|
-#include <libudev.h>
|
||
|
|
||
|
#define LIBINPUT_ATTRIBUTE_PRINTF(_format, _args) \
|
||
|
__attribute__ ((format (printf, _format, _args)))
|
||
|
#define LIBINPUT_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated))
|
||
|
|
||
|
+struct udev;
|
||
|
+struct udev_device;
|
||
|
+
|
||
|
/**
|
||
|
* @ingroup base
|
||
|
* @struct libinput
|
||
|
diff --git a/src/quirks.h b/src/quirks.h
|
||
|
index 88159b59..526177c0 100644
|
||
|
--- a/src/quirks.h
|
||
|
+++ b/src/quirks.h
|
||
|
@@ -28,10 +28,10 @@
|
||
|
#include <stdbool.h>
|
||
|
#include <stdint.h>
|
||
|
|
||
|
-#include <libudev.h>
|
||
|
-
|
||
|
#include "libinput.h"
|
||
|
|
||
|
+struct udev_device;
|
||
|
+
|
||
|
/**
|
||
|
* Handle to the quirks context.
|
||
|
*/
|
||
|
diff --git a/src/udev-seat.c b/src/udev-seat.c
|
||
|
index ce96ece3..3af01606 100644
|
||
|
--- a/src/udev-seat.c
|
||
|
+++ b/src/udev-seat.c
|
||
|
@@ -24,6 +24,7 @@
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
+#include <libudev.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
diff --git a/src/udev-seat.h b/src/udev-seat.h
|
||
|
index ee54b422..196561db 100644
|
||
|
--- a/src/udev-seat.h
|
||
|
+++ b/src/udev-seat.h
|
||
|
@@ -26,7 +26,6 @@
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
-#include <libudev.h>
|
||
|
#include "libinput-private.h"
|
||
|
|
||
|
struct udev_seat {
|
||
|
diff --git a/test/litest.h b/test/litest.h
|
||
|
index ab66ff9e..9d6598be 100644
|
||
|
--- a/test/litest.h
|
||
|
+++ b/test/litest.h
|
||
|
@@ -33,6 +33,7 @@
|
||
|
#include <libevdev/libevdev.h>
|
||
|
#include <libevdev/libevdev-uinput.h>
|
||
|
#include <libinput.h>
|
||
|
+#include <libudev.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
#include "check-double-macros.h"
|
||
|
diff --git a/tools/libinput-debug-gui.c b/tools/libinput-debug-gui.c
|
||
|
index d68f1ea1..ae9364e6 100644
|
||
|
--- a/tools/libinput-debug-gui.c
|
||
|
+++ b/tools/libinput-debug-gui.c
|
||
|
@@ -29,6 +29,7 @@
|
||
|
#include <errno.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <getopt.h>
|
||
|
+#include <libudev.h>
|
||
|
#include <math.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
diff --git a/tools/libinput-debug-tablet.c b/tools/libinput-debug-tablet.c
|
||
|
index b2406d68..a5959fa7 100644
|
||
|
--- a/tools/libinput-debug-tablet.c
|
||
|
+++ b/tools/libinput-debug-tablet.c
|
||
|
@@ -28,6 +28,7 @@
|
||
|
#include <fcntl.h>
|
||
|
#include <inttypes.h>
|
||
|
#include <getopt.h>
|
||
|
+#include <libudev.h>
|
||
|
#include <poll.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
diff --git a/tools/libinput-quirks.c b/tools/libinput-quirks.c
|
||
|
index 1a80f367..6aac4b1e 100644
|
||
|
--- a/tools/libinput-quirks.c
|
||
|
+++ b/tools/libinput-quirks.c
|
||
|
@@ -27,6 +27,7 @@
|
||
|
#include <stdlib.h>
|
||
|
#include <errno.h>
|
||
|
#include <getopt.h>
|
||
|
+#include <libudev.h>
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
#include "quirks.h"
|
||
|
|
||
|
From a6f21673e13efc52fff100d315316ba14c6db848 Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Forney <mforney@mforney.org>
|
||
|
Date: Fri, 3 Jan 2020 21:51:55 -0800
|
||
|
Subject: [PATCH] Make udev optional
|
||
|
|
||
|
---
|
||
|
meson.build | 568 +++++++++++++++++++-----------------
|
||
|
meson_options.txt | 8 +
|
||
|
src/evdev-mt-touchpad.c | 9 +-
|
||
|
src/evdev-tablet-pad-leds.c | 15 +-
|
||
|
src/evdev.c | 117 +++++++-
|
||
|
src/evdev.h | 5 +-
|
||
|
src/libinput.c | 5 +
|
||
|
src/path-seat.c | 115 +++++---
|
||
|
src/quirks.c | 46 +--
|
||
|
src/udev-seat.c | 25 +-
|
||
|
10 files changed, 564 insertions(+), 349 deletions(-)
|
||
|
|
||
|
diff --git a/meson.build b/meson.build
|
||
|
index e65ac51e..75b393f4 100644
|
||
|
--- a/meson.build
|
||
|
+++ b/meson.build
|
||
|
@@ -122,7 +122,6 @@ endif
|
||
|
|
||
|
# Dependencies
|
||
|
pkgconfig = import('pkgconfig')
|
||
|
-dep_udev = dependency('libudev')
|
||
|
dep_mtdev = dependency('mtdev', version : '>= 1.1.0')
|
||
|
dep_libevdev = dependency('libevdev')
|
||
|
dep_lm = cc.find_library('m', required : false)
|
||
|
@@ -152,46 +151,54 @@ endif
|
||
|
|
||
|
############ udev bits ############
|
||
|
|
||
|
-executable('libinput-device-group',
|
||
|
- 'udev/libinput-device-group.c',
|
||
|
- dependencies : [dep_udev, dep_libwacom],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install : true,
|
||
|
- install_dir : dir_udev_callouts)
|
||
|
-executable('libinput-fuzz-extract',
|
||
|
- 'udev/libinput-fuzz-extract.c',
|
||
|
- 'src/util-strings.c',
|
||
|
- 'src/util-prop-parsers.c',
|
||
|
- dependencies : [dep_udev, dep_libevdev, dep_lm],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install : true,
|
||
|
- install_dir : dir_udev_callouts)
|
||
|
-executable('libinput-fuzz-to-zero',
|
||
|
- 'udev/libinput-fuzz-to-zero.c',
|
||
|
- dependencies : [dep_udev, dep_libevdev],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install : true,
|
||
|
- install_dir : dir_udev_callouts)
|
||
|
-
|
||
|
-udev_rules_config = configuration_data()
|
||
|
-udev_rules_config.set('UDEV_TEST_PATH', '')
|
||
|
-configure_file(input : 'udev/80-libinput-device-groups.rules.in',
|
||
|
- output : '80-libinput-device-groups.rules',
|
||
|
- install_dir : dir_udev_rules,
|
||
|
- configuration : udev_rules_config)
|
||
|
-configure_file(input : 'udev/90-libinput-fuzz-override.rules.in',
|
||
|
- output : '90-libinput-fuzz-override.rules',
|
||
|
- install_dir : dir_udev_rules,
|
||
|
- configuration : udev_rules_config)
|
||
|
-
|
||
|
-litest_udev_rules_config = configuration_data()
|
||
|
-litest_udev_rules_config.set('UDEV_TEST_PATH', meson.current_build_dir() + '/')
|
||
|
-litest_groups_rules_file = configure_file(input : 'udev/80-libinput-device-groups.rules.in',
|
||
|
- output : '80-libinput-device-groups-litest.rules',
|
||
|
- configuration : litest_udev_rules_config)
|
||
|
-litest_fuzz_override_file = configure_file(input : 'udev/90-libinput-fuzz-override.rules.in',
|
||
|
- output : '90-libinput-fuzz-override-litest.rules',
|
||
|
- configuration : litest_udev_rules_config)
|
||
|
+have_udev = get_option('udev')
|
||
|
+config_h.set10('HAVE_UDEV', have_udev)
|
||
|
+if have_udev
|
||
|
+ dep_udev = dependency('libudev')
|
||
|
+
|
||
|
+ executable('libinput-device-group',
|
||
|
+ 'udev/libinput-device-group.c',
|
||
|
+ dependencies : [dep_udev, dep_libwacom],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install : true,
|
||
|
+ install_dir : dir_udev_callouts)
|
||
|
+ executable('libinput-fuzz-extract',
|
||
|
+ 'udev/libinput-fuzz-extract.c',
|
||
|
+ 'src/util-strings.c',
|
||
|
+ 'src/util-prop-parsers.c',
|
||
|
+ dependencies : [dep_udev, dep_libevdev, dep_lm],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install : true,
|
||
|
+ install_dir : dir_udev_callouts)
|
||
|
+ executable('libinput-fuzz-to-zero',
|
||
|
+ 'udev/libinput-fuzz-to-zero.c',
|
||
|
+ dependencies : [dep_udev, dep_libevdev],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install : true,
|
||
|
+ install_dir : dir_udev_callouts)
|
||
|
+
|
||
|
+ udev_rules_config = configuration_data()
|
||
|
+ udev_rules_config.set('UDEV_TEST_PATH', '')
|
||
|
+ configure_file(input : 'udev/80-libinput-device-groups.rules.in',
|
||
|
+ output : '80-libinput-device-groups.rules',
|
||
|
+ install_dir : dir_udev_rules,
|
||
|
+ configuration : udev_rules_config)
|
||
|
+ configure_file(input : 'udev/90-libinput-fuzz-override.rules.in',
|
||
|
+ output : '90-libinput-fuzz-override.rules',
|
||
|
+ install_dir : dir_udev_rules,
|
||
|
+ configuration : udev_rules_config)
|
||
|
+
|
||
|
+ litest_udev_rules_config = configuration_data()
|
||
|
+ litest_udev_rules_config.set('UDEV_TEST_PATH', meson.current_build_dir() + '/')
|
||
|
+ litest_groups_rules_file = configure_file(input : 'udev/80-libinput-device-groups.rules.in',
|
||
|
+ output : '80-libinput-device-groups-litest.rules',
|
||
|
+ configuration : litest_udev_rules_config)
|
||
|
+ litest_fuzz_override_file = configure_file(input : 'udev/90-libinput-fuzz-override.rules.in',
|
||
|
+ output : '90-libinput-fuzz-override-litest.rules',
|
||
|
+ configuration : litest_udev_rules_config)
|
||
|
+else
|
||
|
+ dep_udev = declare_dependency()
|
||
|
+endif
|
||
|
|
||
|
############ Check for leftover udev rules ########
|
||
|
|
||
|
@@ -465,256 +472,267 @@ endif
|
||
|
subdir('completion/zsh')
|
||
|
|
||
|
############ tools ############
|
||
|
-libinput_tool_path = dir_libexec
|
||
|
-config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path)
|
||
|
-tools_shared_sources = [ 'tools/shared.c',
|
||
|
- 'tools/shared.h',
|
||
|
- 'src/builddir.h' ]
|
||
|
-deps_tools_shared = [ dep_libinput, dep_libevdev ]
|
||
|
-lib_tools_shared = static_library('tools_shared',
|
||
|
- tools_shared_sources,
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- dependencies : deps_tools_shared)
|
||
|
-dep_tools_shared = declare_dependency(link_with : lib_tools_shared,
|
||
|
- dependencies : deps_tools_shared)
|
||
|
-
|
||
|
-man_config = configuration_data()
|
||
|
-man_config.set('LIBINPUT_VERSION', meson.project_version())
|
||
|
-man_config.set('LIBINPUT_DATA_DIR', dir_data)
|
||
|
-
|
||
|
-deps_tools = [ dep_tools_shared, dep_libinput ]
|
||
|
-libinput_debug_events_sources = [
|
||
|
- 'tools/libinput-debug-events.c',
|
||
|
- libinput_version_h,
|
||
|
-]
|
||
|
-executable('libinput-debug-events',
|
||
|
- libinput_debug_events_sources,
|
||
|
- dependencies : deps_tools,
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install_dir : libinput_tool_path,
|
||
|
- install : true
|
||
|
- )
|
||
|
-configure_file(input : 'tools/libinput-debug-events.man',
|
||
|
- output : 'libinput-debug-events.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-libinput_debug_tablet_sources = [ 'tools/libinput-debug-tablet.c' ]
|
||
|
-executable('libinput-debug-tablet',
|
||
|
- libinput_debug_tablet_sources,
|
||
|
- dependencies : deps_tools,
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install_dir : libinput_tool_path,
|
||
|
- install : true)
|
||
|
-
|
||
|
-configure_file(input : 'tools/libinput-debug-tablet.man',
|
||
|
- output : 'libinput-debug-tablet.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-libinput_quirks_sources = [ 'tools/libinput-quirks.c' ]
|
||
|
-libinput_quirks = executable('libinput-quirks',
|
||
|
- libinput_quirks_sources,
|
||
|
- dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install_dir : libinput_tool_path,
|
||
|
- install : true
|
||
|
- )
|
||
|
-test('validate-quirks',
|
||
|
- libinput_quirks,
|
||
|
- args: ['validate', '--data-dir=@0@'.format(dir_src_quirks)],
|
||
|
- suite : ['all']
|
||
|
- )
|
||
|
|
||
|
-configure_file(input : 'tools/libinput-quirks.man',
|
||
|
- output : 'libinput-quirks.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-# Same man page for the subtools to stay consistent with the other tools
|
||
|
-configure_file(input : 'tools/libinput-quirks.man',
|
||
|
- output : 'libinput-quirks-list.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-configure_file(input : 'tools/libinput-quirks.man',
|
||
|
- output : 'libinput-quirks-validate.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-libinput_list_devices_sources = [ 'tools/libinput-list-devices.c' ]
|
||
|
-libinput_list_devices = executable('libinput-list-devices',
|
||
|
- libinput_list_devices_sources,
|
||
|
- dependencies : deps_tools,
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install_dir : libinput_tool_path,
|
||
|
- install : true,
|
||
|
- )
|
||
|
-test('list-devices',
|
||
|
- libinput_list_devices,
|
||
|
- suite : ['all', 'root', 'hardware'])
|
||
|
-
|
||
|
-configure_file(input : 'tools/libinput-list-devices.man',
|
||
|
- output : 'libinput-list-devices.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-libinput_measure_sources = [ 'tools/libinput-measure.c' ]
|
||
|
-executable('libinput-measure',
|
||
|
- libinput_measure_sources,
|
||
|
- dependencies : deps_tools,
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install_dir : libinput_tool_path,
|
||
|
- install : true,
|
||
|
- )
|
||
|
-configure_file(input : 'tools/libinput-measure.man',
|
||
|
- output : 'libinput-measure.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-src_python_tools = files(
|
||
|
- 'tools/libinput-measure-fuzz.py',
|
||
|
- 'tools/libinput-measure-touchpad-tap.py',
|
||
|
- 'tools/libinput-measure-touchpad-pressure.py',
|
||
|
- 'tools/libinput-measure-touch-size.py',
|
||
|
-)
|
||
|
+if get_option('tools')
|
||
|
+ if not have_udev
|
||
|
+ error('tools require -Dudev=true')
|
||
|
+ endif
|
||
|
|
||
|
-config_noop = configuration_data()
|
||
|
-# Set a dummy replacement to silence meson warnings:
|
||
|
-# meson.build:487: WARNING: Got an empty configuration_data() object and
|
||
|
-# found no substitutions in the input file 'foo'. If you
|
||
|
-# want to copy a file to the build dir, use the 'copy:'
|
||
|
-# keyword argument added in 0.47.0
|
||
|
-config_noop.set('dummy', 'dummy')
|
||
|
-foreach t : src_python_tools
|
||
|
- configure_file(input: t,
|
||
|
- output: '@BASENAME@',
|
||
|
- configuration : config_noop,
|
||
|
- install_dir : libinput_tool_path
|
||
|
- )
|
||
|
-endforeach
|
||
|
+ libinput_tool_path = dir_libexec
|
||
|
+ config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path)
|
||
|
+ tools_shared_sources = [ 'tools/shared.c',
|
||
|
+ 'tools/shared.h',
|
||
|
+ 'src/builddir.h' ]
|
||
|
+ deps_tools_shared = [ dep_libinput, dep_libevdev ]
|
||
|
+ lib_tools_shared = static_library('tools_shared',
|
||
|
+ tools_shared_sources,
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ dependencies : deps_tools_shared)
|
||
|
+ dep_tools_shared = declare_dependency(link_with : lib_tools_shared,
|
||
|
+ dependencies : deps_tools_shared)
|
||
|
+
|
||
|
+ man_config = configuration_data()
|
||
|
+ man_config.set('LIBINPUT_VERSION', meson.project_version())
|
||
|
+ man_config.set('LIBINPUT_DATA_DIR', dir_data)
|
||
|
+
|
||
|
+ deps_tools = [ dep_tools_shared, dep_libinput ]
|
||
|
+ libinput_debug_events_sources = [
|
||
|
+ 'tools/libinput-debug-events.c',
|
||
|
+ libinput_version_h,
|
||
|
+ ]
|
||
|
+ executable('libinput-debug-events',
|
||
|
+ libinput_debug_events_sources,
|
||
|
+ dependencies : deps_tools,
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install_dir : libinput_tool_path,
|
||
|
+ install : true
|
||
|
+ )
|
||
|
+ configure_file(input : 'tools/libinput-debug-events.man',
|
||
|
+ output : 'libinput-debug-events.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
|
||
|
-src_man = files(
|
||
|
- 'tools/libinput-measure-fuzz.man',
|
||
|
- 'tools/libinput-measure-touchpad-tap.man',
|
||
|
- 'tools/libinput-measure-touchpad-pressure.man',
|
||
|
- 'tools/libinput-measure-touch-size.man',
|
||
|
-)
|
||
|
+ libinput_debug_tablet_sources = [ 'tools/libinput-debug-tablet.c' ]
|
||
|
+ executable('libinput-debug-tablet',
|
||
|
+ libinput_debug_tablet_sources,
|
||
|
+ dependencies : deps_tools,
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install_dir : libinput_tool_path,
|
||
|
+ install : true)
|
||
|
|
||
|
-foreach m : src_man
|
||
|
- configure_file(input : m,
|
||
|
- output : '@BASENAME@.1',
|
||
|
+ configure_file(input : 'tools/libinput-debug-tablet.man',
|
||
|
+ output : 'libinput-debug-tablet.1',
|
||
|
configuration : man_config,
|
||
|
- install_dir : dir_man1)
|
||
|
-endforeach
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
|
||
|
-libinput_record_sources = [ 'tools/libinput-record.c', git_version_h ]
|
||
|
-executable('libinput-record',
|
||
|
- libinput_record_sources,
|
||
|
- dependencies : deps_tools + [dep_udev],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install_dir : libinput_tool_path,
|
||
|
- install : true,
|
||
|
- )
|
||
|
-configure_file(input : 'tools/libinput-record.man',
|
||
|
- output : 'libinput-record.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-install_data('tools/libinput-replay',
|
||
|
- install_dir : libinput_tool_path)
|
||
|
-configure_file(input : 'tools/libinput-replay.man',
|
||
|
- output : 'libinput-replay.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-if get_option('debug-gui')
|
||
|
- dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
|
||
|
- dep_cairo = dependency('cairo')
|
||
|
- dep_glib = dependency('glib-2.0')
|
||
|
-
|
||
|
- debug_gui_sources = [ 'tools/libinput-debug-gui.c' ]
|
||
|
- deps_debug_gui = [
|
||
|
- dep_gtk,
|
||
|
- dep_cairo,
|
||
|
- dep_glib,
|
||
|
- ] + deps_tools
|
||
|
- executable('libinput-debug-gui',
|
||
|
- debug_gui_sources,
|
||
|
- dependencies : deps_debug_gui,
|
||
|
+ libinput_quirks_sources = [ 'tools/libinput-quirks.c' ]
|
||
|
+ libinput_quirks = executable('libinput-quirks',
|
||
|
+ libinput_quirks_sources,
|
||
|
+ dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install_dir : libinput_tool_path,
|
||
|
+ install : true
|
||
|
+ )
|
||
|
+ test('validate-quirks',
|
||
|
+ libinput_quirks,
|
||
|
+ args: ['validate', '--data-dir=@0@'.format(dir_src_quirks)],
|
||
|
+ suite : ['all']
|
||
|
+ )
|
||
|
+
|
||
|
+ configure_file(input : 'tools/libinput-quirks.man',
|
||
|
+ output : 'libinput-quirks.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+ # Same man page for the subtools to stay consistent with the other tools
|
||
|
+ configure_file(input : 'tools/libinput-quirks.man',
|
||
|
+ output : 'libinput-quirks-list.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+ configure_file(input : 'tools/libinput-quirks.man',
|
||
|
+ output : 'libinput-quirks-validate.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+
|
||
|
+ libinput_list_devices_sources = [ 'tools/libinput-list-devices.c' ]
|
||
|
+ libinput_list_devices = executable('libinput-list-devices',
|
||
|
+ libinput_list_devices_sources,
|
||
|
+ dependencies : deps_tools,
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install_dir : libinput_tool_path,
|
||
|
+ install : true,
|
||
|
+ )
|
||
|
+ test('list-devices',
|
||
|
+ libinput_list_devices,
|
||
|
+ suite : ['all', 'root', 'hardware'])
|
||
|
+
|
||
|
+ configure_file(input : 'tools/libinput-list-devices.man',
|
||
|
+ output : 'libinput-list-devices.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+
|
||
|
+ libinput_measure_sources = [ 'tools/libinput-measure.c' ]
|
||
|
+ executable('libinput-measure',
|
||
|
+ libinput_measure_sources,
|
||
|
+ dependencies : deps_tools,
|
||
|
include_directories : [includes_src, includes_include],
|
||
|
install_dir : libinput_tool_path,
|
||
|
- install : true
|
||
|
+ install : true,
|
||
|
)
|
||
|
- configure_file(input : 'tools/libinput-debug-gui.man',
|
||
|
- output : 'libinput-debug-gui.1',
|
||
|
+ configure_file(input : 'tools/libinput-measure.man',
|
||
|
+ output : 'libinput-measure.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+
|
||
|
+ src_python_tools = files(
|
||
|
+ 'tools/libinput-measure-fuzz.py',
|
||
|
+ 'tools/libinput-measure-touchpad-tap.py',
|
||
|
+ 'tools/libinput-measure-touchpad-pressure.py',
|
||
|
+ 'tools/libinput-measure-touch-size.py',
|
||
|
+ )
|
||
|
+
|
||
|
+ config_noop = configuration_data()
|
||
|
+ # Set a dummy replacement to silence meson warnings:
|
||
|
+ # meson.build:487: WARNING: Got an empty configuration_data() object and
|
||
|
+ # found no substitutions in the input file 'foo'. If you
|
||
|
+ # want to copy a file to the build dir, use the 'copy:'
|
||
|
+ # keyword argument added in 0.47.0
|
||
|
+ config_noop.set('dummy', 'dummy')
|
||
|
+ foreach t : src_python_tools
|
||
|
+ configure_file(input: t,
|
||
|
+ output: '@BASENAME@',
|
||
|
+ configuration : config_noop,
|
||
|
+ install_dir : libinput_tool_path
|
||
|
+ )
|
||
|
+ endforeach
|
||
|
+
|
||
|
+ src_man = files(
|
||
|
+ 'tools/libinput-measure-fuzz.man',
|
||
|
+ 'tools/libinput-measure-touchpad-tap.man',
|
||
|
+ 'tools/libinput-measure-touchpad-pressure.man',
|
||
|
+ 'tools/libinput-measure-touch-size.man',
|
||
|
+ )
|
||
|
+
|
||
|
+ foreach m : src_man
|
||
|
+ configure_file(input : m,
|
||
|
+ output : '@BASENAME@.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1)
|
||
|
+ endforeach
|
||
|
+
|
||
|
+ libinput_record_sources = [ 'tools/libinput-record.c', git_version_h ]
|
||
|
+ executable('libinput-record',
|
||
|
+ libinput_record_sources,
|
||
|
+ dependencies : deps_tools + [dep_udev],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install_dir : libinput_tool_path,
|
||
|
+ install : true,
|
||
|
+ )
|
||
|
+ configure_file(input : 'tools/libinput-record.man',
|
||
|
+ output : 'libinput-record.1',
|
||
|
configuration : man_config,
|
||
|
install_dir : dir_man1,
|
||
|
)
|
||
|
-endif
|
||
|
|
||
|
-libinput_sources = [ 'tools/libinput-tool.c' ]
|
||
|
+ install_data('tools/libinput-replay',
|
||
|
+ install_dir : libinput_tool_path)
|
||
|
+ configure_file(input : 'tools/libinput-replay.man',
|
||
|
+ output : 'libinput-replay.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
|
||
|
-libinput_tool = executable('libinput',
|
||
|
- libinput_sources,
|
||
|
- dependencies : deps_tools,
|
||
|
+ if get_option('debug-gui')
|
||
|
+ if not have_udev
|
||
|
+ error('debug-gui requires -Dudev=true')
|
||
|
+ endif
|
||
|
+
|
||
|
+ dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
|
||
|
+ dep_cairo = dependency('cairo')
|
||
|
+ dep_glib = dependency('glib-2.0')
|
||
|
+
|
||
|
+ debug_gui_sources = [ 'tools/libinput-debug-gui.c' ]
|
||
|
+ deps_debug_gui = [
|
||
|
+ dep_gtk,
|
||
|
+ dep_cairo,
|
||
|
+ dep_glib,
|
||
|
+ ] + deps_tools
|
||
|
+ executable('libinput-debug-gui',
|
||
|
+ debug_gui_sources,
|
||
|
+ dependencies : deps_debug_gui,
|
||
|
include_directories : [includes_src, includes_include],
|
||
|
+ install_dir : libinput_tool_path,
|
||
|
install : true
|
||
|
- )
|
||
|
-configure_file(input : 'tools/libinput.man',
|
||
|
- output : 'libinput.1',
|
||
|
- configuration : man_config,
|
||
|
- install_dir : dir_man1,
|
||
|
- )
|
||
|
-
|
||
|
-ptraccel_debug_sources = [ 'tools/ptraccel-debug.c' ]
|
||
|
-executable('ptraccel-debug',
|
||
|
- ptraccel_debug_sources,
|
||
|
- dependencies : [ dep_libfilter, dep_libinput ],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install : false
|
||
|
- )
|
||
|
+ )
|
||
|
+ configure_file(input : 'tools/libinput-debug-gui.man',
|
||
|
+ output : 'libinput-debug-gui.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+ endif
|
||
|
|
||
|
-# Don't run the test during a release build because we rely on the magic
|
||
|
-# subtool lookup
|
||
|
-if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
|
||
|
- config_tool_option_test = configuration_data()
|
||
|
- config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui'))
|
||
|
- tool_option_test = configure_file(input: 'tools/test-tool-option-parsing.py',
|
||
|
- output: '@BASENAME@',
|
||
|
- configuration : config_tool_option_test)
|
||
|
- test('tool-option-parsing',
|
||
|
- tool_option_test,
|
||
|
- args : ['--tool-path', libinput_tool.full_path()],
|
||
|
- suite : ['all', 'root'],
|
||
|
- timeout : 240)
|
||
|
-endif
|
||
|
+ libinput_sources = [ 'tools/libinput-tool.c' ]
|
||
|
|
||
|
-# the libinput tools check whether we execute from the builddir, this is
|
||
|
-# the test to verify that lookup. We test twice, once as normal test
|
||
|
-# run from the builddir, once after copying to /tmp
|
||
|
-test_builddir_lookup = executable('test-builddir-lookup',
|
||
|
- 'test/test-builddir-lookup.c',
|
||
|
- dependencies : [ dep_tools_shared],
|
||
|
- include_directories : [includes_src, includes_include],
|
||
|
- install : false)
|
||
|
-test('tools-builddir-lookup',
|
||
|
- test_builddir_lookup,
|
||
|
- args : ['--builddir-is-set'],
|
||
|
- suite : ['all'])
|
||
|
-test('tools-builddir-lookup-installed',
|
||
|
- find_program('test/helper-copy-and-exec-from-tmp.sh'),
|
||
|
- args : [test_builddir_lookup.full_path(), '--builddir-is-null'],
|
||
|
- env : ['LD_LIBRARY_PATH=@0@'.format(meson.current_build_dir())],
|
||
|
- suite : ['all'],
|
||
|
- workdir : '/tmp')
|
||
|
+ libinput_tool = executable('libinput',
|
||
|
+ libinput_sources,
|
||
|
+ dependencies : deps_tools,
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install : true
|
||
|
+ )
|
||
|
+ configure_file(input : 'tools/libinput.man',
|
||
|
+ output : 'libinput.1',
|
||
|
+ configuration : man_config,
|
||
|
+ install_dir : dir_man1,
|
||
|
+ )
|
||
|
+
|
||
|
+ ptraccel_debug_sources = [ 'tools/ptraccel-debug.c' ]
|
||
|
+ executable('ptraccel-debug',
|
||
|
+ ptraccel_debug_sources,
|
||
|
+ dependencies : [ dep_libfilter, dep_libinput ],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install : false
|
||
|
+ )
|
||
|
+
|
||
|
+ # Don't run the test during a release build because we rely on the magic
|
||
|
+ # subtool lookup
|
||
|
+ if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
|
||
|
+ config_tool_option_test = configuration_data()
|
||
|
+ config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui'))
|
||
|
+ tool_option_test = configure_file(input: 'tools/test-tool-option-parsing.py',
|
||
|
+ output: '@BASENAME@',
|
||
|
+ configuration : config_tool_option_test)
|
||
|
+ test('tool-option-parsing',
|
||
|
+ tool_option_test,
|
||
|
+ args : ['--tool-path', libinput_tool.full_path()],
|
||
|
+ suite : ['all', 'root'],
|
||
|
+ timeout : 240)
|
||
|
+ endif
|
||
|
+
|
||
|
+ # the libinput tools check whether we execute from the builddir, this is
|
||
|
+ # the test to verify that lookup. We test twice, once as normal test
|
||
|
+ # run from the builddir, once after copying to /tmp
|
||
|
+ test_builddir_lookup = executable('test-builddir-lookup',
|
||
|
+ 'test/test-builddir-lookup.c',
|
||
|
+ dependencies : [ dep_tools_shared],
|
||
|
+ include_directories : [includes_src, includes_include],
|
||
|
+ install : false)
|
||
|
+ test('tools-builddir-lookup',
|
||
|
+ test_builddir_lookup,
|
||
|
+ args : ['--builddir-is-set'],
|
||
|
+ suite : ['all'])
|
||
|
+ test('tools-builddir-lookup-installed',
|
||
|
+ find_program('test/helper-copy-and-exec-from-tmp.sh'),
|
||
|
+ args : [test_builddir_lookup.full_path(), '--builddir-is-null'],
|
||
|
+ env : ['LD_LIBRARY_PATH=@0@'.format(meson.current_build_dir())],
|
||
|
+ suite : ['all'],
|
||
|
+ workdir : '/tmp')
|
||
|
+endif
|
||
|
|
||
|
############ tests ############
|
||
|
|
||
|
@@ -752,6 +770,10 @@ endif
|
||
|
# This is the test suite runner, we allow disabling that one because of
|
||
|
# dependencies
|
||
|
if get_option('tests')
|
||
|
+ if not have_udev
|
||
|
+ error('tests require -Dudev=true')
|
||
|
+ endif
|
||
|
+
|
||
|
dep_check = dependency('check', version : '>= 0.9.10')
|
||
|
|
||
|
gstack = find_program('gstack', required : false)
|
||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||
|
index 7819449c..c1cf43a6 100644
|
||
|
--- a/meson_options.txt
|
||
|
+++ b/meson_options.txt
|
||
|
@@ -10,6 +10,10 @@ option('libwacom',
|
||
|
type: 'boolean',
|
||
|
value: true,
|
||
|
description: 'Use libwacom for tablet identification (default=true)')
|
||
|
+option('udev',
|
||
|
+ type: 'boolean',
|
||
|
+ value: true,
|
||
|
+ description: 'Use libudev for device detection (default=true)')
|
||
|
option('debug-gui',
|
||
|
type: 'boolean',
|
||
|
value: true,
|
||
|
@@ -18,6 +22,10 @@ option('tests',
|
||
|
type: 'boolean',
|
||
|
value: true,
|
||
|
description: 'Build the tests [default=true]')
|
||
|
+option('tools',
|
||
|
+ type: 'boolean',
|
||
|
+ value: true,
|
||
|
+ description: 'Build the tools [default=true]')
|
||
|
option('install-tests',
|
||
|
type: 'boolean',
|
||
|
value: false,
|
||
|
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
|
||
|
index 29faf59e..3f605c73 100644
|
||
|
--- a/src/evdev-mt-touchpad.c
|
||
|
+++ b/src/evdev-mt-touchpad.c
|
||
|
@@ -27,12 +27,15 @@
|
||
|
#include <math.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <limits.h>
|
||
|
-#include <libudev.h>
|
||
|
|
||
|
#if HAVE_LIBWACOM
|
||
|
#include <libwacom/libwacom.h>
|
||
|
#endif
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
+#include <libudev.h>
|
||
|
+#endif
|
||
|
+
|
||
|
#include "quirks.h"
|
||
|
#include "evdev-mt-touchpad.h"
|
||
|
|
||
|
@@ -2609,8 +2612,12 @@ evdev_tag_touchpad(struct evdev_device *device,
|
||
|
int bustype, vendor;
|
||
|
const char *prop;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
prop = udev_device_get_property_value(udev_device,
|
||
|
"ID_INPUT_TOUCHPAD_INTEGRATION");
|
||
|
+#else
|
||
|
+ prop = NULL;
|
||
|
+#endif
|
||
|
if (prop) {
|
||
|
if (streq(prop, "internal")) {
|
||
|
evdev_tag_touchpad_internal(device);
|
||
|
diff --git a/src/evdev-tablet-pad-leds.c b/src/evdev-tablet-pad-leds.c
|
||
|
index 70df1d06..2cdda68c 100644
|
||
|
--- a/src/evdev-tablet-pad-leds.c
|
||
|
+++ b/src/evdev-tablet-pad-leds.c
|
||
|
@@ -23,7 +23,6 @@
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
-#include <libudev.h>
|
||
|
#include <limits.h>
|
||
|
#include <fcntl.h>
|
||
|
|
||
|
@@ -33,6 +32,10 @@
|
||
|
#include <libwacom/libwacom.h>
|
||
|
#endif
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
+#include <libudev.h>
|
||
|
+#endif
|
||
|
+
|
||
|
struct pad_led_group {
|
||
|
struct libinput_tablet_pad_mode_group base;
|
||
|
struct list led_list;
|
||
|
@@ -187,8 +190,12 @@ pad_group_new_basic(struct pad_dispatch *pad,
|
||
|
static inline bool
|
||
|
is_litest_device(struct evdev_device *device)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
return !!udev_device_get_property_value(device->udev_device,
|
||
|
"LIBINPUT_TEST_DEVICE");
|
||
|
+#else
|
||
|
+ return false;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
static inline struct pad_led_group *
|
||
|
@@ -240,6 +247,7 @@ pad_led_get_sysfs_base_path(struct evdev_device *device,
|
||
|
char *path_out,
|
||
|
size_t path_out_sz)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
struct udev_device *parent, *udev_device;
|
||
|
const char *test_path;
|
||
|
int rc;
|
||
|
@@ -268,6 +276,9 @@ pad_led_get_sysfs_base_path(struct evdev_device *device,
|
||
|
udev_device_get_sysname(parent));
|
||
|
|
||
|
return rc != -1;
|
||
|
+#else
|
||
|
+ return false;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
#if HAVE_LIBWACOM
|
||
|
@@ -499,7 +510,7 @@ pad_init_leds_from_libwacom(struct pad_dispatch *pad,
|
||
|
goto out;
|
||
|
|
||
|
wacom = libwacom_new_from_path(db,
|
||
|
- udev_device_get_devnode(device->udev_device),
|
||
|
+ device->devnode,
|
||
|
WFALLBACK_NONE,
|
||
|
NULL);
|
||
|
if (!wacom)
|
||
|
diff --git a/src/evdev.c b/src/evdev.c
|
||
|
index ba889b6a..34a9d67d 100644
|
||
|
--- a/src/evdev.c
|
||
|
+++ b/src/evdev.c
|
||
|
@@ -31,13 +31,16 @@
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/stat.h>
|
||
|
+#include <sys/types.h>
|
||
|
+#ifndef major
|
||
|
+#include <sys/sysmacros.h>
|
||
|
+#endif
|
||
|
#include "linux/input.h"
|
||
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <mtdev-plumbing.h>
|
||
|
#include <assert.h>
|
||
|
#include <math.h>
|
||
|
-#include <libudev.h>
|
||
|
|
||
|
#include "libinput.h"
|
||
|
#include "evdev.h"
|
||
|
@@ -50,6 +53,12 @@
|
||
|
#include <libwacom/libwacom.h>
|
||
|
#endif
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
+#include <libudev.h>
|
||
|
+#endif
|
||
|
+
|
||
|
+#define INPUT_MAJOR 13
|
||
|
+
|
||
|
#define DEFAULT_WHEEL_CLICK_ANGLE 15
|
||
|
#define DEFAULT_BUTTON_SCROLL_TIMEOUT ms2us(200)
|
||
|
|
||
|
@@ -73,6 +82,7 @@ struct evdev_udev_tag_match {
|
||
|
enum evdev_device_udev_tags tag;
|
||
|
};
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
static const struct evdev_udev_tag_match evdev_udev_tag_matches[] = {
|
||
|
{"ID_INPUT", EVDEV_UDEV_TAG_INPUT},
|
||
|
{"ID_INPUT_KEYBOARD", EVDEV_UDEV_TAG_KEYBOARD},
|
||
|
@@ -88,6 +98,7 @@ static const struct evdev_udev_tag_match evdev_udev_tag_matches[] = {
|
||
|
{"ID_INPUT_TRACKBALL", EVDEV_UDEV_TAG_TRACKBALL},
|
||
|
{"ID_INPUT_SWITCH", EVDEV_UDEV_TAG_SWITCH},
|
||
|
};
|
||
|
+#endif
|
||
|
|
||
|
static inline bool
|
||
|
parse_udev_flag(struct evdev_device *device,
|
||
|
@@ -96,7 +107,11 @@ parse_udev_flag(struct evdev_device *device,
|
||
|
{
|
||
|
const char *val;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
val = udev_device_get_property_value(udev_device, property);
|
||
|
+#else
|
||
|
+ val = NULL;
|
||
|
+#endif
|
||
|
if (!val)
|
||
|
return false;
|
||
|
|
||
|
@@ -1207,7 +1222,11 @@ evdev_read_wheel_click_prop(struct evdev_device *device,
|
||
|
int val;
|
||
|
|
||
|
*angle = DEFAULT_WHEEL_CLICK_ANGLE;
|
||
|
+#if HAVE_UDEV
|
||
|
prop = udev_device_get_property_value(device->udev_device, prop);
|
||
|
+#else
|
||
|
+ prop = NULL;
|
||
|
+#endif
|
||
|
if (!prop)
|
||
|
return false;
|
||
|
|
||
|
@@ -1232,7 +1251,11 @@ evdev_read_wheel_click_count_prop(struct evdev_device *device,
|
||
|
{
|
||
|
int val;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
prop = udev_device_get_property_value(device->udev_device, prop);
|
||
|
+#else
|
||
|
+ prop = NULL;
|
||
|
+#endif
|
||
|
if (!prop)
|
||
|
return false;
|
||
|
|
||
|
@@ -1356,8 +1379,12 @@ evdev_read_dpi_prop(struct evdev_device *device)
|
||
|
if (device->tags & EVDEV_TAG_TRACKPOINT)
|
||
|
return DEFAULT_MOUSE_DPI;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
mouse_dpi = udev_device_get_property_value(device->udev_device,
|
||
|
"MOUSE_DPI");
|
||
|
+#else
|
||
|
+ mouse_dpi = NULL;
|
||
|
+#endif
|
||
|
if (mouse_dpi) {
|
||
|
dpi = parse_mouse_dpi_property(mouse_dpi);
|
||
|
if (!dpi) {
|
||
|
@@ -1558,9 +1585,9 @@ evdev_device_get_udev_tags(struct evdev_device *device,
|
||
|
struct udev_device *udev_device)
|
||
|
{
|
||
|
enum evdev_device_udev_tags tags = 0;
|
||
|
- int i;
|
||
|
|
||
|
- for (i = 0; i < 2 && udev_device; i++) {
|
||
|
+#if HAVE_UDEV
|
||
|
+ for (int i = 0; i < 2 && udev_device; i++) {
|
||
|
unsigned j;
|
||
|
for (j = 0; j < ARRAY_LENGTH(evdev_udev_tag_matches); j++) {
|
||
|
const struct evdev_udev_tag_match match = evdev_udev_tag_matches[j];
|
||
|
@@ -1571,6 +1598,29 @@ evdev_device_get_udev_tags(struct evdev_device *device,
|
||
|
}
|
||
|
udev_device = udev_device_get_parent(udev_device);
|
||
|
}
|
||
|
+#else
|
||
|
+ struct libevdev *evdev = device->evdev;
|
||
|
+ struct stat st;
|
||
|
+ if (fstat(device->fd, &st) < 0)
|
||
|
+ return 0;
|
||
|
+ if (major(st.st_rdev) == INPUT_MAJOR)
|
||
|
+ tags |= EVDEV_UDEV_TAG_INPUT;
|
||
|
+ if (libevdev_has_event_code(evdev, EV_KEY, KEY_ENTER))
|
||
|
+ tags |= EVDEV_UDEV_TAG_KEYBOARD;
|
||
|
+ if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
|
||
|
+ libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
|
||
|
+ libevdev_has_event_code(evdev, EV_KEY, BTN_MOUSE))
|
||
|
+ tags |= EVDEV_UDEV_TAG_MOUSE;
|
||
|
+ if (libevdev_has_event_code(evdev, EV_ABS, ABS_X) &&
|
||
|
+ libevdev_has_event_code(evdev, EV_ABS, ABS_Y)) {
|
||
|
+ if (libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_FINGER) &&
|
||
|
+ !libevdev_has_event_code(evdev, EV_KEY, BTN_TOOL_PEN)) {
|
||
|
+ tags |= EVDEV_UDEV_TAG_TOUCHPAD;
|
||
|
+ } else if (libevdev_has_event_code(evdev, EV_KEY, BTN_MOUSE)) {
|
||
|
+ tags |= EVDEV_UDEV_TAG_MOUSE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+#endif
|
||
|
|
||
|
return tags;
|
||
|
}
|
||
|
@@ -1969,6 +2019,7 @@ evdev_notify_added_device(struct evdev_device *device)
|
||
|
static bool
|
||
|
evdev_device_have_same_syspath(struct udev_device *udev_device, int fd)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
struct udev *udev = udev_device_get_udev(udev_device);
|
||
|
struct udev_device *udev_device_new = NULL;
|
||
|
struct stat st;
|
||
|
@@ -1987,6 +2038,9 @@ evdev_device_have_same_syspath(struct udev_device *udev_device, int fd)
|
||
|
if (udev_device_new)
|
||
|
udev_device_unref(udev_device_new);
|
||
|
return rc;
|
||
|
+#else
|
||
|
+ return true;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
static bool
|
||
|
@@ -1997,8 +2051,12 @@ evdev_set_device_group(struct evdev_device *device,
|
||
|
struct libinput_device_group *group = NULL;
|
||
|
const char *udev_group;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
udev_group = udev_device_get_property_value(udev_device,
|
||
|
"LIBINPUT_DEVICE_GROUP");
|
||
|
+#else
|
||
|
+ udev_group = NULL;
|
||
|
+#endif
|
||
|
if (udev_group)
|
||
|
group = libinput_device_group_find_group(libinput, udev_group);
|
||
|
|
||
|
@@ -2105,7 +2163,7 @@ libevdev_log_func(const struct libevdev *evdev,
|
||
|
struct libinput *libinput = data;
|
||
|
enum libinput_log_priority pri = LIBINPUT_LOG_PRIORITY_ERROR;
|
||
|
const char prefix[] = "libevdev: ";
|
||
|
- char fmt[strlen(format) + strlen(prefix) + 1];
|
||
|
+ char fmt[1024];
|
||
|
|
||
|
switch (priority) {
|
||
|
case LIBEVDEV_LOG_ERROR:
|
||
|
@@ -2129,23 +2187,33 @@ udev_device_should_be_ignored(struct udev_device *udev_device)
|
||
|
{
|
||
|
const char *value;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
value = udev_device_get_property_value(udev_device,
|
||
|
"LIBINPUT_IGNORE_DEVICE");
|
||
|
+#else
|
||
|
+ value = NULL;
|
||
|
+#endif
|
||
|
|
||
|
return value && !streq(value, "0");
|
||
|
}
|
||
|
|
||
|
struct evdev_device *
|
||
|
evdev_device_create(struct libinput_seat *seat,
|
||
|
- struct udev_device *udev_device)
|
||
|
+ struct udev_device *udev_device,
|
||
|
+ const char *devnode, const char *sysname)
|
||
|
{
|
||
|
struct libinput *libinput = seat->libinput;
|
||
|
struct evdev_device *device = NULL;
|
||
|
int rc;
|
||
|
int fd;
|
||
|
int unhandled_device = 0;
|
||
|
- const char *devnode = udev_device_get_devnode(udev_device);
|
||
|
- const char *sysname = udev_device_get_sysname(udev_device);
|
||
|
+
|
||
|
+#if HAVE_UDEV
|
||
|
+ if (udev_device) {
|
||
|
+ devnode = udev_device_get_devnode(udev_device);
|
||
|
+ sysname = udev_device_get_sysname(udev_device);
|
||
|
+ }
|
||
|
+#endif
|
||
|
|
||
|
if (!devnode) {
|
||
|
log_info(libinput, "%s: no device node associated\n", sysname);
|
||
|
@@ -2193,10 +2261,16 @@ evdev_device_create(struct libinput_seat *seat,
|
||
|
device->seat_caps = 0;
|
||
|
device->is_mt = 0;
|
||
|
device->mtdev = NULL;
|
||
|
+#if HAVE_UDEV
|
||
|
device->udev_device = udev_device_ref(udev_device);
|
||
|
+#else
|
||
|
+ device->udev_device = NULL;
|
||
|
+#endif
|
||
|
device->dispatch = NULL;
|
||
|
device->fd = fd;
|
||
|
+ device->devnode = devnode;
|
||
|
device->devname = libevdev_get_name(device->evdev);
|
||
|
+ device->sysname = sysname;
|
||
|
device->scroll.threshold = 5.0; /* Default may be overridden */
|
||
|
device->scroll.direction_lock_threshold = 5.0; /* Default may be overridden */
|
||
|
device->scroll.direction = 0;
|
||
|
@@ -2255,7 +2329,11 @@ evdev_device_get_output(struct evdev_device *device)
|
||
|
const char *
|
||
|
evdev_device_get_sysname(struct evdev_device *device)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
return udev_device_get_sysname(device->udev_device);
|
||
|
+#else
|
||
|
+ return device->sysname;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
const char *
|
||
|
@@ -2279,7 +2357,11 @@ evdev_device_get_id_vendor(struct evdev_device *device)
|
||
|
struct udev_device *
|
||
|
evdev_device_get_udev_device(struct evdev_device *device)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
return udev_device_ref(device->udev_device);
|
||
|
+#else
|
||
|
+ return NULL;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
void
|
||
|
@@ -2360,8 +2442,12 @@ evdev_read_calibration_prop(struct evdev_device *device)
|
||
|
const char *prop;
|
||
|
float calibration[6];
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
prop = udev_device_get_property_value(device->udev_device,
|
||
|
"LIBINPUT_CALIBRATION_MATRIX");
|
||
|
+#else
|
||
|
+ prop = NULL;
|
||
|
+#endif
|
||
|
|
||
|
if (prop == NULL)
|
||
|
return;
|
||
|
@@ -2396,7 +2482,11 @@ evdev_read_fuzz_prop(struct evdev_device *device, unsigned int code)
|
||
|
if (rc == -1)
|
||
|
return 0;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
prop = udev_device_get_property_value(device->udev_device, name);
|
||
|
+#else
|
||
|
+ prop = NULL;
|
||
|
+#endif
|
||
|
if (prop && (safe_atoi(prop, &fuzz) == false || fuzz < 0)) {
|
||
|
evdev_log_bug_libinput(device,
|
||
|
"invalid LIBINPUT_FUZZ property value: %s\n",
|
||
|
@@ -2726,7 +2816,6 @@ evdev_device_resume(struct evdev_device *device)
|
||
|
{
|
||
|
struct libinput *libinput = evdev_libinput_context(device);
|
||
|
int fd;
|
||
|
- const char *devnode;
|
||
|
struct input_event ev;
|
||
|
enum libevdev_read_status status;
|
||
|
|
||
|
@@ -2736,11 +2825,7 @@ evdev_device_resume(struct evdev_device *device)
|
||
|
if (device->was_removed)
|
||
|
return -ENODEV;
|
||
|
|
||
|
- devnode = udev_device_get_devnode(device->udev_device);
|
||
|
- if (!devnode)
|
||
|
- return -ENODEV;
|
||
|
-
|
||
|
- fd = open_restricted(libinput, devnode,
|
||
|
+ fd = open_restricted(libinput, device->devnode,
|
||
|
O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||
|
|
||
|
if (fd < 0)
|
||
|
@@ -2839,7 +2924,9 @@ evdev_device_destroy(struct evdev_device *device)
|
||
|
libinput_timer_destroy(&device->middlebutton.timer);
|
||
|
libinput_seat_unref(device->base.seat);
|
||
|
libevdev_free(device->evdev);
|
||
|
+#if HAVE_UDEV
|
||
|
udev_device_unref(device->udev_device);
|
||
|
+#endif
|
||
|
free(device);
|
||
|
}
|
||
|
|
||
|
@@ -2852,17 +2939,15 @@ evdev_tablet_has_left_handed(struct evdev_device *device)
|
||
|
WacomDeviceDatabase *db = NULL;
|
||
|
WacomDevice *d = NULL;
|
||
|
WacomError *error;
|
||
|
- const char *devnode;
|
||
|
|
||
|
db = libinput_libwacom_ref(li);
|
||
|
if (!db)
|
||
|
goto out;
|
||
|
|
||
|
error = libwacom_error_new();
|
||
|
- devnode = udev_device_get_devnode(device->udev_device);
|
||
|
|
||
|
d = libwacom_new_from_path(db,
|
||
|
- devnode,
|
||
|
+ device->devnode,
|
||
|
WFALLBACK_NONE,
|
||
|
error);
|
||
|
|
||
|
diff --git a/src/evdev.h b/src/evdev.h
|
||
|
index e95f7e60..490d542e 100644
|
||
|
--- a/src/evdev.h
|
||
|
+++ b/src/evdev.h
|
||
|
@@ -167,7 +167,9 @@ struct evdev_device {
|
||
|
struct libevdev *evdev;
|
||
|
struct udev_device *udev_device;
|
||
|
char *output_name;
|
||
|
+ const char *devnode;
|
||
|
const char *devname;
|
||
|
+ const char *sysname;
|
||
|
bool was_removed;
|
||
|
int fd;
|
||
|
enum evdev_device_seat_capability seat_caps;
|
||
|
@@ -375,7 +377,8 @@ evdev_verify_dispatch_type(struct evdev_dispatch *dispatch,
|
||
|
|
||
|
struct evdev_device *
|
||
|
evdev_device_create(struct libinput_seat *seat,
|
||
|
- struct udev_device *device);
|
||
|
+ struct udev_device *device,
|
||
|
+ const char *devnode, const char *sysname);
|
||
|
|
||
|
static inline struct libinput *
|
||
|
evdev_libinput_context(const struct evdev_device *device)
|
||
|
diff --git a/src/libinput.c b/src/libinput.c
|
||
|
index b532f1e3..76c41d6f 100644
|
||
|
--- a/src/libinput.c
|
||
|
+++ b/src/libinput.c
|
||
|
@@ -33,7 +33,10 @@
|
||
|
#include <sys/epoll.h>
|
||
|
#include <unistd.h>
|
||
|
#include <assert.h>
|
||
|
+
|
||
|
+#if HAVE_UDEV
|
||
|
#include <libudev.h>
|
||
|
+#endif
|
||
|
|
||
|
#include "libinput.h"
|
||
|
#include "libinput-private.h"
|
||
|
@@ -1974,9 +1977,11 @@ close_restricted(struct libinput *libinput, int fd)
|
||
|
bool
|
||
|
ignore_litest_test_suite_device(struct udev_device *device)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
if (!getenv("LIBINPUT_RUNNING_TEST_SUITE") &&
|
||
|
udev_device_get_property_value(device, "LIBINPUT_TEST_DEVICE"))
|
||
|
return true;
|
||
|
+#endif
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
diff --git a/src/path-seat.c b/src/path-seat.c
|
||
|
index 99b089a4..22bf06c9 100644
|
||
|
--- a/src/path-seat.c
|
||
|
+++ b/src/path-seat.c
|
||
|
@@ -25,7 +25,9 @@
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <sys/stat.h>
|
||
|
+#if HAVE_UDEV
|
||
|
#include <libudev.h>
|
||
|
+#endif
|
||
|
|
||
|
#include "evdev.h"
|
||
|
|
||
|
@@ -38,6 +40,8 @@ struct path_input {
|
||
|
struct path_device {
|
||
|
struct list link;
|
||
|
struct udev_device *udev_device;
|
||
|
+ const char *devnode;
|
||
|
+ const char *sysname;
|
||
|
};
|
||
|
|
||
|
struct path_seat {
|
||
|
@@ -121,33 +125,36 @@ path_seat_get_named(struct path_input *input,
|
||
|
|
||
|
static struct path_seat *
|
||
|
path_seat_get_for_device(struct path_input *input,
|
||
|
- struct udev_device *udev_device,
|
||
|
+ struct path_device *dev,
|
||
|
const char *seat_logical_name_override)
|
||
|
{
|
||
|
struct path_seat *seat = NULL;
|
||
|
char *seat_name = NULL, *seat_logical_name = NULL;
|
||
|
const char *seat_prop;
|
||
|
|
||
|
- const char *devnode, *sysname;
|
||
|
-
|
||
|
- devnode = udev_device_get_devnode(udev_device);
|
||
|
- sysname = udev_device_get_sysname(udev_device);
|
||
|
-
|
||
|
- seat_prop = udev_device_get_property_value(udev_device, "ID_SEAT");
|
||
|
+#if HAVE_UDEV
|
||
|
+ seat_prop = udev_device_get_property_value(dev->udev_device, "ID_SEAT");
|
||
|
+#else
|
||
|
+ seat_prop = NULL;
|
||
|
+#endif
|
||
|
seat_name = safe_strdup(seat_prop ? seat_prop : default_seat);
|
||
|
|
||
|
if (seat_logical_name_override) {
|
||
|
seat_logical_name = safe_strdup(seat_logical_name_override);
|
||
|
} else {
|
||
|
- seat_prop = udev_device_get_property_value(udev_device, "WL_SEAT");
|
||
|
+#if HAVE_UDEV
|
||
|
+ seat_prop = udev_device_get_property_value(dev->udev_device, "WL_SEAT");
|
||
|
+#else
|
||
|
+ seat_prop = NULL;
|
||
|
+#endif
|
||
|
seat_logical_name = strdup(seat_prop ? seat_prop : default_seat_name);
|
||
|
}
|
||
|
|
||
|
if (!seat_logical_name) {
|
||
|
log_error(&input->base,
|
||
|
"%s: failed to create seat name for device '%s'.\n",
|
||
|
- sysname,
|
||
|
- devnode);
|
||
|
+ dev->sysname,
|
||
|
+ dev->devnode);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
@@ -158,8 +165,8 @@ path_seat_get_for_device(struct path_input *input,
|
||
|
if (!seat) {
|
||
|
log_info(&input->base,
|
||
|
"%s: failed to create seat for device '%s'.\n",
|
||
|
- sysname,
|
||
|
- devnode);
|
||
|
+ dev->sysname,
|
||
|
+ dev->devnode);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
@@ -173,41 +180,41 @@ path_seat_get_for_device(struct path_input *input,
|
||
|
|
||
|
static struct libinput_device *
|
||
|
path_device_enable(struct path_input *input,
|
||
|
- struct udev_device *udev_device,
|
||
|
+ struct path_device *dev,
|
||
|
const char *seat_logical_name_override)
|
||
|
{
|
||
|
struct path_seat *seat;
|
||
|
struct evdev_device *device = NULL;
|
||
|
const char *output_name;
|
||
|
- const char *devnode, *sysname;
|
||
|
-
|
||
|
- devnode = udev_device_get_devnode(udev_device);
|
||
|
- sysname = udev_device_get_sysname(udev_device);
|
||
|
|
||
|
- seat = path_seat_get_for_device(input, udev_device, seat_logical_name_override);
|
||
|
+ seat = path_seat_get_for_device(input, dev, seat_logical_name_override);
|
||
|
if (!seat)
|
||
|
goto out;
|
||
|
|
||
|
- device = evdev_device_create(&seat->base, udev_device);
|
||
|
+ device = evdev_device_create(&seat->base, dev->udev_device, dev->devnode, dev->sysname);
|
||
|
libinput_seat_unref(&seat->base);
|
||
|
|
||
|
if (device == EVDEV_UNHANDLED_DEVICE) {
|
||
|
device = NULL;
|
||
|
log_info(&input->base,
|
||
|
"%-7s - not using input device '%s'.\n",
|
||
|
- sysname,
|
||
|
- devnode);
|
||
|
+ dev->sysname,
|
||
|
+ dev->devnode);
|
||
|
goto out;
|
||
|
} else if (device == NULL) {
|
||
|
log_info(&input->base,
|
||
|
"%-7s - failed to create input device '%s'.\n",
|
||
|
- sysname,
|
||
|
- devnode);
|
||
|
+ dev->sysname,
|
||
|
+ dev->devnode);
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
evdev_read_calibration_prop(device);
|
||
|
- output_name = udev_device_get_property_value(udev_device, "WL_OUTPUT");
|
||
|
+#if HAVE_UDEV
|
||
|
+ output_name = udev_device_get_property_value(dev->udev_device, "WL_OUTPUT");
|
||
|
+#else
|
||
|
+ output_name = NULL;
|
||
|
+#endif
|
||
|
device->output_name = safe_strdup(output_name);
|
||
|
|
||
|
out:
|
||
|
@@ -221,7 +228,7 @@ path_input_enable(struct libinput *libinput)
|
||
|
struct path_device *dev;
|
||
|
|
||
|
list_for_each(dev, &input->path_list, link) {
|
||
|
- if (path_device_enable(input, dev->udev_device, NULL) == NULL) {
|
||
|
+ if (path_device_enable(input, dev, NULL) == NULL) {
|
||
|
path_input_disable(libinput);
|
||
|
return -1;
|
||
|
}
|
||
|
@@ -234,7 +241,11 @@ static void
|
||
|
path_device_destroy(struct path_device *dev)
|
||
|
{
|
||
|
list_remove(&dev->link);
|
||
|
+#if HAVE_UDEV
|
||
|
udev_device_unref(dev->udev_device);
|
||
|
+#else
|
||
|
+ free((char *)dev->devnode);
|
||
|
+#endif
|
||
|
free(dev);
|
||
|
}
|
||
|
|
||
|
@@ -244,16 +255,18 @@ path_input_destroy(struct libinput *input)
|
||
|
struct path_input *path_input = (struct path_input*)input;
|
||
|
struct path_device *dev, *tmp;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
udev_unref(path_input->udev);
|
||
|
+#endif
|
||
|
|
||
|
list_for_each_safe(dev, tmp, &path_input->path_list, link)
|
||
|
path_device_destroy(dev);
|
||
|
-
|
||
|
}
|
||
|
|
||
|
static struct libinput_device *
|
||
|
path_create_device(struct libinput *libinput,
|
||
|
struct udev_device *udev_device,
|
||
|
+ const char *devnode,
|
||
|
const char *seat_name)
|
||
|
{
|
||
|
struct path_input *input = (struct path_input*)libinput;
|
||
|
@@ -261,11 +274,23 @@ path_create_device(struct libinput *libinput,
|
||
|
struct libinput_device *device;
|
||
|
|
||
|
dev = zalloc(sizeof *dev);
|
||
|
+#if HAVE_UDEV
|
||
|
dev->udev_device = udev_device_ref(udev_device);
|
||
|
+ dev->devnode = udev_device_get_devnode(udev_device);
|
||
|
+ dev->sysname = udev_device_get_sysname(udev_device);
|
||
|
+#else
|
||
|
+ dev->udev_device = NULL;
|
||
|
+ dev->devnode = safe_strdup(devnode);
|
||
|
+ dev->sysname = strrchr(devnode, '/');
|
||
|
+ if (dev->sysname)
|
||
|
+ ++dev->sysname;
|
||
|
+ else
|
||
|
+ dev->sysname = "";
|
||
|
+#endif
|
||
|
|
||
|
list_insert(&input->path_list, &dev->link);
|
||
|
|
||
|
- device = path_device_enable(input, udev_device, seat_name);
|
||
|
+ device = path_device_enable(input, dev, seat_name);
|
||
|
|
||
|
if (!device)
|
||
|
path_device_destroy(dev);
|
||
|
@@ -280,15 +305,24 @@ path_device_change_seat(struct libinput_device *device,
|
||
|
struct libinput *libinput = device->seat->libinput;
|
||
|
struct evdev_device *evdev = evdev_device(device);
|
||
|
struct udev_device *udev_device = NULL;
|
||
|
+ char *devnode = NULL;
|
||
|
int rc = -1;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
udev_device = evdev->udev_device;
|
||
|
udev_device_ref(udev_device);
|
||
|
+#else
|
||
|
+ devnode = strdup(evdev->devnode);
|
||
|
+ if (!devnode)
|
||
|
+ return -1;
|
||
|
+#endif
|
||
|
libinput_path_remove_device(device);
|
||
|
|
||
|
- if (path_create_device(libinput, udev_device, seat_name) != NULL)
|
||
|
+ if (path_create_device(libinput, udev_device, devnode, seat_name) != NULL)
|
||
|
rc = 0;
|
||
|
+#if HAVE_UDEV
|
||
|
udev_device_unref(udev_device);
|
||
|
+#endif
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
@@ -309,14 +343,20 @@ libinput_path_create_context(const struct libinput_interface *interface,
|
||
|
if (!interface)
|
||
|
return NULL;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
udev = udev_new();
|
||
|
if (!udev)
|
||
|
return NULL;
|
||
|
+#else
|
||
|
+ udev = NULL;
|
||
|
+#endif
|
||
|
|
||
|
input = zalloc(sizeof *input);
|
||
|
if (libinput_init(&input->base, interface,
|
||
|
&interface_backend, user_data) != 0) {
|
||
|
+#if HAVE_UDEV
|
||
|
udev_unref(udev);
|
||
|
+#endif
|
||
|
free(input);
|
||
|
return NULL;
|
||
|
}
|
||
|
@@ -327,6 +367,7 @@ libinput_path_create_context(const struct libinput_interface *interface,
|
||
|
return &input->base;
|
||
|
}
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
static inline struct udev_device *
|
||
|
udev_device_from_devnode(struct libinput *libinput,
|
||
|
struct udev *udev,
|
||
|
@@ -356,13 +397,12 @@ udev_device_from_devnode(struct libinput *libinput,
|
||
|
|
||
|
return dev;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
LIBINPUT_EXPORT struct libinput_device *
|
||
|
libinput_path_add_device(struct libinput *libinput,
|
||
|
const char *path)
|
||
|
{
|
||
|
- struct path_input *input = (struct path_input *)libinput;
|
||
|
- struct udev *udev = input->udev;
|
||
|
struct udev_device *udev_device;
|
||
|
struct libinput_device *device;
|
||
|
|
||
|
@@ -378,7 +418,10 @@ libinput_path_add_device(struct libinput *libinput,
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
- udev_device = udev_device_from_devnode(libinput, udev, path);
|
||
|
+#if HAVE_UDEV
|
||
|
+ struct path_input *input = (struct path_input *)libinput;
|
||
|
+
|
||
|
+ udev_device = udev_device_from_devnode(libinput, input->udev, path);
|
||
|
if (!udev_device) {
|
||
|
log_bug_client(libinput, "Invalid path %s\n", path);
|
||
|
return NULL;
|
||
|
@@ -388,6 +431,9 @@ libinput_path_add_device(struct libinput *libinput,
|
||
|
udev_device_unref(udev_device);
|
||
|
return NULL;
|
||
|
}
|
||
|
+#else
|
||
|
+ udev_device = NULL;
|
||
|
+#endif
|
||
|
|
||
|
/* We cannot do this during path_create_context because the log
|
||
|
* handler isn't set up there but we really want to log to the right
|
||
|
@@ -396,8 +442,10 @@ libinput_path_add_device(struct libinput *libinput,
|
||
|
*/
|
||
|
libinput_init_quirks(libinput);
|
||
|
|
||
|
- device = path_create_device(libinput, udev_device, NULL);
|
||
|
+ device = path_create_device(libinput, udev_device, path, NULL);
|
||
|
+#if HAVE_UDEV
|
||
|
udev_device_unref(udev_device);
|
||
|
+#endif
|
||
|
return device;
|
||
|
}
|
||
|
|
||
|
@@ -416,7 +464,8 @@ libinput_path_remove_device(struct libinput_device *device)
|
||
|
}
|
||
|
|
||
|
list_for_each(dev, &input->path_list, link) {
|
||
|
- if (dev->udev_device == evdev->udev_device) {
|
||
|
+ if (dev->udev_device == evdev->udev_device &&
|
||
|
+ dev->devnode == evdev->devnode) {
|
||
|
path_device_destroy(dev);
|
||
|
break;
|
||
|
}
|
||
|
diff --git a/src/quirks.c b/src/quirks.c
|
||
|
index 8c0bb96e..ea13f9a7 100644
|
||
|
--- a/src/quirks.c
|
||
|
+++ b/src/quirks.c
|
||
|
@@ -31,11 +31,14 @@
|
||
|
#undef NDEBUG /* You don't get to disable asserts here */
|
||
|
#include <assert.h>
|
||
|
#include <stdlib.h>
|
||
|
-#include <libudev.h>
|
||
|
#include <dirent.h>
|
||
|
#include <fnmatch.h>
|
||
|
#include <libgen.h>
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
+#include <libudev.h>
|
||
|
+#endif
|
||
|
+
|
||
|
#include "libinput-versionsort.h"
|
||
|
#include "libinput-util.h"
|
||
|
|
||
|
@@ -348,34 +351,22 @@ property_cleanup(struct property *p)
|
||
|
static inline char *
|
||
|
init_dmi(void)
|
||
|
{
|
||
|
- struct udev *udev;
|
||
|
- struct udev_device *udev_device;
|
||
|
- const char *modalias = NULL;
|
||
|
+ char modalias[1024];
|
||
|
char *copy = NULL;
|
||
|
- const char *syspath = "/sys/devices/virtual/dmi/id";
|
||
|
+ const char *syspath = "/sys/devices/virtual/dmi/id/modalias";
|
||
|
+ FILE *fp;
|
||
|
|
||
|
if (getenv("LIBINPUT_RUNNING_TEST_SUITE"))
|
||
|
return safe_strdup("dmi:");
|
||
|
|
||
|
- udev = udev_new();
|
||
|
- if (!udev)
|
||
|
+ fp = fopen(syspath, "r");
|
||
|
+ if (!fp)
|
||
|
return NULL;
|
||
|
|
||
|
- udev_device = udev_device_new_from_syspath(udev, syspath);
|
||
|
- if (udev_device)
|
||
|
- modalias = udev_device_get_property_value(udev_device,
|
||
|
- "MODALIAS");
|
||
|
-
|
||
|
- /* Not sure whether this could ever really fail, if so we should
|
||
|
- * open the sysfs file directly. But then udev wouldn't have failed,
|
||
|
- * so... */
|
||
|
- if (!modalias)
|
||
|
- modalias = "dmi:*";
|
||
|
+ if (fgets(modalias, sizeof(modalias), fp))
|
||
|
+ copy = safe_strdup(modalias);
|
||
|
|
||
|
- copy = safe_strdup(modalias);
|
||
|
-
|
||
|
- udev_device_unref(udev_device);
|
||
|
- udev_unref(udev);
|
||
|
+ fclose(fp);
|
||
|
|
||
|
return copy;
|
||
|
}
|
||
|
@@ -1100,6 +1091,7 @@ quirks_context_unref(struct quirks_context *ctx)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
static struct quirks *
|
||
|
quirks_new(void)
|
||
|
{
|
||
|
@@ -1112,6 +1104,7 @@ quirks_new(void)
|
||
|
|
||
|
return q;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
struct quirks *
|
||
|
quirks_unref(struct quirks *q)
|
||
|
@@ -1142,13 +1135,16 @@ quirks_unref(struct quirks *q)
|
||
|
static const char *
|
||
|
udev_prop(struct udev_device *device, const char *prop)
|
||
|
{
|
||
|
- struct udev_device *d = device;
|
||
|
const char *value = NULL;
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
+ struct udev_device *d = device;
|
||
|
+
|
||
|
do {
|
||
|
value = udev_device_get_property_value(d, prop);
|
||
|
d = udev_device_get_parent(d);
|
||
|
} while (value == NULL && d != NULL);
|
||
|
+#endif
|
||
|
|
||
|
return value;
|
||
|
}
|
||
|
@@ -1262,6 +1258,7 @@ match_fill_dmi_dt(struct match *m, char *dmi, char *dt)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
static struct match *
|
||
|
match_new(struct udev_device *device,
|
||
|
char *dmi, char *dt)
|
||
|
@@ -1387,11 +1384,13 @@ quirk_match_section(struct quirks_context *ctx,
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
struct quirks *
|
||
|
quirks_fetch_for_device(struct quirks_context *ctx,
|
||
|
struct udev_device *udev_device)
|
||
|
{
|
||
|
+#if HAVE_UDEV
|
||
|
struct quirks *q = NULL;
|
||
|
struct section *s;
|
||
|
struct match *m;
|
||
|
@@ -1420,6 +1419,9 @@ quirks_fetch_for_device(struct quirks_context *ctx,
|
||
|
list_insert(&ctx->quirks, &q->link);
|
||
|
|
||
|
return q;
|
||
|
+#else
|
||
|
+ return NULL;
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
diff --git a/src/udev-seat.c b/src/udev-seat.c
|
||
|
index 3af01606..df280d9a 100644
|
||
|
--- a/src/udev-seat.c
|
||
|
+++ b/src/udev-seat.c
|
||
|
@@ -24,6 +24,8 @@
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
+#if HAVE_UDEV
|
||
|
+
|
||
|
#include <libudev.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
@@ -81,7 +83,7 @@ device_added(struct udev_device *udev_device,
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
- device = evdev_device_create(&seat->base, udev_device);
|
||
|
+ device = evdev_device_create(&seat->base, udev_device, NULL, NULL);
|
||
|
libinput_seat_unref(&seat->base);
|
||
|
|
||
|
if (device == EVDEV_UNHANDLED_DEVICE) {
|
||
|
@@ -412,3 +414,24 @@ libinput_udev_assign_seat(struct libinput *libinput,
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
+
|
||
|
+#else
|
||
|
+
|
||
|
+#include "udev-seat.h"
|
||
|
+
|
||
|
+LIBINPUT_EXPORT struct libinput *
|
||
|
+libinput_udev_create_context(const struct libinput_interface *interface,
|
||
|
+ void *user_data,
|
||
|
+ struct udev *udev)
|
||
|
+{
|
||
|
+ return NULL;
|
||
|
+}
|
||
|
+
|
||
|
+LIBINPUT_EXPORT int
|
||
|
+libinput_udev_assign_seat(struct libinput *libinput,
|
||
|
+ const char *seat_id)
|
||
|
+{
|
||
|
+ return -1;
|
||
|
+}
|
||
|
+
|
||
|
+#endif /* HAVE_UDEV */
|
||
|
|
||
|
From 597b16f5134b8d095039efb3a27a4d0b643718c3 Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Forney <mforney@mforney.org>
|
||
|
Date: Fri, 3 Jan 2020 22:08:41 -0800
|
||
|
Subject: [PATCH] Add netlink seat
|
||
|
|
||
|
---
|
||
|
meson.build | 2 +
|
||
|
src/libinput.h | 42 +++++
|
||
|
src/netlink-seat.c | 373 +++++++++++++++++++++++++++++++++++++++++++++
|
||
|
src/netlink-seat.h | 42 +++++
|
||
|
4 files changed, 459 insertions(+)
|
||
|
create mode 100644 src/netlink-seat.c
|
||
|
create mode 100644 src/netlink-seat.h
|
||
|
|
||
|
diff --git a/meson.build b/meson.build
|
||
|
index 75b393f4..7d66eba2 100644
|
||
|
--- a/meson.build
|
||
|
+++ b/meson.build
|
||
|
@@ -392,6 +392,8 @@ src_libinput = src_libfilter + [
|
||
|
'src/evdev-tablet-pad.c',
|
||
|
'src/evdev-tablet-pad.h',
|
||
|
'src/evdev-tablet-pad-leds.c',
|
||
|
+ 'src/netlink-seat.c',
|
||
|
+ 'src/netlink-seat.h',
|
||
|
'src/path-seat.c',
|
||
|
'src/udev-seat.c',
|
||
|
'src/udev-seat.h',
|
||
|
diff --git a/src/libinput.h b/src/libinput.h
|
||
|
index f5ae835d..b90cb4ab 100644
|
||
|
--- a/src/libinput.h
|
||
|
+++ b/src/libinput.h
|
||
|
@@ -3304,6 +3304,7 @@ libinput_event_switch_get_time_usec(struct libinput_event_switch *event);
|
||
|
*
|
||
|
* @see libinput_udev_create_context
|
||
|
* @see libinput_path_create_context
|
||
|
+ * @see libinput_netlink_create_context
|
||
|
*/
|
||
|
struct libinput_interface {
|
||
|
/**
|
||
|
@@ -3439,6 +3440,47 @@ libinput_path_add_device(struct libinput *libinput,
|
||
|
void
|
||
|
libinput_path_remove_device(struct libinput_device *device);
|
||
|
|
||
|
+/**
|
||
|
+ * @ingroup base
|
||
|
+ *
|
||
|
+ * Create a new libinput context from netlink. This context is inactive until
|
||
|
+ * assigned a seat ID with libinput_netlink_assign_seat().
|
||
|
+ *
|
||
|
+ * @param interface The callback interface
|
||
|
+ * @param user_data Caller-specific data passed to the various callback
|
||
|
+ * interfaces.
|
||
|
+ *
|
||
|
+ * @return An initialized, but inactive libinput context or NULL on error
|
||
|
+ */
|
||
|
+struct libinput *
|
||
|
+libinput_netlink_create_context(const struct libinput_interface *interface,
|
||
|
+ void *user_data);
|
||
|
+
|
||
|
+/**
|
||
|
+ * @ingroup base
|
||
|
+ *
|
||
|
+ * Assign a seat to this libinput context. New devices or the removal of
|
||
|
+ * existing devices will appear as events during libinput_dispatch().
|
||
|
+ *
|
||
|
+ * libinput_netlink_assign_seat() succeeds even if no input devices are currently
|
||
|
+ * available on this seat, or if devices are available but fail to open in
|
||
|
+ * @ref libinput_interface::open_restricted. Devices that do not have the
|
||
|
+ * minimum capabilities to be recognized as pointer, keyboard or touch
|
||
|
+ * device are ignored. Such devices and those that failed to open
|
||
|
+ * ignored until the next call to libinput_resume().
|
||
|
+ *
|
||
|
+ * This function may only be called once per context.
|
||
|
+ *
|
||
|
+ * @param libinput A libinput context initialized with
|
||
|
+ * libinput_udev_create_context()
|
||
|
+ * @param seat_id A seat identifier. This string must not be NULL.
|
||
|
+ *
|
||
|
+ * @return 0 on success or -1 on failure.
|
||
|
+ */
|
||
|
+int
|
||
|
+libinput_netlink_assign_seat(struct libinput *libinput,
|
||
|
+ const char *seat_id);
|
||
|
+
|
||
|
/**
|
||
|
* @ingroup base
|
||
|
*
|
||
|
diff --git a/src/netlink-seat.c b/src/netlink-seat.c
|
||
|
new file mode 100644
|
||
|
index 00000000..d22a2821
|
||
|
--- /dev/null
|
||
|
+++ b/src/netlink-seat.c
|
||
|
@@ -0,0 +1,373 @@
|
||
|
+/*
|
||
|
+ * Copyright © 2013 Intel Corporation
|
||
|
+ * Copyright © 2013-2015 Red Hat, Inc.
|
||
|
+ * Copyright © 2017 Michael Forney
|
||
|
+ *
|
||
|
+ * 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.
|
||
|
+ */
|
||
|
+
|
||
|
+#include "config.h"
|
||
|
+
|
||
|
+#include <stdlib.h>
|
||
|
+#include <stdio.h>
|
||
|
+#include <string.h>
|
||
|
+#include <unistd.h>
|
||
|
+#include <fcntl.h>
|
||
|
+#include <dirent.h>
|
||
|
+
|
||
|
+#include <sys/socket.h>
|
||
|
+#include <linux/netlink.h>
|
||
|
+
|
||
|
+#include "evdev.h"
|
||
|
+#include "netlink-seat.h"
|
||
|
+
|
||
|
+#define INPUT_MAJOR 13
|
||
|
+
|
||
|
+static const char default_seat[] = "seat0";
|
||
|
+static const char default_seat_name[] = "default";
|
||
|
+
|
||
|
+static struct netlink_seat *
|
||
|
+netlink_seat_create(struct netlink_input *input,
|
||
|
+ const char *device_seat,
|
||
|
+ const char *seat_name);
|
||
|
+static struct netlink_seat *
|
||
|
+netlink_seat_get_named(struct netlink_input *input, const char *seat_name);
|
||
|
+
|
||
|
+static int
|
||
|
+device_added(struct netlink_input *input,
|
||
|
+ const char *devnode)
|
||
|
+{
|
||
|
+ struct evdev_device *device;
|
||
|
+ const char *device_seat, *seat_name, *sysname;
|
||
|
+ struct netlink_seat *seat;
|
||
|
+
|
||
|
+ device_seat = default_seat;
|
||
|
+ seat_name = default_seat_name;
|
||
|
+ seat = netlink_seat_get_named(input, seat_name);
|
||
|
+
|
||
|
+ if (seat)
|
||
|
+ libinput_seat_ref(&seat->base);
|
||
|
+ else {
|
||
|
+ seat = netlink_seat_create(input, device_seat, seat_name);
|
||
|
+ if (!seat)
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ sysname = strrchr(devnode, '/');
|
||
|
+ if (sysname)
|
||
|
+ ++sysname;
|
||
|
+ else
|
||
|
+ sysname = "";
|
||
|
+
|
||
|
+ device = evdev_device_create(&seat->base, NULL, devnode, sysname);
|
||
|
+ libinput_seat_unref(&seat->base);
|
||
|
+
|
||
|
+ if (device == EVDEV_UNHANDLED_DEVICE) {
|
||
|
+ log_info(&input->base,
|
||
|
+ "%-7s - not using input device '%s'\n",
|
||
|
+ sysname,
|
||
|
+ devnode);
|
||
|
+ return 0;
|
||
|
+ } else if (device == NULL) {
|
||
|
+ log_info(&input->base,
|
||
|
+ "%-7s - failed to create input device '%s'\n",
|
||
|
+ sysname,
|
||
|
+ devnode);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ evdev_read_calibration_prop(device);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+device_removed(struct netlink_input *input, const char *devnode)
|
||
|
+{
|
||
|
+ struct evdev_device *device, *next;
|
||
|
+ struct netlink_seat *seat;
|
||
|
+
|
||
|
+ list_for_each(seat, &input->base.seat_list, base.link) {
|
||
|
+ list_for_each_safe(device, next,
|
||
|
+ &seat->base.devices_list, base.link) {
|
||
|
+ if (streq(devnode, device->devnode)) {
|
||
|
+ evdev_device_remove(device);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+select_device(const struct dirent *entry)
|
||
|
+{
|
||
|
+ const char *p;
|
||
|
+
|
||
|
+ if (strncmp(entry->d_name, "event", 5) != 0)
|
||
|
+ return 0;
|
||
|
+ for (p = entry->d_name + 5; '0' <= *p && *p <= '9'; ++p)
|
||
|
+ ;
|
||
|
+ return *p == '\0';
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+netlink_input_add_devices(struct netlink_input *input)
|
||
|
+{
|
||
|
+ struct dirent **devices;
|
||
|
+ char path[PATH_MAX];
|
||
|
+ int i, n, len;
|
||
|
+
|
||
|
+ n = scandir("/dev/input", &devices, &select_device, &alphasort);
|
||
|
+ if (n == -1)
|
||
|
+ return -1;
|
||
|
+ for (i = 0; i < n; ++i) {
|
||
|
+ len = snprintf(path, sizeof(path), "/dev/input/%s", devices[i]->d_name);
|
||
|
+ free(devices[i]);
|
||
|
+ if (len < 0 || (size_t)len >= sizeof(path)) {
|
||
|
+ free(devices);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ device_added(input, path);
|
||
|
+ }
|
||
|
+ free(devices);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+netlink_input_remove_devices(struct netlink_input *input)
|
||
|
+{
|
||
|
+ struct evdev_device *device, *next;
|
||
|
+ struct netlink_seat *seat, *tmp;
|
||
|
+
|
||
|
+ list_for_each_safe(seat, tmp, &input->base.seat_list, base.link) {
|
||
|
+ libinput_seat_ref(&seat->base);
|
||
|
+ list_for_each_safe(device, next,
|
||
|
+ &seat->base.devices_list, base.link) {
|
||
|
+ evdev_device_remove(device);
|
||
|
+ }
|
||
|
+ libinput_seat_unref(&seat->base);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+netlink_input_disable(struct libinput *libinput)
|
||
|
+{
|
||
|
+ struct netlink_input *input = (struct netlink_input*)libinput;
|
||
|
+
|
||
|
+ if (input->sock == -1)
|
||
|
+ return;
|
||
|
+
|
||
|
+ close(input->sock);
|
||
|
+ input->sock = -1;
|
||
|
+ libinput_remove_source(&input->base, input->source);
|
||
|
+ input->source = NULL;
|
||
|
+
|
||
|
+ netlink_input_remove_devices(input);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+netlink_handler(void *data)
|
||
|
+{
|
||
|
+ struct netlink_input *input = data;
|
||
|
+ char buf[BUFSIZ], *key, *val;
|
||
|
+ ssize_t n;
|
||
|
+ size_t len;
|
||
|
+ char *action = NULL, *devname = NULL, *devnode, *sysname;
|
||
|
+
|
||
|
+ n = read(input->sock, buf, sizeof(buf));
|
||
|
+ if (n <= 0)
|
||
|
+ return;
|
||
|
+ for (key = buf; key < buf + n; key += len + 1) {
|
||
|
+ len = strlen(key);
|
||
|
+ val = strchr(key, '=');
|
||
|
+ if (!val)
|
||
|
+ continue;
|
||
|
+ *val++ = '\0';
|
||
|
+ if (strcmp(key, "ACTION") == 0) {
|
||
|
+ action = val;
|
||
|
+ } else if (strcmp(key, "SUBSYSTEM") == 0) {
|
||
|
+ if (strcmp(val, "input") != 0)
|
||
|
+ return;
|
||
|
+ } else if (strcmp(key, "DEVNAME") == 0) {
|
||
|
+ devname = val;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (!action || !devname)
|
||
|
+ return;
|
||
|
+ sysname = strrchr(devname, '/');
|
||
|
+ if (sysname)
|
||
|
+ ++sysname;
|
||
|
+ else
|
||
|
+ sysname = devname;
|
||
|
+ if (strncmp(sysname, "event", 5) != 0)
|
||
|
+ return;
|
||
|
+ devnode = devname - 5;
|
||
|
+ memcpy(devnode, "/dev/", 5);
|
||
|
+ if (strcmp(action, "add") == 0)
|
||
|
+ device_added(input, devnode);
|
||
|
+ else if (strcmp(action, "remove") == 0)
|
||
|
+ device_removed(input, devnode);
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+netlink_input_enable(struct libinput *libinput)
|
||
|
+{
|
||
|
+ int s;
|
||
|
+ struct sockaddr_nl addr = {
|
||
|
+ .nl_family = AF_NETLINK,
|
||
|
+ .nl_groups = 1,
|
||
|
+ };
|
||
|
+ struct netlink_input *input = (struct netlink_input*)libinput;
|
||
|
+
|
||
|
+ if (input->sock != -1)
|
||
|
+ return 0;
|
||
|
+ s = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);
|
||
|
+ if (s == -1)
|
||
|
+ return -1;
|
||
|
+ if (bind(s, (void *)&addr, sizeof(addr)) < 0) {
|
||
|
+ close(s);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ input->source = libinput_add_fd(&input->base, s, netlink_handler, input);
|
||
|
+ if (!input->source) {
|
||
|
+ close(s);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+ input->sock = s;
|
||
|
+ if (netlink_input_add_devices(input) < 0) {
|
||
|
+ netlink_input_disable(libinput);
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+netlink_input_destroy(struct libinput *input)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+netlink_seat_destroy(struct libinput_seat *seat)
|
||
|
+{
|
||
|
+ struct netlink_seat *nseat = (struct netlink_seat*)seat;
|
||
|
+ free(nseat);
|
||
|
+}
|
||
|
+
|
||
|
+static struct netlink_seat *
|
||
|
+netlink_seat_create(struct netlink_input *input,
|
||
|
+ const char *device_seat,
|
||
|
+ const char *seat_name)
|
||
|
+{
|
||
|
+ struct netlink_seat *seat;
|
||
|
+
|
||
|
+ seat = zalloc(sizeof(*seat));
|
||
|
+
|
||
|
+ libinput_seat_init(&seat->base, &input->base,
|
||
|
+ device_seat, seat_name,
|
||
|
+ netlink_seat_destroy);
|
||
|
+
|
||
|
+ return seat;
|
||
|
+}
|
||
|
+
|
||
|
+static struct netlink_seat *
|
||
|
+netlink_seat_get_named(struct netlink_input *input, const char *seat_name)
|
||
|
+{
|
||
|
+ struct netlink_seat *seat;
|
||
|
+
|
||
|
+ list_for_each(seat, &input->base.seat_list, base.link) {
|
||
|
+ if (streq(seat->base.logical_name, seat_name))
|
||
|
+ return seat;
|
||
|
+ }
|
||
|
+
|
||
|
+ return NULL;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+netlink_device_change_seat(struct libinput_device *device,
|
||
|
+ const char *seat_name)
|
||
|
+{
|
||
|
+ struct libinput *libinput = device->seat->libinput;
|
||
|
+ struct netlink_input *input = (struct netlink_input *)libinput;
|
||
|
+ struct evdev_device *evdev = evdev_device(device);
|
||
|
+ char *devnode;
|
||
|
+ int rc;
|
||
|
+
|
||
|
+ devnode = safe_strdup(evdev->devnode);
|
||
|
+ device_removed(input, devnode);
|
||
|
+ rc = device_added(input, devnode);
|
||
|
+ free(devnode);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+static const struct libinput_interface_backend interface_backend = {
|
||
|
+ .resume = netlink_input_enable,
|
||
|
+ .suspend = netlink_input_disable,
|
||
|
+ .destroy = netlink_input_destroy,
|
||
|
+ .device_change_seat = netlink_device_change_seat,
|
||
|
+};
|
||
|
+
|
||
|
+LIBINPUT_EXPORT struct libinput *
|
||
|
+libinput_netlink_create_context(const struct libinput_interface *interface,
|
||
|
+ void *user_data)
|
||
|
+{
|
||
|
+ struct netlink_input *input;
|
||
|
+
|
||
|
+ if (!interface)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ input = zalloc(sizeof(*input));
|
||
|
+ input->sock = -1;
|
||
|
+
|
||
|
+ if (libinput_init(&input->base, interface,
|
||
|
+ &interface_backend, user_data) != 0) {
|
||
|
+ libinput_unref(&input->base);
|
||
|
+ free(input);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return &input->base;
|
||
|
+}
|
||
|
+
|
||
|
+LIBINPUT_EXPORT int
|
||
|
+libinput_netlink_assign_seat(struct libinput *libinput,
|
||
|
+ const char *seat_id)
|
||
|
+{
|
||
|
+ struct netlink_input *input = (struct netlink_input*)libinput;
|
||
|
+
|
||
|
+ if (libinput->interface_backend != &interface_backend) {
|
||
|
+ log_bug_client(libinput, "Mismatching backends.\n");
|
||
|
+ return -1;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* We cannot do this during netlink_create_context because the log
|
||
|
+ * handler isn't set up there but we really want to log to the right
|
||
|
+ * place if the quirks run into parser errors. So we have to do it
|
||
|
+ * here since we can expect the log handler to be set up by now.
|
||
|
+ */
|
||
|
+ libinput_init_quirks(libinput);
|
||
|
+
|
||
|
+ if (netlink_input_enable(&input->base) < 0)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
diff --git a/src/netlink-seat.h b/src/netlink-seat.h
|
||
|
new file mode 100644
|
||
|
index 00000000..cd8d3ef2
|
||
|
--- /dev/null
|
||
|
+++ b/src/netlink-seat.h
|
||
|
@@ -0,0 +1,42 @@
|
||
|
+/*
|
||
|
+ * Copyright © 2013 Intel Corporation
|
||
|
+ * Copyright © 2017 Michael Forney
|
||
|
+ *
|
||
|
+ * 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.
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef _NETLINK_SEAT_H_
|
||
|
+#define _NETLINK_SEAT_H_
|
||
|
+
|
||
|
+#include "config.h"
|
||
|
+
|
||
|
+#include "libinput-private.h"
|
||
|
+
|
||
|
+struct netlink_seat {
|
||
|
+ struct libinput_seat base;
|
||
|
+};
|
||
|
+
|
||
|
+struct netlink_input {
|
||
|
+ struct libinput base;
|
||
|
+ struct libinput_source *source;
|
||
|
+ int sock;
|
||
|
+};
|
||
|
+
|
||
|
+#endif
|
||
|
|