Compare commits
No commits in common. "main" and "1.2.903" have entirely different histories.
|
|
@ -1,82 +0,0 @@
|
|||
AlignAfterOpenBracket: Align
|
||||
# This option we want but it's frequently broken and causes bad
|
||||
# misalignment. The canary is wheel_click_count_parser, if that works
|
||||
# we can actually enable it.
|
||||
# AlignArrayOfStructures: Left
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: true
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: true
|
||||
AlignCaseColons: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: OnePerLine
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
BreakAfterReturnType: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 88
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: false
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^(<|")config\.h(>|")'
|
||||
Priority: 0
|
||||
SortPriority: 0
|
||||
- Regex: '^<.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
- Regex: '^"util-.*'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
IndentCaseLabels: false
|
||||
IndentGotoLabels: false
|
||||
IndentWidth: 8
|
||||
MaxEmptyLinesToKeep: 1
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
RemoveEmptyLinesInUnwrappedLines: true
|
||||
RemoveParentheses: MultipleParentheses
|
||||
RemoveSemicolon: true
|
||||
SkipMacroDefinitionBody: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInParens: Custom
|
||||
TabWidth: 8
|
||||
UseTab: ForContinuationAndIndentation
|
||||
|
||||
ForEachMacros:
|
||||
- ARRAY_FOR_EACH
|
||||
- list_for_each
|
||||
- list_for_each_safe
|
||||
- tp_for_each_touch
|
||||
- range_for_each
|
||||
- litest_log_group
|
||||
- litest_with_logcapture
|
||||
- litest_with_parameters
|
||||
- litest_with_event_frame
|
||||
- udev_list_entry_foreach
|
||||
# END_TEST is defined as something that enforces a line break
|
||||
Macros: [ "CASE_RETURN_STRING(s)=case s: return s", "START_TEST(s)=static void s(void)", "END_TEST=enum foo;"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
include/**/*
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# optin.core.unix.Malloc: disabled so we can use __attribute__((cleanup)) without leak complaints
|
||||
# optin.core.EnumCastOutOfRange: disabled because we use a lot of "wrong" enum values for testing
|
||||
# and internally and don't want those values leak into the public API
|
||||
Checks: >
|
||||
-clang-analyzer-unix.Malloc,
|
||||
-clang-analyzer-optin.core.EnumCastOutOfRange
|
||||
WarningsAsErrors: '*'
|
||||
|
|
@ -1 +0,0 @@
|
|||
include/*
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
((nil . ((indent-tabs-mode . t)
|
||||
(tab-width . 8)
|
||||
(fill-column . 80)))
|
||||
(c-mode . ((c-basic-offset . 8))))
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{c,h}]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
[{meson.build,meson_options.txt}]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[*.sym]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# This file contains revisions to be ignored by git blame.
|
||||
# These revisions are expected to be formatting-only changes.
|
||||
#
|
||||
# Calling `git blame --ignore-revs-file .git-blame-ignore-revs` will
|
||||
# tell git blame to ignore changes made by these revisions when assigning
|
||||
# assigning blame, as if the change never happened.
|
||||
#
|
||||
# You can enable this as a default for your local repository by running
|
||||
# `git config blame.ignoreRevsFile .git-blame-ignore-revs`
|
||||
# Important: if you do this, then switch to a branch without this file,
|
||||
# `git blame` will fail with an error.
|
||||
#
|
||||
|
||||
# Run clang-format over the code
|
||||
2a1095924b0be60f822bc0ff20d567e209a9db73
|
||||
|
||||
# Add trailing commas to prevent clang-format oddities
|
||||
aebf3cd4915adc576cf055926caa621e098ec32b
|
||||
|
||||
# Fix some inconsistent whitespace.
|
||||
60abf1575560cb8e2220ae48a67e7f74b5dc70dd
|
||||
33
.gitignore
vendored
|
|
@ -1,3 +1,7 @@
|
|||
*.o
|
||||
*.pc
|
||||
*.la
|
||||
*.lo
|
||||
*.swp
|
||||
*~
|
||||
*.sig
|
||||
|
|
@ -6,7 +10,30 @@
|
|||
*.patch
|
||||
*.rej
|
||||
*.trs
|
||||
*.gcda
|
||||
*.gcno
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h1
|
||||
.libs/
|
||||
.deps/
|
||||
src/libinput-version.h
|
||||
doc/libinput.doxygen
|
||||
doc/html
|
||||
tags
|
||||
*.gnuplot
|
||||
test/test-*
|
||||
test/symbols-leak-test*
|
||||
test-driver
|
||||
|
|
|
|||
1362
.gitlab-ci.yml
|
|
@ -1,803 +0,0 @@
|
|||
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
|
||||
|
||||
{# You're looking at the template here, so you can ignore the below
|
||||
warning. This is the right file to edit #}
|
||||
########################################
|
||||
# #
|
||||
# THIS FILE IS GENERATED, DO NOT EDIT #
|
||||
# #
|
||||
########################################
|
||||
|
||||
# To change the gitlab CI, edit .gitlab-ci/ci.template and/or .gitlab-ci/config.yaml
|
||||
# and run ci-fairy generate-template. For details, see
|
||||
# https://freedesktop.pages.freedesktop.org/ci-templates/ci-fairy.html#templating-gitlab-ci-yml
|
||||
|
||||
# This is a bit complicated for two reasons:
|
||||
# - we really want to run dnf/apt/... only once, updating on the test runner for
|
||||
# each job takes forever. So we create a container image for each distribution
|
||||
# tested, then run the tests on this container image.
|
||||
#
|
||||
# This is handled by the ci-templates, ensuring containers are only rebuilt
|
||||
# when the TAG changes.
|
||||
#
|
||||
# - GitLab only allows one script: set per job but we have a bunch of commands
|
||||
# we need to re-run for each build (meson && ninja && etc). YAML cannot merge
|
||||
# arrays so we're screwed.
|
||||
#
|
||||
# So instead we use a default_build template and override everything with
|
||||
# variables. The only two variables that matter:
|
||||
# MESON_ARGS=-Denable-something=true
|
||||
# NINJA_ARGS=dist ... to run 'ninja -C builddir dist'
|
||||
# Note that you cannot use scripts: in any target if you expect default_build
|
||||
# to work.
|
||||
#
|
||||
#
|
||||
# All jobs must follow the naming scheme of
|
||||
# <distribution>:<version>@activity:
|
||||
# e.g. fedora:31@build-default
|
||||
|
||||
.templates_sha: &template_sha c6aeb16f86e32525fa630fb99c66c4f3e62fc3cb
|
||||
|
||||
include:
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: *template_sha
|
||||
file:
|
||||
- '/templates/ci-fairy.yml'
|
||||
{% for distro in distributions|sort(attribute="name") %}
|
||||
# {{ distro.name.capitalize() }} container builder template
|
||||
- '/templates/{{distro.name}}.yml'
|
||||
{% endfor %}
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
# do not duplicate pipelines on merge pipelines
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
# merge pipeline
|
||||
- if: &is-merge-attempt $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
variables:
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: priority:high
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: priority:high-kvm
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: priority:high-aarch64
|
||||
# post-merge pipeline
|
||||
- if: &is-post-merge $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "push"
|
||||
variables:
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: priority:high
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: priority:high-kvm
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: priority:high-aarch64
|
||||
# Pre-merge pipeline
|
||||
- if: &is-pre-merge $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# Push to a branch on a fork
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
stages:
|
||||
- sanity check # CI/commit checks
|
||||
- prep # prep work like rebuilding the container images if there is a change
|
||||
- build # for actually building and testing things in a container
|
||||
- test-suite # for running the test suite in a VM
|
||||
- test-suite-no-libwacom # for running the test suite in a VM (libwacom disabled)
|
||||
- valgrind # for running the test suite under valgrind in a VM
|
||||
- distro # distribs test
|
||||
- deploy # trigger wayland's website generation
|
||||
- container_clean # clean up unused container images (scheduled jobs only)
|
||||
|
||||
variables:
|
||||
###############################################################################
|
||||
# This is the list of packages required to build libinput with the default #
|
||||
# configuration. #
|
||||
# #
|
||||
# Run dnf install/apt-get install/.. with the list of packages for your #
|
||||
# distribution #
|
||||
# #
|
||||
# See the documentation here: #
|
||||
# https://wayland.freedesktop.org/libinput/doc/latest/building.html #
|
||||
###############################################################################
|
||||
{% for distro in distributions %}
|
||||
{{"%-17s" | format(distro.name.upper() + '_PACKAGES:')}} '{{ distro.packages|join(' ')}}'
|
||||
{% endfor %}
|
||||
############################ end of package lists #############################
|
||||
|
||||
# these tags should be updated each time the list of packages is updated
|
||||
# changing these will force rebuilding the associated image
|
||||
# Note: these tags have no meaning and are not tied to a particular
|
||||
# libinput version
|
||||
{% for distro in distributions %}
|
||||
{{"%-13s"| format(distro.name.upper() + '_TAG:')}}'{{distro.tag}}'
|
||||
{% endfor %}
|
||||
|
||||
FDO_UPSTREAM_REPO: libinput/libinput
|
||||
|
||||
MESON_BUILDDIR: "build dir"
|
||||
NINJA_ARGS: ''
|
||||
MESON_ARGS: ''
|
||||
MESON_TEST_ARGS: '--no-suite=hardware'
|
||||
|
||||
# udev isn't available/working properly in the containers
|
||||
UDEV_NOT_AVAILABLE: 1
|
||||
GIT_DEPTH: 1
|
||||
|
||||
# Default priority for non-merge pipelines
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: "" # Empty tags are ignored by gitlab
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: kvm
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: aarch64
|
||||
|
||||
.policy:
|
||||
retry:
|
||||
max: 2
|
||||
when:
|
||||
- runner_system_failure
|
||||
- stuck_or_timeout_failure
|
||||
# cancel run when a newer version is pushed to the branch
|
||||
interruptible: true
|
||||
dependencies: []
|
||||
|
||||
.policy-retry-on-failure:
|
||||
retry:
|
||||
max: 1
|
||||
when:
|
||||
- runner_system_failure
|
||||
- stuck_or_timeout_failure
|
||||
# cancel run when a newer version is pushed to the branch
|
||||
interruptible: true
|
||||
dependencies: []
|
||||
|
||||
.default_artifacts:
|
||||
artifacts:
|
||||
name: "meson-logs-$CI_JOB_NAME"
|
||||
when: always
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- $MESON_BUILDDIR/meson-logs
|
||||
- $MESON_BUILDDIR/valgrind.*.log
|
||||
reports:
|
||||
junit: $MESON_BUILDDIR/*junit*.xml
|
||||
|
||||
.fdo-runner-tags:
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64
|
||||
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# sanity check stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
fail-if-fork-is-not-public:
|
||||
extends:
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- |
|
||||
if [ $CI_PROJECT_VISIBILITY != "public" ]; then
|
||||
echo "*************************************************************************************"
|
||||
echo "Project visibility must be set to 'public'"
|
||||
echo "Change this in $CI_PROJECT_URL/edit under 'Visibility, project features, permissions'"
|
||||
echo "*************************************************************************************"
|
||||
exit 1
|
||||
fi
|
||||
except:
|
||||
- main@libinput/libinput
|
||||
|
||||
# Re-generate the CI script and make sure it's the one currently checked in
|
||||
# If this job fails, re-generate the gitlab-ci.yml script, see
|
||||
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
|
||||
#
|
||||
check-ci-script:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- ci-fairy generate-template --verify && exit 0 || true
|
||||
- >
|
||||
printf "%s\n" \
|
||||
"Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify" \
|
||||
"https://wayland.freedesktop.org/libinput/doc/latest/contributing.html"
|
||||
- exit 1
|
||||
|
||||
#
|
||||
# Verify that commit messages are as expected, etc.
|
||||
#
|
||||
|
||||
check-commit:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- ci-fairy -vv check-commits --junit-xml=results.xml && exit 0 || true
|
||||
- >
|
||||
printf "%s\n" \
|
||||
"Error checking commit format. Please verify" \
|
||||
"https://wayland.freedesktop.org/libinput/doc/latest/contributing.html"
|
||||
- exit 1
|
||||
except:
|
||||
- main@libinput/libinput
|
||||
variables:
|
||||
GIT_DEPTH: 100
|
||||
artifacts:
|
||||
reports:
|
||||
junit: results.xml
|
||||
|
||||
|
||||
#
|
||||
# Check for trailing whitespaces
|
||||
#
|
||||
|
||||
check-whitespace:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- .gitlab-ci/whitespace-check.py $(git ls-files)
|
||||
|
||||
#
|
||||
# pre-commit hooks
|
||||
#
|
||||
|
||||
pre-commit-hooks:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip3 install pre-commit
|
||||
- pre-commit run --all-files
|
||||
- git diff --exit-code || (echo "ERROR - Code style errors found, please fix" && false)
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# prep stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
{% for distro in distributions %}
|
||||
{% for version in distro.versions %}
|
||||
{{distro.name}}:{{version}}@container-prep:
|
||||
extends:
|
||||
{% if distro.qemu_based %}
|
||||
- .fdo.qemu-build@{{distro.name}}
|
||||
{% else %}
|
||||
- .fdo.container-build@{{distro.name}}
|
||||
{% endif %}
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
{% if distro.qemu_based %}
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
||||
{% endif %}
|
||||
stage: prep
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_PACKAGES: ${{distro.name.upper()}}_PACKAGES
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# container clean stage #
|
||||
# run during the clean stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
#
|
||||
# This stage will look for the container images we currently have in
|
||||
# the registry and will remove any that are not tagged with the provided
|
||||
# $container_image:$tag
|
||||
#
|
||||
.container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: container_clean
|
||||
script:
|
||||
# Go to your Profile, Settings, Access Tokens
|
||||
# Create a personal token with 'api' scope, copy the value.
|
||||
# Go to CI/CD, Schedules, schedule a new monthly job (or edit the existing one)
|
||||
# Define a variable of type File named AUTHFILE. Content is that token
|
||||
# value.
|
||||
- ci-fairy -v --authfile $AUTHFILE delete-image
|
||||
--repository $FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION
|
||||
--exclude-tag $FDO_DISTRIBUTION_TAG
|
||||
allow_failure: true
|
||||
only:
|
||||
- schedules
|
||||
|
||||
{% for distro in distributions %}
|
||||
{% for version in distro.versions %}
|
||||
{{distro.name}}:{{version}}@container-clean:
|
||||
extends:
|
||||
- .policy
|
||||
- .container-clean
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/{{distro.name}}/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# build stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
.build@template:
|
||||
extends:
|
||||
- .policy
|
||||
- .default_artifacts
|
||||
- .fdo-runner-tags
|
||||
stage: build
|
||||
script:
|
||||
- .gitlab-ci/meson-build.sh
|
||||
|
||||
|
||||
# Run meson and meson test in the container image through qemu
|
||||
.build-in-vng@template:
|
||||
extends:
|
||||
- .policy
|
||||
- .default_artifacts
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
||||
variables:
|
||||
MESON_BUILDDIR: build_dir
|
||||
VNG_KERNEL: {{ vng.kernel }}
|
||||
script:
|
||||
# first build in the host container
|
||||
- .gitlab-ci/meson-build.sh --skip-test
|
||||
|
||||
- mkdir -p $MESON_BUILDDIR
|
||||
- curl -LO $VNG_KERNEL
|
||||
|
||||
- export -p > .vngenv
|
||||
|
||||
# runs the test suite only
|
||||
- |
|
||||
vng --run ./bzImage \
|
||||
--user root \
|
||||
--overlay-rwdir=$HOME \
|
||||
--append HOME=$HOME \
|
||||
--overlay-rwdir=$(pwd) \
|
||||
--rwdir=$MESON_BUILDDIR \
|
||||
--exec "source $PWD/.vngenv; rm $PWD/.vngenv; .gitlab-ci/meson-build.sh --skip-setup --skip-build --run-test"
|
||||
|
||||
#
|
||||
# Fedora
|
||||
#
|
||||
|
||||
.check_tainted: &check_tainted |
|
||||
# make sure the kernel is not tainted
|
||||
if [[ "$(ssh localhost -p 5555 cat /proc/sys/kernel/tainted)" -gt 0 ]];
|
||||
then
|
||||
echo tainted kernel ;
|
||||
exit 1 ;
|
||||
fi
|
||||
|
||||
# Run meson and meson test in the qemu image
|
||||
.build-in-qemu@template:
|
||||
extends:
|
||||
- .policy
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
||||
variables:
|
||||
MESON_BUILDDIR: build_dir
|
||||
script:
|
||||
# start our vm, no args required
|
||||
- /app/vmctl start || (echo "Error - Failed to start the VM." && exit 1)
|
||||
|
||||
- *check_tainted
|
||||
|
||||
- "scp -r $PWD vm:"
|
||||
- echo "CI_JOB_ID=\"$CI_JOB_ID\"" > sshenv
|
||||
- echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
|
||||
- echo "MESON_ARGS=\"$MESON_ARGS\"" >> sshenv
|
||||
- echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
|
||||
- echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS\"" >> sshenv
|
||||
- echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
|
||||
- "scp sshenv vm:~/$CI_PROJECT_NAME/.meson_environment"
|
||||
- /app/vmctl exec "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 -r vm:$CI_PROJECT_NAME/$MESON_BUILDDIR .
|
||||
|
||||
- *check_tainted
|
||||
|
||||
- /app/vmctl stop
|
||||
|
||||
- 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
|
||||
|
||||
|
||||
# Run in a test suite. Special variables:
|
||||
# - SUITES: the meson test suites to run, or
|
||||
# - SUITE_NAMES: all elements will be expanded to libinput-test-suite-$value
|
||||
# Set one or the other, not both.
|
||||
.test-suite-vm:
|
||||
extends:
|
||||
- .build-in-vng@template
|
||||
stage: test-suite
|
||||
variables:
|
||||
# remove the global --no-suite=hardware
|
||||
MESON_TEST_ARGS: ''
|
||||
LITEST_JOBS: 4
|
||||
before_script:
|
||||
- if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi
|
||||
- echo "Testing $SUITES"
|
||||
- export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES"
|
||||
|
||||
|
||||
{# qemu tests are only done for the latest version of any distribution #}
|
||||
{% for distro in distributions if distro.use_for_qemu_tests %}
|
||||
{% set version = "{}".format(distro.versions|last()) %}
|
||||
.{{distro.name}}:{{version}}@test-suite-vm:
|
||||
extends:
|
||||
- .fdo.distribution-image@{{distro.name}}
|
||||
- .test-suite-vm
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: {{version}}
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
needs:
|
||||
- "{{distro.name}}:{{version}}@container-prep"
|
||||
|
||||
|
||||
{% for suite in test_suites %}
|
||||
vm-{{suite.name}}:
|
||||
extends:
|
||||
- .{{distro.name}}:{{version}}@test-suite-vm
|
||||
variables:
|
||||
SUITE_NAMES: '{{suite.suites|join(' ')}}'
|
||||
|
||||
vm-{{suite.name}}-no-libwacom:
|
||||
extends:
|
||||
- vm-{{suite.name}}
|
||||
stage: test-suite-no-libwacom
|
||||
variables:
|
||||
MESON_ARGS: '-Dlibwacom=false'
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% for suite in test_suites %}
|
||||
vm-valgrind-{{suite.name}}:
|
||||
stage: valgrind
|
||||
extends:
|
||||
- vm-{{suite.name}}
|
||||
- .policy-retry-on-failure
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--setup=valgrind'
|
||||
LITEST_JOBS: 0
|
||||
retry:
|
||||
max: 2
|
||||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}{# for if distro.use_for_qemu_tests #}
|
||||
|
||||
{% for distro in distributions if distro.use_for_custom_build_tests %}
|
||||
{% set version = "{}".format(distro.versions|last()) %}
|
||||
.{{distro.name}}-build@template:
|
||||
extends:
|
||||
- .fdo.distribution-image@{{distro.name}}
|
||||
- .build@template
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
needs:
|
||||
- "{{distro.name}}:{{version}}@container-prep"
|
||||
|
||||
default-build-release@{{distro.name}}:{{version}}:
|
||||
stage: distro
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dbuildtype=release"
|
||||
CFLAGS: "-Werror"
|
||||
|
||||
clang-tidy@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
NINJA_ARGS: ''
|
||||
MESON_TEST_ARGS: ''
|
||||
CC: 'clang'
|
||||
script:
|
||||
- .gitlab-ci/meson-build.sh
|
||||
- ninja -C "$MESON_BUILDDIR" clang-tidy
|
||||
|
||||
# Below jobs are build option combinations. We only
|
||||
# run them on one image, they shouldn't fail on one distro
|
||||
# when they succeed on another.
|
||||
|
||||
build-no-libwacom@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlibwacom=false"
|
||||
|
||||
build-no-libwacom-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlibwacom=false"
|
||||
before_script:
|
||||
- dnf remove -y libwacom libwacom-devel
|
||||
|
||||
build-no-mtdev@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dmtdev=false"
|
||||
|
||||
build-no-mtdev-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dmtdev=false"
|
||||
before_script:
|
||||
- dnf remove -y mtdev mtdev-devel
|
||||
|
||||
build-no-lua@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
|
||||
build-no-lua-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
before_script:
|
||||
- dnf remove -y lua lua-devel
|
||||
|
||||
build-docs@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Ddocumentation=true"
|
||||
|
||||
build-no-docs-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Ddocumentation=false"
|
||||
before_script:
|
||||
- dnf remove -y doxygen graphviz
|
||||
|
||||
build-no-debuggui@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Ddebug-gui=false"
|
||||
|
||||
build-no-debuggui-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Ddebug-gui=false"
|
||||
before_script:
|
||||
- dnf remove -y gtk3-devel gtk4-devel
|
||||
|
||||
build-no-tests@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dtests=false"
|
||||
|
||||
build-no-tests-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dtests=false"
|
||||
before_script:
|
||||
- dnf remove -y check-devel
|
||||
|
||||
valgrind@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--suite=valgrind --no-suite=hardware --setup=valgrind'
|
||||
|
||||
# Python checks, only run on Fedora
|
||||
|
||||
usr-bin-env-python@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
script:
|
||||
- |
|
||||
if git grep -l '^#!/usr/bin/python'; then
|
||||
echo "Use '/usr/bin/env python3' in the above files";
|
||||
/bin/false
|
||||
fi
|
||||
|
||||
# A job to check we're actually running all test suites in the CI
|
||||
check-test-suites:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
script:
|
||||
- meson setup builddir
|
||||
- meson introspect builddir --test | jq -r '.[].name' | grep 'libinput-test-suite' | sort > meson-testsuites
|
||||
- |
|
||||
cat <<EOF > ci-testsuites ;
|
||||
{% for suite in test_suites %}
|
||||
{% for name in suite.suites %}
|
||||
libinput-test-suite-{{name}}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
EOF
|
||||
- sort -o ci-testsuites ci-testsuites
|
||||
- diff -u8 -w ci-testsuites meson-testsuites || (echo "Some test suites are not run in the CI" && false)
|
||||
only:
|
||||
changes:
|
||||
- "meson.build"
|
||||
- ".gitlab-ci.yml"
|
||||
{% endfor %}
|
||||
|
||||
#
|
||||
# coverity run
|
||||
#
|
||||
# This requires the COVERITY_SCAN_TOKEN. Log into scan.coverity.com and get
|
||||
# the token from the respective project settings page.
|
||||
# Schedule a pipeline and set a variable COVERITY_SCAN_TOKEN with the token value.
|
||||
# https://gitlab.freedesktop.org/$CI_PROJECT_PATH/-/pipeline_schedules
|
||||
# Email from coverity will be sent to the GITLAB_USER_EMAIL that scheduled the
|
||||
# job.
|
||||
#
|
||||
# Coverity ratelimits submissions and the coverity tools download is about
|
||||
# 700M, do not run this too often.
|
||||
#
|
||||
coverity:
|
||||
extends:
|
||||
- .fdo.distribution-image@debian
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: build
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 'stable'
|
||||
FDO_DISTRIBUTION_TAG: $DEBIAN_TAG
|
||||
# so git-describe works, or should work
|
||||
GIT_DEPTH: 200
|
||||
only:
|
||||
variables:
|
||||
- $COVERITY_SCAN_TOKEN
|
||||
script:
|
||||
- curl https://scan.coverity.com/download/linux64
|
||||
-o /tmp/cov-analysis-linux64.tgz
|
||||
--form project=$CI_PROJECT_NAME
|
||||
--form token=$COVERITY_SCAN_TOKEN
|
||||
- tar xfz /tmp/cov-analysis-linux64.tgz
|
||||
# coverity has special build options in meson, make sure we enable those
|
||||
- meson coverity-build -Ddocumentation=false -Dcoverity=true
|
||||
- cov-analysis-linux64-*/bin/cov-build --dir cov-int ninja -C coverity-build
|
||||
- tar cfz cov-int.tar.gz cov-int
|
||||
- curl https://scan.coverity.com/builds?project=$CI_PROJECT_NAME
|
||||
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
|
||||
--form file=@cov-int.tar.gz --form version="$(git describe --tags)"
|
||||
--form description="$(git describe --tags) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
|
||||
artifacts:
|
||||
name: "coverity-submit-data"
|
||||
when: always
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- cov-int.tar.gz
|
||||
needs:
|
||||
- "debian:stable@container-prep"
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# distro stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
{% for distro in distributions %}
|
||||
{% if not distro.qemu_based %}
|
||||
{% for version in distro.versions %}
|
||||
{{distro.name}}:{{version}}@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
- .build@template
|
||||
- .fdo.distribution-image@{{distro.name}}
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
{# Where we have extra_variables defined, add them to the list #}
|
||||
{% if distro.build is defined and distro.build.extra_variables is defined %}
|
||||
{% for var in distro.build.extra_variables %}
|
||||
{{var}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
needs:
|
||||
- "{{distro.name}}:{{version}}@container-prep"
|
||||
|
||||
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set version = "{}".format(distro.versions|last()) %}
|
||||
{{distro.name}}:{{version}}@default-build:
|
||||
stage: distro
|
||||
extends:
|
||||
- .build-in-qemu@template
|
||||
- .fdo.distribution-image@{{distro.name}}
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
{# Where we have extra_variables defined, add them to the list #}
|
||||
{% if distro.build is defined and distro.build.extra_variables is defined %}
|
||||
{% for var in distro.build.extra_variables %}
|
||||
{{var}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
needs:
|
||||
- "{{distro.name}}:{{version}}@container-prep"
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# deploy stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
{% for distro in distributions if distro.name == "fedora" %}
|
||||
{% set version = "{}".format(distro.versions|last()) %}
|
||||
build rpm:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: deploy
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:{{version}}@container-prep"
|
||||
script:
|
||||
- meson "$MESON_BUILDDIR"
|
||||
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
|
||||
- sed -e "s/@PIPELINEID@/${CI_PIPELINE_ID}/"
|
||||
-e "s/@GITVERSION@/${CI_COMMIT_SHA}/"
|
||||
-e "s/@VERSION@/${VERSION}/" .gitlab-ci/libinput.spec.in > libinput.spec
|
||||
- git config --local user.name 'gitlab CI'
|
||||
- git config --local user.email 'noreply@nowhere'
|
||||
- git add libinput.spec && git commit -m 'Add libinput.spec for build testing' libinput.spec
|
||||
- cd "$MESON_BUILDDIR"
|
||||
- meson dist --no-test
|
||||
- rpmbuild -ta meson-dist/libinput*.tar.xz
|
||||
{% endfor %}
|
||||
|
||||
|
||||
wayland-web:
|
||||
stage: deploy
|
||||
trigger: wayland/wayland.freedesktop.org
|
||||
variables:
|
||||
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
||||
MESON_BUILDDIR: 'builddir'
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
|
||||
when: on_success
|
||||
- when: never
|
||||
|
|
@ -1,217 +0,0 @@
|
|||
# This file contains the configuration for the gitlab ci.
|
||||
# See the .gitlab-ci/generate-gitlab-ci.py file for more info
|
||||
#
|
||||
|
||||
# We're happy to rebuild all containers when one changes.
|
||||
.default_tag: &default_tag '2026-01-09.0'
|
||||
|
||||
distributions:
|
||||
- name: fedora
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- '42'
|
||||
- '43'
|
||||
use_for_custom_build_tests: true
|
||||
use_for_qemu_tests: true
|
||||
packages:
|
||||
- git-core
|
||||
- gcc
|
||||
- gcc-c++
|
||||
- pkgconf-pkg-config
|
||||
- meson
|
||||
- check-devel
|
||||
- libudev-devel
|
||||
- libevdev-devel
|
||||
- doxygen
|
||||
- graphviz
|
||||
- python3-sphinx
|
||||
- python3-recommonmark
|
||||
- python3-sphinx_rtd_theme
|
||||
- python3-pytest-xdist
|
||||
- libwacom-devel
|
||||
- cairo-devel
|
||||
- gtk4-devel
|
||||
- glib2-devel
|
||||
- mtdev-devel
|
||||
- diffutils
|
||||
- wayland-protocols-devel
|
||||
- black # for the Python black job, optional
|
||||
- clang # for the clang-tidy build, optional
|
||||
- clang-tools-extra # for clang-tidy, optional
|
||||
- jq # for the test suite check job, optional
|
||||
- rpmdevtools # for the rpm build job, optional
|
||||
- valgrind # for the valgrind run, optional
|
||||
# below packages are for the qemu runs, so optional
|
||||
- systemd-udev # for the qemu run
|
||||
- qemu-img
|
||||
- qemu-system-x86-core
|
||||
- qemu-system-aarch64-core
|
||||
- jq
|
||||
- python3-click
|
||||
- python3-rich
|
||||
- virtme-ng
|
||||
- lua-devel
|
||||
- name: debian
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- 'stable'
|
||||
packages:
|
||||
- git
|
||||
- gcc
|
||||
- g++
|
||||
- pkg-config
|
||||
- meson
|
||||
- check
|
||||
- libudev-dev
|
||||
- libevdev-dev
|
||||
- doxygen
|
||||
- graphviz
|
||||
- python3-sphinx
|
||||
- python3-recommonmark
|
||||
- python3-sphinx-rtd-theme
|
||||
- python3-pytest-xdist
|
||||
- libwacom-dev
|
||||
- libcairo2-dev
|
||||
- libgtk-3-dev
|
||||
- libglib2.0-dev
|
||||
- libmtdev-dev
|
||||
- curl # for the coverity job
|
||||
- lua5.4-dev
|
||||
- name: ubuntu
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- '25.10'
|
||||
packages:
|
||||
- git
|
||||
- gcc
|
||||
- g++
|
||||
- pkg-config
|
||||
- meson
|
||||
- check
|
||||
- libudev-dev
|
||||
- libevdev-dev
|
||||
- doxygen
|
||||
- graphviz
|
||||
- python3-sphinx
|
||||
- python3-recommonmark
|
||||
- python3-sphinx-rtd-theme
|
||||
- python3-pytest-xdist
|
||||
- libwacom-dev
|
||||
- libcairo2-dev
|
||||
- libgtk-3-dev
|
||||
- libglib2.0-dev
|
||||
- libmtdev-dev
|
||||
- lua5.4-dev
|
||||
- name: arch
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- 'rolling'
|
||||
packages:
|
||||
- git
|
||||
- gcc
|
||||
- pkgconfig
|
||||
- meson
|
||||
- check
|
||||
- libsystemd
|
||||
- libevdev
|
||||
- python-pytest-xdist
|
||||
- libwacom
|
||||
- gtk4
|
||||
- mtdev
|
||||
- diffutils
|
||||
- lua
|
||||
build:
|
||||
extra_variables:
|
||||
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
|
||||
- name: alpine
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- 'latest'
|
||||
packages:
|
||||
- git
|
||||
- gcc build-base
|
||||
- pkgconfig
|
||||
- meson
|
||||
- check-dev
|
||||
- eudev-dev
|
||||
- libevdev-dev
|
||||
- libwacom-dev
|
||||
- cairo-dev
|
||||
- gtk4.0-dev
|
||||
- mtdev-dev
|
||||
- bash
|
||||
- lua5.4-dev
|
||||
build:
|
||||
extra_variables:
|
||||
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"
|
||||
# We don't run the tests on alpine. The litest-selftest fails
|
||||
# for any tcase_add_exit_test/tcase_add_test_raise_signal
|
||||
# but someone more invested in musl will have to figure that out.
|
||||
- "MESON_TEST_ARGS: '' # litest-selftest fails on musl"
|
||||
|
||||
test_suites:
|
||||
- name: touchpad
|
||||
suites:
|
||||
- touchpad
|
||||
- name: touchpad_palm
|
||||
suites:
|
||||
- touchpad_palm
|
||||
- name: touchpad_dwt
|
||||
suites:
|
||||
- touchpad_dwt
|
||||
- name: tap
|
||||
suites:
|
||||
- touchpad_tap
|
||||
- name: tap-drag
|
||||
suites:
|
||||
- touchpad_tap_drag
|
||||
- name: tap-palm
|
||||
suites:
|
||||
- touchpad_tap_palm
|
||||
- name: touchpad-buttons
|
||||
suites:
|
||||
- touchpad_buttons
|
||||
- name: tablet
|
||||
suites:
|
||||
- tablet
|
||||
- name: tablet_left_handed
|
||||
suites:
|
||||
- tablet_left_handed
|
||||
- name: tablet_proximity_tip
|
||||
suites:
|
||||
- tablet_proximity
|
||||
- tablet_tip
|
||||
- name: tablet_eraser
|
||||
suites:
|
||||
- tablet_eraser
|
||||
- name: gestures
|
||||
suites:
|
||||
- gestures
|
||||
- name: backends
|
||||
suites:
|
||||
- path
|
||||
- udev
|
||||
- name: misc
|
||||
suites:
|
||||
- log
|
||||
- misc
|
||||
- quirks
|
||||
- device
|
||||
- name: other devices
|
||||
suites:
|
||||
- keyboard
|
||||
- pad
|
||||
- switch
|
||||
- trackball
|
||||
- trackpoint
|
||||
- totem
|
||||
- touch
|
||||
- name: pointer
|
||||
suites:
|
||||
- pointer
|
||||
- name: lua
|
||||
suites:
|
||||
- lua
|
||||
|
||||
vng:
|
||||
kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.14/bzImage
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
# This specfile should not be used outside the CI
|
||||
# Its main purpose is to sound alarm if files disappear or are added that
|
||||
# weren't intended.
|
||||
|
||||
%global udevdir %(pkg-config --variable=udevdir udev)
|
||||
|
||||
%global pipelineid @PIPELINEID@
|
||||
%global gitversion @GITVERSION@
|
||||
|
||||
Name: libinput
|
||||
Version: @VERSION@
|
||||
Release: %{pipelineid}git%{gitversion}%{?dist}
|
||||
Summary: Input device library
|
||||
|
||||
License: MIT
|
||||
URL: http://www.freedesktop.org/wiki/Software/libinput/
|
||||
Source0: %{name}-%{version}.tar.xz
|
||||
|
||||
# No BuildRequires, we rely on the container setup to have
|
||||
# all the requires installed
|
||||
|
||||
%description
|
||||
libinput is a library that handles input devices for display servers and other
|
||||
applications that need to directly deal with input devices.
|
||||
|
||||
It provides device detection, device handling, input device event processing
|
||||
and abstraction so minimize the amount of custom input code the user of
|
||||
libinput need to provide the common set of functionality that users expect.
|
||||
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
The %{name}-devel package contains libraries and header files for
|
||||
developing applications that use %{name}.
|
||||
|
||||
%package utils
|
||||
Summary: Utilities and tools for debugging %{name}
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
Requires: python3-pyudev python3-libevdev
|
||||
|
||||
%description utils
|
||||
The %{name}-utils package contains tools to debug hardware and analyze
|
||||
%{name}.
|
||||
|
||||
%package test
|
||||
Summary: libinput integration test suite
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description test
|
||||
The %{name}-test package contains the libinput test suite. It is not
|
||||
intended to be run by users.
|
||||
|
||||
%prep
|
||||
%autosetup -S git -n %{name}-%{version}
|
||||
|
||||
%build
|
||||
%meson -Dtests=true \
|
||||
-Dinstall-tests=true \
|
||||
-Dudev-dir=%{udevdir}
|
||||
%meson_build
|
||||
|
||||
%install
|
||||
%meson_install
|
||||
|
||||
%post
|
||||
%{?ldconfig}
|
||||
|
||||
%ldconfig_postun
|
||||
|
||||
|
||||
%files
|
||||
%doc COPYING
|
||||
%dir %{_sysconfdir}/libinput
|
||||
%{_libdir}/libinput.so.*
|
||||
%{udevdir}/libinput-device-group
|
||||
%{udevdir}/libinput-fuzz-extract
|
||||
%{udevdir}/libinput-fuzz-to-zero
|
||||
%{udevdir}/rules.d/80-libinput-device-groups.rules
|
||||
%{udevdir}/rules.d/90-libinput-fuzz-override.rules
|
||||
%{_bindir}/libinput
|
||||
%dir %{_libexecdir}/libinput/
|
||||
%{_libexecdir}/libinput/libinput-debug-events
|
||||
%{_libexecdir}/libinput/libinput-list-devices
|
||||
%{_mandir}/man1/libinput.1*
|
||||
%{_datadir}/libinput/*.quirks
|
||||
%dir %{_datadir}/zsh
|
||||
%dir %{_datadir}/zsh/site-functions
|
||||
%{_datadir}/zsh/site-functions/*
|
||||
%{_mandir}/man1/libinput-list-devices.1*
|
||||
%{_mandir}/man1/libinput-debug-events.1*
|
||||
|
||||
%files devel
|
||||
%{_includedir}/libinput.h
|
||||
%{_libdir}/libinput.so
|
||||
%{_libdir}/pkgconfig/libinput.pc
|
||||
|
||||
%files utils
|
||||
%{_libexecdir}/libinput/libinput-debug-gui
|
||||
%{_libexecdir}/libinput/libinput-debug-tablet
|
||||
%{_libexecdir}/libinput/libinput-debug-tablet-pad
|
||||
%{_libexecdir}/libinput/libinput-list-kernel-devices
|
||||
%{_libexecdir}/libinput/libinput-measure
|
||||
%{_libexecdir}/libinput/libinput-measure-fuzz
|
||||
%{_libexecdir}/libinput/libinput-measure-touchpad-tap
|
||||
%{_libexecdir}/libinput/libinput-measure-touchpad-pressure
|
||||
%{_libexecdir}/libinput/libinput-measure-touch-size
|
||||
%{_libexecdir}/libinput/libinput-measure-touchpad-size
|
||||
%{_libexecdir}/libinput/libinput-quirks
|
||||
%{_libexecdir}/libinput/libinput-record
|
||||
%{_libexecdir}/libinput/libinput-replay
|
||||
%{_libexecdir}/libinput/libinput-analyze
|
||||
%{_libexecdir}/libinput/libinput-analyze-buttons
|
||||
%{_libexecdir}/libinput/libinput-analyze-per-slot-delta
|
||||
%{_libexecdir}/libinput/libinput-analyze-recording
|
||||
%{_libexecdir}/libinput/libinput-analyze-touch-down-state
|
||||
%{_mandir}/man1/libinput-debug-gui.1*
|
||||
%{_mandir}/man1/libinput-debug-tablet.1*
|
||||
%{_mandir}/man1/libinput-debug-tablet-pad.1*
|
||||
%{_mandir}/man1/libinput-list-kernel-devices.1*
|
||||
%{_mandir}/man1/libinput-measure.1*
|
||||
%{_mandir}/man1/libinput-measure-fuzz.1*
|
||||
%{_mandir}/man1/libinput-measure-touchpad-tap.1*
|
||||
%{_mandir}/man1/libinput-measure-touch-size.1*
|
||||
%{_mandir}/man1/libinput-measure-touchpad-size.1*
|
||||
%{_mandir}/man1/libinput-measure-touchpad-pressure.1*
|
||||
%{_mandir}/man1/libinput-quirks.1*
|
||||
%{_mandir}/man1/libinput-quirks-list.1*
|
||||
%{_mandir}/man1/libinput-quirks-validate.1*
|
||||
%{_mandir}/man1/libinput-record.1*
|
||||
%{_mandir}/man1/libinput-replay.1*
|
||||
%{_mandir}/man1/libinput-analyze.1*
|
||||
%{_mandir}/man1/libinput-analyze-buttons.1*
|
||||
%{_mandir}/man1/libinput-analyze-per-slot-delta.1*
|
||||
%{_mandir}/man1/libinput-analyze-recording.1*
|
||||
%{_mandir}/man1/libinput-analyze-touch-down-state.1*
|
||||
|
||||
%files test
|
||||
%{_libexecdir}/libinput/libinput-test
|
||||
%{_libexecdir}/libinput/libinput-test-suite
|
||||
%{_libexecdir}/libinput/libinput-test-utils
|
||||
%{_mandir}/man1/libinput-test.1*
|
||||
%{_mandir}/man1/libinput-test-suite.1*
|
||||
|
||||
%changelog
|
||||
* Wed Jul 15 2020 Peter Hutterer <peter.hutterer@redhat.com>
|
||||
- Add basic spec file for package build testing
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
#!/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
|
||||
fi
|
||||
|
||||
# emulate a few gitlab variables to make it easier to
|
||||
# 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="$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
|
||||
|
||||
if [[ -z "$MESON_SKIP_SETUP" ]]; then
|
||||
rm -rf "$MESON_BUILDDIR"
|
||||
meson setup "$MESON_BUILDDIR" $MESON_ARGS
|
||||
fi
|
||||
meson configure "$MESON_BUILDDIR"
|
||||
|
||||
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
|
||||
|
||||
if [[ -n "$MESON_RUN_TEST" ]]; then
|
||||
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
|
||||
fi
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/sh
|
||||
scan-build -v --status-bugs -plist-html "$@"
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
@dataclass
|
||||
class WhitespaceError:
|
||||
message: str
|
||||
lineno: int
|
||||
nlines: int = 1
|
||||
column: None | int = None
|
||||
ncolumns: int = 1
|
||||
|
||||
|
||||
def test_duplicate_empty_lines(lines: list[str]) -> list[WhitespaceError]:
|
||||
errors = []
|
||||
for idx, (l1, l2) in enumerate(itertools.pairwise(lines)):
|
||||
if not l1 and not l2:
|
||||
errors.append(WhitespaceError("Duplicated empty lines", idx, nlines=2))
|
||||
return errors
|
||||
|
||||
|
||||
def test_tab_after_space(lines: list[str]) -> list[WhitespaceError]:
|
||||
errors = []
|
||||
for idx, l in enumerate(lines):
|
||||
index = l.find(" \t")
|
||||
if index > -1:
|
||||
errors.append(
|
||||
WhitespaceError(
|
||||
"Tab after space", idx, nlines=index, column=index, ncolumns=2
|
||||
)
|
||||
)
|
||||
return errors
|
||||
|
||||
|
||||
def test_trailing_whitespace(lines: list[str]) -> list[WhitespaceError]:
|
||||
errors = []
|
||||
for idx, l in enumerate(lines):
|
||||
if l.rstrip() != l:
|
||||
errors.append(WhitespaceError("Trailing whitespace", idx))
|
||||
return errors
|
||||
|
||||
|
||||
def test_empty_line_between_braces(lines: list[str]) -> list[WhitespaceError]:
|
||||
errors = []
|
||||
for idx in range(len(lines) - 3):
|
||||
l1 = lines[idx]
|
||||
l2 = lines[idx + 1]
|
||||
l3 = lines[idx + 2]
|
||||
if l1.strip() == "}" and l3.strip() == "}" and l2.strip() == "":
|
||||
errors.append(WhitespaceError("Empty line between closing braces", idx + 1))
|
||||
return errors
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Whitespace checker script")
|
||||
parser.add_argument(
|
||||
"files",
|
||||
metavar="FILES",
|
||||
type=Path,
|
||||
nargs="+",
|
||||
help="The files to check",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
have_errors: bool = False
|
||||
|
||||
if os.isatty(sys.stderr.fileno()):
|
||||
red = "\x1b[0;31m"
|
||||
reset = "\x1b[0m"
|
||||
else:
|
||||
red = ""
|
||||
reset = ""
|
||||
|
||||
for file in args.files:
|
||||
lines = [l.rstrip("\n") for l in file.open().readlines()]
|
||||
|
||||
errors = []
|
||||
errors.extend(test_tab_after_space(lines))
|
||||
errors.extend(test_trailing_whitespace(lines))
|
||||
if any(file.name.endswith(suffix) for suffix in [".c", ".h"]):
|
||||
if not file.parts[0] == "include":
|
||||
errors.extend(test_duplicate_empty_lines(lines))
|
||||
errors.extend(test_empty_line_between_braces(lines))
|
||||
|
||||
for e in errors:
|
||||
print(f"{red}ERROR: {e.message} in {file}:{reset}", file=sys.stderr)
|
||||
print(f"{'-' * 72}", file=sys.stderr)
|
||||
lineno = max(0, e.lineno - 5)
|
||||
for idx, l in enumerate(lines[lineno : lineno + 10]):
|
||||
if e.lineno <= lineno + idx < e.lineno + e.nlines:
|
||||
prefix = "->"
|
||||
hl = red
|
||||
nohl = reset
|
||||
else:
|
||||
prefix = " "
|
||||
hl = ""
|
||||
nohl = ""
|
||||
print(f"{hl}{lineno + idx:3d}: {prefix} {l.rstrip()}{nohl}")
|
||||
|
||||
print(f"{'-' * 72}", file=sys.stderr)
|
||||
|
||||
if errors:
|
||||
have_errors = True
|
||||
|
||||
if have_errors:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<!--
|
||||
|
||||
Before your file a feature request, please read
|
||||
|
||||
https://wayland.freedesktop.org/libinput/doc/latest/what-is-libinput.html
|
||||
|
||||
The amount of developer time libinput has available is very small.
|
||||
Requesting a feature is no guarantee that it will get implemented. Someone
|
||||
(you!) needs to step up to do the work.
|
||||
|
||||
-->
|
||||
|
||||
## Summary
|
||||
|
||||
<!-- Summarize the requested feature in a few sentences. -->
|
||||
|
||||
## Feature details
|
||||
|
||||
<!-- A step-by-step list of what the feature should achieve (where applicable) -->
|
||||
|
||||
## Affected Hardware
|
||||
|
||||
<!-- Which hardware types would be affected by this -->
|
||||
|
||||
## Implementation in Other Systems
|
||||
|
||||
<!-- Does this feature already exist elsewhere? How does it work there? Try
|
||||
to provide as many details as possible -->
|
||||
|
||||
|
||||
|
||||
/label ~enhancement ~"needs triage"
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
## Summary
|
||||
|
||||
<!--
|
||||
Summarize the bug encountered concisely. See
|
||||
https://wayland.freedesktop.org/libinput/doc/latest/reporting-bugs.html for
|
||||
detailed instructions to report bugs
|
||||
-->
|
||||
|
||||
## Steps to reproduce
|
||||
|
||||
<!-- How to reproduce the issue on a developer machine - this is very important -->
|
||||
|
||||
## Required information
|
||||
|
||||
<!-- Note: if your libinput version is older than the current stable version,
|
||||
please reproduce with a current version instead -->
|
||||
|
||||
- libinput version:
|
||||
- hardware information:
|
||||
- `libinput record` output: do not paste, **attach** the file
|
||||
- `libinput debug-events --verbose` output: do not paste, **attach the file**
|
||||
|
||||
<!--
|
||||
|
||||
Paste any other relevant logs - please use code blocks (```) to format
|
||||
console output, logs, and code as it's very hard to read otherwise.)
|
||||
|
||||
Do not paste logs longer than 10 lines, **attach** those instead.
|
||||
|
||||
If your libinput record is longer than 5-10s, we will not be able to process
|
||||
it.
|
||||
|
||||
-->
|
||||
|
||||
/label ~"bug" ~"needs triage"
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: no-commit-to-branch
|
||||
args: ['--branch', 'main']
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.12.2
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
args: ['--ignore=E741,E501', '--extend-exclude=subprojects', '.']
|
||||
- id: ruff-format
|
||||
args: ['--check', '--diff']
|
||||
- repo: https://gitlab.freedesktop.org/freedesktop/ci-templates.git
|
||||
rev: e195d80f35b45cc73668be3767b923fd76c70ed5
|
||||
hooks:
|
||||
- id: check-commits
|
||||
- id: generate-template
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: run-sed-script
|
||||
name: Check for whitespace errors
|
||||
entry: ./.gitlab-ci/whitespace-check.py
|
||||
language: system
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v20.1.6
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c]
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
# This is a set of bugbot commands for issues and merge requests - setting any of the
|
||||
# bugbot::foo labels will trigger gitlab-triage to run with this ruleset (well, the
|
||||
# one we have on the main branch at the time)
|
||||
#
|
||||
# Note that for adding labels, the label must first created in the project.
|
||||
|
||||
# Re-used in issues and mrs
|
||||
.close_needinfo: &close_needinfo
|
||||
name: "Close stale needinfo bugs"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::needinfo-timeout"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::needinfo-timeout"
|
||||
comment: |
|
||||
I'm closing this bug because some information we requested a while ago was never supplied and
|
||||
we're not able to continue without this information.
|
||||
Please feel free to re-open.
|
||||
status: "close"
|
||||
|
||||
.remind_needinfo: &remind_needinfo
|
||||
name: "Remind users of needinfo bugs"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::needinfo-reminder"
|
||||
actions:
|
||||
labels:
|
||||
- "waiting on reporter"
|
||||
remove_labels:
|
||||
- "bugbot::needinfo-reminder"
|
||||
comment: |
|
||||
Hi. This is a friendly reminder that the maintainers are waiting on some information by
|
||||
you (or maybe someone cc'd on this bug). If the information is not provided we may not
|
||||
be able to proceed with this issue or merge request. Please check the recent comments, thanks.
|
||||
|
||||
.help_needed: &help_needed
|
||||
name: "Remind users help is needed"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::help-needed"
|
||||
actions:
|
||||
labels:
|
||||
- "help needed"
|
||||
remove_labels:
|
||||
- "bugbot::help-needed"
|
||||
comment: |
|
||||
Hi. This issue or merge request needs help. This simply means that for
|
||||
the foreseeable future, the maintainers will not have time to work on
|
||||
this.
|
||||
|
||||
If this is a request for a new feature, then the feature is unlikely to
|
||||
be implemented unless you or another contributor files a merge request.
|
||||
If a merge request already exists maybe it needs finishing which often
|
||||
involves adding documentation or tests.
|
||||
|
||||
If this is an issue affecting a specific device then it is unlikely to be
|
||||
fixed. This may be because it requires specific hardware to reproduce or
|
||||
it may be that the use case is niche enough that the maintainers do not
|
||||
have time to implement it.
|
||||
|
||||
In short, to resolve this issue or get this merge request into libinput
|
||||
help is needed.
|
||||
|
||||
.libinput_record: &libinput_record
|
||||
name: "Request libinput record output"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::libinput-record"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::libinput-record"
|
||||
comment: |
|
||||
Looks like we may need some extra information. Please **attach** (do not paste) the full output
|
||||
of `libinput record` and `libinput debug-events --verbose` (if you haven't yet).
|
||||
The [documentation](https://wayland.freedesktop.org/libinput/doc/latest/tools.html#libinput-record-and-libinput-replay)
|
||||
has some information on what we're looking for to be able to triage bugs.
|
||||
|
||||
.hid_recorder: &hid_recorder
|
||||
name: "Request hid-recorder output"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::hid-recorder"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::hid-recorder"
|
||||
comment: |
|
||||
Looks like we may need some extra information that isn't yet available in this issue.
|
||||
Please **attach** (do not paste) the output of [`hid-recorder`](https://github.com/hidutils/hid-recorder/)
|
||||
for this device (run `sudo hid-recorder` without argument and it will let you pick the device).
|
||||
This should show the data the kernel receives from the device and may provide a hint on what's going on here.
|
||||
|
||||
.udev_hid_bpf: &udev_hid_bpf
|
||||
name: "Punt to udev-hid-bpf"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::udev-hid-bpf"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::udev-hid-bpf"
|
||||
comment: |
|
||||
This issue looks like it could or should be fixed with [udev-hid-bpf](https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/).
|
||||
udev-hid-bpf is a collection of BPF programs that modify the HID Report Descriptor and/or HID Reports from the device,
|
||||
making it possible to change the properties of a device and/or the events to make them compatible with the
|
||||
expectations the kernel and userspace has of such devices.
|
||||
|
||||
Please see the [udev-hid-bpf documentation](https://libevdev.pages.freedesktop.org/udev-hid-bpf/) for details
|
||||
and/or in particular the [udev-hid-bpf tutorial](https://libevdev.pages.freedesktop.org/udev-hid-bpf/tutorial.html)
|
||||
if you need to enable a new device.
|
||||
status: "close"
|
||||
|
||||
resource_rules:
|
||||
issues:
|
||||
rules:
|
||||
- name: "Close kernel bugs"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::kernel"
|
||||
actions:
|
||||
labels:
|
||||
- "kernel"
|
||||
remove_labels:
|
||||
- "bugbot::kernel"
|
||||
comment: |
|
||||
This bug looks like a kernel issue and it cannot be fixed
|
||||
in libinput directly. I'm closing this bug but do feel free
|
||||
to continue discussing the issue here.
|
||||
|
||||
Kernel bugs are usually best sent to the [`linux-input` list](https://lore.kernel.org/linux-input/).
|
||||
status: "close"
|
||||
- name: "Expect a merge request"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::expect-mr"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::expect-mr"
|
||||
comment: |
|
||||
I'm closing this bug in anticipation of a merge request that fixes this issue.
|
||||
|
||||
If you are a new contributor, please see
|
||||
[the freedesktop.org wiki](https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home)
|
||||
on how to get permissions to fork a project and file a merge request.
|
||||
|
||||
The [libinput documentation](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html)
|
||||
also has more details on how to get started.
|
||||
status: "close"
|
||||
- name: "Point to 60-evdev.hwdb"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::evdev-hwdb"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::evdev-hwdb"
|
||||
comment: |
|
||||
Looks like this issue may be solved with a device-specific entry in systemd's hwdb.
|
||||
|
||||
You should have a /usr/lib/udev/hwdb.d/60-evdev.hwdb file which includes those quirks. Please see
|
||||
the top of the file for instructions and follow those. Once the quirk is confirmed working
|
||||
this issue (or parts thereof) should be fixed and you can submit a pull request to the
|
||||
[systemd](https://github.com/systemd/systemd/) repository to get that quirk included.
|
||||
Please link to the systemd issue here, thanks.
|
||||
|
||||
I'm closing this issue now, if the hwdb entry does not fix this issue here, please re-open.
|
||||
status: "close"
|
||||
- name: "Close bug for reopening"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::close"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::close"
|
||||
comment: |
|
||||
I'm temporarily closing this bug. The bug may not be fixed yet (see any comments above)
|
||||
and we **want you to reopen it when/if it becomes actionable again**.
|
||||
|
||||
This process may feel unfamiliar but unfortunately closing/re-opening is the only action
|
||||
all GitLab users are permitted to do. So we close it, you re-open it when whatever
|
||||
above has been addressed and then we know we need to look at it again.
|
||||
This issue may be closed more than once in a similar fashion but I only leave this
|
||||
comment once since now you understand how it works. :smile:
|
||||
|
||||
For a detailed explanation on the how and why of this process please see
|
||||
the [Closed Issues wiki page](https://gitlab.freedesktop.org/libinput/libinput/-/wikis/Closed-Issues).
|
||||
status: "close"
|
||||
- name: "Re-close bug for reopening"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::re-close"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::re-close"
|
||||
comment: |
|
||||
I'm temporarily closing this bug again. This is not a final close, see my comments above for the open/close process.
|
||||
status: "close"
|
||||
- *udev_hid_bpf
|
||||
- *libinput_record
|
||||
- *hid_recorder
|
||||
- *close_needinfo
|
||||
- *remind_needinfo
|
||||
- *help_needed
|
||||
merge_requests:
|
||||
rules:
|
||||
- name: "Remind contributor of commit rules"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::commit-rules"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::commit-rules"
|
||||
comment: |
|
||||
Hi. Looks like the pipeline failed because one or more of the commits in this MR do not meet our requirements.
|
||||
Most commonly this the format of the commit message itself. The "Test summary" above has the details.
|
||||
|
||||
Please see [our docs for commit messages](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#commit-messages)
|
||||
and [our docs for submitting code](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#submitting-code)
|
||||
that explain how to amend and force-push to this repo.
|
||||
- name: "Remind contributor that info needs to be in commit messages"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::info-in-commit-message"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::info-in-commit-message"
|
||||
comment: |
|
||||
Hi. Thanks for the merge request. I'm here to request that you add
|
||||
some documentation about this merge request to the
|
||||
**commit message** (or messages). You may have already written some
|
||||
in the merge request description and in many cases it's fine to
|
||||
copy/paste that into the commit message(s).
|
||||
|
||||
The reason is simple: once merged, no-one really looks at this this
|
||||
page here anymore. The git log on the other hand is what developers
|
||||
will use to understand the code so the information must be quickly
|
||||
accessible via git.
|
||||
|
||||
Please see [our docs for submitting code](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#submitting-code)
|
||||
that explain how to amend and force-push to this repo.
|
||||
- *udev_hid_bpf
|
||||
- *libinput_record
|
||||
- *hid_recorder
|
||||
- *close_needinfo
|
||||
- *remind_needinfo
|
||||
- *help_needed
|
||||
116
CODING_STYLE
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
||||
vertical alignment is required (see below)
|
||||
|
||||
- Max line width 80ch, do not break up printed strings though
|
||||
|
||||
- Break up long lines at logical groupings, one line for each logical group
|
||||
|
||||
int a = somelongname() +
|
||||
someotherlongname();
|
||||
|
||||
if (a < 0 &&
|
||||
(b > 20 & d < 10) &&
|
||||
d != 0.0)
|
||||
|
||||
|
||||
somelongfunctioncall(arg1,
|
||||
arg2,
|
||||
arg3);
|
||||
|
||||
- Function declarations: return type on separate line, {} on separate line,
|
||||
arguments broken up as above.
|
||||
|
||||
static inline int
|
||||
foobar(int a, int b)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
somenamethatiswaytoolong(int a,
|
||||
int b,
|
||||
int c)
|
||||
{
|
||||
}
|
||||
|
||||
- /* comments only */, no // comments
|
||||
|
||||
- variable_name, not VariableName or variableName. same for functions.
|
||||
|
||||
- no typedefs of structs, enums, unions
|
||||
|
||||
- if it generates a compiler warning, it needs to be fixed
|
||||
- if it generates a static checker warning, it needs to be fixed or
|
||||
commented
|
||||
|
||||
- declare variables at the top, try to keep them as local as possible.
|
||||
Exception: if the same variable is re-used in multiple blocks, declare it
|
||||
at the top.
|
||||
|
||||
int a;
|
||||
int c;
|
||||
|
||||
if (foo) {
|
||||
int b;
|
||||
|
||||
c = get_value();
|
||||
usevalue(c);
|
||||
}
|
||||
|
||||
if (bar) {
|
||||
c = get_value();
|
||||
useit(c);
|
||||
}
|
||||
|
||||
- do not mix function invocations and variable definitions.
|
||||
|
||||
wrong:
|
||||
|
||||
{
|
||||
int a = foo();
|
||||
int b = 7;
|
||||
}
|
||||
|
||||
right:
|
||||
{
|
||||
int a;
|
||||
int b = 7;
|
||||
|
||||
a = foo();
|
||||
}
|
||||
|
||||
There are exceptions here, e.g. tp_libinput_context(),
|
||||
litest_current_device()
|
||||
|
||||
- if/else: { on the same line, no curly braces if both blocks are a single
|
||||
statement. If either if or else block are multiple statements, both must
|
||||
have curly braces.
|
||||
|
||||
if (foo) {
|
||||
blah();
|
||||
bar();
|
||||
} else {
|
||||
a = 10;
|
||||
}
|
||||
|
||||
- public functions MUST be doxygen-commented, use doxygen's @foo rather than
|
||||
\foo notation
|
||||
|
||||
- include "config.h" comes first, followed by system headers, followed by
|
||||
external library headers, followed by internal headers.
|
||||
sort alphabetically where it makes sense (specifically system headers)
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "libinput-private.h"
|
||||
|
||||
- goto jumps only to the end of the function, and only for good reasons
|
||||
(usually cleanup). goto never jumps backwards
|
||||
|
||||
- Use stdbool.h's bool for booleans within the library (instead of 'int').
|
||||
Exception: the public API uses int, not bool.
|
||||
244
CODING_STYLE.md
|
|
@ -1,244 +0,0 @@
|
|||
# Coding style
|
||||
|
||||
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
||||
vertical alignment is required (see below)
|
||||
|
||||
**Note: this file uses spaces due to markdown rendering issues for tabs.
|
||||
Code must be implemented using tabs.**
|
||||
|
||||
- Max line width 80ch, do not break up printed strings though
|
||||
|
||||
- Break up long lines at logical groupings, one line for each logical group
|
||||
|
||||
```c
|
||||
int a = somelongname() +
|
||||
someotherlongname();
|
||||
|
||||
if (a < 0 &&
|
||||
(b > 20 & d < 10) &&
|
||||
d != 0.0)
|
||||
|
||||
|
||||
somelongfunctioncall(arg1,
|
||||
arg2,
|
||||
arg3);
|
||||
```
|
||||
|
||||
- Function declarations: return type on separate line, {} on separate line,
|
||||
arguments broken up as above.
|
||||
|
||||
```c
|
||||
static inline int
|
||||
foobar(int a, int b)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
somenamethatiswaytoolong(int a,
|
||||
int b,
|
||||
int c)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
- `/* comments only */`, no `// comments`
|
||||
|
||||
- `variable_name`, not `VariableName` or `variableName`. same for functions.
|
||||
|
||||
- no typedefs of structs, enums, unions
|
||||
|
||||
- if it generates a compiler warning, it needs to be fixed
|
||||
- if it generates a static checker warning, it needs to be fixed or
|
||||
commented
|
||||
|
||||
- declare variables when they are used first and try to keep them as local as possible.
|
||||
Exception: basic loop variables, e.g. for (int i = 0; ...) should always be
|
||||
declared inside the loop even where multiple loops exist
|
||||
|
||||
```c
|
||||
int a;
|
||||
|
||||
if (foo) {
|
||||
int b = 10;
|
||||
|
||||
a = get_value();
|
||||
usevalue(a, b);
|
||||
}
|
||||
|
||||
if (bar) {
|
||||
a = get_value();
|
||||
useit(a);
|
||||
}
|
||||
|
||||
int c = a * 100;
|
||||
useit(c);
|
||||
```
|
||||
|
||||
- avoid uninitialized variables where possible, declare them late instead.
|
||||
Note that most of libinput predates this style, try to stick with the code
|
||||
around you if in doubt.
|
||||
|
||||
wrong:
|
||||
|
||||
```c
|
||||
int *a;
|
||||
int b = 7;
|
||||
|
||||
... some code ...
|
||||
|
||||
a = zalloc(32);
|
||||
```
|
||||
|
||||
right:
|
||||
|
||||
```c
|
||||
int b = 7;
|
||||
... some code ...
|
||||
|
||||
int *a = zalloc(32);
|
||||
```
|
||||
|
||||
- avoid calling non-obvious functions inside declaration blocks for multiple
|
||||
variables.
|
||||
|
||||
bad:
|
||||
|
||||
```c
|
||||
{
|
||||
int a = 7;
|
||||
int b = some_complicated_function();
|
||||
int *c = zalloc(32);
|
||||
}
|
||||
```
|
||||
|
||||
better:
|
||||
```c
|
||||
{
|
||||
int a = 7;
|
||||
int *c = zalloc(32);
|
||||
|
||||
int b = some_complicated_function();
|
||||
}
|
||||
```
|
||||
|
||||
There is a bit of gut-feeling involved with this, but the goal is to make
|
||||
the variable values immediately recognizable.
|
||||
|
||||
- Where statements are near-identical and repeated, try to keep them
|
||||
identical:
|
||||
|
||||
bad:
|
||||
```c
|
||||
int a = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
```
|
||||
better:
|
||||
|
||||
```c
|
||||
int a;
|
||||
a = = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
```
|
||||
|
||||
- if/else: { on the same line, no curly braces if both blocks are a single
|
||||
statement. If either if or else block are multiple statements, both must
|
||||
have curly braces.
|
||||
|
||||
```c
|
||||
if (foo) {
|
||||
blah();
|
||||
bar();
|
||||
} else {
|
||||
a = 10;
|
||||
}
|
||||
```
|
||||
|
||||
- public functions MUST be doxygen-commented, use doxygen's `@foo` rather than
|
||||
`\foo` notation
|
||||
|
||||
- `#include "config.h"` comes first, followed by system headers, followed by
|
||||
external library headers, followed by internal headers.
|
||||
sort alphabetically where it makes sense (specifically system headers)
|
||||
|
||||
```c
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#include "libinput-private.h"
|
||||
```
|
||||
|
||||
- goto jumps only to the end of the function, and only for good reasons
|
||||
(usually cleanup). goto never jumps backwards
|
||||
|
||||
- Use stdbool.h's bool for booleans within the library (instead of `int`).
|
||||
Exception: the public API uses int, not bool.
|
||||
|
||||
# Git commit message requirements
|
||||
|
||||
Our CI will check the commit messages for a few requirements. Below is the
|
||||
list of what we expect from a git commit.
|
||||
|
||||
## Commit message content
|
||||
|
||||
A [good commit message](http://who-t.blogspot.com/2009/12/on-commit-messages.html) needs to
|
||||
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
|
||||
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
|
||||
was.
|
||||
- What effects does the patch have? (In addition to the obvious ones, this
|
||||
may include benchmarks, side effects, etc.)
|
||||
|
||||
These three questions establish the context for the actual code changes, put
|
||||
reviewers and others into the frame of mind to look at the diff and check if
|
||||
the approach chosen was correct. A good commit message also helps
|
||||
maintainers to decide if a given patch is suitable for stable branches or
|
||||
inclusion in a distribution.
|
||||
|
||||
## Commit message format
|
||||
|
||||
The canonical git commit message format is:
|
||||
|
||||
```
|
||||
one line as the subject line with a high-level note
|
||||
|
||||
full explanation of the patch follows after an empty line. This explanation
|
||||
can be multiple paragraphs and is largely free-form. Markdown is not
|
||||
supported.
|
||||
|
||||
You can include extra data where required like:
|
||||
- benchmark one says 10s
|
||||
- benchmark two says 12s
|
||||
```
|
||||
|
||||
The subject line is the first thing everyone sees about this commit, so make
|
||||
sure it's on point.
|
||||
|
||||
## Commit message technical requirements
|
||||
|
||||
- The commit message should use present tense (not past tense). Do write
|
||||
"change foo to bar", not "changed foo to bar".
|
||||
- The text width of the commit should be 78 chars or less, especially the
|
||||
subject line.
|
||||
- The author must be the name you usually identify as and email address. We do
|
||||
not accept the default `@users.noreply` gitlab addresses.
|
||||
```
|
||||
git config --global user.name Your Name
|
||||
git config --global user.email your@email
|
||||
```
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Thank you for your interest in contributing to libinput.
|
||||
|
||||
Please find more information about how to contribute in
|
||||
[the documentation](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html).
|
||||
2
COPYING
|
|
@ -31,4 +31,4 @@ This copy is provided to provide consistent behavior regardless which kernel
|
|||
version libinput is compiled against. The header is used during compilation
|
||||
only, libinput does not link against GPL libraries.
|
||||
|
||||
[1] https://gitlab.freedesktop.org/libinput/libinput/blob/main/include/linux/input.h
|
||||
[1] http://cgit.freedesktop.org/wayland/libinput/tree/include/linux/input.h
|
||||
|
|
|
|||
6
Makefile.am
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
SUBDIRS = src doc test tools udev
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
valgrind:
|
||||
(cd test; $(MAKE) valgrind)
|
||||
84
README.md
|
|
@ -1,84 +0,0 @@
|
|||
libinput
|
||||
========
|
||||
|
||||
libinput is a library that provides a full input stack for display servers
|
||||
and other applications that need to handle input devices provided by the
|
||||
kernel.
|
||||
|
||||
libinput provides device detection, event handling and abstraction to
|
||||
minimize the amount of custom input code the user of libinput needs to
|
||||
provide the common set of functionality that users expect. Input event
|
||||
processing includes scaling touch coordinates, generating
|
||||
relative pointer events from touchpads, pointer acceleration, etc.
|
||||
|
||||
User documentation
|
||||
------------------
|
||||
|
||||
Documentation explaining features available in libinput is available
|
||||
[here](https://wayland.freedesktop.org/libinput/doc/latest/features.html).
|
||||
|
||||
This includes the [FAQ](https://wayland.freedesktop.org/libinput/doc/latest/faqs.html)
|
||||
and the instructions on
|
||||
[reporting bugs](https://wayland.freedesktop.org/libinput/doc/latest/reporting-bugs.html).
|
||||
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
The source code of libinput can be found at:
|
||||
https://gitlab.freedesktop.org/libinput/libinput
|
||||
|
||||
For a list of current and past releases visit:
|
||||
https://www.freedesktop.org/wiki/Software/libinput/
|
||||
|
||||
Build instructions:
|
||||
https://wayland.freedesktop.org/libinput/doc/latest/building.html
|
||||
|
||||
Reporting Bugs
|
||||
--------------
|
||||
|
||||
Bugs can be filed on freedesktop.org GitLab:
|
||||
https://gitlab.freedesktop.org/libinput/libinput/issues/
|
||||
|
||||
Where possible, please provide the `libinput record` output
|
||||
of the input device and/or the event sequence in question.
|
||||
|
||||
See https://wayland.freedesktop.org/libinput/doc/latest/reporting-bugs.html
|
||||
for more info.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- Developer API documentation: https://wayland.freedesktop.org/libinput/doc/latest/development.html
|
||||
- High-level documentation about libinput's features:
|
||||
https://wayland.freedesktop.org/libinput/doc/latest/features.html
|
||||
- Build instructions:
|
||||
https://wayland.freedesktop.org/libinput/doc/latest/building.html
|
||||
- Documentation for previous versions of libinput: https://wayland.freedesktop.org/libinput/doc/
|
||||
|
||||
Examples of how to use libinput are the debugging tools in the libinput
|
||||
repository. Developers are encouraged to look at those tools for a
|
||||
real-world (yet simple) example on how to use libinput.
|
||||
|
||||
- A commandline debugging tool: https://gitlab.freedesktop.org/libinput/libinput/tree/main/tools/libinput-debug-events.c
|
||||
- A GTK application that draws cursor/touch/tablet positions: https://gitlab.freedesktop.org/libinput/libinput/tree/main/tools/libinput-debug-gui.c
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
libinput is licensed under the MIT license.
|
||||
|
||||
> 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: [...]
|
||||
|
||||
See the [COPYING](https://gitlab.freedesktop.org/libinput/libinput/tree/main/COPYING)
|
||||
file for the full license information.
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
Documentation generated from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
||||
85
README.txt
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*!@mainpage
|
||||
|
||||
libinput
|
||||
========
|
||||
|
||||
libinput is a library that handles input devices for display servers and other
|
||||
applications that need to directly deal with input devices.
|
||||
|
||||
It provides device detection, device handling, input device event processing
|
||||
and abstraction so minimize the amount of custom input code the user of
|
||||
libinput need to provide the common set of functionality that users expect.
|
||||
Input event processing includes scaling touch coordinates, generating
|
||||
pointer events from touchpads, pointer acceleration, etc.
|
||||
|
||||
libinput originates from
|
||||
[weston](http://cgit.freedesktop.org/wayland/weston/), the Wayland reference
|
||||
compositor.
|
||||
|
||||
Architecture
|
||||
------------
|
||||
|
||||
libinput is not used directly by applications, rather it is used by the
|
||||
xf86-input-libinput X.Org driver or wayland compositors. The typical
|
||||
software stack for a system running Wayland is:
|
||||
|
||||
@dotfile libinput-stack-wayland.gv
|
||||
|
||||
Where the Wayland compositor may be Weston, mutter, KWin, etc. Note that
|
||||
Wayland encourages the use of toolkits, so the Wayland client (your
|
||||
application) does not usually talk directly to the compositor but rather
|
||||
employs a toolkit (e.g. GTK) to do so.
|
||||
|
||||
The simplified software stack for a system running X.Org is:
|
||||
|
||||
@dotfile libinput-stack-xorg.gv
|
||||
|
||||
Again, on a modern system the application does not usually talk directly to
|
||||
the X server using Xlib but rather employs a toolkit to do so.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
The source code of libinput can be found at:
|
||||
http://cgit.freedesktop.org/wayland/libinput
|
||||
|
||||
For a list of current and past releases visit:
|
||||
http://www.freedesktop.org/wiki/Software/libinput/
|
||||
|
||||
Reporting Bugs
|
||||
--------------
|
||||
|
||||
Bugs can be filed in the libinput component of Wayland:
|
||||
https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=libinput
|
||||
|
||||
Where possible, please provide an
|
||||
[evemu](http://www.freedesktop.org/wiki/Evemu/) recording of the input
|
||||
device and/or the event sequence in question.
|
||||
|
||||
See @ref reporting_bugs for more info.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Developer API documentation:
|
||||
http://wayland.freedesktop.org/libinput/doc/latest/modules.html
|
||||
|
||||
High-level documentation about libinput's features:
|
||||
http://wayland.freedesktop.org/libinput/doc/latest/pages.html
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
libinput is licensed under the MIT license.
|
||||
|
||||
> 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: [...]
|
||||
|
||||
See the [COPYING](http://cgit.freedesktop.org/wayland/libinput/tree/COPYING)
|
||||
file for the full license information.
|
||||
|
||||
*/
|
||||
9
autogen.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
test -n "$srcdir" || srcdir=`dirname "$0"`
|
||||
test -n "$srcdir" || srcdir=.
|
||||
(
|
||||
cd "$srcdir" &&
|
||||
autoreconf --force -v --install
|
||||
) || exit
|
||||
test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"
|
||||
|
|
@ -1,282 +0,0 @@
|
|||
#compdef libinput
|
||||
|
||||
(( $+functions[_libinput_commands] )) || _libinput_commands()
|
||||
{
|
||||
local -a commands
|
||||
commands=(
|
||||
"list-devices:List all devices recognized by libinput"
|
||||
"debug-events:Print all events as seen by libinput"
|
||||
"debug-gui:Show a GUI to visualize libinput's events"
|
||||
"debug-tablet:Show tablet axis and button values"
|
||||
"measure:Measure various properties of devices"
|
||||
"analyze:Analyze device data"
|
||||
"record:Record the events from a device"
|
||||
"replay:Replay the events from a device"
|
||||
)
|
||||
|
||||
_describe -t commands 'command' commands
|
||||
}
|
||||
|
||||
__all_seats()
|
||||
{
|
||||
# Obviously only works with logind
|
||||
local -a seats
|
||||
seats=${(f)"$(loginctl --no-legend --no-pager list-seats 2>/dev/null)"}
|
||||
if [[ -z $seats ]]; then
|
||||
# Can always offer seat0, even if we can't enumerate the seats
|
||||
compadd "$@" - seat0
|
||||
else
|
||||
compadd "$@" - $seats
|
||||
fi
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_list-devices] )) || _libinput_list-devices()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help and exit]' \
|
||||
'--version[show version information and exit]'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_debug-events] )) || _libinput_debug-events()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show debug-events help and exit]' \
|
||||
'--quiet[Only print libinput messages and nothing from this tool]' \
|
||||
'--verbose[Use verbose output]' \
|
||||
'--show-keycodes[Make all keycodes visible]' \
|
||||
'--grab[Exclusively grab all opened devices]' \
|
||||
'--compress-motion-events[Compress repeated motion events on a TTY]' \
|
||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
||||
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
|
||||
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
|
||||
'--disable-sendevents=[Disable send-events option for the devices matching the pattern]:pattern' \
|
||||
'--set-area=[Set the desired area as "x1/y1 x2/y2" (within \[0.0, 1.0\]) ]' \
|
||||
'--set-calibration=[Set the first 6 elements of the 3x3 calibration matrix ("1.0 0.0 0.0 0.0 1.0 0.0")]' \
|
||||
'--set-click-method=[Set the desired click method]:click-method:(none clickfinger buttonareas)' \
|
||||
'--set-clickfinger-map=[Set button mapping for clickfinger]:tap-map:(( \
|
||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
||||
))' \
|
||||
'--set-eraser-button-button=[Set button mapping for the eraser button]:eraser-button:(BTN_STYLUS BTN_STYLUS2 BTN_STYLUS3)' \
|
||||
'--set-eraser-button-mode=[Set the eraser button mode]:eraser-mode:(default button)' \
|
||||
'--set-pressure-range=[Set the tablet tool pressure range (within range \[0.0, 1.0\])]' \
|
||||
'--set-profile=[Set pointer acceleration profile]:accel-profile:(adaptive flat custom)' \
|
||||
'--set-rotation-angle=[Set the rotation angle in degrees]' \
|
||||
'--set-scroll-button=[Set the button to the given button code]' \
|
||||
'--set-scroll-method=[Set the desired scroll method]:scroll-method:(none twofinger edge button)' \
|
||||
'--set-speed=[Set pointer acceleration speed (within range \[-1, 1\])]' \
|
||||
'--set-tap-map=[Set button mapping for tapping]:tap-map:(( \
|
||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
||||
))' \
|
||||
+ '(custom pointer acceleration)' \
|
||||
'--set-custom-points=[Set n points defining a custom acceleration function]' \
|
||||
'--set-custom-step=[Set the distance along the x axis between the custom points]' \
|
||||
'--set-custom-type=[Set the type of the acceleration function]:custom-type:(fallback motion scroll)' \
|
||||
+ '(drag)' \
|
||||
'--enable-drag[Enable tap-and-drag]' \
|
||||
'--disable-drag[Disable tap-and-drag]' \
|
||||
+ '(drag-lock)' \
|
||||
'--enable-drag-lock[Enable drag-lock]' \
|
||||
'--disable-drag-lock[Disable drag-lock]' \
|
||||
+ '(dwt)' \
|
||||
'--enable-dwt[Enable disable-while-typing]' \
|
||||
'--disable-dwt[Disable disable-while-typing]' \
|
||||
+ '(dwtp)' \
|
||||
'--enable-dwtp[Enable disable-while-trackpointing]' \
|
||||
'--disable-dwtp[Disable disable-while-trackpointing]' \
|
||||
+ '(left-handed)' \
|
||||
'--enable-left-handed[Enable left handed button configuration]' \
|
||||
'--disable-left-handed[Disable left handed button configuration]' \
|
||||
+ '(middlebutton)' \
|
||||
'--enable-middlebutton[Enable middle button emulation]' \
|
||||
'--disable-middlebutton[Disable middle button emulation]' \
|
||||
+ '(natural-scrolling)' \
|
||||
'--enable-natural-scrolling[Enable natural scrolling]' \
|
||||
'--disable-natural-scrolling[Disable natural scrolling]' \
|
||||
+ '(plugins)' \
|
||||
'--enable-plugins[Enable plugins]' \
|
||||
'--disable-plugins[Disable plugins]' \
|
||||
+ '(tap-to-click)' \
|
||||
'--enable-tap[Enable tap-to-click]' \
|
||||
'--disable-tap[Disable tap-to-click]'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_debug-gui] )) || _libinput_debug-gui()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show debug-gui help and exit]' \
|
||||
'--verbose[Use verbose output]' \
|
||||
'--grab[Exclusively grab all opened devices]' \
|
||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
||||
'--udev=[Listen for notifications on the given seat]:seat:_libinput_all_seats'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_debug-tablet] )) || _libinput_debug-tablet()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show debug-tablet help and exit]' \
|
||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
||||
'--udev=[Use the first tablet device on the given seat]:seat:_libinput_all_seats'
|
||||
}
|
||||
|
||||
|
||||
(( $+functions[_libinput_measure] )) || _libinput_measure()
|
||||
{
|
||||
local curcontext=$curcontext state line ret=1
|
||||
local features
|
||||
features=(
|
||||
"fuzz:Measure touch fuzz to avoid pointer jitter"
|
||||
"touch-size:Measure touch size and orientation"
|
||||
"touchpad-tap:Measure tap-to-click time"
|
||||
"touchpad-pressure:Measure touch pressure"
|
||||
)
|
||||
|
||||
_arguments -C \
|
||||
'--help[Print help and exit]' \
|
||||
':feature:->feature' \
|
||||
'*:: :->option-or-argument'
|
||||
|
||||
case $state in
|
||||
(feature)
|
||||
_describe -t features 'feature' features
|
||||
;;
|
||||
(option-or-argument)
|
||||
curcontext=${curcontext%:*:*}:libinput-measure-$words[1]:
|
||||
if ! _call_function ret _libinput_measure_$words[1]; then
|
||||
_message "unknown feature: $words[1]"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
return ret
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_measure_fuzz] )) || _libinput_measure_fuzz()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
':device:_files -W /dev/input/ -P /dev/input/'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_measure_touch-size] )) || _libinput_measure_touch-size()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
'--touch-threshold=[Assume a touch pressure threshold of "down:up"]' \
|
||||
'--palm-threshold=[Assume a palm threshold of N]' \
|
||||
':device:_files -W /dev/input/ -P /dev/input/'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_measure_touchpad-pressure] )) || _libinput_measure_touchpad-pressure()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
'--touch-threshold=[Assume a touch pressure threshold of "down:up"]' \
|
||||
'--palm-threshold=[Assume a palm threshold of N]' \
|
||||
':device:_files -W /dev/input/ -P /dev/input/'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_measure_touchpad-tap] )) || _libinput_measure_touchpad-tap()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
'--format=dat[Specify the data format to be printed. The default is "summary"]' \
|
||||
':device:_files -W /dev/input/ -P /dev/input/'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_analyze_per-slot-delta] )) || _libinput_analyze_per-slot-delta()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
':recording:_files'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_analyze_touch-down-state] )) || _libinput_analyze_touch-down-state()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
':recording:_files'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_analyze_recording] )) || _libinput_analyze_recording()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
':recording:_files'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_analyze] )) || _libinput_analyze()
|
||||
{
|
||||
local curcontext=$curcontext state line ret=1
|
||||
local features
|
||||
features=(
|
||||
"per-slot-delta:analyze relative movement per touch per slot"
|
||||
"recording:analyze a recording by printing a pretty table"
|
||||
"touch-down-state:analyze a recording for logical touch down states"
|
||||
)
|
||||
|
||||
_arguments -C \
|
||||
'--help[Print help and exit]' \
|
||||
':feature:->feature' \
|
||||
'*:: :->option-or-argument'
|
||||
|
||||
case $state in
|
||||
(feature)
|
||||
_describe -t features 'feature' features
|
||||
;;
|
||||
(option-or-argument)
|
||||
curcontext=${curcontext%:*:*}:libinput-analyze-$words[1]:
|
||||
if ! _call_function ret _libinput_analyze_$words[1]; then
|
||||
_message "unknown feature: $words[1]"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
return ret
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_record] )) || _libinput_record()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
'--all[Record all /dev/input/event* devices available on the system]' \
|
||||
'--autorestart=[Terminate the current recording after s seconds of device inactivity]' \
|
||||
{-o+,--output=}'[Specify the output file to use]:file:_files -g "*.yml"' \
|
||||
'--multiple[Record multiple devices at once]' \
|
||||
'--show-keycodes[Show keycodes as-is in the recording]' \
|
||||
'--with-libinput[Record libinput events alongside device events]' \
|
||||
'--with-hidraw[Record hidraw events alongside device events]' \
|
||||
'*::device:_files -W /dev/input/ -P /dev/input/'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_replay] )) || _libinput_replay()
|
||||
{
|
||||
_arguments \
|
||||
'--help[Show help message and exit]' \
|
||||
':recording:_files'
|
||||
}
|
||||
|
||||
_libinput()
|
||||
{
|
||||
local curcontext=$curcontext state line ret=1
|
||||
|
||||
_arguments -C \
|
||||
{-h,--help}'[Show help message and exit]' \
|
||||
'--version[Show version information and exit]' \
|
||||
':command:->command' \
|
||||
'*:: :->option-or-argument' && return
|
||||
|
||||
case $state in
|
||||
(command)
|
||||
_libinput_commands && ret=0
|
||||
;;
|
||||
(option-or-argument)
|
||||
curcontext=${curcontext%:*:*}:libinput-$words[1]:
|
||||
if ! _call_function ret _libinput_$words[1]; then
|
||||
_message "unknown libinput command: $words[1]"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
return ret
|
||||
}
|
||||
|
||||
_libinput
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
zshcompletiondir = get_option('zshcompletiondir')
|
||||
if zshcompletiondir == ''
|
||||
zshcompletiondir = get_option('datadir') / 'zsh' / 'site-functions'
|
||||
endif
|
||||
|
||||
if zshcompletiondir != 'no'
|
||||
install_data(
|
||||
'_libinput',
|
||||
install_dir: zshcompletiondir,
|
||||
install_mode: 'rw-r--r--',
|
||||
)
|
||||
endif
|
||||
241
configure.ac
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
AC_PREREQ([2.64])
|
||||
|
||||
m4_define([libinput_major_version], [1])
|
||||
m4_define([libinput_minor_version], [2])
|
||||
m4_define([libinput_micro_version], [903])
|
||||
m4_define([libinput_version],
|
||||
[libinput_major_version.libinput_minor_version.libinput_micro_version])
|
||||
|
||||
AC_INIT([libinput],
|
||||
[libinput_version],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=libinput&version=libinput_version],
|
||||
[libinput],
|
||||
[http://www.freedesktop.org/wiki/Software/libinput/])
|
||||
|
||||
AC_SUBST([LIBINPUT_VERSION_MAJOR], [libinput_major_version])
|
||||
AC_SUBST([LIBINPUT_VERSION_MINOR], [libinput_minor_version])
|
||||
AC_SUBST([LIBINPUT_VERSION_MICRO], [libinput_micro_version])
|
||||
AC_SUBST([LIBINPUT_VERSION], [libinput_version])
|
||||
|
||||
AC_DEFINE([LIBINPUT_VERSION_MAJOR], [libinput_major_version], "libinput major version number")
|
||||
AC_DEFINE([LIBINPUT_VERSION_MINOR], [libinput_minor_version], "libinput minor version number")
|
||||
AC_DEFINE([LIBINPUT_VERSION_MICRO], [libinput_micro_version], "libinput micro version number")
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
|
||||
|
||||
# Before making a release, the LIBINPUT_LT_VERSION string should be
|
||||
# modified.
|
||||
# The string is of the form C:R:A.
|
||||
# a) If binary compatibility has been broken (eg removed or changed interfaces)
|
||||
# change to C+1:0:0. DO NOT DO THIS! Use symbol versioning instead and
|
||||
# do b) instead.
|
||||
# b) If interfaces have been changed or added, but binary compatibility has
|
||||
# been preserved, change to C+1:0:A+1
|
||||
# c) If the interface is the same as the previous version, change to C:R+1:A
|
||||
LIBINPUT_LT_VERSION=18:2:8
|
||||
AC_SUBST(LIBINPUT_LT_VERSION)
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
# Check for programs
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CXX # Only used by build C++ test
|
||||
AC_PROG_GREP
|
||||
|
||||
# Initialize libtool
|
||||
LT_PREREQ([2.2])
|
||||
LT_INIT
|
||||
|
||||
AC_CHECK_DECL(EPOLL_CLOEXEC, [],
|
||||
[AC_MSG_ERROR("EPOLL_CLOEXEC is needed to compile libinput")],
|
||||
[[#include <sys/epoll.h>]])
|
||||
AC_CHECK_DECL(TFD_CLOEXEC,[],
|
||||
[AC_MSG_ERROR("TFD_CLOEXEC is needed to compile libinput")],
|
||||
[[#include <sys/timerfd.h>]])
|
||||
AC_CHECK_DECL(CLOCK_MONOTONIC,[],
|
||||
[AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile libinput")],
|
||||
[[#include <time.h>]])
|
||||
|
||||
PKG_PROG_PKG_CONFIG()
|
||||
PKG_CHECK_MODULES(MTDEV, [mtdev >= 1.1.0])
|
||||
PKG_CHECK_MODULES(LIBUDEV, [libudev])
|
||||
PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4])
|
||||
|
||||
AC_ARG_WITH(libunwind,
|
||||
AS_HELP_STRING([--without-libunwind],[Do not use libunwind]))
|
||||
|
||||
AS_IF([test "x$with_libunwind" != "xno"],
|
||||
[PKG_CHECK_MODULES(LIBUNWIND,
|
||||
[libunwind],
|
||||
[HAVE_LIBUNWIND=yes],
|
||||
[HAVE_LIBUNWIND=no])],
|
||||
[HAVE_LIBUNWIND=no])
|
||||
|
||||
AS_IF([test "x$HAVE_LIBUNWIND" = "xyes"],
|
||||
[AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support])],
|
||||
[AS_IF([test "x$with_libunwind" = "xyes"],
|
||||
[AC_MSG_ERROR([libunwind requested but not found])])])
|
||||
|
||||
AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes])
|
||||
AC_PATH_PROG(ADDR2LINE, [addr2line])
|
||||
if test "x$ADDR2LINE" != "x"; then
|
||||
AC_DEFINE_UNQUOTED(HAVE_ADDR2LINE, 1, [addr2line found])
|
||||
AC_DEFINE_UNQUOTED(ADDR2LINE, ["$ADDR2LINE"], [Path to addr2line])
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([m], [atan2])
|
||||
AC_CHECK_LIB([rt], [clock_gettime])
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
GCC_CXXFLAGS="-Wall -Wextra -Wno-unused-parameter -g -fvisibility=hidden"
|
||||
GCC_CFLAGS="$GCC_CXXFLAGS -Wmissing-prototypes -Wstrict-prototypes"
|
||||
fi
|
||||
AC_SUBST(GCC_CFLAGS)
|
||||
AC_SUBST(GCC_CXXFLAGS)
|
||||
|
||||
udev_dir_default="$libdir/udev"
|
||||
AC_ARG_WITH(udev-dir,
|
||||
AS_HELP_STRING([--with-udev-dir=DIR],
|
||||
[udev base directory [[default=$udev_dir_default]]]),
|
||||
[],
|
||||
[with_udev_dir="yes"])
|
||||
AS_CASE($with_udev_dir,
|
||||
[no|""], [AC_MSG_ERROR([You must define a udev base directory])],
|
||||
[yes], [udevdir="$udev_dir_default"],
|
||||
[udevdir="$with_udev_dir"])
|
||||
UDEV_DIR=${udevdir}
|
||||
AC_SUBST(UDEV_DIR)
|
||||
|
||||
AC_ARG_ENABLE([documentation],
|
||||
[AC_HELP_STRING([--enable-documentation],
|
||||
[Enable building the documentation (default=auto)])],
|
||||
[build_documentation="$enableval"],
|
||||
[build_documentation="auto"])
|
||||
|
||||
if test "x$build_documentation" = "xyes" -o "x$build_documentation" = "xauto"; then
|
||||
AC_PATH_PROG(DOXYGEN, doxygen)
|
||||
if test "x$DOXYGEN" = "x"; then
|
||||
if test "x$build_documentation" = "xyes"; then
|
||||
AC_MSG_ERROR([Documentation build requested but doxygen not found. Install doxygen or disable the documentation using --disable-documentation])
|
||||
fi
|
||||
else
|
||||
AC_MSG_CHECKING([for compatible doxygen version])
|
||||
doxygen_version=`$DOXYGEN --version`
|
||||
AS_VERSION_COMPARE([$doxygen_version], [1.6.0],
|
||||
[AC_MSG_RESULT([no])
|
||||
DOXYGEN=""],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([yes])])
|
||||
if test "x$DOXYGEN" = "x" -a "x$build_documentation" = "xyes"; then
|
||||
AC_MSG_ERROR([Doxygen $doxygen_version too old. Doxygen 1.6+ required for documentation build. Install required doxygen version or disable the documentation using --disable-documentation])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(DOT, dot)
|
||||
if test "x$DOT" = "x"; then
|
||||
if test "x$build_documentation" = "xyes"; then
|
||||
AC_MSG_ERROR([Documentation build requested but graphviz's dot not found. Install graphviz or disable the documentation using --disable-documentation])
|
||||
fi
|
||||
else
|
||||
AC_MSG_CHECKING([for compatible dot version])
|
||||
dot_version=`$DOT -V 2>&1|$GREP -oP '(?<=version\W)@<:@0-9.@:>@*(?=\W(.*))'`
|
||||
AS_VERSION_COMPARE([$dot_version], [2.26.0],
|
||||
[AC_MSG_RESULT([no])
|
||||
DOT=""],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([yes])])
|
||||
if test "x$DOT" = "x" -a "x$build_documentation" = "xyes"; then
|
||||
AC_MSG_ERROR([Graphviz dot $dot_version too old. Graphviz 2.26+ required for documentation build. Install required graphviz version or disable the documentation using --disable-documentation])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$DOXYGEN" != "x" -a "x$DOT" != "x"; then
|
||||
build_documentation="yes"
|
||||
else
|
||||
build_documentation="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(event-gui,
|
||||
AS_HELP_STRING([--enable-event-gui], [Build the GUI event viewer (default=auto)]),
|
||||
[build_eventgui="$enableval"],
|
||||
[build_eventgui="auto"])
|
||||
PKG_CHECK_EXISTS([cairo glib-2.0 gtk+-3.0], [HAVE_GUILIBS="yes"], [HAVE_GUILIBS="no"])
|
||||
|
||||
if test "x$build_eventgui" = "xauto"; then
|
||||
build_eventgui="$HAVE_GUILIBS"
|
||||
fi
|
||||
if test "x$build_eventgui" = "xyes"; then
|
||||
PKG_CHECK_MODULES(CAIRO, [cairo])
|
||||
PKG_CHECK_MODULES(GTK, [glib-2.0 gtk+-3.0])
|
||||
fi
|
||||
AM_CONDITIONAL(BUILD_EVENTGUI, [test "x$build_eventgui" = "xyes"])
|
||||
|
||||
AC_ARG_ENABLE(tests,
|
||||
AS_HELP_STRING([--enable-tests], [Build the tests (default=auto)]),
|
||||
[build_tests="$enableval"],
|
||||
[build_tests="auto"])
|
||||
|
||||
PKG_CHECK_MODULES(CHECK, [check >= 0.9.10], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
|
||||
|
||||
if test "x$build_tests" = "xauto"; then
|
||||
build_tests="$HAVE_CHECK"
|
||||
fi
|
||||
if test "x$build_tests" = "xyes"; then
|
||||
if test "x$HAVE_CHECK" = "xno"; then
|
||||
AC_MSG_ERROR([Cannot build tests, check is missing])
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(VALGRIND, [valgrind])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(libwacom,
|
||||
AS_HELP_STRING([--enable-libwacom],
|
||||
[Use libwacom for tablet identification (default=enabled)]),
|
||||
[use_libwacom="$enableval"],
|
||||
[use_libwacom="yes"])
|
||||
if test "x$use_libwacom" = "xyes"; then
|
||||
PKG_CHECK_MODULES(LIBWACOM, [libwacom >= 0.12], [HAVE_LIBWACOM="yes"])
|
||||
AC_DEFINE(HAVE_LIBWACOM, 1, [Build with libwacom])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_VALGRIND, [test "x$VALGRIND" != "x"])
|
||||
AM_CONDITIONAL(BUILD_TESTS, [test "x$build_tests" = "xyes"])
|
||||
AM_CONDITIONAL(BUILD_DOCS, [test "x$build_documentation" = "xyes"])
|
||||
|
||||
# Used by the udev rules so we can use callouts during testing without
|
||||
# installing everything first. Default is the empty string so the installed
|
||||
# rule will use udev's default path. Override is in udev/Makefile.am
|
||||
AC_SUBST(UDEV_TEST_PATH, "")
|
||||
AC_PATH_PROG(SED, [sed])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
doc/Makefile
|
||||
doc/libinput.doxygen
|
||||
src/Makefile
|
||||
src/libinput.pc
|
||||
src/libinput-version.h
|
||||
test/Makefile
|
||||
tools/Makefile
|
||||
udev/Makefile
|
||||
udev/80-libinput-device-groups.rules
|
||||
udev/90-libinput-model-quirks.rules])
|
||||
AC_CONFIG_FILES([test/symbols-leak-test],
|
||||
[chmod +x test/symbols-leak-test])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_RESULT([
|
||||
Prefix ${prefix}
|
||||
udev base dir ${UDEV_DIR}
|
||||
|
||||
libwacom enabled ${use_libwacom}
|
||||
Build documentation ${build_documentation}
|
||||
Build tests ${build_tests}
|
||||
Tests use valgrind ${VALGRIND}
|
||||
Tests use libunwind ${HAVE_LIBUNWIND}
|
||||
Build GUI event tool ${build_eventgui}
|
||||
])
|
||||
86
doc/Makefile.am
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
EXTRA_DIST = \
|
||||
middle-button-emulation.svg \
|
||||
touchpad-tap-state-machine.svg \
|
||||
touchpad-softbutton-state-machine.svg
|
||||
|
||||
if BUILD_DOCS
|
||||
|
||||
noinst_DATA = html/index.html
|
||||
|
||||
header_files = \
|
||||
$(top_srcdir)/src/libinput.h \
|
||||
$(top_srcdir)/README.txt \
|
||||
$(srcdir)/absolute-axes.dox \
|
||||
$(srcdir)/clickpad-softbuttons.dox \
|
||||
$(srcdir)/device-configuration-via-udev.dox \
|
||||
$(srcdir)/faqs.dox \
|
||||
$(srcdir)/gestures.dox \
|
||||
$(srcdir)/normalization-of-relative-motion.dox \
|
||||
$(srcdir)/palm-detection.dox \
|
||||
$(srcdir)/page-hierarchy.dox \
|
||||
$(srcdir)/pointer-acceleration.dox \
|
||||
$(srcdir)/reporting-bugs.dox \
|
||||
$(srcdir)/scrolling.dox \
|
||||
$(srcdir)/seats.dox \
|
||||
$(srcdir)/t440-support.dox \
|
||||
$(srcdir)/tablet-support.dox \
|
||||
$(srcdir)/tapping.dox \
|
||||
$(srcdir)/test-suite.dox \
|
||||
$(srcdir)/tools.dox \
|
||||
$(srcdir)/touchpad-jumping-cursors.dox \
|
||||
$(srcdir)/touchpads.dox
|
||||
|
||||
diagram_files = \
|
||||
$(srcdir)/dot/seats-sketch.gv \
|
||||
$(srcdir)/dot/seats-sketch-libinput.gv \
|
||||
$(srcdir)/dot/libinput-stack-wayland.gv \
|
||||
$(srcdir)/dot/libinput-stack-xorg.gv \
|
||||
$(srcdir)/dot/libinput-stack-gnome.gv \
|
||||
$(srcdir)/dot/evemu.gv \
|
||||
$(srcdir)/svg/software-buttons.svg \
|
||||
$(srcdir)/svg/clickfinger.svg \
|
||||
$(srcdir)/svg/button-scrolling.svg \
|
||||
$(srcdir)/svg/edge-scrolling.svg \
|
||||
$(srcdir)/svg/palm-detection.svg \
|
||||
$(srcdir)/svg/pinch-gestures.svg \
|
||||
$(srcdir)/svg/ptraccel-linear.svg \
|
||||
$(srcdir)/svg/ptraccel-low-dpi.svg \
|
||||
$(srcdir)/svg/ptraccel-touchpad.svg \
|
||||
$(srcdir)/svg/ptraccel-trackpoint.svg \
|
||||
$(srcdir)/svg/swipe-gestures.svg \
|
||||
$(srcdir)/svg/tap-n-drag.svg \
|
||||
$(srcdir)/svg/thumb-detection.svg \
|
||||
$(srcdir)/svg/top-software-buttons.svg \
|
||||
$(srcdir)/svg/touchscreen-gestures.svg \
|
||||
$(srcdir)/svg/twofinger-scrolling.svg
|
||||
|
||||
style_files = \
|
||||
style/header.html \
|
||||
style/footer.html \
|
||||
style/customdoxygen.css \
|
||||
style/bootstrap.css
|
||||
|
||||
html/index.html: libinput.doxygen $(header_files) $(diagram_files) $(style_files)
|
||||
$(AM_V_GEN)(cat $<; \
|
||||
echo "INPUT = $(header_files)"; \
|
||||
) | $(DOXYGEN) -
|
||||
|
||||
clean-local:
|
||||
$(AM_V_at)rm -rf html
|
||||
|
||||
doc_src= $(shell find html -type f -printf "html/%P\n" 2>/dev/null)
|
||||
EXTRA_DIST += $(builddir)/html/index.html \
|
||||
$(doc_src) \
|
||||
$(diagram_files) \
|
||||
$(header_files) \
|
||||
$(style_files)
|
||||
endif
|
||||
|
||||
# make sure doc was built before running dist
|
||||
dist-hook:
|
||||
@test -f $(distdir)/html/index.html || (\
|
||||
echo "******************************************************" && \
|
||||
echo "Couldn't find documentation files, refusing make dist." && \
|
||||
echo "Install doxygen to build documentation for tarball." && \
|
||||
echo "******************************************************" && \
|
||||
test )
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
.. _absolute_axes:
|
||||
|
||||
==============================================================================
|
||||
Absolute axes
|
||||
==============================================================================
|
||||
/**
|
||||
@page absolute_axes Absolute axes
|
||||
|
||||
Devices with absolute axes are those that send positioning data for an axis in
|
||||
a device-specific coordinate range, defined by a minimum and a maximum value.
|
||||
|
|
@ -13,7 +10,7 @@ libinput supports three types of devices with absolute axes:
|
|||
|
||||
- multi-touch screens
|
||||
- single-touch screens
|
||||
- :ref:`graphics tablets <tablet-support>`
|
||||
- @ref tablet-support "graphics tablets"
|
||||
|
||||
Touchpads are technically absolute devices but libinput converts the axis values
|
||||
to directional motion and posts events as relative events. Touchpads do not count
|
||||
|
|
@ -22,15 +19,11 @@ as absolute devices in libinput.
|
|||
For all absolute devices in libinput, the default unit for x/y coordinates is
|
||||
in mm off the top left corner on the device, or more specifically off the
|
||||
device's sensor. If the device is physically rotated from its natural
|
||||
position and this rotation was communicated to libinput (e.g. by setting
|
||||
the device left-handed),
|
||||
the coordinate origin is the top left corner in the current rotation.
|
||||
position and this rotation was communicated to libinput (e.g.
|
||||
@ref libinput_device_config_left_handed_set "by setting the device left-handed"),
|
||||
the coordinate origin is the top left corner of in the current rotation.
|
||||
|
||||
.. _absolute_axes_handling:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Handling of absolute coordinates
|
||||
------------------------------------------------------------------------------
|
||||
@section absolute_axes_handling Handling of absolute coordinates
|
||||
|
||||
In most use-cases, absolute input devices are mapped to a single screen. For
|
||||
direct input devices such as touchscreens the aspect ratio of the screen and
|
||||
|
|
@ -38,8 +31,8 @@ the device match. Mapping the input device position to the output position is
|
|||
thus a simple mapping between two coordinates. libinput provides the API for
|
||||
this with
|
||||
|
||||
- **libinput_event_pointer_get_absolute_x_transformed()** for pointer events
|
||||
- **libinput_event_touch_get_x_transformed()** for touch events
|
||||
- libinput_event_pointer_get_absolute_x_transformed() for pointer events
|
||||
- libinput_event_touch_get_x_transformed() for touch events
|
||||
|
||||
libinput's API only provides the call to map into a single coordinate range.
|
||||
If the coordinate range has an offset, the compositor is responsible for
|
||||
|
|
@ -47,98 +40,97 @@ applying that offset after the mapping. For example, if the device is mapped
|
|||
to the right of two outputs, add the output offset to the transformed
|
||||
coordinate.
|
||||
|
||||
.. _absolute_axes_nores:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Devices without x/y resolution
|
||||
------------------------------------------------------------------------------
|
||||
@section absolute_axes_nores Devices without x/y resolution
|
||||
|
||||
An absolute device that does not provide a valid resolution is considered
|
||||
buggy and must be fixed in the kernel. Some touchpad devices do not
|
||||
provide resolution, those devices are correctly handled within libinput
|
||||
(touchpads are not absolute devices, as mentioned above).
|
||||
|
||||
.. _calibration:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Calibration of absolute devices
|
||||
------------------------------------------------------------------------------
|
||||
@section calibration Calibration of absolute devices
|
||||
|
||||
Absolute devices may require calibration to map precisely into the output
|
||||
range required. This is done by setting a transformation matrix, see
|
||||
**libinput_device_config_calibration_set_matrix()** which is applied to
|
||||
libinput_device_config_calibration_set_matrix() which is applied to
|
||||
each input coordinate.
|
||||
|
||||
.. math::
|
||||
\begin{pmatrix}
|
||||
cos\theta & -sin\theta & xoff \\
|
||||
sin\theta & cos\theta & yoff \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix} \begin{pmatrix}
|
||||
x \\ y \\ 1
|
||||
\end{pmatrix}
|
||||
@f[
|
||||
\begin{pmatrix}
|
||||
cos\theta & -sin\theta & xoff \\
|
||||
sin\theta & cos\theta & yoff \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix} \begin{pmatrix}
|
||||
x \\ y \\ 1
|
||||
\end{pmatrix}
|
||||
@f]
|
||||
|
||||
:math:`\theta` is the rotation angle. The offsets :math:`xoff` and :math:`yoff` are
|
||||
specified in device dimensions, i.e. a value of 1 equals one device width or
|
||||
height. Note that rotation applies to the device's origin, rotation usually
|
||||
requires an offset to move the coordinates back into the original range.
|
||||
@f$\theta@f$ is the rotation angle. The offsets @f$xoff@f$ and @f$yoff@f$ are
|
||||
specified in device dimensions, i.e. a value of 1 equals one device width
|
||||
or height. Note that rotation applies to the device's origin, rotation
|
||||
usually requires an offset to move the coordinates back into the original
|
||||
range.
|
||||
|
||||
The most common matrices are:
|
||||
|
||||
- 90 degree clockwise:
|
||||
.. math::
|
||||
\begin{pmatrix}
|
||||
0 & -1 & 1 \\
|
||||
1 & 0 & 0 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
\begin{pmatrix}
|
||||
0 & -1 & 1 \\
|
||||
1 & 0 & 0 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
|
||||
- 180 degree clockwise:
|
||||
.. math::
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 1 \\
|
||||
0 & -1 & 1 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 1 \\
|
||||
0 & -1 & 1 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
|
||||
- 270 degree clockwise:
|
||||
.. math::
|
||||
\begin{pmatrix}
|
||||
0 & 1 & 0 \\
|
||||
-1 & 0 & 1 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
\begin{pmatrix}
|
||||
0 & 1 & 0 \\
|
||||
-1 & 0 & 1 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
|
||||
- reflection along y axis:
|
||||
.. math::
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 1 \\
|
||||
1 & 0 & 0 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 1 \\
|
||||
1 & 0 & 0 \\
|
||||
0 & 0 & 1
|
||||
\end{pmatrix}
|
||||
@f$
|
||||
|
||||
See Wikipedia's
|
||||
`Transformation Matrix article <http://en.wikipedia.org/wiki/Transformation_matrix>`_
|
||||
for more information on the matrix maths. See
|
||||
**libinput_device_config_calibration_get_default_matrix()** for how these
|
||||
<a href="http://en.wikipedia.org/wiki/Transformation_matrix">Transformation
|
||||
Matrix article</a> for more information on the matrix maths. See
|
||||
libinput_device_config_calibration_get_default_matrix() for how these
|
||||
matrices must be supplied to libinput.
|
||||
|
||||
Once applied, any x and y axis value has the calibration applied before it
|
||||
is made available to the caller. libinput does not provide access to the
|
||||
raw coordinates before the calibration is applied.
|
||||
|
||||
.. _absolute_axes_nonorm:
|
||||
@section absolute_axes_nonorm Why x/y coordinates are not normalized
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Why x/y coordinates are not normalized
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
x/y are not given in :ref:`normalized coordinates <motion_normalization>`
|
||||
x/y are not given in @ref motion_normalization "normalized coordinates"
|
||||
([0..1]) for one simple reason: the aspect ratio of virtually all current
|
||||
devices is something other than 1:1. A normalized axes thus is only useful to
|
||||
determine that the stylus is e.g. at 78% from the left, 34% from the top of
|
||||
the device. Without knowing the per-axis resolution, these numbers are
|
||||
meaningless. Worse, calculation based on previous coordinates is simply wrong:
|
||||
a movement from 0/0 to 50%/50% is not a 45-degree line.
|
||||
a movement from 0/0 to 50%/50% is not a 45% degree line.
|
||||
|
||||
This could be alleviated by providing resolution and information about the
|
||||
aspect ratio to the caller. Which shifts processing and likely errors into the
|
||||
caller for little benefit. Providing the x/y axes in mm from the outset
|
||||
removes these errors.
|
||||
|
||||
*/
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
PROJECT_NAME = @PACKAGE_NAME@
|
||||
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
PROJECT_BRIEF = "A wrapper library for input devices"
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
TAB_SIZE = 8
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_STATIC = YES
|
||||
MAX_INITIALIZER_LINES = 0
|
||||
WARNINGS = YES
|
||||
QUIET = YES
|
||||
INPUT = "@builddir@"
|
||||
IMAGE_PATH = "@builddir@"
|
||||
OUTPUT_DIRECTORY = doc
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
SEARCHENGINE = NO
|
||||
USE_MATHJAX = YES
|
||||
MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
|
||||
GENERATE_LATEX = NO
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
|
||||
LIBINPUT_ATTRIBUTE_DEPRECATED
|
||||
DOTFILE_DIRS = "@builddir@"
|
||||
EXAMPLE_PATH = "@builddir@"
|
||||
SHOW_NAMESPACES = NO
|
||||
HAVE_DOT = YES
|
||||
|
||||
HTML_HEADER = "@builddir@/header.html"
|
||||
HTML_FOOTER = "@builddir@/footer.html"
|
||||
HTML_EXTRA_STYLESHEET = "@builddir@/bootstrap.css" \
|
||||
"@builddir@/customdoxygen.css" \
|
||||
"@builddir@/libinputdoxygen.css"
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
/**
|
||||
@mainpage
|
||||
|
||||
This is the libinput API reference.
|
||||
|
||||
This documentation is aimed at developers of Wayland compositors. User
|
||||
documentation is available
|
||||
[here](https://wayland.freedesktop.org/libinput/doc/latest).
|
||||
|
||||
@section concepts Concepts
|
||||
|
||||
@subsection concepts_initialization Initialization of a libinput context
|
||||
|
||||
libinput provides two different backends:
|
||||
- a @ref libinput_udev_create_context "udev backend" where notifications
|
||||
about new and removed devices are provided by udev, and
|
||||
- a @ref libinput_path_create_context "path backend" where
|
||||
@ref libinput_path_add_device "device addition" and
|
||||
@ref libinput_path_remove_device "device removal" need to be handled by
|
||||
the caller.
|
||||
|
||||
See section @ref base for information about initializing a libinput context.
|
||||
|
||||
@subsection concepts_events Monitoring for events
|
||||
|
||||
libinput exposes a single @ref libinput_get_fd "file descriptor" to the
|
||||
caller. This file descriptor should be monitored by the caller, whenever
|
||||
data is available the caller **must** immediately call libinput_dispatch().
|
||||
Failure to do so will result in erroneous behavior.
|
||||
|
||||
libinput_dispatch() may result in one or more events being available to the
|
||||
caller. After libinput_dispatch() a caller **should** call
|
||||
libinput_get_event() to retrieve and process this event. Whenever
|
||||
libinput_get_event() returns `NULL`, no further events are available.
|
||||
|
||||
See section @ref event for more information about events.
|
||||
|
||||
@subsection concepts_seats Device grouping into seats
|
||||
|
||||
All devices are grouped into physical and logical seats. Button and key
|
||||
states are available per-device and per-seat. See @ref seat for more
|
||||
information.
|
||||
|
||||
@subsection concepts_devices Device capabilities
|
||||
|
||||
libinput does not use device types. All devices have @ref
|
||||
libinput_device_has_capability "capabilities" that define which events may
|
||||
be generated. See @ref device for more information about devices.
|
||||
|
||||
Specific event types include:
|
||||
- @ref event_keyboard
|
||||
- @ref event_pointer
|
||||
- @ref event_touch
|
||||
- @ref event_gesture
|
||||
- @ref event_tablet
|
||||
- @ref event_tablet_pad
|
||||
- @ref event_switch
|
||||
|
||||
|
||||
@subsection concepts_configuration Device configuration
|
||||
|
||||
libinput relies on the caller for device configuration. See
|
||||
@ref config for more information.
|
||||
|
||||
@subsection example An example libinput program
|
||||
|
||||
The simplest libinput program looks like this:
|
||||
|
||||
@code
|
||||
static int open_restricted(const char *path, int flags, void *user_data)
|
||||
{
|
||||
int fd = open(path, flags);
|
||||
return fd < 0 ? -errno : fd;
|
||||
}
|
||||
|
||||
static void close_restricted(int fd, void *user_data)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
const static struct libinput_interface interface = {
|
||||
.open_restricted = open_restricted,
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
|
||||
int main(void) {
|
||||
struct libinput *li;
|
||||
struct libinput_event *event;
|
||||
|
||||
li = libinput_udev_create_context(&interface, NULL, udev);
|
||||
libinput_udev_assign_seat(li, "seat0");
|
||||
libinput_dispatch(li);
|
||||
|
||||
while ((event = libinput_get_event(li)) != NULL) {
|
||||
|
||||
// handle the event here
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_dispatch(li);
|
||||
}
|
||||
|
||||
libinput_unref(li);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@endcode
|
||||
|
||||
@section building_against Building against libinput
|
||||
|
||||
libinput provides a
|
||||
[pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) file.
|
||||
Software that uses libinput should use pkg-config and the
|
||||
`PKG_CHECK_MODULES` autoconf macro.
|
||||
Otherwise, the most rudimentary way to compile and link a program against
|
||||
libinput is:
|
||||
|
||||
@verbatim
|
||||
gcc -o myprogram myprogram.c `pkg-config --cflags --libs libinput`
|
||||
@endverbatim
|
||||
|
||||
For further information on using pkgconfig see the pkg-config documentation.
|
||||
|
||||
@section stability Backwards-compatibility
|
||||
|
||||
libinput promises backwards-compatibility across all the 1.x.y version. An
|
||||
application built against libinput 1.x.y will work with any future 1.*.*
|
||||
release.
|
||||
|
||||
@section About
|
||||
|
||||
Documentation generated from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
||||
|
||||
*/
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
prg_install = find_program('install')
|
||||
|
||||
doxygen = find_program('doxygen', required : false)
|
||||
if not doxygen.found()
|
||||
error('Program "doxygen" not found or not executable. Try building with -Ddocumentation=false')
|
||||
endif
|
||||
dot = find_program('dot', required : false)
|
||||
if not dot.found()
|
||||
error('Program "dot" not found or not executable. Try building with -Ddocumentation=false')
|
||||
endif
|
||||
|
||||
mainpage = vcs_tag(command : ['git', 'log', '-1', '--format=%h'],
|
||||
fallback : 'unknown',
|
||||
input : 'mainpage.dox',
|
||||
output : 'mainpage.dox',
|
||||
replace_string: '__GIT_VERSION__')
|
||||
|
||||
src_doxygen = files(
|
||||
# source files
|
||||
'../../src/libinput.h',
|
||||
# style files
|
||||
'style/header.html',
|
||||
'style/footer.html',
|
||||
'style/customdoxygen.css',
|
||||
'style/bootstrap.css',
|
||||
'style/libinputdoxygen.css',
|
||||
)
|
||||
|
||||
doxyfiles = []
|
||||
foreach f : src_doxygen
|
||||
df = configure_file(input: f,
|
||||
output: '@PLAINNAME@',
|
||||
copy : true)
|
||||
doxyfiles += [ df ]
|
||||
endforeach
|
||||
|
||||
doc_config = configuration_data()
|
||||
doc_config.set('PACKAGE_NAME', meson.project_name())
|
||||
doc_config.set('PACKAGE_VERSION', meson.project_version())
|
||||
doc_config.set('builddir', meson.current_build_dir())
|
||||
|
||||
doxyfile = configure_file(input : 'libinput.doxygen.in',
|
||||
output : 'libinput.doxygen',
|
||||
configuration : doc_config)
|
||||
|
||||
custom_target('doxygen',
|
||||
input : [ doxyfiles, doxyfile, mainpage ] + src_doxygen,
|
||||
output : [ 'html' ],
|
||||
command : [ doxygen, doxyfile ],
|
||||
install : false,
|
||||
depends: [ mainpage ],
|
||||
build_by_default : true)
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/**
|
||||
|
||||
@page Tablets
|
||||
|
||||
- @subpage tablet serial numbers
|
||||
|
||||
*/
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
@import url("https://fonts.googleapis.com/css?family=Roboto+Mono");
|
||||
|
||||
dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title .ingroups {
|
||||
font-size: 50%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 150%;
|
||||
color: #354C7B;
|
||||
background: none;
|
||||
border-bottom: 1px solid #879ECB;
|
||||
font-size: 150%;
|
||||
font-weight: normal;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
padding-left: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 120%;
|
||||
color: #354C7B;
|
||||
background: none;
|
||||
border-bottom: 1px solid #879ECB;
|
||||
font-size: 150%;
|
||||
font-weight: normal;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
padding-left: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sm-dox li {
|
||||
float:left;
|
||||
border-top: 0;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.sm li, .sm a {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sm, .sm ul, .sm li {
|
||||
list-style: none;
|
||||
display: block;
|
||||
line-height: normal;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.sm, .sm *, .sm *::before, .sm *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#main-nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
/* Main menu sub-items like file-list, etc */
|
||||
#main-menu li ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paramname {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.memtitle {
|
||||
background-image: none;
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
.headertitle {
|
||||
background-image: none;
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
div.header {
|
||||
border: none;
|
||||
}
|
||||
|
||||
td.fieldname {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
|
||||
.fieldtable th {
|
||||
background-image: none;
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
body {
|
||||
letter-spacing: 0px;
|
||||
}
|
||||
|
||||
.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams {
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2873b0;
|
||||
|
||||
}
|
||||
|
||||
.navpath ul {
|
||||
background-image: none;
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 97 KiB |
|
|
@ -1,50 +0,0 @@
|
|||
# Source for the button debouncing wave diagram
|
||||
# Paste into http://wavedrom.com/editor.html
|
||||
{signal: [
|
||||
{name:'current mode', wave: '3............', data: ['normal button press and release']},
|
||||
{name:'physical button', wave: '01......0....'},
|
||||
{name:'application ', wave: '01......0....'},
|
||||
{},
|
||||
['bounce mode',
|
||||
{name:'current mode', wave: '4............', data: ['debounced button press']},
|
||||
{name:'physical button', wave: '0101...0.....'},
|
||||
{name: 'timeouts', wave: '01...0.1...0.'},
|
||||
{name:'application ', wave: '01.....0.....'},
|
||||
{},
|
||||
{name:'current mode', wave: '4............', data: ['debounced button release']},
|
||||
{name:'physical button', wave: '1...010......'},
|
||||
{name: 'timeouts', wave: '0...1...0....'},
|
||||
{name:'application ', wave: '1...0........'},
|
||||
{},
|
||||
{name:'current mode', wave: '5............', data: ['delayed button press']},
|
||||
{name:'physical button', wave: '1...01.......'},
|
||||
{name: 'timeouts', wave: '0...1...0....'},
|
||||
{name:'application ', wave: '1...0...1....'},
|
||||
{},
|
||||
{name:'current mode', wave: '5............', data: ['delayed button release']},
|
||||
{name:'physical button', wave: '0...10.......'},
|
||||
{name: 'timeouts', wave: '0...1...0....'},
|
||||
{name:'application ', wave: '0...1...0....'},
|
||||
],
|
||||
{},
|
||||
['spurious mode',
|
||||
{name:'current mode', wave: '3............', data: ['first spurious button release ']},
|
||||
{name:'physical button', wave: '1.......01...'},
|
||||
{name:'application ', wave: '1.......01...'},
|
||||
{},
|
||||
{name:'current mode', wave: '3............', data: ['later spurious button release ']},
|
||||
{name:'physical button', wave: '1....01......'},
|
||||
{name: 'timeouts', wave: '0....1..0....'},
|
||||
{name:'application ', wave: '1............'},
|
||||
{},
|
||||
{name:'current mode', wave: '3............', data: ['delayed release in spurious mode ']},
|
||||
{name:'physical button', wave: '1....0.......'},
|
||||
{name: 'timeouts', wave: '0....1..0....'},
|
||||
{name:'application ', wave: '1.......0....'}
|
||||
],
|
||||
|
||||
],
|
||||
head:{
|
||||
text:'Button Debouncing Scenarios',
|
||||
},
|
||||
}
|
||||
99
doc/clickpad-softbuttons.dox
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
@page clickpad_softbuttons Clickpad software button behavior
|
||||
|
||||
Clickpad is the name given to touchpads without physical buttons below the
|
||||
touchpad. Instead, the whole touchpad acts as a button and left or right
|
||||
button clicks are distinguished by the location and/or number of fingers on
|
||||
the touchpad. <a href="http://www.synaptics.com/en/clickpad.php">"ClickPad" is
|
||||
a trademark by Synaptics Inc.</a> but for simplicity we refer to any
|
||||
touchpad with the above feature as Clickpad, regardless of the manufacturer.
|
||||
|
||||
A clickpad is always marked with the <a
|
||||
href="https://www.kernel.org/doc/Documentation/input/event-codes.txt">INPUT_PROP_BUTTONPAD</a> property.
|
||||
To perform a right-click on a Clickpad, libinput provides @ref
|
||||
software_buttons and @ref clickfinger.
|
||||
|
||||
In the page below, the term "click" shall refer to a physical button press
|
||||
and/or release of the touchpad, the term "button event" refers to the events
|
||||
generated by libinput and passed to the caller in response to a click.
|
||||
|
||||
@section software_buttons Software button areas
|
||||
|
||||
On most clickpads, this is the default behavior. The bottom of the touchpad
|
||||
is split into three distinct areas generate left, middle or right button
|
||||
events on click. The height of the button area depends on the hardware but
|
||||
is usually around 10mm.
|
||||
|
||||
Left, right and middle button events can be triggered as follows:
|
||||
- if a finger is in the main area or the left button area, a click generates
|
||||
left button events.
|
||||
- if a finger is in the right area, a click generates right button events.
|
||||
- if a finger is in the middle area, a click generates middle button events.
|
||||
|
||||
The middle button is always centered on the touchpad and smaller in size
|
||||
than the left or right button. The actual size is device-dependent though as
|
||||
many touchpads do not have visible markings for the middle button the exact
|
||||
location of the button is not visibly obvious.
|
||||
|
||||
@image html software-buttons.svg "Left, right and middle-button click with software button areas"
|
||||
|
||||
If fingers are down in the main area in addition to fingers in the
|
||||
left or right button area, those fingers are are ignored.
|
||||
A release event always releases the buttons logically down, regardless of
|
||||
the current finger position
|
||||
|
||||
The movement of a finger can alter the button area behavior:
|
||||
- if a finger starts in the main area and moves into the software button
|
||||
area, the software buttons do not apply to that finger
|
||||
- a finger in the software button area does not move the pointer
|
||||
- if a finger moves out out of the button area it will control the pointer
|
||||
if it's the first finger in the main area
|
||||
- once a finger has moved out of the button area, it cannot move back in and
|
||||
trigger a right or middle button event
|
||||
|
||||
On some touchpads, notably the 2015 Lenovo X1 Carbon 3rd series, the very
|
||||
bottom end of the touchpad is outside of the sensor range but it is possible
|
||||
to trigger a physical click there. To libinput, the click merely shows up as
|
||||
a left button click without any positional finger data and it is
|
||||
impossible to determine whether it is a left or a right click. libinput
|
||||
ignores such button clicks, this behavior is intentional.
|
||||
|
||||
@section clickfinger Clickfinger behavior
|
||||
|
||||
This is the default behavior on Apple touchpads.
|
||||
Here, a left, right, middle button event is generated when one, two, or
|
||||
three fingers are held down on the touchpad when a physical click is
|
||||
generated. The location of the fingers does not matter and there are no
|
||||
software-defined button areas.
|
||||
|
||||
@image html clickfinger.svg "One, two and three-finger click with Clickfinger behavior"
|
||||
|
||||
On some touchpads, libinput imposes a limit on how the fingers may be placed
|
||||
on the touchpad. In the most common use-case this allows for a user to
|
||||
trigger a click with the thumb while leaving the pointer-moving finger on
|
||||
the touchpad.
|
||||
|
||||
@image html clickfinger-distance.svg "Illustration of the distance detection algorithm"
|
||||
|
||||
In the illustration above the red area marks the proximity area around the
|
||||
first finger. Since the thumb is outside of that area libinput considers the
|
||||
click a single-finger click rather than a two-finger click.
|
||||
|
||||
Clickfinger configuration can be enabled through the
|
||||
libinput_device_config_click_set_method() call. If clickfingers are
|
||||
enabled on a touchpad with top software buttons, the top area will keep
|
||||
acting as softbuttons for use with the trackpoint. Clickfingers will be used
|
||||
everywhere else on the touchpad.
|
||||
|
||||
@section special_clickpads Special Clickpads
|
||||
|
||||
The Lenovo *40 series laptops have a clickpad that provides two software button sections, one at
|
||||
the top and one at the bottom. See @ref t440_support "Lenovo *40 series touchpad support"
|
||||
for details on the top software button.
|
||||
|
||||
Some Clickpads, notably some Cypress ones, perform right button detection in
|
||||
firmware and appear to userspace as if the touchpad had physical buttons.
|
||||
While physically clickpads, these are not handled by the software and
|
||||
treated like traditional touchpads.
|
||||
|
||||
*/
|
||||
138
doc/device-configuration-via-udev.dox
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
@page udev_config Static device configuration via udev
|
||||
|
||||
libinput supports some static configuration through udev properties.
|
||||
These properties are read when the device is initially added
|
||||
to libinput's device list, i.e. before the @ref
|
||||
LIBINPUT_EVENT_DEVICE_ADDED event is generated.
|
||||
|
||||
The following udev properties are supported:
|
||||
<dl>
|
||||
<dt>LIBINPUT_CALIBRATION_MATRIX</dt>
|
||||
<dd>Sets the calibration matrix, see
|
||||
libinput_device_config_calibration_get_default_matrix(). If unset,
|
||||
defaults to the identity matrix.
|
||||
|
||||
The udev property is parsed as 6 floating point numbers separated by a
|
||||
single space each (scanf(3) format "%f %f %f %f %f %f").
|
||||
The 6 values represent the first two rows of the calibration matrix as
|
||||
described in libinput_device_config_calibration_set_matrix().
|
||||
|
||||
Example values are:
|
||||
@code
|
||||
ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0" # default
|
||||
ENV{LIBINPUT_CALIBRATION_MATRIX}="0 -1 1 1 0 0" # 90 degree clockwise
|
||||
ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 0 -1 1" # 180 degree clockwise
|
||||
ENV{LIBINPUT_CALIBRATION_MATRIX}="0 1 0 -1 0 1" # 270 degree clockwise
|
||||
ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 1 0 0" # reflect along y axis
|
||||
@endcode
|
||||
</dd>
|
||||
<dt>LIBINPUT_DEVICE_GROUP</dt>
|
||||
<dd>A string identifying the @ref libinput_device_group for this device. Two
|
||||
devices with the same property value are grouped into the same device group,
|
||||
the value itself is irrelevant otherwise.
|
||||
</dd>
|
||||
<dt>ID_SEAT</dt>
|
||||
<dd>Assigns the physical seat for this device. See
|
||||
libinput_seat_get_physical_name(). Defaults to "seat0".</dd>
|
||||
<dt>ID_INPUT</dt>
|
||||
<dd>If this property is set, the device is considered an input device. Any
|
||||
device with this property missing will be ignored, see @ref
|
||||
udev_device_type.</dt>
|
||||
</dd>
|
||||
<dt>ID_INPUT_KEYBOARD, ID_INPUT_KEY, ID_INPUT_MOUSE, ID_INPUT_TOUCHPAD,
|
||||
ID_INPUT_TOUCHSCREEN, ID_INPUT_TABLET, ID_INPUT_JOYSTICK,
|
||||
ID_INPUT_ACCELEROMETER</dt>
|
||||
<dd>If any of the above is set, libinput initializes the device as the given
|
||||
type, see @ref udev_device_type. Note that for historical reasons more than
|
||||
one of these may be set at any time, libinput will select only one of these
|
||||
to determine the device type. To ensure libinput selects the correct device
|
||||
type, only set one of them.</dd>
|
||||
<dt>WL_SEAT</dt>
|
||||
<dd>Assigns the logical seat for this device. See
|
||||
libinput_seat_get_logical_name()
|
||||
context. Defaults to "default".</dd>
|
||||
<dt>MOUSE_DPI</dt>
|
||||
<dd>HW resolution and sampling frequency of a relative pointer device.
|
||||
See @ref motion_normalization for details.
|
||||
</dd>
|
||||
<dt>MOUSE_WHEEL_CLICK_ANGLE</dt>
|
||||
<dd>The angle in degrees for each click on a mouse wheel. See
|
||||
libinput_pointer_get_axis_source() for details.
|
||||
</dd>
|
||||
<dt>POINTINGSTICK_CONST_ACCEL</dt>
|
||||
<dd>A constant (linear) acceleration factor to apply to pointingstick deltas
|
||||
to normalize them.
|
||||
<dt>LIBINPUT_MODEL_*</dt>
|
||||
<dd><b>This prefix is reserved as private API, do not use.</b> See @ref
|
||||
model_specific_configuration for details.
|
||||
</dd>
|
||||
<dt>LIBINPUT_ATTR_*</dt>
|
||||
<dd><b>This prefix is reserved as private API, do not use.</b> See @ref
|
||||
model_specific_configuration for details.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
Below is an example udev rule to assign "seat1" to a device from vendor
|
||||
0x012a with the model ID of 0x034b.
|
||||
@code
|
||||
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||
ENV{ID_MODEL_ID}=="034b", ENV{ID_SEAT}="seat1"
|
||||
@endcode
|
||||
|
||||
|
||||
@section udev_device_type Device type assignment via udev
|
||||
|
||||
libinput requires the <b>ID_INPUT</b> property to be set on a device,
|
||||
otherwise the device will be ignored. In addition, one of <b>
|
||||
ID_INPUT_KEYBOARD, ID_INPUT_KEY, ID_INPUT_MOUSE, ID_INPUT_TOUCHPAD,
|
||||
ID_INPUT_TOUCHSCREEN, ID_INPUT_TABLET, ID_INPUT_JOYSTICK,
|
||||
ID_INPUT_ACCELEROMETER</b> must be set on the device to determine the
|
||||
device type. The usual error handling applies within libinput and a device
|
||||
type label does not guarantee that the device is initialized by libinput.
|
||||
If a device fails to meet the requirements for a device type (e.g. a keyboard
|
||||
labelled as touchpad) the device will not be available through libinput.
|
||||
|
||||
Only one device type should be set per device at a type, though libinput can
|
||||
handle some combinations for historical reasons.
|
||||
|
||||
Below is an example udev rule to remove an <b>ID_INPUT_TOUCHPAD</b> setting
|
||||
and change it into an <b>ID_INPUT_TABLET</b> setting. This rule would apply
|
||||
for a device with the vendor/model ID of 012a/034b.
|
||||
|
||||
@code
|
||||
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||
ENV{ID_MODEL_ID}=="034b", ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
|
||||
@endcode
|
||||
|
||||
@section model_specific_configuration Model-specific configuration
|
||||
|
||||
libinput reserves the property prefixes <b>LIBINPUT_MODEL_</b> and
|
||||
<b>LIBINPUT_ATTR_*</b> for model-specific configuration. <b>These prefixes
|
||||
are reserved as private API, do not use.</b>
|
||||
|
||||
The effect of these properties may be to enable or disable certain
|
||||
features on a specific device or set of devices, to change configuration
|
||||
defaults or any other reason. The effects of setting these properties, the
|
||||
format of the property and the value of the property are subject to change
|
||||
at any time.
|
||||
|
||||
@subsection model_specific_configuration_x220fw81 Lenovo x220 with touchpad firmware v8.1
|
||||
|
||||
The property <b>LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81</b> may be set by a
|
||||
user in a local hwdb file. This property designates the touchpad on a Lenovo
|
||||
x220 with a touchpad firmware version 8.1. When this firmware version is
|
||||
installed, the touchpad is imprecise. The touchpad device does not send
|
||||
continuos x/y axis position updates, a behavior also observed on its
|
||||
successor model, the Lenovo x230 which has the same firmware version. If the
|
||||
above property is set, libinput adjusts its behavior to better suit this
|
||||
particular model.
|
||||
|
||||
The touchpad firmware version cannot be detected automatically by libinput,
|
||||
local configuration is required to set this property. Refer to the libinput
|
||||
model quirks hwdb for instructions.
|
||||
|
||||
This property must not be used for any other purpose, no specific behavior
|
||||
is guaranteed.
|
||||
|
||||
*/
|
||||
|
|
@ -23,7 +23,7 @@ digraph stack
|
|||
gsettings
|
||||
}
|
||||
|
||||
gsd [label="mutter"];
|
||||
gsd [label="gnome-settings-daemon"];
|
||||
|
||||
gsd -> gsettings
|
||||
gsd -> xserver
|
||||
17
doc/dot/libinput-stack-wayland.gv
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
digraph stack
|
||||
{
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
kernel [label="Kernel"];
|
||||
|
||||
libinput;
|
||||
compositor [label="Wayland Compositor"];
|
||||
client [label="Wayland Client"];
|
||||
|
||||
kernel -> libinput
|
||||
libinput -> compositor
|
||||
compositor -> client
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
digraph stack
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
|
|
@ -9,12 +8,12 @@ digraph stack
|
|||
kernel [label="Kernel"];
|
||||
|
||||
libinput;
|
||||
xf86libinput [label="xf86-input-libinput"];
|
||||
xserver [label="X Server"];
|
||||
record [label="libinput record"];
|
||||
client [label="X11 client"];
|
||||
|
||||
kernel -> libinput
|
||||
libinput -> xserver
|
||||
|
||||
kernel -> record;
|
||||
record -> stdout
|
||||
libinput -> xf86libinput
|
||||
xf86libinput -> xserver
|
||||
xserver -> client
|
||||
}
|
||||
57
doc/faqs.dox
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
@page faq FAQs - Frequently Asked Questions
|
||||
|
||||
Frequently asked questions about libinput.
|
||||
|
||||
@section faq_fast_mouse My mouse moves too fast, even at the slowest setting
|
||||
|
||||
This is a symptom of high-dpi mice (greater than 1000dpi). These devices
|
||||
need a udev hwdb entry to normalize their motion. See @ref
|
||||
motion_normalization for a detailed explanation.
|
||||
|
||||
@section faq_kinetic_scrolling Kinetic scrolling does not work
|
||||
|
||||
The X.Org synaptics driver implemented kinetic scrolling in the driver. It
|
||||
measures the scroll speed and once the finger leaves the touchpad the driver
|
||||
keeps sending scroll events for a predetermined time. This effectively
|
||||
provides for kinetic scrolling without client support but triggers an
|
||||
unfixable [bug](https://bugs.freedesktop.org/show_bug.cgi?id=38909): the
|
||||
client cannot know that the events are from a kinetic scroll source. Scroll
|
||||
events in X are always sent to the current cursor position, a movement of the
|
||||
cursor after lifting the finger will send the kinetic scroll events to the
|
||||
new client, something the user does not usually expect. A key event during
|
||||
the kinetic scroll procedure causes side-effects such as triggering zoom.
|
||||
|
||||
libinput does not implement kinetic scrolling for touchpads. Instead it
|
||||
provides the libinput_event_pointer_get_axis_source() function that enables
|
||||
callers to implement kinetic scrolling on a per-widget basis, see @ref
|
||||
scroll_sources.
|
||||
|
||||
@section faq_gpl Is libinput GPL-licensed?
|
||||
|
||||
No, libinput is MIT licensed. The Linux kernel header file linux/input.h in
|
||||
libinput's tree is provided to ensure the same behavior regardless of which
|
||||
kernel version libinput is built on. It does not make libinput GPL-licensed.
|
||||
|
||||
@section faq_config_options Where is the configuration stored?
|
||||
|
||||
libinput does not store configuration options, it is up to the caller to
|
||||
manage these and decide which configuration option to apply to each device.
|
||||
This must be done at startup, after a resume and whenever a new device is
|
||||
detected.
|
||||
|
||||
In a GNOME X.Org stack a user would usually toggle an option in
|
||||
the gnome-control-center which adjusts a gsettings entry. That change is
|
||||
picked up by gnome-settings-daemon and applied to the device by adjusting
|
||||
input device properties that the xf86-input-libinput driver provides.
|
||||
The input device property changes map to the respective libinput
|
||||
configuration options.
|
||||
|
||||
@dotfile libinput-stack-gnome.gv
|
||||
|
||||
This has an effect on the availability of configuration options: if an
|
||||
option is not exposed by the intermediary, it cannot be configured by the
|
||||
client. Also some configuration options that are provided by the
|
||||
intermediary may not be libinput-specific configuration options.
|
||||
|
||||
*/
|
||||
129
doc/gestures.dox
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
@page gestures Gestures
|
||||
|
||||
libinput supports basic gestures on touchpads and other indirect input
|
||||
devices. Two types of gestures are supported: @ref gestures_pinch and @ref
|
||||
gestures_swipe. Support for gestures depends on the hardware device, most
|
||||
touchpads support both gestures and any device that may send gesture events
|
||||
has the @ref LIBINPUT_DEVICE_CAP_GESTURE capability set.
|
||||
|
||||
Note that libinput **does not** support gestures on touchscreens, see
|
||||
@ref gestures_touchscreens.
|
||||
|
||||
@section gestures_lifetime Lifetime of a gesture
|
||||
|
||||
A gesture's lifetime has three distinct stages: begin, update and end, each
|
||||
with their own event types. Begin is sent when the fingers are first set
|
||||
down or libinput decides that the gesture begins. For @ref gestures_pinch
|
||||
this sets the initial scale. Any events changing properties of the gesture
|
||||
are sent as update events. On termination of the gesture, an end event is
|
||||
sent.
|
||||
|
||||
A gesture includes the finger count (see
|
||||
libinput_event_gesture_get_finger_count()) and that finger count remains the
|
||||
same for the lifetime of a gesture. Thus, if a user puts down a fourth
|
||||
finger during a three-finger swipe gesture, libinput will end
|
||||
the three-finger gesture and, if applicable, start a four-finger swipe
|
||||
gesture. A caller may decide that those gestures are semantically identical
|
||||
and continue the two gestures as one single gesture.
|
||||
|
||||
@see LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
|
||||
@see LIBINPUT_EVENT_GESTURE_PINCH_UPDATE
|
||||
@see LIBINPUT_EVENT_GESTURE_PINCH_END
|
||||
@see LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
|
||||
@see LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE
|
||||
@see LIBINPUT_EVENT_GESTURE_SWIPE_END
|
||||
|
||||
@section gestures_pinch Pinch gestures
|
||||
|
||||
Pinch gestures are executed when two or more fingers are located on the
|
||||
touchpad and are either changing the relative distance to each other
|
||||
(pinching) or are changing the relative angle (rotate). Pinch gestures may
|
||||
change both rotation and distance at the same time. For such gestures,
|
||||
libinput calculates a logical center for the gestures and provides the
|
||||
caller with the delta x/y coordinates of that center, the relative angle of
|
||||
the fingers compared to the previous event, and the absolute scale compared
|
||||
to the initial finger position.
|
||||
|
||||
@image html pinch-gestures.svg "The pinch and rotate gestures"
|
||||
|
||||
The illustration above shows a basic pinch in the left image and a rotate in
|
||||
the right angle. Not shown is a movement of the logical center if the
|
||||
fingers move unevenly. Such a movement is supported by libinput, it is
|
||||
merely left out of the illustration.
|
||||
|
||||
Note that while position and angle is relative to the previous event, the
|
||||
scale is always absolute and a multiplier of the initial finger position's
|
||||
scale.
|
||||
|
||||
@section gestures_swipe Swipe gestures
|
||||
|
||||
Swipe gestures are executed when three or more fingers are moved
|
||||
synchronously in the same direction. libinput provides x and y coordinates
|
||||
in the gesture and thus allows swipe gestures in any direction, including
|
||||
the tracing of complex paths. It is up to the caller to interpret the
|
||||
gesture into an action or limit a gesture to specific directions only.
|
||||
|
||||
@image html swipe-gestures.svg "The swipe gestures"
|
||||
|
||||
The illustration above shows a vertical three-finger swipe. The coordinates
|
||||
provided during the gesture are the movements of the logical center.
|
||||
|
||||
@section gestures_touchscreens Touchscreen gestures
|
||||
|
||||
Touchscreen gestures are **not** interpreted by libinput. Rather, any touch
|
||||
point is passed to the caller and any interpretation of gestures is up to
|
||||
the caller or, eventually, the X or Wayland client.
|
||||
|
||||
Interpreting gestures on a touchscreen requires context that libinput does
|
||||
not have, such as the location of windows and other virtual objects on the
|
||||
screen as well as the context of those virtual objects:
|
||||
|
||||
@image html touchscreen-gestures.svg "Context-sensitivity of touchscreen gestures"
|
||||
|
||||
In this example, the finger movements are identical but in the left case
|
||||
both fingers are located within the same window, thus suggesting an attempt
|
||||
to zoom. In the right case both fingers are located on a window border,
|
||||
thus suggesting a window movement. libinput only has knowledge of the finger
|
||||
coordinates (and even then only in device coordinates, not in screen
|
||||
coordinates) and thus cannot differentiate the two.
|
||||
|
||||
@section gestures_softbuttons Gestures with enabled software buttons
|
||||
|
||||
If the touchpad device is a @ref touchpads_buttons_clickpads "Clickpad", it
|
||||
is recommended that a caller switches to @ref clickfinger.
|
||||
Usually fingers placed in a @ref software_buttons "software button area" is not
|
||||
considered for gestures, resulting in some gestures to be interpreted as
|
||||
pointer motion or two-finger scroll events.
|
||||
|
||||
@image html pinch-gestures-softbuttons.svg "Interference of software buttons and pinch gestures"
|
||||
|
||||
In the example above, the software button area is highlighted in red. The
|
||||
user executes a three-finger pinch gesture, with the thumb remaining in the
|
||||
software button area. libinput ignores fingers within the software button
|
||||
areas, the movement of the remaining fingers is thus interpreted as a
|
||||
two-finger scroll motion.
|
||||
|
||||
@section gestures_twofinger_touchpads Gestures on two-finger touchpads
|
||||
|
||||
As of kernel 4.2, many @ref touchpads_touch_partial_mt provide only two
|
||||
slots. This affects how gestures can be interpreted. Touchpads with only two
|
||||
slots can identify two touches by position but can usually tell that there
|
||||
is a third (or fourth) finger down on the touchpad - without providing
|
||||
positional information for that finger.
|
||||
|
||||
Touchpoints are assigned in sequential order and only the first two touch
|
||||
points are trackable. For libinput this produces an ambiguity where it is
|
||||
impossible to detect whether a gesture is a pinch gesture or a swipe gesture
|
||||
whenever a user puts the index and middle finger down first. Since the third
|
||||
finger does not have positional information, it's location cannot be
|
||||
determined.
|
||||
|
||||
@image html gesture-2fg-ambiguity.svg "Ambiguity of three-finger gestures on two-finger touchpads"
|
||||
|
||||
The image above illustrates this ambiguity. The index and middle finger are
|
||||
set down first, the data stream from both finger positions looks identical.
|
||||
In this case, libinput assumes the fingers are in a horizontal arrangement
|
||||
(the right image above) and use a swipe gesture.
|
||||
|
||||
*/
|
||||
29
doc/libinput.doxygen.in
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
PROJECT_NAME = @PACKAGE_NAME@
|
||||
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
PROJECT_BRIEF = "A wrapper library for input devices"
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
TAB_SIZE = 8
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_STATIC = YES
|
||||
MAX_INITIALIZER_LINES = 0
|
||||
QUIET = YES
|
||||
INPUT = @top_srcdir@/src/libinput.h \
|
||||
@top_srcdir@/README.txt
|
||||
IMAGE_PATH = @top_srcdir@/doc/svg \
|
||||
@top_srcdir@/doc/dot
|
||||
GENERATE_HTML = YES
|
||||
HTML_TIMESTAMP = YES
|
||||
USE_MATHJAX = YES
|
||||
GENERATE_LATEX = NO
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, \
|
||||
a)= \
|
||||
LIBINPUT_ATTRIBUTE_DEPRECATED
|
||||
DOTFILE_DIRS = @top_srcdir@/doc/dot
|
||||
|
||||
HTML_HEADER = @top_srcdir@/doc/style/header.html
|
||||
HTML_FOOTER = @top_srcdir@/doc/style/footer.html
|
||||
HTML_EXTRA_STYLESHEET = @top_srcdir@/doc/style/customdoxygen.css \
|
||||
@top_srcdir@/doc/style/bootstrap.css
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
.. _motion_normalization:
|
||||
|
||||
==============================================================================
|
||||
Normalization of relative motion
|
||||
==============================================================================
|
||||
/**
|
||||
@page motion_normalization Normalization of relative motion
|
||||
|
||||
Most relative input devices generate input in so-called "mickeys". A
|
||||
mickey is in device-specific units that depend on the resolution
|
||||
|
|
@ -27,20 +24,11 @@ libinput applies a dpi-dependent acceleration function. At low speeds, a
|
|||
movement speed increases, acceleration is applied - at high speeds a low-dpi
|
||||
device will roughly feel the same as a higher-dpi mouse.
|
||||
|
||||
The reason for the normalization is convenience: a caller can assume that a
|
||||
delta of 1 should result in a movement of 1 pixel on a traditional
|
||||
(low-dpi) screen. On screens with high resolutions, the caller must scale
|
||||
according to the UI scale factors.
|
||||
|
||||
This normalization only applies to accelerated coordinates, unaccelerated
|
||||
coordinates are left in device-units. It is up to the caller to interpret
|
||||
those coordinates correctly.
|
||||
|
||||
.. _motion_normalization_touchpad:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Normalization of touchpad coordinates
|
||||
------------------------------------------------------------------------------
|
||||
@section motion_normalization_touchpad Normalization of touchpad coordinates
|
||||
|
||||
Touchpads may have a different resolution for the horizontal and vertical
|
||||
axis. Interpreting coordinates from the touchpad without taking resolution
|
||||
|
|
@ -48,50 +36,49 @@ into account results in uneven motion.
|
|||
|
||||
libinput scales unaccelerated touchpad motion to the resolution of the
|
||||
touchpad's x axis, i.e. the unaccelerated value for the y axis is:
|
||||
``y = (x / resolution_x) * resolution_y``.
|
||||
y = (x / resolution_x) * resolution_y
|
||||
|
||||
.. _motion_normalization_tablet:
|
||||
@section motion_normalization_tablet Normalization of tablet coordinates
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Normalization of tablet coordinates
|
||||
------------------------------------------------------------------------------
|
||||
See @ref tablet-relative-motion
|
||||
|
||||
See :ref:`tablet-relative-motion`
|
||||
|
||||
.. _motion_normalization_customization:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Setting custom DPI settings
|
||||
------------------------------------------------------------------------------
|
||||
@section motion_normalization_customization Setting custom DPI settings
|
||||
|
||||
Devices usually do not advertise their resolution and libinput relies on
|
||||
the udev property **MOUSE_DPI** for this information. This property is usually
|
||||
set via the
|
||||
`udev hwdb <http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/70-mouse.hwdb>`_.
|
||||
The ``mouse-dpi-tool`` utility provided by
|
||||
`libevdev <https://freedesktop.org/wiki/Software/libevdev/>`_ should be
|
||||
the udev property <b>MOUSE_DPI</b> for this information. This property is usually
|
||||
set via the <a
|
||||
href="http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/70-mouse.hwdb">udev hwdb</a>.
|
||||
The "mouse-dpi-tool" utility provided by <a
|
||||
href="http://freedesktop.org/wiki/Software/libevdev/">libevdev</a> should be
|
||||
used to measure a device's resolution.
|
||||
|
||||
The format of the property for single-resolution mice is: ::
|
||||
|
||||
MOUSE_DPI=resolution@frequency
|
||||
The format of the property for single-resolution mice is:
|
||||
@code
|
||||
MOUSE_DPI=resolution@frequency
|
||||
@endcode
|
||||
|
||||
The resolution is in dots per inch, the frequency in Hz.
|
||||
The format of the property for multi-resolution mice may list multiple
|
||||
resolutions and frequencies: ::
|
||||
|
||||
MOUSE_DPI=r1@f1 *r2@f2 r3@f3
|
||||
resolutions and frequencies:
|
||||
@code
|
||||
MOUSE_DPI=r1@f1 *r2@f2 r3@f3
|
||||
@endcode
|
||||
|
||||
The default frequency must be pre-fixed with an asterisk.
|
||||
|
||||
For example, these two properties are valid: ::
|
||||
For example, these two properties are valid:
|
||||
@code
|
||||
MOUSE_DPI=800@125
|
||||
MOUSE_DPI=400@125 800@125 *1000@500 5500@500
|
||||
@endcode
|
||||
|
||||
MOUSE_DPI=800@125
|
||||
MOUSE_DPI=400@125 800@125 *1000@500 5500@500
|
||||
The behavior for a malformed property is undefined.
|
||||
|
||||
The behavior for a malformed property is undefined. If the property is
|
||||
unset, libinput assumes the resolution is 1000dpi.
|
||||
If the property is unset, libinput assumes the resolution is 1000dpi.
|
||||
|
||||
Note that HW does not usually provide information about run-time
|
||||
resolution changes, libinput will thus not detect when a resolution
|
||||
changes to the non-default value.
|
||||
|
||||
*/
|
||||
|
||||
41
doc/page-hierarchy.dox
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
@page touchpads Touchpads
|
||||
|
||||
- @subpage scrolling
|
||||
- @subpage clickpad_softbuttons
|
||||
- @subpage tapping
|
||||
- @subpage gestures
|
||||
- @subpage palm_detection
|
||||
- @subpage t440_support
|
||||
- @subpage touchpad_jumping_cursor
|
||||
|
||||
@page touchscreens Touchscreens
|
||||
|
||||
- @subpage absolute_axes
|
||||
|
||||
@page pointers Mice, Trackballs, etc.
|
||||
|
||||
- @subpage motion_normalization
|
||||
|
||||
@page tablets Graphics Tablets
|
||||
|
||||
- @subpage tablet-support
|
||||
|
||||
@page general General setup
|
||||
|
||||
- @subpage udev_config
|
||||
- @subpage seats
|
||||
|
||||
@page misc Users
|
||||
|
||||
- @subpage faq
|
||||
- @subpage tools
|
||||
- @subpage reporting_bugs
|
||||
|
||||
@page developers Developers
|
||||
|
||||
- @subpage test-suite
|
||||
- @subpage tools
|
||||
- @subpage pointer-acceleration
|
||||
|
||||
*/
|
||||
114
doc/palm-detection.dox
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
@page palm_detection Palm detection
|
||||
|
||||
Palm detection tries to identify accidental touches while typing.
|
||||
|
||||
On most laptops typing on the keyboard generates accidental touches on the
|
||||
touchpad with the palm (usually the area below the thumb). This can lead to
|
||||
cursor jumps or accidental clicks.
|
||||
|
||||
Interference from a palm depends on the size of the touchpad and the position
|
||||
of the user's hand. Data from touchpads showed that almost all palm events on a
|
||||
Lenovo T440 happened in the left-most and right-most 5% of the touchpad. The
|
||||
T440 series has one of the largest touchpads, other touchpads are less
|
||||
affected by palm touches.
|
||||
|
||||
@section palm_exclusion_zones Palm exclusion zones
|
||||
|
||||
libinput enables palm detection on the edge of the touchpad. Two exclusion
|
||||
zones are defined on the left and right edge of the touchpad.
|
||||
If a touch starts in the exclusion zone, it is considered a palm and the
|
||||
touch point is ignored. However, for fast cursor movements across the
|
||||
screen, it is common for a finger to start inside an exclusion zone and move
|
||||
rapidly across the touchpad. libinput detects such movements and avoids palm
|
||||
detection on such touch sequences.
|
||||
|
||||
Each exclusion zone is divided into a top part and a bottom part. A touch
|
||||
starting in the top part of the exclusion zone does not trigger a
|
||||
tap (see @ref tapping).
|
||||
|
||||
In the diagram below, the exclusion zones are painted red.
|
||||
Touch 'A' starts inside the exclusion zone and moves
|
||||
almost vertically. It is considered a palm and ignored for cursor movement,
|
||||
despite moving out of the exclusion zone.
|
||||
|
||||
Touch 'B' starts inside the exclusion zone but moves horizontally out of the
|
||||
zone. It is considered a valid touch and controls the cursor.
|
||||
|
||||
Touch 'C' occurs in the top part of the exclusion zone. Despite being a
|
||||
tapping motion, it does not generate an emulated button event. Touch 'D'
|
||||
likewise occurs within the exclusion zone but in the bottom half. libinput
|
||||
will generate a button event for this touch.
|
||||
|
||||
@image html palm-detection.svg
|
||||
|
||||
@section trackpoint-disabling Palm detection during trackpoint use
|
||||
|
||||
If a device provides a <a
|
||||
href="http://en.wikipedia.org/wiki/Pointing_stick">trackpoint</a>, it is
|
||||
usually located above the touchpad. This increases the likelihood of
|
||||
accidental touches whenever the trackpoint is used.
|
||||
|
||||
libinput disables the touchpad whenever it detects trackpoint activity for a
|
||||
certain timeout until after trackpoint activity stops. Touches generated
|
||||
during this timeout will not move the pointer, and touches started during
|
||||
this timeout will likewise not move the pointer (allowing for a user to rest
|
||||
the palm on the touchpad while using the trackstick).
|
||||
If the touchpad is disabled, the @ref t440_support "top software buttons"
|
||||
remain enabled.
|
||||
|
||||
@section disable-while-typing Disable-while-typing
|
||||
|
||||
libinput automatically disables the touchpad for a timeout after a key
|
||||
press, a feature traditionally referred to as "disable while typing" and
|
||||
previously available through the
|
||||
[syndaemon(1)](http://linux.die.net/man/1/syndaemon) command. libinput does
|
||||
not require an external command and the feature is currently enabled for all
|
||||
touchpads but will be reduced in the future to only apply to touchpads where
|
||||
finger width or pressure data is unreliable.
|
||||
|
||||
Notable behaviors of libinput's disable-while-typing feature:
|
||||
- Two different timeouts are used, after a single key press the timeout is
|
||||
short to ensure responsiveness. After multiple key events, the timeout is
|
||||
longer to avoid accidental pointer manipulation while typing.
|
||||
- Some keys do not trigger the timeout, specifically some modifier keys
|
||||
(Ctrl, Alt, Shift, and Fn). Actions such as Ctrl + click thus stay
|
||||
responsive.
|
||||
- Touches started while typing do not control the cursor even after typing
|
||||
has stopped, it is thus possible to rest the palm on the touchpad while
|
||||
typing.
|
||||
- Physical buttons work even while the touchpad is disabled. This includes
|
||||
@ref t440_support "software-emulated buttons".
|
||||
|
||||
Disable-while-typing can be enabled and disabled by calling
|
||||
libinput_device_config_dwt_set_enabled().
|
||||
|
||||
@section thumb-detection Thumb detection
|
||||
|
||||
Many users rest their thumb on the touchpad while using the index finger to
|
||||
move the finger around. For clicks, often the thumb is used rather than the
|
||||
finger. The thumb should otherwise be ignored as a touch, i.e. it should not
|
||||
count towards @ref clickfinger and it should not cause a single-finger
|
||||
movement to trigger @ref twofinger_scrolling.
|
||||
|
||||
libinput uses two triggers for thumb detection: pressure and
|
||||
location. A touch exceeding a pressure threshold is considered a thumb if it
|
||||
is within the thumb detection zone.
|
||||
|
||||
@note "Pressure" on touchpads is synonymous with "contact area", a large
|
||||
touch surface area has a higher pressure and thus hints at a thumb or palm
|
||||
touching the surface.
|
||||
|
||||
Pressure readings are unreliable at the far bottom of the touchpad as a
|
||||
thumb hanging mostly off the touchpad will have a small surface area.
|
||||
libinput has a definitive thumb zone where any touch is considered a resting
|
||||
thumb.
|
||||
|
||||
@image html thumb-detection.svg
|
||||
|
||||
The picture above shows the two detection areas. In the larger (light red)
|
||||
area, a touch is labelled as thumb when it exceeds a device-specific
|
||||
pressure threshold. In the lower (dark red) area, a touch is labelled as
|
||||
thumb if it remains in that area for a time without moving outside.
|
||||
|
||||
*/
|
||||
133
doc/pointer-acceleration.dox
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
@page pointer-acceleration Pointer acceleration
|
||||
|
||||
libinput uses device-specific pointer acceleration methods, with the default
|
||||
being the @ref ptraccel-linear. The methods share common properties, such as
|
||||
@ref ptraccel-velocity.
|
||||
|
||||
This page explains the high-level concepts used in the code. It aims to
|
||||
provide an overview for developers and is not necessarily useful for
|
||||
users.
|
||||
|
||||
@section ptraccel-profiles Pointer acceleration profiles
|
||||
|
||||
The profile decides the general method of pointer acceleration.
|
||||
libinput currently supports two profiles: "adaptive" and "flat". The aptive
|
||||
profile is the default profile for all devices and takes the current speed
|
||||
of the device into account when deciding on acceleration. The flat profile
|
||||
is simply a constant factor applied to all device deltas, regardless of the
|
||||
speed of motion (see @ref ptraccel-profile-flat). Most of this document
|
||||
describes the adaptive pointer acceleration.
|
||||
|
||||
@section ptraccel-velocity Velocity calculation
|
||||
|
||||
The device's speed of movement is measured across multiple input events
|
||||
through so-called "trackers". Each event prepends a the tracker item, each
|
||||
subsequent tracker contains the delta of that item to the current position,
|
||||
the timestamp of the event that created it and the cardinal direction of the
|
||||
movement at the time. If a device moves into the same direction, the
|
||||
velocity is calculated across multiple trackers. For example, if a device
|
||||
moves steadily for 10 events to the left, the velocity is calculated across
|
||||
all 10 events.
|
||||
|
||||
Whenever the movement changes direction or significantly changes speed, the
|
||||
velocity is calculated from the direction/speed change only. For example, if
|
||||
a device moves steadily for 8 events to the left and then 2 events to the
|
||||
right, the velocity is only that of the last 2 events.
|
||||
|
||||
An extra time limit prevents events that are too old to factor into the
|
||||
velocity calculation. For example, if a device moves steadily for 5 events
|
||||
to the left, then pauses, then moves again for 5 events to the left, only
|
||||
the last 5 events are used for velocity calculation.
|
||||
|
||||
The velocity is then used to calculate the acceleration factor
|
||||
|
||||
@section ptraccel-factor Acceleration factor
|
||||
|
||||
The acceleration factor is the final outcome of the pointer acceleration
|
||||
calculations. It is a unitless factor that is applied to the current delta,
|
||||
a factor of 2 doubles the delta (i.e. speeds up the movement), a factor of
|
||||
less than 1 reduces the delta (i.e. slows the movement).
|
||||
|
||||
Any factor less than 1 requires the user to move the device further to move
|
||||
the visible pointer. This is called deceleration and enables high precision
|
||||
target selection through subpixel movements. libinput's current maximum
|
||||
deceleration factor is 0.3 (i.e. slow down to 30% of the pointer speed).
|
||||
|
||||
A factor higher than 1 moves the pointer further than the physical device
|
||||
moves. This is acceleration and allows a user to cross the screen quickly
|
||||
but effectively skips pixels. libinput's current maximum acceleration factor
|
||||
is 3.5.
|
||||
|
||||
@section ptraccel-linear Linear pointer acceleration
|
||||
|
||||
The linear pointer acceleration method is the default for most pointer
|
||||
devices. It provides deceleration at very slow movements, a 1:1 mapping for
|
||||
regular movements and a linear increase to the maximum acceleration factor
|
||||
for fast movements.
|
||||
|
||||
Linear pointer acceleration applies to devices with above 1000dpi resolution
|
||||
and after @ref motion_normalization is applied.
|
||||
|
||||
@image html ptraccel-linear.svg "Linear pointer acceleration"
|
||||
|
||||
The image above shows the linear pointer acceleration settings at various
|
||||
speeds. The line for 0.0 is the default acceleration curve, speed settings
|
||||
above 0.0 accelerate sooner, faster and to a higher maximum acceleration.
|
||||
Speed settings below 0 delay when acceleration kicks in, how soon the
|
||||
maximum acceleration is reached and the maximum acceleration factor.
|
||||
|
||||
Extremely low speed settings provide no acceleration and additionally
|
||||
decelerate all movement by a constant factor.
|
||||
|
||||
@section ptraccel-low-dpi Pointer acceleration for low-dpi devices
|
||||
|
||||
Low-dpi devices are those with a physical resolution of less than 1000 dots
|
||||
per inch (dpi). The pointer acceleration is adjusted to provide roughly the
|
||||
same feel for all devices at normal to high speeds. At slow speeds, the
|
||||
pointer acceleration works on device-units rather than normalized
|
||||
coordinates (see @ref motion_normalization).
|
||||
|
||||
@image html ptraccel-low-dpi.svg "Pointer acceleration for low-dpi devices"
|
||||
|
||||
The image above shows the default pointer acceleration curve for a speed of
|
||||
0.0 at different DPI settings. A device with low DPI has the acceleration
|
||||
applied sooner and with a stronger acceleration factor.
|
||||
|
||||
@section ptraccel-touchpad Pointer acceleration on touchpads
|
||||
|
||||
Touchpad pointer acceleration uses the @ref ptraccel-linear profile, with a
|
||||
constant deceleration factor applied. The user expectation of how much a
|
||||
pointer should move in response to finger movement is different to that of a
|
||||
mouse device, hence the constant deceleration factor.
|
||||
|
||||
@image html ptraccel-touchpad.svg "Pointer acceleration curve for touchpads"
|
||||
|
||||
The image above shows the touchpad acceleration profile in comparison to the
|
||||
@ref ptraccel-linear. The shape of the curve is identical but vertically squashed.
|
||||
|
||||
@section ptraccel-trackpoint Pointer acceleration on trackpoints
|
||||
|
||||
Trackpoint pointer acceleration uses the @ref ptraccel-low-dpi profile, with a
|
||||
constant deceleration factor taking the place of the DPI settings.
|
||||
|
||||
@image html ptraccel-trackpoint.svg "Pointer acceleration curves for trackpoints"
|
||||
|
||||
The image above shows the trackpoint acceleration profile in comparison to the
|
||||
@ref ptraccel-linear. The constant acceleration factor, usually applied by
|
||||
udev, shapes the acceleration profile.
|
||||
|
||||
@section ptraccel-profile-flat The flat pointer acceleration profile
|
||||
|
||||
In a flat profile, the acceleration factor is constant regardless of the
|
||||
velocity of the pointer and each delta (dx, dy) results in an accelerated delta
|
||||
(dx * factor, dy * factor). This provides 1:1 movement between the device
|
||||
and the pointer on-screen.
|
||||
|
||||
@section ptraccel-tablet Pointer acceleration on tablets
|
||||
|
||||
Pointer acceleration for relative motion on tablet devices is a flat
|
||||
acceleration, with the speed seeting slowing down or speeding up the pointer
|
||||
motion by a constant factor. Tablets do not allow for switchable profiles.
|
||||
|
||||
*/
|
||||
94
doc/reporting-bugs.dox
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
@page reporting_bugs Reporting bugs
|
||||
|
||||
A new bug can be filed here:
|
||||
https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=libinput
|
||||
|
||||
When reporting bugs against libinput, please follow the instructions below
|
||||
and provide the required data. This will speed up triage, resulting in a
|
||||
quicker bugfix.
|
||||
|
||||
First, try to identify the bug by reproducing it reliably. The more
|
||||
specific a bug description is, the easier it is to fix. The @ref
|
||||
libinput-debug-events helper tool can help identify whether the bug is in
|
||||
libinput at all. This tool is a direct hook to libinput without a desktop
|
||||
stack in between and can thus help to identify whether a bug is in libinput
|
||||
or in one of the higher layers. See the @ref libinput-debug-events section
|
||||
for information on this tool.
|
||||
|
||||
@section triage Required information for triage
|
||||
|
||||
When you file a bug, please attach the following information:
|
||||
- a virtual description of your input device, see @ref evemu. This is the
|
||||
most important piece of information, do not forget it!
|
||||
- the libinput version. Either the package version from your distribution
|
||||
or, when running from git: <tt>git log -n 1 HEAD</tt> or <tt>git describe
|
||||
HEAD</tt>. As a last resort: <tt>libinput-list-devices --version</tt>.
|
||||
- the current libinput settings for the device. This is a bit harder to
|
||||
obtain, for now we'll assume you are running X11. The current settings can
|
||||
be obtained with <tt>xinput list-props "your device name"</tt>. Use
|
||||
<tt>xinput list</tt> to obtain the device name.
|
||||
- if the device is a touchpad or a pointing stick, the vendor model number
|
||||
of your laptop, and the content of <tt>/sys/class/dmi/id/modalias</tt>.
|
||||
- if the device is a touchpad, the physical dimensions of your touchpad in
|
||||
mm
|
||||
|
||||
@section evemu Recording devices with evemu
|
||||
|
||||
<a href="http://www.freedesktop.org/wiki/Evemu/">evemu</a> records the
|
||||
device capabilities together with the event stream from the kernel. On our
|
||||
side, this allows us to recreate a virtual device identical to your device
|
||||
and re-play the event sequence, hopefully triggering the same bug.
|
||||
|
||||
evemu-record takes a <tt>/dev/input/eventX</tt> event node, but without arguments
|
||||
it will simply show the list of devices and let you select:
|
||||
@code
|
||||
$ sudo evemu-record > scroll.evemu
|
||||
Available devices:
|
||||
/dev/input/event0: Lid Switch
|
||||
/dev/input/event1: Sleep Button
|
||||
/dev/input/event2: Power Button
|
||||
/dev/input/event3: AT Translated Set 2 keyboard
|
||||
/dev/input/event4: SynPS/2 Synaptics TouchPad
|
||||
/dev/input/event5: Video Bus
|
||||
/dev/input/event6: ELAN Touchscreen
|
||||
/dev/input/event10: ThinkPad Extra Buttons
|
||||
/dev/input/event11: HDA Intel HDMI HDMI/DP,pcm=3
|
||||
/dev/input/event12: HDA Intel HDMI HDMI/DP,pcm=7
|
||||
/dev/input/event13: HDA Intel HDMI HDMI/DP,pcm=8
|
||||
/dev/input/event14: HDA Intel PCH Dock Mic
|
||||
/dev/input/event15: HDA Intel PCH Mic
|
||||
/dev/input/event16: HDA Intel PCH Dock Headphone
|
||||
/dev/input/event17: HDA Intel PCH Headphone
|
||||
/dev/input/event18: Integrated Camera
|
||||
/dev/input/event19: TPPS/2 IBM TrackPoint
|
||||
Select the device event number [0-19]:
|
||||
@endcode
|
||||
|
||||
Select the device that triggers the issue, then reproduce the bug and Ctrl+C
|
||||
the process. The resulting recording, ("scroll.evemu" in this example) will
|
||||
contain the sequence required to reproduce the bug. If the bug fails to
|
||||
reproduce during recording, simply Ctrl+C and restart evemu-record.
|
||||
Always start the recording from a neutral state, i.e. without any buttons or
|
||||
keys down, with the position of the device in the neutral position, without
|
||||
touching the screen/touchpad.
|
||||
|
||||
@note The longer the recording, the harder it is to identify the event
|
||||
sequence triggering the bug. Please keep the event sequence as short as possible.
|
||||
|
||||
To verify that the recording contains the bug, you can replay it on your
|
||||
device. For example, to replay the sequence recorded in the example above:
|
||||
@code
|
||||
$ sudo evemu-play /dev/input/event4 < scroll.evemu
|
||||
@endcode
|
||||
|
||||
If the bug is triggered by replaying on your device, attach the recording to
|
||||
the bug report.
|
||||
|
||||
@note libinput does not affect the evemu recording. libinput and evemu talk
|
||||
directly to the kernel's device nodes. An evemu recording is not influenced
|
||||
by the libinput version or whether a libinput context is currently active.
|
||||
|
||||
@dotfile evemu.gv
|
||||
|
||||
*/
|
||||
106
doc/scrolling.dox
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
@page scrolling Scrolling
|
||||
|
||||
libinput supports three different types of scrolling methods: @ref
|
||||
twofinger_scrolling, @ref edge_scrolling and @ref button_scrolling. Some
|
||||
devices support multiple methods, though only one can be enabled at a time.
|
||||
As a general overview:
|
||||
- touchpad devices with physical buttons below the touchpad support edge and
|
||||
two-finger scrolling
|
||||
- touchpad devices without physical buttons (@ref clickpad_softbuttons
|
||||
"clickpads") support two-finger scrolling only
|
||||
- pointing sticks provide on-button scrolling by default
|
||||
- mice and other pointing devices support on-button scrolling but it is not
|
||||
enabled by default
|
||||
|
||||
A device may differ from the above based on its capabilities. See
|
||||
libinput_device_config_scroll_set_method() for documentation on how to
|
||||
switch methods and libinput_device_config_scroll_get_methods() for
|
||||
documentation on how to query a device for available scroll methods.
|
||||
|
||||
@section horizontal_scrolling Horizontal scrolling
|
||||
|
||||
Scroll movements provide vertical and horizontal directions, each
|
||||
scroll event contains both directions where applicable, see
|
||||
libinput_event_pointer_get_axis_value(). libinput does not provide separate
|
||||
toggles to enable or disable horizontal scrolling. Instead, horizontal
|
||||
scrolling is always enabled. This is intentional, libinput does not have
|
||||
enough context to know when horizontal scrolling is appropriate for a given
|
||||
widget. The task of filtering horizontal movements is up to the caller.
|
||||
|
||||
@section twofinger_scrolling Two-finger scrolling
|
||||
|
||||
The default on two-finger capable touchpads (almost all modern touchpads are
|
||||
capable of detecting two fingers). Scrolling is triggered by two fingers
|
||||
being placed on the surface of the touchpad, then moving those fingers
|
||||
vertically or horizontally.
|
||||
|
||||
@image html twofinger-scrolling.svg "Vertical and horizontal two-finger scrolling"
|
||||
|
||||
For scrolling to trigger, a built-in distance threshold has to be met but once
|
||||
engaged any movement will scroll. In other words, to start scrolling a
|
||||
sufficiently large movement is required, once scrolling tiny amounts of
|
||||
movements will translate into tiny scroll movements.
|
||||
Scrolling in both directions at once is possible by meeting the required
|
||||
distance thresholds to enable each direction separately.
|
||||
|
||||
Two-finger scrolling requires the touchpad to track both touch points with
|
||||
reasonable precision. Unfortunately, some so-called "semi-mt" touchpads can
|
||||
only track the bounding box of the two fingers rather than the actual
|
||||
position of each finger. In addition, that bounding box usually suffers from
|
||||
a low resolution, causing jumpy movement during two-finger scrolling.
|
||||
libinput does not provide two-finger scrolling on those touchpads.
|
||||
|
||||
@section edge_scrolling Edge scrolling
|
||||
|
||||
On some touchpads, edge scrolling is available, triggered by moving a single
|
||||
finger along the right edge (vertical scroll) or bottom edge (horizontal
|
||||
scroll).
|
||||
|
||||
@image html edge-scrolling.svg "Vertical and horizontal edge scrolling"
|
||||
|
||||
Due to the layout of the edges, diagonal scrolling is not possible. The
|
||||
behavior of edge scrolling using both edges at the same time is undefined.
|
||||
|
||||
Edge scrolling overlaps with @ref clickpad_softbuttons. A physical click on
|
||||
a clickpad ends scrolling.
|
||||
|
||||
@section button_scrolling On-Button scrolling
|
||||
|
||||
On-button scrolling converts the motion of a device into scroll events while
|
||||
a designated button is held down. For example, Lenovo devices provide a
|
||||
<a href="http://en.wikipedia.org/wiki/Pointing_stick">pointing stick</a> that emulates
|
||||
scroll events when the trackstick's middle mouse button is held down.
|
||||
|
||||
@note On-button scrolling is enabled by default for pointing sticks. This
|
||||
prevents middle-button dragging; all motion events while the middle button is
|
||||
down are converted to scroll events.
|
||||
|
||||
@image html button-scrolling.svg "Button scrolling"
|
||||
|
||||
The button may be changed with
|
||||
libinput_device_config_scroll_set_button() but must be on the same device as
|
||||
the motion events. Cross-device scrolling is not supported but
|
||||
for one exception: libinput's @ref t440_support enables the use of the middle
|
||||
button for button scrolling (even when the touchpad is disabled).
|
||||
|
||||
@section scroll_sources Scroll sources
|
||||
|
||||
libinput provides a pointer axis *source* for each scroll event. The
|
||||
source can be obtained with the libinput_event_pointer_get_axis_source()
|
||||
function and is one of **wheel**, **finger**, or **continuous**. The source
|
||||
information lets a caller decide when to implement kinetic scrolling.
|
||||
Usually, a caller will process events of source wheel as they come in.
|
||||
For events of source finger a caller should calculate the velocity of the
|
||||
scroll motion and upon finger release start a kinetic scrolling motion (i.e.
|
||||
continue executing a scroll according to some friction factor).
|
||||
libinput expects the caller to be in charge of widget handling, the source
|
||||
information is thus enough to provide kinetic scrolling on a per-widget
|
||||
basis. A caller should cancel kinetic scrolling when the pointer leaves the
|
||||
current widget or when a key is pressed.
|
||||
|
||||
See the libinput_event_pointer_get_axis_source() for details on the
|
||||
behavior of each scroll source.
|
||||
|
||||
See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
|
||||
*/
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
.. _seats:
|
||||
|
||||
==============================================================================
|
||||
Seats
|
||||
==============================================================================
|
||||
/**
|
||||
@page seats Seats
|
||||
|
||||
Each device in libinput is assigned to one seat.
|
||||
A seat has two identifiers, the physical name and the logical name. The
|
||||
|
|
@ -13,15 +10,11 @@ seats as independent device sets. Alternatively, a compositor may limit
|
|||
itself to a single logical seat, leaving a second compositor to manage
|
||||
devices on the other logical seats.
|
||||
|
||||
.. _seats_overview:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Overview
|
||||
------------------------------------------------------------------------------
|
||||
@section Overview
|
||||
|
||||
Below is an illustration of how physical seats and logical seats interact:
|
||||
|
||||
.. graphviz:: seats-sketch.gv
|
||||
@dotfile seats-sketch.gv
|
||||
|
||||
The devices "Foo", "Bar" and "Spam" share the same physical seat and are
|
||||
thus available in the same libinput context. Only "Foo" and "Bar" share the
|
||||
|
|
@ -29,19 +22,15 @@ same logical seat. The device "Egg" is not available in the libinput context
|
|||
associated with the physical seat 0.
|
||||
|
||||
The above graph is for illustration purposes only. In libinput, a struct
|
||||
**libinput_seat** comprises both physical seat and logical seat. From a
|
||||
@ref libinput_seat comprises both physical seat and logical seat. From a
|
||||
caller's point-of-view the above device layout is presented as:
|
||||
|
||||
.. graphviz:: seats-sketch-libinput.gv
|
||||
@dotfile seats-sketch-libinput.gv
|
||||
|
||||
Thus, devices "Foo" and "Bar" both reference the same struct
|
||||
**libinput_seat**, all other devices reference their own respective seats.
|
||||
Thus, devices "Foo" and "Bar" both reference the same struct @ref
|
||||
libinput_seat, all other devices reference their own respective seats.
|
||||
|
||||
.. _seats_and_features:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
The effect of seat assignment
|
||||
------------------------------------------------------------------------------
|
||||
@section seats_and_features The effect of seat assignment
|
||||
|
||||
A logical set is interpreted as a group of devices that usually belong to a
|
||||
single user that interacts with a computer. Thus, the devices are
|
||||
|
|
@ -59,27 +48,26 @@ semantically related. This means for devices within the same logical seat:
|
|||
two touches down.
|
||||
|
||||
libinput provides functions to aid with the above:
|
||||
**libinput_event_pointer_get_seat_button_count()**,
|
||||
**libinput_event_keyboard_get_seat_key_count()**, and
|
||||
**libinput_event_touch_get_seat_slot()**.
|
||||
libinput_event_pointer_get_seat_button_count(),
|
||||
libinput_event_keyboard_get_seat_key_count(), and
|
||||
libinput_event_touch_get_seat_slot().
|
||||
|
||||
Internally, libinput counts devices within the same logical seat as related.
|
||||
Cross-device features only activate if all required devices are in the same
|
||||
logical seat. For example, libinput will only activate the top software
|
||||
buttons (see :ref:`t440_support`) if both trackstick and touchpad are assigned
|
||||
buttons (see @ref t440_support) if both trackstick and touchpad are assigned
|
||||
to the same logical seat.
|
||||
|
||||
|
||||
.. _changing_seats:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Changing seats
|
||||
------------------------------------------------------------------------------
|
||||
@section changing_seats Changing seats
|
||||
|
||||
A device may change the logical seat it is assigned to at runtime with
|
||||
**libinput_device_set_seat_logical_name()**. The physical seat is immutable and
|
||||
libinput_device_set_seat_logical_name(). The physical seat is immutable and
|
||||
may not be changed.
|
||||
|
||||
Changing the logical seat for a device is equivalent to unplugging the
|
||||
device and plugging it back in with the new logical seat. No device state
|
||||
carries over across a logical seat change.
|
||||
|
||||
|
||||
*/
|
||||
|
|
@ -252,3 +252,4 @@ blockquote {
|
|||
margin: 0 24px 0 4px;
|
||||
padding: 0 12px 0 16px;
|
||||
}
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
||||
|
||||
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
|
||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
$mathjax
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
$extrastylesheet
|
||||
|
||||
<link href="bootstrap.css" rel="stylesheet" type="text/css" />
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="doxy-boot.js"></script>
|
||||
</head>
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
|
@ -36,17 +36,16 @@
|
|||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1016"
|
||||
inkscape:window-height="1136"
|
||||
id="namedview3477"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.5662625"
|
||||
inkscape:cx="180.54059"
|
||||
inkscape:cy="269.48563"
|
||||
inkscape:cx="199.35048"
|
||||
inkscape:cy="156.74673"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:document-rotation="0" />
|
||||
inkscape:current-layer="svg2" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
|
|
@ -138,8 +137,16 @@
|
|||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6, 1;stroke-dashoffset:0;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow1Lend-2)"
|
||||
id="path13492"
|
||||
d="m 38.928571,67.914286 c 0,0 3.508205,24.810617 9.642857,57.857144 6.134651,33.04652 23.277202,79.68584 89.642852,90.35714" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:3.30527353px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="rect3490"
|
||||
width="65.272476"
|
||||
height="136.21509"
|
||||
x="7.0411549"
|
||||
y="7.0411549" />
|
||||
<text
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
|
||||
sodipodi:linespacing="100%"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:100%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text13874"
|
||||
y="63.628628"
|
||||
|
|
@ -148,8 +155,16 @@
|
|||
id="tspan13876"
|
||||
y="63.628628"
|
||||
x="33.214291">A</tspan></text>
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:3.30527353px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="rect3490-2"
|
||||
width="65.272476"
|
||||
height="136.21509"
|
||||
x="321.23563"
|
||||
y="6.7607527" />
|
||||
<text
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
sodipodi:linespacing="100%"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:100%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text13874-8"
|
||||
y="98.748993"
|
||||
|
|
@ -168,7 +183,8 @@
|
|||
id="layer1"
|
||||
style="display:inline" />
|
||||
<text
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
sodipodi:linespacing="100%"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:100%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text13874-8-1"
|
||||
y="46.009491"
|
||||
|
|
@ -177,6 +193,17 @@
|
|||
id="tspan13876-7-9"
|
||||
y="46.009491"
|
||||
x="342.27759">C</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:100%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text13874-8-1-4"
|
||||
y="215.65927"
|
||||
x="37.970726"><tspan
|
||||
style="font-size:18px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
id="tspan13876-7-9-5"
|
||||
y="215.65927"
|
||||
x="37.970726">D</tspan></text>
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path4401"
|
||||
|
|
@ -184,18 +211,11 @@
|
|||
cy="24.53549"
|
||||
r="4.0658817"
|
||||
transform="scale(-1,1)" />
|
||||
<rect
|
||||
width="248.87633"
|
||||
height="6.8111157"
|
||||
x="72.35215"
|
||||
y="7.1355872"
|
||||
id="rect4355"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:0.32017547;fill-rule:nonzero;stroke:none;stroke-width:1.11822701;marker:none;enable-background:accumulate" />
|
||||
<rect
|
||||
y="7.1355872"
|
||||
x="72.35215"
|
||||
height="6.8111153"
|
||||
width="248.87634"
|
||||
id="rect4353"
|
||||
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:1.44321382px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path4401-9"
|
||||
cx="-36.452721"
|
||||
cy="194.8819"
|
||||
r="4.0658817"
|
||||
transform="scale(-1,1)" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
5486
doc/svg/ptraccel-linear.svg
Normal file
|
After Width: | Height: | Size: 550 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg
|
||||
<svg
|
||||
width="600" height="480"
|
||||
viewBox="0 0 600 480"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -3745,3 +3745,4 @@
|
|||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 377 KiB After Width: | Height: | Size: 377 KiB |
1723
doc/svg/ptraccel-touchpad.svg
Normal file
|
After Width: | Height: | Size: 171 KiB |
3689
doc/svg/ptraccel-trackpoint.svg
Normal file
|
After Width: | Height: | Size: 371 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
|
@ -1,43 +1,29 @@
|
|||
.. _t440_support:
|
||||
/**
|
||||
@page t440_support Lenovo *40 series touchpad support
|
||||
|
||||
==============================================================================
|
||||
Lenovo \*40 series touchpad support
|
||||
==============================================================================
|
||||
|
||||
The Lenovo \*40 series emulates trackstick buttons on the top part of the
|
||||
The Lenovo *40 series emulates trackstick buttons on the top part of the
|
||||
touchpads.
|
||||
|
||||
.. _t440_support_overview:
|
||||
@section t440_support_overview Overview
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Overview
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Lenovo \*40 series introduced a new type of touchpad. Previously, all
|
||||
The Lenovo *40 series introduced a new type of touchpad. Previously, all
|
||||
laptops had a separate set of physical buttons for the
|
||||
`trackstick <http://en.wikipedia.org/wiki/Pointing_stick>`_. This
|
||||
<a href="http://en.wikipedia.org/wiki/Pointing_stick">trackstick</a>. This
|
||||
series removed these buttons, relying on a software emulation of the top
|
||||
section of the touchpad. This is visually marked on the trackpad itself,
|
||||
and clicks can be triggered by pressing the touchpad down with a finger in
|
||||
the respective area:
|
||||
|
||||
.. figure:: top-software-buttons.svg
|
||||
:align: center
|
||||
|
||||
Left, right and middle-button click with top software button areas
|
||||
@image html top-software-buttons.svg "Left, right and middle-button click with top software button areas"
|
||||
|
||||
This page only covers the top software buttons, the bottom button behavior
|
||||
is covered in :ref:`Clickpad software buttons <clickpad_softbuttons>`.
|
||||
is covered in @ref clickpad_softbuttons "Clickpad software buttons".
|
||||
|
||||
Clickpads with a top button area are marked with the
|
||||
`INPUT_PROP_TOPBUTTONPAD <https://www.kernel.org/doc/Documentation/input/event-codes.txt>`_
|
||||
Clickpads with a top button area are marked with the <a
|
||||
href="https://www.kernel.org/doc/Documentation/input/event-codes.txt">INPUT_PROP_TOPBUTTONPAD</a>
|
||||
property.
|
||||
|
||||
.. _t440_support_btn_size:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Size of the buttons
|
||||
------------------------------------------------------------------------------
|
||||
@section t440_support_btn_size Size of the buttons
|
||||
|
||||
The size of the buttons matches the visual markings on this touchpad.
|
||||
The width of the left and right buttons is approximately 42% of the
|
||||
|
|
@ -49,23 +35,16 @@ measurements of button presses showed that the size of the buttons needs to
|
|||
be approximately 10mm high to work reliable (especially when using the
|
||||
thumb to press the button).
|
||||
|
||||
.. _t440_support_btn_behavior:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Button behavior
|
||||
------------------------------------------------------------------------------
|
||||
@section t440_support_btn_behavior Button behavior
|
||||
|
||||
Movement in the top button area does not generate pointer movement. These
|
||||
buttons are not replacement buttons for the bottom button area but have
|
||||
their own behavior. Semantically attached to the trackstick device, libinput
|
||||
re-routes events from these buttons to appear through the trackstick device.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph top_button_routing
|
||||
{
|
||||
@dot
|
||||
digraph top_button_routing
|
||||
{
|
||||
rankdir="LR";
|
||||
node [shape="box";]
|
||||
|
||||
|
|
@ -95,8 +74,8 @@ re-routes events from these buttons to appear through the trackstick device.
|
|||
|
||||
libinput_tp -> events_tp [arrowhead="none"]
|
||||
libinput_ts -> events_topbutton [color="red4"]
|
||||
}
|
||||
|
||||
}
|
||||
@enddot
|
||||
|
||||
|
||||
The top button areas work even if the touchpad is disabled but will be
|
||||
|
|
@ -106,23 +85,20 @@ and must be lifted to generate future buttons. Likewise, movement into the
|
|||
top button area does not trigger button events, a click has to start inside
|
||||
this area to take effect.
|
||||
|
||||
.. _t440_support_identification:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Kernel support
|
||||
------------------------------------------------------------------------------
|
||||
@section t440_support_identification Kernel support
|
||||
|
||||
The firmware on the first generation of touchpads providing top software
|
||||
buttons is buggy and announces wrong ranges.
|
||||
`Kernel patches <https://lkml.org/lkml/2014/3/7/722>`_ are required;
|
||||
<a href="https://lkml.org/lkml/2014/3/7/722">Kernel patches</a> are required;
|
||||
these fixes are available in kernels 3.14.1, 3.15 and later but each
|
||||
touchpad needs a separate fix.
|
||||
|
||||
The October 2014 refresh of these laptops do not have this firmware bug
|
||||
anymore and should work without per-device patches, though
|
||||
`this kernel commit <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=02e07492cdfae9c86e3bd21c0beec88dbcc1e9e8>`_
|
||||
is required.
|
||||
<a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=02e07492cdfae9c86e3bd21c0beec88dbcc1e9e8">this kernel commit</a> is required.
|
||||
|
||||
For a complete list of supported touchpads check
|
||||
`the kernel source <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/mouse/synaptics.c>`_
|
||||
(search for "topbuttonpad_pnp_ids").
|
||||
For a complete list of supported touchpads check <a
|
||||
href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/mouse/synaptics.c">the
|
||||
kernel source</a> (search for "topbuttonpad_pnp_ids").
|
||||
|
||||
*/
|
||||
248
doc/tablet-support.dox
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/**
|
||||
@page tablet-support Tablet support
|
||||
|
||||
This page provides details about the graphics tablet
|
||||
support in libinput. Note that the term "tablet" in libinput refers to
|
||||
graphics tablets only (e.g. Wacom Intuos), not to tablet devices like the
|
||||
Apple iPad.
|
||||
|
||||
@image html tablet.svg "Illustration of a graphics tablet"
|
||||
|
||||
@section tablet-tools Pad buttons vs. tablet tools
|
||||
|
||||
Most tablets provide two types of devices. The physical tablet often
|
||||
provides a number of buttons and a touch ring or strip. Interaction on the
|
||||
drawing surface of the tablet requires a tool, usually in the shape of a
|
||||
stylus. The libinput interface exposed by devices with the @ref
|
||||
LIBINPUT_DEVICE_CAP_TABLET_TOOL capability applies only to events generated
|
||||
by tools.
|
||||
|
||||
Buttons, rings or strips on the physical tablet hardware (the "pad") are
|
||||
exposed by devices with the @ref LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
|
||||
Pad events do not require a tool to be in proximity. Note that both
|
||||
capabilities may exist on the same device though usually they are split
|
||||
across multiple kernel devices.
|
||||
|
||||
@image html tablet-interfaces.svg "Difference between Pad and Tool buttons"
|
||||
|
||||
Touch events on the tablet integrated into a screen itself are exposed
|
||||
through the @ref LIBINPUT_DEVICE_CAP_TOUCH capability. Touch events on a
|
||||
standalone tablet are exposed through the @ref LIBINPUT_DEVICE_CAP_POINTER
|
||||
capability. In both cases, the kernel usually provides a separate event
|
||||
node for the touch device, resulting in a separate libinput device.
|
||||
See libinput_device_get_device_group() for information on how to associate
|
||||
the touch part with other devices exposed by the same physical hardware.
|
||||
|
||||
@section tablet-tip Tool tip events vs. tool button events
|
||||
|
||||
The primary use of a tablet tool is to draw on the surface of the tablet.
|
||||
When the tool tip comes into contact with the surface, libinput sends an
|
||||
event of type @ref LIBINPUT_EVENT_TABLET_TOOL_TIP, and again when the tip
|
||||
ceases contact with the surface.
|
||||
|
||||
Tablet tools may send button events; these are exclusively for extra buttons
|
||||
unrelated to the tip. A button event is independent of the tip and can while
|
||||
the tip is down or up.
|
||||
|
||||
Some tablet tools' pressure detection is too sensitive, causing phantom
|
||||
touches when the user only slightly brushes the surfaces. For example, some
|
||||
tools are capable of detecting 1 gram of pressure.
|
||||
|
||||
libinput uses a device-specific pressure threshold to determine when the tip
|
||||
is considered logically down. As a result, libinput may send a nonzero
|
||||
pressure value while the tip is logically up. Most application can and
|
||||
should ignore pressure information until they receive the event of type @ref
|
||||
LIBINPUT_EVENT_TABLET_TOOL_TIP. Applications that require extremely
|
||||
fine-grained pressure sensitivity should use the pressure data instead of
|
||||
the tip events to determine a logical tip down state and treat the tip
|
||||
events like axis events otherwise.
|
||||
|
||||
Note that the pressure threshold to trigger a logical tip event may be zero
|
||||
on some devices. On tools without pressure sensitivity, determining when a
|
||||
tip is down is device-specific.
|
||||
|
||||
@section tablet-relative-motion Relative motion for tablet tools
|
||||
|
||||
libinput calculates the relative motion vector for each event and converts
|
||||
it to the same coordinate space that a normal mouse device would use. For
|
||||
the caller, this means that the delta coordinates returned by
|
||||
libinput_event_tablet_tool_get_dx() and
|
||||
libinput_event_tablet_tool_get_dy() can be used identical to the delta
|
||||
coordinates from any other pointer event. Any resolution differences between
|
||||
the x and y axes are accommodated for, a delta of N/N represents a 45 degree
|
||||
diagonal move on the tablet.
|
||||
|
||||
The delta coordinates are available for all tablet events, it is up to the
|
||||
caller to decide when a tool should be used in relative mode. It is
|
||||
recommended that mouse and lens cursor tool default to relative mode and
|
||||
all pen-like tools to absolute mode.
|
||||
|
||||
If a tool in relative mode must not use pointer acceleration, callers
|
||||
should use the absolute coordinates returned by
|
||||
libinput_event_tablet_tool_get_x() and libinput_event_tablet_tool_get_y()
|
||||
and calculate the delta themselves. Callers that require exact physical
|
||||
distance should also use these functions to calculate delta movements.
|
||||
|
||||
@section tablet-axes Special axes on tablet tools
|
||||
|
||||
A tablet tool usually provides additional information beyond x/y positional
|
||||
information and the tip state. A tool may provide the distance to the tablet
|
||||
surface and the pressure exerted on the tip when in contact. Some tablets
|
||||
additionally provide tilt information along the x and y axis.
|
||||
|
||||
@image html tablet-axes.svg "Illustration of the distance, pressure and tilt axes"
|
||||
|
||||
The granularity and precision of the distance and pressure axes varies
|
||||
between tablet devices and cannot usually be mapped into a physical unit.
|
||||
libinput normalizes distance and pressure into the [0, 1] range.
|
||||
|
||||
While the normalization range is identical for these axes, a caller should
|
||||
not interpret identical values as identical across axes, i.e. a value v1 on
|
||||
the distance axis has no relation to the same value v1 on the pressure axis.
|
||||
|
||||
The tilt axes provide the angle in degrees between a vertical line out of
|
||||
the tablet and the top of the stylus. The angle is measured along the x and
|
||||
y axis, respectively, a positive tilt angle thus means that the stylus' top
|
||||
is tilted towards the logical right and/or bottom of the tablet.
|
||||
|
||||
@section tablet-fake-proximity Handling of proximity events
|
||||
|
||||
libinput's @ref LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY events notify a caller
|
||||
when a tool comes into sensor range or leaves the sensor range. On some
|
||||
tools this range does not represent the physical range but a reduced
|
||||
tool-specific logical range. If the range is reduced, this is done
|
||||
transparent to the caller.
|
||||
|
||||
For example, the Wacom mouse and lens cursor tools are usually
|
||||
used in relative mode, lying flat on the tablet. Movement typically follows
|
||||
the interaction normal mouse movements have, i.e. slightly lift the tool and
|
||||
place it in a separate location. The proximity detection on Wacom
|
||||
tablets however extends further than the user may lift the mouse, i.e. the
|
||||
tool may not be lifted out of physical proximity. For such tools, libinput
|
||||
provides software-emulated proximity.
|
||||
|
||||
Events from the pad do not require proximity, they may be sent any time.
|
||||
|
||||
@section tablet-pressure-offset Pressure offset on worn-out tools
|
||||
|
||||
When a tool is used for an extended period it can wear down physically. A
|
||||
worn-down tool may never return a zero pressure value. Even when hovering
|
||||
above the surface, the pressure value returned by the tool is nonzero,
|
||||
creating a fake surface touch and making interaction with the tablet less
|
||||
predictable.
|
||||
|
||||
libinput automatically detects pressure offsets and rescales the remaining
|
||||
pressure range into the available range, making pressure-offsets transparent
|
||||
to the caller. A tool with a pressure offset will thus send a 0 pressure
|
||||
value for the detected offset and nonzero pressure values for values higher
|
||||
than that offset.
|
||||
|
||||
Some limitations apply to avoid misdetection of pressure offsets,
|
||||
specifically:
|
||||
- pressure offset is only detected on proximity in, and if a device is
|
||||
capable of detection distances,
|
||||
- pressure offset is only detected if the distance between the tool and the
|
||||
tablet is high enough,
|
||||
- pressure offset is only used if it is 20% or less of the pressure range
|
||||
available to the tool. A pressure offset higher than 20% indicates either
|
||||
a misdetection or a tool that should be replaced, and
|
||||
- if a pressure value less than the current pressure offset is seen, the
|
||||
offset resets to that value.
|
||||
|
||||
Pressure offsets are not detected on @ref LIBINPUT_TABLET_TOOL_TYPE_MOUSE
|
||||
and @ref LIBINPUT_TABLET_TOOL_TYPE_LENS tools.
|
||||
|
||||
@section tablet-serial-numbers Tracking unique tools
|
||||
|
||||
Some tools provide hardware information that enables libinput to uniquely
|
||||
identify the physical device. For example, tools compatible with the Wacom
|
||||
Intuos 4, Intuos 5, Intuos Pro and Cintiq series are uniquely identifiable
|
||||
through a serial number. libinput does not specify how a tool can be
|
||||
identified uniquely, a caller should use libinput_tablet_tool_is_unique() to
|
||||
check if the tool is unique.
|
||||
|
||||
libinput creates a struct libinput_tablet_tool on the first proximity in of
|
||||
this tool. By default, this struct is destroyed on proximity out and
|
||||
re-initialized on the next proximity in. If a caller keeps a reference to
|
||||
the tool by using libinput_tablet_tool_ref() libinput re-uses this struct
|
||||
whenever that same physical tool comes into proximity on any tablet
|
||||
recognized by libinput. It is possible to attach tool-specific virtual state
|
||||
to the tool. For example, a graphics program such as the GIMP may assign a
|
||||
specific color to each tool, allowing the artist to use the tools like
|
||||
physical pens of different color. In multi-tablet setups it is also
|
||||
possible to track the tool across devices.
|
||||
|
||||
If the tool does not have a unique identifier, libinput creates a single
|
||||
struct libinput_tablet_tool per tool type on each tablet the tool is used
|
||||
on.
|
||||
|
||||
@section tablet-tool-types Vendor-specific tablet tool types
|
||||
|
||||
libinput supports a number of high-level tool types that describe the
|
||||
general interaction expected with the tool. For example, a user would expect
|
||||
a tool of type @ref LIBINPUT_TABLET_TOOL_TYPE_PEN to interact with a
|
||||
graphics application taking pressure and tilt into account. The default
|
||||
virtual tool assigned should be a drawing tool, e.g. a virtual pen or brush.
|
||||
A tool of type @ref LIBINPUT_TABLET_TOOL_TYPE_ERASER would normally be
|
||||
mapped to an eraser-like virtual tool. See @ref libinput_tablet_tool_type
|
||||
for the list of all available tools.
|
||||
|
||||
Vendors may provide more fine-grained information about the tool in use by
|
||||
adding a hardware-specific tool ID. libinput provides this ID to the caller
|
||||
with libinput_tablet_tool_get_tool_id() but makes no promises about the
|
||||
content or format of the ID.
|
||||
|
||||
libinput currently supports Wacom-style tool IDs as provided on the Wacom
|
||||
Intuos 3, 4, 5, Wacon Cintiq and Wacom Intuos Pro series. The tool ID can
|
||||
be used to distinguish between e.g. a Wacom Classic Pen or a Wacom Pro Pen.
|
||||
It is the caller's responsibility to interpret the tool ID.
|
||||
|
||||
@section tablet-bounds Out-of-bounds motion events
|
||||
|
||||
Some tablets integrated into a screen (e.g. Wacom Cintiq 24HD, 27QHD and
|
||||
13HD series, etc.) have a sensor larger than the display area. libinput uses
|
||||
the range advertised by the kernel as the valid range unless device-specific
|
||||
quirks are present. Events outside this range will produce coordinates that
|
||||
may be negative or larger than the tablet's width and/or height. It is up to
|
||||
the caller to ignore these events.
|
||||
|
||||
@image html tablet-out-of-bounds.svg "Illustration of the out-of-bounds area on a tablet"
|
||||
|
||||
In the image above, the display area is shown in black. The red area around
|
||||
the display illustrates the sensor area that generates input events. Events
|
||||
within this area will have negative coordinate or coordinates larger than
|
||||
the width/height of the tablet.
|
||||
|
||||
If events outside the logical bounds of the input area are scaled into a
|
||||
custom range with libinput_event_tablet_tool_get_x_transformed() and
|
||||
libinput_event_tablet_tool_get_y_transformed() the resulting value may be
|
||||
less than 0 or larger than the upper range provided. It is up to the caller
|
||||
to test for this and handle or ignore these events accordingly.
|
||||
|
||||
@section tablet-pad-buttons Tablet pad button numbers
|
||||
|
||||
Tablet Pad buttons are numbered sequentially, starting with button 0. Thus
|
||||
button numbers returned by libinput_event_tablet_pad_get_button_number()
|
||||
have no semantic meaning, a notable difference to the button codes returned
|
||||
by other libinput interfaces (e.g. libinput_event_tablet_tool_get_button()).
|
||||
|
||||
The Linux kernel requires all input events to have semantic event codes,
|
||||
but generic buttons like those on a pad cannot easily be assigned semantic
|
||||
codes. The kernel supports generic codes in the form of BTN_0 through to
|
||||
BTN_9 and additional unnamed space up until code 0x10f. Additional generic
|
||||
buttons are available as BTN_A in the range dedicated for gamepads and
|
||||
joysticks. Thus, tablet with a large number of buttons have to map across
|
||||
two semantic ranges, have to use unnamed kernel button codes or risk leaking
|
||||
into an unrelated range. libinput transparently maps the kernel event codes
|
||||
into a sequential button range on the pad. Callers should use external
|
||||
sources like libwacom to associate button numbers to their position on the
|
||||
tablet.
|
||||
|
||||
Some buttons may have expected default behaviors. For example, on Wacom
|
||||
Intuos Pro series tablets, the button inside the touch ring is expected to
|
||||
switch between a mode switch. Mode switching is a feature implemented in the
|
||||
caller and libinput does not provide specific handling. Callers should use
|
||||
external sources like libwacom to identify which buttons have semantic
|
||||
behaviors.
|
||||
|
||||
*/
|
||||
70
doc/tapping.dox
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
@page tapping Tap-to-click behaviour
|
||||
|
||||
"Tapping" or "tap-to-click" is the name given to the behavior where a short
|
||||
finger touch down/up sequence maps into a button click. This is most
|
||||
commonly used on touchpads, but may be available on other devices.
|
||||
|
||||
libinput implements tapping for one, two, and three fingers, where supported
|
||||
by the hardware, and maps those taps into a left, right, and middle button
|
||||
click, respectively. Not all devices support three fingers, libinput will
|
||||
support tapping up to whatever is supported by the hardware. libinput does
|
||||
not support four-finger taps or any tapping with more than four fingers,
|
||||
even though some hardware can distinguish between that many fingers.
|
||||
|
||||
Tapping is **disabled** by default, see [this
|
||||
commit](http://cgit.freedesktop.org/wayland/libinput/commit/?id=2219c12c3aa45b80f235e761e87c17fb9ec70eae)
|
||||
because:
|
||||
- if you don't know that tapping is a thing (or enabled by default), you get
|
||||
spurious button events that make the desktop feel buggy.
|
||||
- if you do know what tapping is and you want it, you usually know where to
|
||||
enable it, or at least you can search for it.
|
||||
|
||||
Tapping can be enabled on a per-device basis. See
|
||||
libinput_device_config_tap_set_enabled() for details.
|
||||
|
||||
@section tapndrag Tap-and-drag
|
||||
|
||||
libinput also supports "tap-and-drag" where a tap immediately followed by a
|
||||
finger down and that finger being held down emulates a button press. Moving
|
||||
the finger around can thus drag the selected item on the screen.
|
||||
Tap-and-drag is optional and can be enabled or disabled with
|
||||
libinput_device_config_tap_set_drag_enabled(). Most devices have
|
||||
tap-and-drag enabled by default.
|
||||
|
||||
Also optional is a feature called "drag lock". With drag lock disabled, lifting
|
||||
the finger will stop any drag process. When enabled, libinput will ignore a
|
||||
finger up event during a drag process, provided the finger is set down again
|
||||
within a implementation-specific timeout. Drag lock can be enabled and
|
||||
disabled with libinput_device_config_tap_set_drag_lock_enabled().
|
||||
Note that drag lock only applies if tap-and-drag is be enabled.
|
||||
|
||||
@image html tap-n-drag.svg "Tap-and-drag process"
|
||||
|
||||
The above diagram explains the process, a tap (a) followed by a finger held
|
||||
down (b) starts the drag process and logically holds the left mouse button
|
||||
down. A movement of the finger (c) will drag the selected item until the
|
||||
finger is released (e). If needed and drag lock is enabled, the finger's
|
||||
position can be reset by lifting and quickly setting it down again on the
|
||||
touchpad (d). This will be interpreted as continuing move and is especially
|
||||
useful on small touchpads or with slow pointer acceleration.
|
||||
If drag lock is enabled, the release of the mouse buttons after the finger
|
||||
release (e) is triggered by a timeout. To release the button immediately,
|
||||
simply tap again (f).
|
||||
|
||||
If two fingers are supported by the hardware, a second finger can be used to
|
||||
drag while the first is held in-place.
|
||||
|
||||
@section tap_constraints Constraints while tapping
|
||||
|
||||
A couple of constraints apply to the contact to be converted into a press, the most common ones are:
|
||||
- the touch down and touch up must happen within an implementation-defined timeout
|
||||
- if a finger moves more than an implementation-defined distance while in contact, it's not a tap
|
||||
- tapping within @ref clickpad_softbuttons "clickpad software buttons" may not trigger an event
|
||||
- a tap not meeting required pressure thresholds can be ignored as accidental touch
|
||||
- a tap exceeding certain pressure thresholds can be ignored (see @ref
|
||||
palm_detection)
|
||||
- a tap on the edges of the touchpad can usually be ignored (see @ref
|
||||
palm_detection)
|
||||
|
||||
*/
|
||||
92
doc/test-suite.dox
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
@page test-suite libinput test suite
|
||||
|
||||
The libinput test suite is based on
|
||||
[Check](http://check.sourceforge.net/doc/check_html/) and runs automatically
|
||||
during `make check`. Check itself is wrapped into a libinput-specific test
|
||||
suite called *litest*. Tests are found in `$srcdir/test/`, the test binaries are
|
||||
prefixed with `test-` and can be run individually.
|
||||
|
||||
@section test-config X.Org config to avoid interference
|
||||
|
||||
uinput devices created by the test suite are usually recognised by X as
|
||||
input devices. All events sent through these devices will generate X events
|
||||
and interfere with your desktop.
|
||||
|
||||
Copy the file `$srcdir/test/50-litest.conf` into your `/etc/X11/xorg.conf.d`
|
||||
and restart X. This will ignore any litest devices and thus not interfere
|
||||
with your desktop.
|
||||
|
||||
@section test-root Permissions required to run tests
|
||||
|
||||
Most tests require the creation of uinput devices and access to the
|
||||
resulting `/dev/input/eventX` nodes. Some tests require temporary udev rules.
|
||||
<b>This usually requires the tests to be run as root</b>.
|
||||
|
||||
@section test-filtering Selective running of tests
|
||||
|
||||
litest's tests are grouped by test groups and devices. A test group is e.g.
|
||||
"touchpad:tap" and incorporates all tapping-related tests for touchpads.
|
||||
Each test function is (usually) run with one or more specific devices.
|
||||
The `--list` commandline argument shows the list of suites and tests.
|
||||
@code
|
||||
$ ./test/test-device --list
|
||||
device:wheel:
|
||||
wheel only
|
||||
blackwidow
|
||||
device:invalid devices:
|
||||
no device
|
||||
device:group:
|
||||
no device
|
||||
logitech trackball
|
||||
MS surface cover
|
||||
mouse_roccat
|
||||
wheel only
|
||||
blackwidow
|
||||
...
|
||||
@endcode
|
||||
|
||||
In the above example, the "device:wheel" suite is run for the "wheel only" and
|
||||
the "blackwidow" device. Both devices are automatically instantiated through
|
||||
uinput by litest. The "no device" entry signals that litest does not
|
||||
instantiate a uinput device for a specific test (though the test itself may
|
||||
instantiate one).
|
||||
|
||||
The `--filter-test` argument enables selective running of tests through
|
||||
basic shell-style function name matching. For example:
|
||||
|
||||
@code
|
||||
$ ./test/test-touchpad --filter-test="*1fg_tap*"
|
||||
@endcode
|
||||
|
||||
The `--filter-device` argument enables selective running of tests through
|
||||
basic shell-style device name matching. The device names matched are the
|
||||
litest-specific shortnames, see the output of `--list`. For example:
|
||||
|
||||
@code
|
||||
$ ./test/test-touchpad --filter-device="synaptics*"
|
||||
@endcode
|
||||
|
||||
The `--filter-group` argument enables selective running of test groups
|
||||
through basic shell-style test group matching. The test groups matched are
|
||||
litest-specific test groups, see the output of `--list`. For example:
|
||||
|
||||
@code
|
||||
$ ./test/test-touchpad --filter-group="touchpad:*hover*"
|
||||
@endcode
|
||||
|
||||
The `--filter-device` and `--filter-group` arguments can be combined with
|
||||
`--list` to show which groups and devices will be affected.
|
||||
|
||||
@section test-verbosity Controlling test output
|
||||
|
||||
Each test supports the `--verbose` commandline option to enable debugging
|
||||
output, see libinput_log_set_priority() for details. The `LITEST_VERBOSE`
|
||||
environment variable, if set, also enables verbose mode.
|
||||
|
||||
@code
|
||||
$ ./test/test-device --verbose
|
||||
$ LITEST_VERBOSE=1 make check
|
||||
@endcode
|
||||
|
||||
*/
|
||||
102
doc/tools.dox
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
@page tools Helper tools
|
||||
|
||||
libinput provides a couple of tools to query state and events. Two of these
|
||||
tools are usually installed, others are @ref developer_tools only.
|
||||
|
||||
@section user_tools User tools
|
||||
|
||||
libinput ships with two tools to gather information about devices:
|
||||
@ref libinput-list-devices and @ref libinput-debug-events. Both tools must
|
||||
be run as root to have access to the kernel's @c /dev/input/event* device
|
||||
files.
|
||||
|
||||
@subsection libinput-list-devices
|
||||
|
||||
The libinput-list-devices tool shows information about devices recognized by
|
||||
libinput and can help identifying why a device behaves different than
|
||||
expected. For example, if a device does not show up in the output, it is not
|
||||
a supported input device.
|
||||
|
||||
@verbatim
|
||||
$ sudo libinput-list-devices
|
||||
[...]
|
||||
Device: SynPS/2 Synaptics TouchPad
|
||||
Kernel: /dev/input/event4
|
||||
Group: 9
|
||||
Seat: seat0, default
|
||||
Size: 97.33x66.86mm
|
||||
Capabilities: pointer
|
||||
Tap-to-click: disabled
|
||||
Tap drag lock: disabled
|
||||
Left-handed: disabled
|
||||
Nat.scrolling: disabled
|
||||
Middle emulation: n/a
|
||||
Calibration: n/a
|
||||
Scroll methods: *two-finger
|
||||
Click methods: *button-areas clickfinger
|
||||
[...]
|
||||
@endverbatim
|
||||
|
||||
The above listing shows example output for a touchpad. The
|
||||
libinput-list-devices tool lists general information about the device (the
|
||||
kernel event node) but also the configuration options. If an option is
|
||||
"n/a" it does not exist on this device. Otherwise, the tool will show the
|
||||
default configuration for this device, for options that have more than a
|
||||
binary state all available options are listed, with the default one prefixed
|
||||
with an asterisk (*). In the example above, the default click method is
|
||||
button-areas but clickinger is available.
|
||||
|
||||
Note that the default configuration may differ from the configuration
|
||||
applied by the desktop environment.
|
||||
|
||||
@note This tool is intended to be human-readable and may change its output
|
||||
at any time.
|
||||
|
||||
@subsection libinput-debug-events
|
||||
This is an installed version of the @ref event-debug developer tool. It
|
||||
prints events from devices and can help to identify why a device behaves
|
||||
different than expected.
|
||||
|
||||
@verbatim
|
||||
$ sudo libinput-debug-events --enable-tapping --set-click-method=clickfinger
|
||||
@endverbatim
|
||||
|
||||
See the man page or the @c --help output for information about the available
|
||||
options.
|
||||
|
||||
@section developer_tools Developer tools
|
||||
|
||||
The two most common tools used by developers are @ref event-debug and @ref
|
||||
event-gui.
|
||||
|
||||
@subsection event-debug
|
||||
This is the in-tree version of the @ref libinput-debug-events tool and is
|
||||
linked to allow for easy debugging (i.e. it avoids libtool shenanigans). The
|
||||
code is the same. For debugging, run it against a single device only and
|
||||
enable the --verbose flag. This will print the various state machine
|
||||
transitions in addition to the events.
|
||||
|
||||
@verbatim
|
||||
$ sudo ./tools/event-debug --verbose --device /dev/input/event3
|
||||
@endverbatim
|
||||
|
||||
See the @c --help output for information about the available options.
|
||||
|
||||
@subsection event-gui
|
||||
|
||||
A simple GTK-based graphical tool that shows the behavior and location of
|
||||
touch events, pointer motion, scroll axes and gestures. Since this tool
|
||||
gathers data directly from libinput, it is thus suitable for
|
||||
pointer-acceleration testing.
|
||||
|
||||
@verbatim
|
||||
$ sudo ./tools/event-gui
|
||||
@endverbatim
|
||||
|
||||
See the @c --help output for information about the available options.
|
||||
|
||||
@note The @c --grab flag puts an exclusive @c EVIOCGRAB on the device to
|
||||
avoid interference with the desktop while testing.
|
||||
|
||||
*/
|
||||
|
Before Width: | Height: | Size: 147 KiB |
54
doc/touchpad-jumping-cursors.dox
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
@page touchpad_jumping_cursor Touchpad jumping cursor bugs
|
||||
|
||||
A common bug encountered on touchpads is a cursor jump when alternating
|
||||
between fingers on a multi-touch-capable touchpad. For example, after moving
|
||||
the cursor a user may use a second finger in the software button area to
|
||||
physically click the touchpad. Upon setting the finger down, the cursor
|
||||
exhibits a jump towards the bottom left or right, depending on the finger
|
||||
position.
|
||||
|
||||
When libinput detects a cursor jump it prints a bug warning to the log with
|
||||
the text <b>"Touch jump detected and discarded."</b> and a link to this page.
|
||||
|
||||
In most cases, this is a bug in the kernel driver and to libinput it appears
|
||||
that the touch point moves from its previous position. The pointer jump can
|
||||
usually be seen in the evemu-record output for the device:
|
||||
|
||||
<pre>
|
||||
E: 249.206319 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||
E: 249.218008 0003 0035 3764 # EV_ABS / ABS_MT_POSITION_X 3764
|
||||
E: 249.218008 0003 0036 2221 # EV_ABS / ABS_MT_POSITION_Y 2221
|
||||
E: 249.218008 0003 003a 0065 # EV_ABS / ABS_MT_PRESSURE 65
|
||||
E: 249.218008 0003 0000 3764 # EV_ABS / ABS_X 3764
|
||||
E: 249.218008 0003 0001 2216 # EV_ABS / ABS_Y 2216
|
||||
E: 249.218008 0003 0018 0065 # EV_ABS / ABS_PRESSURE 65
|
||||
E: 249.218008 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||
E: 249.230881 0003 0035 3752 # EV_ABS / ABS_MT_POSITION_X 3752
|
||||
E: 249.230881 0003 003a 0046 # EV_ABS / ABS_MT_PRESSURE 46
|
||||
E: 249.230881 0003 0000 3758 # EV_ABS / ABS_X 3758
|
||||
E: 249.230881 0003 0018 0046 # EV_ABS / ABS_PRESSURE 46
|
||||
E: 249.230881 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||
E: 249.242648 0003 0035 1640 # EV_ABS / ABS_MT_POSITION_X 1640
|
||||
E: 249.242648 0003 0036 4681 # EV_ABS / ABS_MT_POSITION_Y 4681
|
||||
E: 249.242648 0003 003a 0025 # EV_ABS / ABS_MT_PRESSURE 25
|
||||
E: 249.242648 0003 0000 1640 # EV_ABS / ABS_X 1640
|
||||
E: 249.242648 0003 0001 4681 # EV_ABS / ABS_Y 4681
|
||||
E: 249.242648 0003 0018 0025 # EV_ABS / ABS_PRESSURE 25
|
||||
E: 249.242648 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||
E: 249.254568 0003 0035 1648 # EV_ABS / ABS_MT_POSITION_X 1648
|
||||
E: 249.254568 0003 003a 0027 # EV_ABS / ABS_MT_PRESSURE 27
|
||||
E: 249.254568 0003 0000 1644 # EV_ABS / ABS_X 1644
|
||||
E: 249.254568 0003 0018 0027 # EV_ABS / ABS_PRESSURE 27
|
||||
</pre>
|
||||
|
||||
In this recording, the pointer jumps from its position 3752/2216 to
|
||||
1640/4681 within a single frame. On this particular touchpad, this would
|
||||
represent a physical move of almost 50mm. libinput detects some of these
|
||||
jumps and discards the movement but otherwise continues as usual. However,
|
||||
the bug should be fixed at the kernel level.
|
||||
|
||||
When you encounter the warning in the log, please generate an evemu
|
||||
recording of your touchpad and file a bug. See @ref reporting_bugs for more
|
||||
details.
|
||||
*/
|
||||
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 127 KiB |
162
doc/touchpads.dox
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
@page touchpads Touchpads
|
||||
|
||||
This page provides an outline of touchpad devices. Touchpads aren't simply
|
||||
categorised into a single type, instead they have a set of properties, a
|
||||
combination of number of physical buttons, multitouch support abilities and
|
||||
other properties.
|
||||
|
||||
@section touchpads_buttons Number of buttons
|
||||
|
||||
@subsection touchapds_buttons_phys Physically separate buttons
|
||||
|
||||
Touchpads with physical buttons usually provide two buttons, left and right.
|
||||
A few touchpads with three buttons exist, and Apple used to have touchpads
|
||||
with a single physical buttons until ca 2008. Touchpads with only two
|
||||
buttons require the software stack to emulate a middle button. libinput does
|
||||
this when both buttons are pressed simultaneously.
|
||||
|
||||
Note that many Lenovo laptops provide a pointing stick above the touchpad.
|
||||
This pointing stick has a set of physical buttons just above the touchpad.
|
||||
While many users use those as substitute touchpad buttons, they logically
|
||||
belong to the pointing stick. The *40 and *50 series are an exception here,
|
||||
the former had no physical buttons on the touchpad and required the top
|
||||
section of the pad to emulate pointing stick buttons, the *50 series has
|
||||
physical buttons but they are wired to the touchpads. The kernel re-routes
|
||||
those buttons through the trackstick device. See @ref t440_support for more
|
||||
information.
|
||||
|
||||
@subsection touchpads_buttons_clickpads Clickpads
|
||||
|
||||
Clickpads are the most common type of touchpads these days. A Clickpad has
|
||||
no separate physical buttons, instead the touchpad itself is clickable as a
|
||||
whole, i.e. a user presses down on the touch area and triggers a physical
|
||||
click. Clickpads thus only provide a single button, everything else needs to
|
||||
be software-emulated. See @ref clickpad_softbuttons for more information.
|
||||
|
||||
Clickpads are labelled by the kernel with the @c INPUT_PROP_BUTTONPAD input
|
||||
property.
|
||||
|
||||
@subsection touchpads_buttons_forcepads Forcepads
|
||||
|
||||
Forcepads are Clickpads without a physical button underneath the hardware.
|
||||
They provide pressure and may have a vibration element that is
|
||||
software-controlled. This element can simulate the feel of a physical
|
||||
click or be co-opted for other tasks.
|
||||
|
||||
|
||||
@section touchpads_touch Touch capabilities
|
||||
|
||||
Virtually all touchpads available now can <b>detect</b> multiple fingers on
|
||||
the touchpad, i.e. provide information on how many fingers are on the
|
||||
touchpad. The touch capabilities described here specify how many fingers a
|
||||
device can <b>track</b>, i.e. provide reliable positional information for.
|
||||
In the kernel each finger is tracked in a so-called "slot", the number of
|
||||
slots thus equals the number of simultaneous touches a device can track.
|
||||
|
||||
@subsection touchapds_touch_st Single-touch touchpads
|
||||
|
||||
Single-finger touchpads can track a single touchpoint. Most single-touch
|
||||
touchpads can also detect three fingers on the touchpad, but no positional
|
||||
information is provided for those. In libinput, these touches are termed
|
||||
"fake touches". The kernel sends @c BTN_TOOL_DOUBLETAP, @c
|
||||
BTN_TOOL_TRIPLETAP, @c BTN_TOOL_QUADTAP and @c BTN_TOOL_QUINTTAP events when
|
||||
multiple fingers are detected.
|
||||
|
||||
@subsection touchpads_touch_mt Pure multi-touch touchpads
|
||||
|
||||
Pure multi-touch touchpads are those that can track, i.e. identify the
|
||||
location of all fingers on the touchpad. Apple's touchpads support 16
|
||||
touches, others support 5 touches like the Synaptics touchpads when using
|
||||
SMBus.
|
||||
|
||||
These touchpads usually also provide extra information. Apple touchpads
|
||||
provide an ellipse and the orientation of the ellipse for each touch point.
|
||||
Other touchpads provide a pressure value for each touch point (see @ref
|
||||
touchpads_pressure_handling).
|
||||
|
||||
Note that the kernel sends @c BTN_TOOL_DOUBLETAP, @c
|
||||
BTN_TOOL_TRIPLETAP, @c BTN_TOOL_QUADTAP and @c BTN_TOOL_QUINTTAP events for
|
||||
all touches for backwards compatibility. libinput ignores these events if
|
||||
the touchpad can track touches correctly.
|
||||
|
||||
@subsection touchpads_touch_partial_mt Partial multi-touch touchpads
|
||||
|
||||
The vast majority of touchpads fall into this category, the half-way
|
||||
point between single-touch and pure multi-touch. These devices can track N
|
||||
fingers, but detect more than N. For example, when using the serial
|
||||
protocol, Synaptics touchpads can track two fingers but may detect up to
|
||||
five.
|
||||
|
||||
The number of slots may limit which features are available in libinput.
|
||||
Any device with two slots can support two-finger scrolling, but @ref
|
||||
thumb-detection or @ref palm_detection may be limited if only two slots are
|
||||
available.
|
||||
|
||||
@subsection touchpads_touch_semi_mt Semi-mt touchpads
|
||||
|
||||
A sub-class of partial multi-touch touchpads. These touchpads can
|
||||
technically detect two fingers but the location of both is limited to the
|
||||
bounding box, i.e. the first touch is always the top-left one and the second
|
||||
touch is the bottom-right one. Coordinates jump around as fingers move past
|
||||
each other.
|
||||
|
||||
Many semi-mt touchpads also have a lower resolution for the second touch, or
|
||||
both touches. This may limit some features such as @ref gestures or
|
||||
@ref scrolling.
|
||||
|
||||
Semi-mt are labelled by the kernel with the @c INPUT_PROP_SEMI_MT input
|
||||
property.
|
||||
|
||||
@section touchpads_mis Other touchpad properties
|
||||
|
||||
@subsection touchpads_external External touchpads
|
||||
|
||||
External touchpads are USB or Bluetooth touchpads not in a laptop chassis,
|
||||
e.g. Apple Magic Trackpad or the Logitech T650. These are usually @ref
|
||||
touchpads_buttons_clickpads the biggest difference is that they can be
|
||||
removed or added at runtime.
|
||||
|
||||
One interaction method that is only possible on external touchpads is a
|
||||
thumb resting on the very edge/immediately next to the touchpad. On the far
|
||||
edge, touchpads don't always detect the finger location so clicking with a
|
||||
thumb barely touching the edge makes it hard or impossible to figure out
|
||||
which software button area the finger is on.
|
||||
|
||||
These touchpads also don't need @ref palm_detection - since they're not
|
||||
located underneath the keyboard, accidental palm touches are a non-issue.
|
||||
|
||||
@subsection touchpads_pressure_handling Touchpads pressure handling
|
||||
|
||||
Pressure is usually directly related to contact area. Human fingers flatten
|
||||
out as the pressure on the pad increases, resulting in a bigger contact area
|
||||
and the firmware then calculates that back into a pressure reading.
|
||||
|
||||
libinput uses pressure to detect accidental palm contact and thumbs, though
|
||||
pressure data is often device-specific and unreliable.
|
||||
|
||||
@subsection touchpads_circular Circular touchpads
|
||||
|
||||
Only listed for completeness, circular touchpads have not been used in
|
||||
laptops for a number of years. These touchpad shaped in an ellipse or
|
||||
straight.
|
||||
|
||||
@subsection touchpads_tablets Graphics tablets
|
||||
|
||||
Touch-capable graphics tablets are effectively external touchpads, with two
|
||||
differentiators: they are larger than normal touchpads and they have no
|
||||
regular touchpad buttons. They either work like a @ref
|
||||
touchpads_buttons_forcepads Forcepad, or rely on interaction methods that
|
||||
don't require buttons (like @ref tapping). Since the physical device is
|
||||
shared with the pen input, some touch arbitration is required to avoid touch
|
||||
input interfering when the pen is in use.
|
||||
|
||||
@subsection touchpads_edge_zone Dedicated edge scroll area
|
||||
|
||||
Before @ref twofinger_scrolling became the default scroll method, some
|
||||
touchpads provided a marking on the touch area that designates the
|
||||
edge to be used for scrolling. A finger movement in that edge zone should
|
||||
trigger vertical motions. Some touchpads had markers for a horizontal
|
||||
scroll area too at the bottom of the touchpad.
|
||||
*/
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
:orphan:
|
||||
|
||||
===
|
||||
404
|
||||
===
|
||||
|
||||
This page has permanently moved, probably to `<@TARGET@>`_
|
||||
|
||||
This placeholder page will be removed soon.
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
.. _absolute_coordinate_ranges:
|
||||
|
||||
==============================================================================
|
||||
Coordinate ranges for absolute axes
|
||||
==============================================================================
|
||||
|
||||
libinput requires that all touchpads provide a correct axis range and
|
||||
resolution. These are used to enable or disable certain features or adapt
|
||||
the interaction with the touchpad. For example, the software button area is
|
||||
narrower on small touchpads to avoid reducing the interactive surface too
|
||||
much. Likewise, palm detection works differently on small touchpads as palm
|
||||
interference is less likely to happen.
|
||||
|
||||
Touchpads with incorrect axis ranges generate error messages
|
||||
in the form:
|
||||
<blockquote>
|
||||
Axis 0x35 value 4000 is outside expected range [0, 3000]
|
||||
</blockquote>
|
||||
|
||||
This error message indicates that the ABS_MT_POSITION_X axis (i.e. the x
|
||||
axis) generated an event outside the expected range of 0-3000. In this case
|
||||
the value was 4000.
|
||||
This discrepancy between the coordinate range the kernels advertises vs.
|
||||
what the touchpad sends can be the source of a number of perceived
|
||||
bugs in libinput.
|
||||
|
||||
.. _absolute_coordinate_ranges_fix:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Measuring and fixing touchpad ranges
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
To fix the touchpad you need to:
|
||||
|
||||
#. measure the physical size of your touchpad in mm
|
||||
#. run the ``libinput measure touchpad-size`` tool
|
||||
#. verify the hwdb entry provided by this tool
|
||||
#. test locally
|
||||
#. send a patch to the `systemd project <https://github.com/systemd/systemd>`_.
|
||||
|
||||
Detailed explanations are below.
|
||||
|
||||
The ``libinput measure touchpad-size`` tool is an interactive tool. It must
|
||||
be called with the physical dimensions of the touchpad in mm. In the example
|
||||
below, we use 100mm wide and 55mm high. The tool will find the touchpad device
|
||||
automatically.
|
||||
|
||||
::
|
||||
|
||||
$> sudo libinput measure touchpad-size 100x55
|
||||
Using "Touchpad SynPS/2 Synaptics TouchPad": /dev/input/event4
|
||||
|
||||
Kernel specified touchpad size: 99.7x75.9mm
|
||||
User specified touchpad size: 100.0x55.0mm
|
||||
|
||||
Kernel axis range: x [1024..5112], y [2024..4832]
|
||||
Detected axis range: x [ 0.. 0], y [ 0.. 0]
|
||||
|
||||
Move one finger along all edges of the touchpad
|
||||
until the detected axis range stops changing.
|
||||
|
||||
...
|
||||
|
||||
Move the finger around until the detected axis range matches the data sent
|
||||
by the device. ``Ctrl+C`` terminates the tool and prints a
|
||||
suggested hwdb entry. ::
|
||||
|
||||
...
|
||||
Kernel axis range: x [1024..5112], y [2024..4832]
|
||||
^C
|
||||
Detected axis range: x [2072..4880], y [2159..4832]
|
||||
Resolutions calculated based on user-specified size: x 28, y 49 units/mm
|
||||
|
||||
Suggested hwdb entry:
|
||||
Note: the dmi modalias match is a guess based on your machine's modalias:
|
||||
dmi:bvnLENOVO:bvrGJET72WW(2.22):bd02/21/2014:svnLENOVO:pn20ARS25701:pvrThinkPadT440s:rvnLENOVO:rn20ARS25701:rvrSDK0E50512STD:cvnLENOVO:ct10:cvrNotAvailable:
|
||||
Please verify that this is the most sensible match and adjust if necessary.
|
||||
-8<--------------------------
|
||||
# Laptop model description (e.g. Lenovo X1 Carbon 5th)
|
||||
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadT440s*
|
||||
EVDEV_ABS_00=2072:4880:28
|
||||
EVDEV_ABS_01=2159:4832:49
|
||||
EVDEV_ABS_35=2072:4880:28
|
||||
EVDEV_ABS_36=2159:4832:49
|
||||
-8<--------------------------
|
||||
Instructions on what to do with this snippet are in /usr/lib/udev/hwdb.d/60-evdev.hwdb
|
||||
|
||||
|
||||
If there are discrepancies between the coordinate range the kernels
|
||||
advertises and what what the touchpad sends, the hwdb entry should be added to the
|
||||
``60-evdev.hwdb`` file provided by the `systemd project <https://github.com/systemd/systemd>`_.
|
||||
An example commit can be found
|
||||
`here <https://github.com/systemd/systemd/commit/26f667eac1c5e89b689aa0a1daef6a80f473e045>`_.
|
||||
|
||||
The ``libinput measure touchpad-size`` tool attempts to provide the correct
|
||||
dmi match but it does require user verification.
|
||||
|
||||
In most cases the dmi match can and should be trimmed to the system vendor (``svn``)
|
||||
and the product version (``pvr``) or product name (``pn``), with everything else
|
||||
replaced by a wildcard (``*``). In the above case, the match string is:
|
||||
|
||||
::
|
||||
|
||||
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadT440s*
|
||||
|
||||
As a general rule: for Lenovo devices use ``pvr`` and for all others use
|
||||
``pn``.
|
||||
|
||||
.. note:: hwdb match strings only allow for alphanumeric ascii characters. Use a
|
||||
wildcard (* or ?, whichever appropriate) for special characters.
|
||||
|
||||
The actual axis overrides are in the form:
|
||||
|
||||
::
|
||||
|
||||
# axis number=min:max:resolution
|
||||
EVDEV_ABS_00=2072:4880:28
|
||||
|
||||
or, if the range is correct but the resolution is wrong
|
||||
|
||||
::
|
||||
|
||||
# axis number=::resolution
|
||||
EVDEV_ABS_00=::28
|
||||
|
||||
|
||||
Note the leading single space. The axis numbers are in hex and can be found
|
||||
in ``linux/input-event-codes.h``. For touchpads ``ABS_X``, ``ABS_Y``,
|
||||
``ABS_MT_POSITION_X`` and ``ABS_MT_POSITION_Y`` are required.
|
||||
|
||||
.. note:: The touchpad's ranges and/or resolution should only be fixed when
|
||||
there is a significant discrepancy. A few units do not make a
|
||||
difference and a resolution that is off by 2 or less usually does
|
||||
not matter either.
|
||||
|
||||
Once a match and override rule has been found, follow the instructions at
|
||||
the top of the
|
||||
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`_
|
||||
file to save it locally and trigger the udev hwdb reload. Rebooting is
|
||||
always a good idea. If the match string is correct, the new properties will
|
||||
show up in the
|
||||
output of
|
||||
|
||||
::
|
||||
|
||||
udevadm info /sys/class/input/event4
|
||||
|
||||
|
||||
Adjust the command for the event node of your touchpad.
|
||||
A udev builtin will apply the new axis ranges automatically.
|
||||
|
||||
When the axis override is confirmed to work, please submit it as a pull
|
||||
request to the `systemd project <https://github.com/systemd/systemd>`_.
|
||||
|
|
@ -1,416 +0,0 @@
|
|||
.. _architecture:
|
||||
|
||||
==============================================================================
|
||||
libinput's internal architecture
|
||||
==============================================================================
|
||||
|
||||
This page provides an outline of libinput's internal architecture. The goal
|
||||
here is to get the high-level picture across and point out the components
|
||||
and their interplay to new developers.
|
||||
|
||||
The public facing API is in ``libinput.c``, this file is thus the entry point
|
||||
for almost all API calls. General device handling is in ``evdev.c`` with the
|
||||
device-type-specific implementations in ``evdev-<type>.c``. It is not
|
||||
necessary to understand all of libinput to contribute a patch.
|
||||
|
||||
As of libinput 1.29 libinput has an internal plugin pipeline that modifies
|
||||
the event stream before libinput proper sees it, see
|
||||
:ref:`architecture-plugins`.
|
||||
|
||||
:ref:`architecture-contexts` is the only user-visible implementation detail,
|
||||
everything else is purely internal implementation and may change when
|
||||
required.
|
||||
|
||||
.. _architecture-contexts:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
The udev and path contexts
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The first building block is the "context" which can be one of
|
||||
two types, "path" and "udev". See **libinput_path_create_context()** and
|
||||
**libinput_udev_create_context()**. The path/udev specific bits are in
|
||||
``path-seat.c`` and ``udev-seat.c``. This includes the functions that add new
|
||||
devices to a context.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
libudev [label="libudev 'add' event"]
|
||||
udev [label="**libinput_udev_create_context()**"];
|
||||
udev_backend [label="udev-specific backend"];
|
||||
context [label="libinput context"]
|
||||
udev -> udev_backend;
|
||||
libudev -> udev_backend;
|
||||
udev_backend -> context;
|
||||
}
|
||||
|
||||
|
||||
The udev context provides automatic device hotplugging as udev's "add"
|
||||
events are handled directly by libinput. The path context requires that the
|
||||
caller adds devices.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
path [label="**libinput_path_create_context()**"];
|
||||
path_backend [label="path-specific backend"];
|
||||
xdriver [label="**libinput_path_add_device()**"]
|
||||
context [label="libinput context"]
|
||||
path -> path_backend;
|
||||
xdriver -> path_backend;
|
||||
path_backend -> context;
|
||||
}
|
||||
|
||||
|
||||
As a general rule: all Wayland compositors use a udev context, the X.org
|
||||
stack uses a path context.
|
||||
|
||||
Which context was initialized only matters for creating/destroying a context
|
||||
and adding devices. The device handling itself is the same for both types of
|
||||
context.
|
||||
|
||||
.. _architecture-device:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Device initialization
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput only supports evdev devices, all the device initialization is done
|
||||
in ``evdev.c``. Much of the libinput public API is also a thin wrapper around
|
||||
the matching implementation in the evdev device.
|
||||
|
||||
There is a 1:1 mapping between libinput devices and ``/dev/input/eventX``
|
||||
device nodes.
|
||||
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
devnode [label="/dev/input/event0"]
|
||||
|
||||
libudev [label="libudev 'add' event"]
|
||||
xdriver [label="**libinput_path_add_device()**"]
|
||||
context [label="libinput context"]
|
||||
|
||||
evdev [label="evdev_device_create()"]
|
||||
|
||||
devnode -> xdriver;
|
||||
devnode -> libudev;
|
||||
xdriver -> context;
|
||||
libudev -> context;
|
||||
|
||||
context->evdev;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Entry point for all devices is ``evdev_device_create()``, this function
|
||||
decides to create a ``struct evdev_device`` for the given device node.
|
||||
Based on the udev tags (e.g. ``ID_INPUT_TOUCHPAD``), a
|
||||
:ref:`architecture-dispatch` is initialized. All event handling is then in this
|
||||
dispatch.
|
||||
|
||||
Rejection of devices and the application of quirks is generally handled in
|
||||
``evdev.c`` as well. Common functionality shared across multiple device types
|
||||
(like button-scrolling) is also handled here.
|
||||
|
||||
.. _architecture-dispatch:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Device-type specific event dispatch
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Depending on the device type, ``evdev_configure_device`` creates the matching
|
||||
``struct evdev_dispatch``. This dispatch interface contains the function
|
||||
pointers to handle events. Four such dispatch methods are currently
|
||||
implemented: touchpad, tablet, tablet pad, and the fallback dispatch which
|
||||
handles mice, keyboards and touchscreens.
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
evdev [label="evdev_device_create()"]
|
||||
|
||||
fallback [label="evdev-fallback.c"]
|
||||
touchpad [label="evdev-mt-touchpad.c"]
|
||||
tablet [label="evdev-tablet.c"]
|
||||
pad [label="evdev-tablet-pad.c"]
|
||||
|
||||
evdev -> fallback;
|
||||
evdev -> touchpad;
|
||||
evdev -> tablet;
|
||||
evdev -> pad;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Event dispatch is done per "evdev frame", a collection of events up until including
|
||||
the ``SYN_REPORT``. One such ``struct evdev_frame`` represents all state **updates**
|
||||
to the previous frame.
|
||||
|
||||
While ``evdev.c`` pulls the event out of libevdev, the actual handling of the
|
||||
events is performed within the dispatch method.
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
evdev [label="evdev_device_dispatch()"]
|
||||
|
||||
plugins [label="plugin pipline"]
|
||||
|
||||
fallback [label="fallback_interface_process()"];
|
||||
touchpad [label="tp_interface_process()"]
|
||||
tablet [label="tablet_process()"]
|
||||
pad [label="pad_process()"]
|
||||
|
||||
evdev -> plugins;
|
||||
plugins -> fallback;
|
||||
plugins -> touchpad;
|
||||
plugins -> tablet;
|
||||
plugins -> pad;
|
||||
}
|
||||
|
||||
|
||||
The dispatch methods then look at the ``struct evdev_frame`` and proceed to
|
||||
update the state.
|
||||
|
||||
.. _architecture-plugins:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
The Plugin Pipeline
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
As of libinput 1.29 libinput has an **internal** plugin pipeline. These plugins
|
||||
logically sit between libevdev and the :ref:`architecture-dispatch` and modify
|
||||
the device and/or event stream. The primary motivation of such plugins is that
|
||||
modifying the event stream is often simpler than analyzing the state later.
|
||||
|
||||
Plugins are loaded on libinput context startup and are executed in-order. The last
|
||||
plugin is the hardcoded `evdev-plugin.c` which takes the modified event stream and
|
||||
passes the events to the dispatch.
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
evdev [label="evdev_device_dispatch()"]
|
||||
|
||||
p1 [label="P1"]
|
||||
p2 [label="P2"]
|
||||
p3 [label="P3"]
|
||||
ep [label="evdev-plugin"]
|
||||
|
||||
fallback [label="fallback_interface_process()"];
|
||||
touchpad [label="tp_interface_process()"]
|
||||
tablet [label="tablet_process()"]
|
||||
pad [label="pad_process()"]
|
||||
|
||||
evdev -> p1;
|
||||
p1 -> p2;
|
||||
p2 -> p3;
|
||||
p3 -> ep;
|
||||
ep -> fallback;
|
||||
ep -> touchpad;
|
||||
ep -> tablet;
|
||||
ep -> pad;
|
||||
}
|
||||
|
||||
Each plugin may not only modify the current event frame (this includes adding/removing events
|
||||
from the frame), it may also append or prepend additional event frames. For
|
||||
example the tablet proximity-timer plugin adds proximity in/out events to the
|
||||
event stream.
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
n0 [label= "", shape=none,height=.0,width=.0]
|
||||
n1 [label= "", shape=none,height=.0,width=.0]
|
||||
|
||||
p1 [label="P1"]
|
||||
p2 [label="P2"]
|
||||
p3 [label="P3"]
|
||||
ep [label="evdev-plugin"]
|
||||
|
||||
n0 -> p1 [label="F1"];
|
||||
p1 -> p2 [label="F1"];
|
||||
p2 -> p3 [label="F1,F2"];
|
||||
p3 -> ep [label="F3,F1,F2"];
|
||||
ep -> n1 [label="F3,F1,F2"];
|
||||
}
|
||||
|
||||
In the diagram above, the plugin ``P2`` *appends* a new frame (``F2``), the plugin ``P3``
|
||||
*prepends* a new frame (``F3``). The original event frame ``F1`` thus becomes the event frame
|
||||
sequence ``F3``, ``F1``, ``F2`` by the time it reaches the :ref:`architecture-dispatch`.
|
||||
|
||||
Note that each plugin only sees one event frame at a time, so ``P3`` would see ``F1`` first,
|
||||
decides to prepend ``F3`` and passes ``F1`` through. It then sees ``F2`` but does nothing with
|
||||
it (optionally modified in-place).
|
||||
|
||||
.. _architecture-configuration:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Device configuration
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
All device-specific configuration is handled through ``struct
|
||||
libinput_device_config_FOO`` instances. These are set up during device init
|
||||
and provide the function pointers for the ``get``, ``set``, ``get_default``
|
||||
triplet of configuration queries (or more, where applicable).
|
||||
|
||||
For example, the ``struct tablet_dispatch`` for tablet devices has a
|
||||
``struct libinput_device_config_accel``. This struct is set up with the
|
||||
required function pointers to change the profiles.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
tablet [label="struct tablet_dispatch"]
|
||||
config [label="struct libinput_device_config_accel"];
|
||||
tablet_config [label="tablet_accel_config_set_profile()"];
|
||||
tablet->config;
|
||||
config->tablet_config;
|
||||
}
|
||||
|
||||
|
||||
When the matching ``**libinput_device_config_set_FOO()**`` is called, this goes
|
||||
through to the config struct and invokes the function there. Thus, it is
|
||||
possible to have different configuration functions for a mouse vs a
|
||||
touchpad, even though the interface is the same.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
libinput [label="**libinput_device_config_accel_set_profile()**"];
|
||||
tablet_config [label="tablet_accel_config_set_profile()"];
|
||||
libinput->tablet_config;
|
||||
}
|
||||
|
||||
|
||||
.. _architecture-filter:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Pointer acceleration filters
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
All pointer acceleration is handled in the ``filter.c`` file and its
|
||||
associated files.
|
||||
|
||||
The ``struct motion_filter`` is initialized during device init, whenever
|
||||
deltas are available they are passed to ``filter_dispatch()``. This function
|
||||
returns a set of :ref:`normalized coordinates <motion_normalization_customization>`.
|
||||
|
||||
All actual acceleration is handled within the filter, the device itself has
|
||||
no further knowledge. Thus it is possible to have different acceleration
|
||||
filters for the same device types (e.g. the Lenovo X230 touchpad has a
|
||||
custom filter).
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
fallback [label="fallback deltas"];
|
||||
touchpad [label="touchpad deltas"];
|
||||
tablet [label="tablet deltas"];
|
||||
|
||||
filter [label="filter_dispatch"];
|
||||
|
||||
fallback->filter;
|
||||
touchpad->filter;
|
||||
tablet->filter;
|
||||
|
||||
flat [label="accelerator_interface_flat()"];
|
||||
x230 [label="accelerator_filter_x230()"];
|
||||
pen [label="tablet_accelerator_filter_flat_pen()"];
|
||||
|
||||
filter->flat;
|
||||
filter->x230;
|
||||
filter->pen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Most filters convert the deltas (incl. timestamps) to a motion speed and
|
||||
then apply a so-called profile function. This function returns a factor that
|
||||
is then applied to the current delta, converting it into an accelerated
|
||||
delta. See :ref:`pointer-acceleration` for more details.
|
||||
the current
|
||||
|
|
@ -1,299 +0,0 @@
|
|||
.. _building_libinput:
|
||||
|
||||
==============================================================================
|
||||
libinput build instructions
|
||||
==============================================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
Instructions on how to build libinput and its tools and how to build against
|
||||
libinput.
|
||||
|
||||
The build instruction on this page detail how to overwrite your
|
||||
system-provided libinput with one from the git repository, see
|
||||
see :ref:`reverting_install` to revert to the previous state.
|
||||
|
||||
.. _distribution_repos:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Distribution repositories for libinput from git
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Some distributions provide package repositories for users that want to test
|
||||
the latest libinput without building it manually.
|
||||
|
||||
.. note:: The list below is provided for convenience. The libinput community
|
||||
cannot provide any guarantees that the packages in those repositories are
|
||||
correct, up-to-date and/or unmodified from the git branch. Due dilligence
|
||||
is recommended.
|
||||
|
||||
The following repositories provide an up-to-date package for libinput:
|
||||
|
||||
- **Arch:** https://aur.archlinux.org/packages/libinput-git/
|
||||
- **Fedora:** https://copr.fedorainfracloud.org/coprs/whot/libinput-git/
|
||||
|
||||
Please follow the respective repositories for instructions on how to enable
|
||||
the repository and install libinput.
|
||||
|
||||
|
||||
.. _building:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Building libinput
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput uses `meson <https://www.mesonbuild.com>`_ and
|
||||
`ninja <https://www.ninja-build.org>`_. A build is usually the three-step
|
||||
process below. A successful build requires the
|
||||
:ref:`building_dependencies` to be installed before running meson.
|
||||
|
||||
|
||||
::
|
||||
|
||||
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
||||
$> cd libinput
|
||||
$> meson setup --prefix=/usr builddir/
|
||||
$> ninja -C builddir/
|
||||
$> sudo ninja -C builddir/ install
|
||||
|
||||
|
||||
When running libinput versions 1.11.x or earlier, you must run
|
||||
|
||||
::
|
||||
|
||||
$> sudo systemd-hwdb update
|
||||
|
||||
|
||||
Additional options may also be specified. For example:
|
||||
|
||||
::
|
||||
|
||||
$> meson setup --prefix=/usr -Ddocumentation=false builddir/
|
||||
|
||||
|
||||
We recommend that users disable the documentation, it's not usually required
|
||||
for testing and reduces the number of dependencies needed.
|
||||
|
||||
The ``prefix`` or other options can be changed later with the
|
||||
``meson configure`` command. For example:
|
||||
|
||||
::
|
||||
|
||||
$> meson configure builddir/ -Dprefix=/some/other/prefix -Ddocumentation=true
|
||||
$> ninja -C builddir
|
||||
$> sudo ninja -C builddir/ install
|
||||
|
||||
|
||||
Running ``meson configure builddir/`` with no other arguments lists all
|
||||
configurable options meson provides.
|
||||
|
||||
To rebuild from scratch, simply remove the build directory and run meson
|
||||
again:
|
||||
|
||||
::
|
||||
|
||||
$> rm -r builddir/
|
||||
$> meson setup --prefix=....
|
||||
|
||||
|
||||
.. _verifying_install:
|
||||
|
||||
..............................................................................
|
||||
Verifying the install
|
||||
..............................................................................
|
||||
|
||||
To verify the install worked correctly, check that libinput.so.x.x.x is in
|
||||
the library path and that all symlinks point to the new library.
|
||||
|
||||
::
|
||||
|
||||
$> ldconfig -p | grep libinput | awk '{print $NF}' | xargs ls -l
|
||||
lrwxrwxrwx 1 root root 14 lug 22 13:06 /usr/lib/x86_64-linux-gnu/libinput.so -> libinput.so.10
|
||||
lrwxrwxrwx 1 root root 19 lug 22 13:06 /usr/lib/x86_64-linux-gnu/libinput.so.10 -> libinput.so.10.13.0
|
||||
-rwxr-xr-x 1 root root 1064144 lug 22 13:06 /usr/lib/x86_64-linux-gnu/libinput.so.10.13.0
|
||||
|
||||
.. _reverting_install:
|
||||
|
||||
..............................................................................
|
||||
Reverting to the system-provided libinput package
|
||||
..............................................................................
|
||||
|
||||
The recommended way to revert to the system install is to use the package
|
||||
manager to reinstall the libinput package. In some cases, this may leave
|
||||
files in the system (e.g. ``/usr/lib/libinput.la``) but these files are
|
||||
usually harmless. To definitely remove all files, run the following command
|
||||
from the libinput source directory:
|
||||
|
||||
|
||||
::
|
||||
|
||||
$> sudo ninja -C builddir/ uninstall
|
||||
# WARNING: Do not restart the computer/X/the Wayland compositor after
|
||||
# uninstall, reinstall the system package immediately!
|
||||
|
||||
|
||||
The following commands reinstall the current system package for libinput,
|
||||
overwriting manually installed files.
|
||||
|
||||
- **Debian/Ubuntu** based distributions: ``sudo apt-get install --reinstall libinput``
|
||||
- **Fedora 22** and later: ``sudo dnf reinstall libinput``
|
||||
- **RHEL/CentOS/Fedora 21** and earlier: ``sudo yum reinstall libinput``
|
||||
- **openSUSE**: ``sudo zypper install --force libinput10``
|
||||
- **Arch**: ``sudo pacman -S libinput``
|
||||
|
||||
.. _building_selinux:
|
||||
|
||||
..............................................................................
|
||||
SELinux adjustments
|
||||
..............................................................................
|
||||
|
||||
.. note:: This section only applies to meson version < 0.42.0
|
||||
|
||||
On systems with SELinux, overwriting the distribution-provided package with
|
||||
a manually built libinput may cause SELinux denials. This usually manifests
|
||||
when gdm does not start because it is denied access to libinput. The journal
|
||||
shows a log message in the form of:
|
||||
|
||||
|
||||
::
|
||||
|
||||
May 25 15:28:42 localhost.localdomain audit[23268]: AVC avc: denied { execute } for pid=23268 comm="gnome-shell" path="/usr/lib64/libinput.so.10.12.2" dev="dm-0" ino=1709093 scontext=system_u:system_r:xdm_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
|
||||
May 25 15:28:42 localhost.localdomain org.gnome.Shell.desktop[23270]: /usr/bin/gnome-shell: error while loading shared libraries: libinput.so.10: failed to map segment from shared object
|
||||
|
||||
|
||||
The summary of this error message is that gdm's gnome-shell runs in the
|
||||
``system_u:system_r:xdm_t`` context but libinput is installed with the
|
||||
context ``unconfined_u:object_r:user_home_t``.
|
||||
|
||||
To avoid this issue, restore the SELinux context for any system files.
|
||||
|
||||
|
||||
::
|
||||
|
||||
$> sudo restorecon /usr/lib*/libinput.so.*
|
||||
|
||||
|
||||
This issue is tracked in https://github.com/mesonbuild/meson/issues/1967.
|
||||
|
||||
.. _building_dependencies:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Build dependencies
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput has a few build-time dependencies that must be installed prior to
|
||||
running meson.
|
||||
|
||||
.. hint:: The build dependencies for some distributions can be found in the
|
||||
`GitLab Continuous Integration file <https://gitlab.freedesktop.org/libinput/libinput/blob/main/.gitlab-ci.yml>`_.
|
||||
Search for **FEDORA_PACKAGES** in the **variables:** definition
|
||||
and check the list for an entry for your distribution.
|
||||
|
||||
In most cases, it is sufficient to install the dependencies that your
|
||||
distribution uses to build the libinput package. These can be installed
|
||||
with one of the following commands:
|
||||
|
||||
- **Debian/Ubuntu** based distributions: ``sudo apt-get build-dep libinput``
|
||||
- **Fedora 22** and later: ``sudo dnf builddep libinput``
|
||||
- **RHEL/CentOS/Fedora 21** and earlier: ``sudo yum-builddep libinput``
|
||||
- **openSUSE**: ::
|
||||
|
||||
$> sudo zypper modifyrepo --enable ``zypper repos | grep source | awk '{print $5}'``
|
||||
$> sudo zypper source-install -d libinput10
|
||||
$> sudo zypper install autoconf automake libtool
|
||||
$> sudo zypper modifyrepo --disable ``zypper repos | grep source | awk '{print $5}'``
|
||||
|
||||
|
||||
- **Arch**: ::
|
||||
|
||||
$> sudo pacman -S asp
|
||||
$> cd $(mktemp -d)
|
||||
$> asp export libinput
|
||||
$> cd libinput
|
||||
$> makepkg --syncdeps --nobuild --noextract
|
||||
|
||||
|
||||
|
||||
If dependencies are missing, meson shows a message ``No package 'foo'
|
||||
found``. See
|
||||
`this blog post here <https://who-t.blogspot.com/2018/07/meson-fails-with-native-dependency-not-found.html>`_
|
||||
for instructions on how to fix it.
|
||||
|
||||
..............................................................................
|
||||
Build dependencies per distribution
|
||||
..............................................................................
|
||||
|
||||
|
||||
.. include:: dependencies.rst
|
||||
|
||||
|
||||
.. _building_conditional:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Conditional builds
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput supports several meson options to disable parts of the build. See
|
||||
the ``meson_options.txt`` file in the source tree for a full list of
|
||||
available options. The default build enables most options and thus requires
|
||||
more build dependencies. On systems where build dependencies are an issue,
|
||||
options may be disabled with this meson command: ::
|
||||
|
||||
meson setup --prefix=/usr -Dsomefeature=false builddir
|
||||
|
||||
Where ``-Dsomefeature=false`` may be one of:
|
||||
|
||||
- ``-Ddocumentation=false``
|
||||
Disables the documentation build (this website). Building the
|
||||
documentation is only needed on the maintainer machine.
|
||||
- ``-Dtests=false``
|
||||
Disables the test suite. The test suite is only needed on developer
|
||||
systems.
|
||||
- ``-Ddebug-gui=false``
|
||||
Disables the ``libinput debug-gui`` helper tool (see :ref:`tools`),
|
||||
dropping GTK and other build dependencies. The debug-gui is only
|
||||
required for troubleshooting.
|
||||
- ``-Dlibwacom=false``
|
||||
libwacom is required by libinput's tablet code to gather additional
|
||||
information about tablets that is not available from the kernel device.
|
||||
It is not recommended to disable libwacom unless libinput is used in an
|
||||
environment where tablet support is not required. libinput provides tablet
|
||||
support even without libwacom, but some features may be missing or working
|
||||
differently.
|
||||
|
||||
.. _building_against:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Building against libinput
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput provides a
|
||||
`pkg-config <https://www.freedesktop.org/wiki/Software/pkg-config/>`_ file.
|
||||
Software that uses autotools should use the ``PKG_CHECK_MODULES`` autoconf
|
||||
macro: ::
|
||||
|
||||
PKG_CHECK_MODULES(LIBINPUT, "libinput")
|
||||
|
||||
Software that uses meson should use the ``dependency()`` function: ::
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
dep_libinput = dependency('libinput')
|
||||
|
||||
Software that uses CMake should use: ::
|
||||
|
||||
find_package(Libinput)
|
||||
target_link_libraries(myprogram PRIVATE Libinput::Libinput)
|
||||
|
||||
Otherwise, the most rudimentary way to compile and link a program against
|
||||
libinput is:
|
||||
|
||||
|
||||
::
|
||||
|
||||
gcc -o myprogram myprogram.c ``pkg-config --cflags --libs libinput``
|
||||
|
||||
|
||||
For further information on using pkgconfig see the pkg-config documentation.
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
|
||||
.. _button_debouncing:
|
||||
|
||||
==============================================================================
|
||||
Button debouncing
|
||||
==============================================================================
|
||||
|
||||
Physical buttons experience wear-and-tear with usage. On some devices this
|
||||
can result in an effect called "contact bouncing" or "chatter". This effect
|
||||
can cause the button to send multiple events within a short time frame, even
|
||||
though the user only pressed or clicked the button once. This effect can be
|
||||
counteracted by "debouncing" the buttons, usually by ignoring erroneous
|
||||
events.
|
||||
|
||||
libinput provides two methods of debouncing buttons, referred to as the
|
||||
"bounce" and "spurious" methods:
|
||||
|
||||
- In the "bounce" method, libinput monitors hardware bouncing on button
|
||||
state changes, i.e. when a user clicks or releases a button. For example,
|
||||
if a user presses a button but the hardware generates a
|
||||
press-release-press sequence in quick succession, libinput ignores the
|
||||
release and second press event. This method is always enabled.
|
||||
- in the "spurious" method, libinput detects spurious releases of a button
|
||||
while the button is physically held down by the user. These releases are
|
||||
immediately followed by a press event. libinput monitors for these events
|
||||
and ignores the release and press event. This method is disabled by
|
||||
default and enables once libinput detects the first faulty event sequence.
|
||||
|
||||
The "bounce" method guarantees that all press events are delivered
|
||||
immediately and most release events are delivered immediately. The
|
||||
"spurious" method requires that release events are delayed, libinput thus
|
||||
does not enable this method unless a faulty event sequence is detected. A
|
||||
message is printed to the log when spurious deboucing was detected.
|
||||
|
||||
libinput's debouncing is supposed to correct hardware damage or
|
||||
substandard hardware. Debouncing also exists as an accessibility feature
|
||||
but the requirements are different. In the accessibility feature, multiple
|
||||
physical key presses, usually caused by involuntary muscle movement, must be
|
||||
filtered to only one key press. This feature must be implemented higher in
|
||||
the stack, libinput is limited to hardware debouncing.
|
||||
|
||||
Below is an illustration of the button debouncing modes to show the relation
|
||||
of the physical button state and the application state. Where applicable, an
|
||||
extra line is added to show the timeouts used by libinput that
|
||||
affect the button state handling. The waveform's high and low states
|
||||
correspond to the buttons 'pressed' and 'released' states, respectively.
|
||||
|
||||
.. figure:: button-debouncing-wave-diagram.svg
|
||||
:align: center
|
||||
|
||||
Diagram illustrating button debouncing
|
||||
|
||||
|
||||
Some devices send events in bursts, erroneously triggering the button
|
||||
debouncing detection. Please :ref:`file a bug <reporting_bugs>` if that
|
||||
occurs for your device.
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
.. _clickpad_softbuttons:
|
||||
|
||||
==============================================================================
|
||||
Clickpad software button behavior
|
||||
==============================================================================
|
||||
|
||||
"Clickpads" are touchpads without separate physical buttons. Instead, the
|
||||
whole touchpad acts as a button and left or right button clicks are
|
||||
distinguished by :ref:`the location of the fingers <software_buttons>` or
|
||||
the :ref:`number of fingers on the touchpad <clickfinger>`.
|
||||
"ClickPad" is a trademark by `Synaptics Inc. <http://www.synaptics.com/en/clickpad.php>`_
|
||||
but for simplicity we refer to any touchpad with the above feature as Clickpad,
|
||||
regardless of the manufacturer.
|
||||
|
||||
The kernel marks clickpads with the
|
||||
`INPUT_PROP_BUTTONPAD <https://www.kernel.org/doc/Documentation/input/event-codes.txt>`_
|
||||
property. Without this property, libinput would not know whether a touchpad
|
||||
is a clickpad or not. To perform a right-click on a Clickpad, libinput
|
||||
provides :ref:`software_buttons` and :ref:`clickfinger`.
|
||||
|
||||
.. note:: The term "click" refers refer to a physical button press
|
||||
and/or release of the touchpad, the term "button event" refers to
|
||||
the events generated by libinput in response to a click.
|
||||
|
||||
.. _software_buttons:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Software button areas
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The bottom of the touchpad is split into three distinct areas generate left,
|
||||
middle or right button events on click. The height of the button area
|
||||
depends on the hardware but is usually around 10mm.
|
||||
|
||||
.. figure :: software-buttons-visualized.svg
|
||||
:align: center
|
||||
|
||||
The locations of the virtual button areas.
|
||||
|
||||
|
||||
Left, right and middle button events can be triggered as follows:
|
||||
|
||||
- if a finger is in the main area or the left button area, a click generates
|
||||
left button events.
|
||||
- if a finger is in the right area, a click generates right button events.
|
||||
- if a finger is in the middle area, a click generates middle button events.
|
||||
|
||||
.. figure:: software-buttons.svg
|
||||
:align: center
|
||||
|
||||
Left, right and middle-button click with software button areas
|
||||
|
||||
The middle button is always centered on the touchpad and smaller in size
|
||||
than the left or right button. The actual size is device-dependent. Many
|
||||
touchpads do not have visible markings so the exact location of the button
|
||||
is unfortunately not visibly obvious.
|
||||
|
||||
.. note:: If :ref:`middle button emulation <middle_button_emulation>` is
|
||||
enabled on a clickpad, only left and right button areas are
|
||||
available.
|
||||
|
||||
If fingers are down in the main area in addition to fingers in the
|
||||
left or right button area, those fingers are are ignored.
|
||||
A release event always releases the buttons logically down, regardless of
|
||||
the current finger position
|
||||
|
||||
.. figure:: software-buttons-thumbpress.svg
|
||||
:align: center
|
||||
|
||||
Only the location of the thumb determines whether it is a left, right or
|
||||
middle click.
|
||||
|
||||
The movement of a finger can alter the button area behavior:
|
||||
|
||||
- if a finger starts in the main area and moves into the software button
|
||||
area, the software buttons do not apply to that finger
|
||||
- once a finger has moved out of the button area, it cannot move back in and
|
||||
trigger a right or middle button event
|
||||
- a finger moving within the software button area does not move the pointer
|
||||
- once a finger moves out out of the button area it will control the
|
||||
pointer (this only applies if there is no other finger down on the
|
||||
touchpad)
|
||||
|
||||
.. figure:: software-buttons-conditions.svg
|
||||
:align: center
|
||||
|
||||
**Left:** moving a finger into the right button area does not trigger a
|
||||
right-button click.
|
||||
**Right:** moving within the button areas does not generate pointer
|
||||
motion.
|
||||
|
||||
On some touchpads, notably the 2015 Lenovo X1 Carbon 3rd series, the very
|
||||
bottom end of the touchpad is outside of the sensor range but it is possible
|
||||
to trigger a physical click there. To libinput, the click merely shows up as
|
||||
a left button click without any positional finger data and it is
|
||||
impossible to determine whether it is a left or a right click. libinput
|
||||
ignores such button clicks, this behavior is intentional.
|
||||
|
||||
.. _clickfinger:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Clickfinger behavior
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
This is the default behavior on Apple touchpads. Here, a left, right, middle
|
||||
button event is generated when one, two, or three fingers are held down on the
|
||||
touchpad when a physical click is generated, given the default mapping. The
|
||||
location of the fingers does not matter and there are no software-defined
|
||||
button areas. It is possible to swap right and middle buttons, the same way as
|
||||
with :ref:`tapping <tapping>`.
|
||||
|
||||
.. figure:: clickfinger.svg
|
||||
:align: center
|
||||
|
||||
One, two and three-finger click with Clickfinger behavior
|
||||
|
||||
On some touchpads, libinput imposes a limit on how the fingers may be placed
|
||||
on the touchpad. In the most common use-case this allows for a user to
|
||||
trigger a click with the thumb while leaving the pointer-moving finger on
|
||||
the touchpad.
|
||||
|
||||
.. figure:: clickfinger-distance.svg
|
||||
:align: center
|
||||
|
||||
Illustration of the distance detection algorithm
|
||||
|
||||
In the illustration above the red area marks the proximity area around the
|
||||
first finger. Since the thumb is outside of that area libinput considers the
|
||||
click a single-finger click rather than a two-finger click.
|
||||
|
||||
.. _special_clickpads:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Special Clickpads
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The Lenovo \*40 series laptops have a clickpad that provides two software button sections, one at
|
||||
the top and one at the bottom. See :ref:`Lenovo \*40 series touchpad support <t440_support>`
|
||||
for details on the top software button.
|
||||
|
||||
Some Clickpads, notably some Cypress ones, perform right button detection in
|
||||
firmware and appear to userspace as if the touchpad had physical buttons.
|
||||
While physically clickpads, these are not handled by the software and
|
||||
treated like traditional touchpads.
|
||||