Compare commits
20 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94b5be448e | ||
|
|
39d353ddcb | ||
|
|
e4fdb5fe86 | ||
|
|
f634256ab0 | ||
|
|
65cfa032a0 | ||
|
|
68b471b31f | ||
|
|
47df5c173a | ||
|
|
e3d402fa3c | ||
|
|
f65b1a2e33 | ||
|
|
6dc9de071e | ||
|
|
fa10459082 | ||
|
|
34a7365235 | ||
|
|
62382f7d79 | ||
|
|
a7d2b749f3 | ||
|
|
c8daa2c0a1 | ||
|
|
093a87898b | ||
|
|
ad7708f6a5 | ||
|
|
b927b42235 | ||
|
|
b9ba9e7236 | ||
|
|
535cc9879b |
|
|
@ -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,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
|
|
||||||
1532
.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 "$@"
|
|
||||||
13
.gitlab-ci/ubuntu_install.sh
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
apt-get install -y software-properties-common
|
||||||
|
add-apt-repository universe
|
||||||
|
apt-get update
|
||||||
|
apt-get -y upgrade
|
||||||
|
|
||||||
|
apt-get install -y $@
|
||||||
|
|
@ -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()
|
|
||||||
31
.gitlab/issue_templates/Bug.md
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
## 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 one can reproduce the issue - this is very important -->
|
||||||
|
|
||||||
|
## libinput version you encountered the bug on
|
||||||
|
|
||||||
|
<!-- Note: if your libinput version is older than the current stable version,
|
||||||
|
please reproduce with a current version instead -->
|
||||||
|
|
||||||
|
## Hardware information:
|
||||||
|
|
||||||
|
<!-- Model name/number and general hardware information if applicable -->
|
||||||
|
|
||||||
|
## Other log output:
|
||||||
|
|
||||||
|
- `libinput record` output: <!-- attach file here -->
|
||||||
|
- `libinput debug-events --verbose` output: <!-- attach file here -->
|
||||||
|
|
||||||
|
<!-- Paste any other relevant logs - please use code blocks (```) to format
|
||||||
|
console output, logs, and code as it's very hard to read otherwise.) -->
|
||||||
|
|
||||||
|
|
||||||
|
/label ~bug ~"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
|
|
||||||
147
CODING_STYLE.md
|
|
@ -1,4 +1,3 @@
|
||||||
# Coding style
|
|
||||||
|
|
||||||
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
||||||
vertical alignment is required (see below)
|
vertical alignment is required (see below)
|
||||||
|
|
@ -52,102 +51,51 @@ somenamethatiswaytoolong(int a,
|
||||||
- if it generates a static checker warning, it needs to be fixed or
|
- if it generates a static checker warning, it needs to be fixed or
|
||||||
commented
|
commented
|
||||||
|
|
||||||
- declare variables when they are used first and try to keep them as local as possible.
|
- declare variables at the top, try to keep them as local as possible.
|
||||||
Exception: basic loop variables, e.g. for (int i = 0; ...) should always be
|
Exception: if the same variable is re-used in multiple blocks, declare it
|
||||||
declared inside the loop even where multiple loops exist
|
at the top.
|
||||||
|
Exception: basic loop variables, e.g. for (int i = 0; ...)
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int a;
|
int a;
|
||||||
|
int c;
|
||||||
|
|
||||||
if (foo) {
|
if (foo) {
|
||||||
int b = 10;
|
int b;
|
||||||
|
|
||||||
a = get_value();
|
c = get_value();
|
||||||
usevalue(a, b);
|
usevalue(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bar) {
|
if (bar) {
|
||||||
a = get_value();
|
c = get_value();
|
||||||
useit(a);
|
useit(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int c = a * 100;
|
|
||||||
useit(c);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- avoid uninitialized variables where possible, declare them late instead.
|
- do not mix function invocations and variable definitions.
|
||||||
Note that most of libinput predates this style, try to stick with the code
|
|
||||||
around you if in doubt.
|
|
||||||
|
|
||||||
wrong:
|
wrong:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int *a;
|
{
|
||||||
|
int a = foo();
|
||||||
int b = 7;
|
int b = 7;
|
||||||
|
}
|
||||||
... some code ...
|
|
||||||
|
|
||||||
a = zalloc(32);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
right:
|
right:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
{
|
||||||
|
int a;
|
||||||
int b = 7;
|
int b = 7;
|
||||||
... some code ...
|
|
||||||
|
|
||||||
int *a = zalloc(32);
|
a = foo();
|
||||||
```
|
|
||||||
|
|
||||||
- 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:
|
There are exceptions here, e.g. `tp_libinput_context()`,
|
||||||
```c
|
`litest_current_device()`
|
||||||
{
|
|
||||||
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
|
- 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
|
statement. If either if or else block are multiple statements, both must
|
||||||
|
|
@ -185,60 +133,3 @@ if (foo) {
|
||||||
|
|
||||||
- Use stdbool.h's bool for booleans within the library (instead of `int`).
|
- Use stdbool.h's bool for booleans within the library (instead of `int`).
|
||||||
Exception: the public API uses int, not bool.
|
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
|
version libinput is compiled against. The header is used during compilation
|
||||||
only, libinput does not link against GPL libraries.
|
only, libinput does not link against GPL libraries.
|
||||||
|
|
||||||
[1] https://gitlab.freedesktop.org/libinput/libinput/blob/main/include/linux/input.h
|
[1] https://gitlab.freedesktop.org/libinput/libinput/blob/master/include/linux/input.h
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ Examples of how to use libinput are the debugging tools in the libinput
|
||||||
repository. Developers are encouraged to look at those tools for a
|
repository. Developers are encouraged to look at those tools for a
|
||||||
real-world (yet simple) example on how to use libinput.
|
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 commandline debugging tool: https://gitlab.freedesktop.org/libinput/libinput/tree/master/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
|
- A GTK application that draws cursor/touch/tablet positions: https://gitlab.freedesktop.org/libinput/libinput/tree/master/tools/libinput-debug-gui.c
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
@ -75,10 +75,10 @@ libinput is licensed under the MIT license.
|
||||||
> and/or sell copies of the Software, and to permit persons to whom the
|
> 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: [...]
|
> Software is furnished to do so, subject to the following conditions: [...]
|
||||||
|
|
||||||
See the [COPYING](https://gitlab.freedesktop.org/libinput/libinput/tree/main/COPYING)
|
See the [COPYING](https://gitlab.freedesktop.org/libinput/libinput/tree/master/COPYING)
|
||||||
file for the full license information.
|
file for the full license information.
|
||||||
|
|
||||||
About
|
About
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Documentation generated from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
Documentation generated by from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@
|
||||||
"list-devices:List all devices recognized by libinput"
|
"list-devices:List all devices recognized by libinput"
|
||||||
"debug-events:Print all events as seen by libinput"
|
"debug-events:Print all events as seen by libinput"
|
||||||
"debug-gui:Show a GUI to visualize libinput's events"
|
"debug-gui:Show a GUI to visualize libinput's events"
|
||||||
"debug-tablet:Show tablet axis and button values"
|
|
||||||
"measure:Measure various properties of devices"
|
"measure:Measure various properties of devices"
|
||||||
"analyze:Analyze device data"
|
|
||||||
"record:Record the events from a device"
|
"record:Record the events from a device"
|
||||||
"replay:Replay the events from a device"
|
"replay:Replay the events from a device"
|
||||||
)
|
)
|
||||||
|
|
@ -45,61 +43,40 @@ __all_seats()
|
||||||
'--verbose[Use verbose output]' \
|
'--verbose[Use verbose output]' \
|
||||||
'--show-keycodes[Make all keycodes visible]' \
|
'--show-keycodes[Make all keycodes visible]' \
|
||||||
'--grab[Exclusively grab all opened devices]' \
|
'--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/' \
|
'--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' \
|
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
|
||||||
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
|
'--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' \
|
'--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-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-scroll-method=[Set the desired scroll method]:scroll-method:(none twofinger edge button)' \
|
||||||
|
'--set-scroll-button=[Set the button to the given button code]' \
|
||||||
|
'--set-profile=[Set pointer acceleration profile]:accel-profile:(adaptive flat)' \
|
||||||
'--set-speed=[Set pointer acceleration speed (within range \[-1, 1\])]' \
|
'--set-speed=[Set pointer acceleration speed (within range \[-1, 1\])]' \
|
||||||
'--set-tap-map=[Set button mapping for tapping]:tap-map:(( \
|
'--set-tap-map=[Set button mapping for tapping]:tap-map:(( \
|
||||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
||||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
||||||
))' \
|
))' \
|
||||||
+ '(custom pointer acceleration)' \
|
+ '(tap-to-click)' \
|
||||||
'--set-custom-points=[Set n points defining a custom acceleration function]' \
|
'--enable-tap[Enable tap-to-click]' \
|
||||||
'--set-custom-step=[Set the distance along the x axis between the custom points]' \
|
'--disable-tap[Disable tap-to-click]' \
|
||||||
'--set-custom-type=[Set the type of the acceleration function]:custom-type:(fallback motion scroll)' \
|
|
||||||
+ '(drag)' \
|
+ '(drag)' \
|
||||||
'--enable-drag[Enable tap-and-drag]' \
|
'--enable-drag[Enable tap-and-drag]' \
|
||||||
'--disable-drag[Disable tap-and-drag]' \
|
'--disable-drag[Disable tap-and-drag]' \
|
||||||
+ '(drag-lock)' \
|
+ '(drag-lock)' \
|
||||||
'--enable-drag-lock[Enable drag-lock]' \
|
'--enable-drag-lock[Enable drag-lock]' \
|
||||||
'--disable-drag-lock[Disable drag-lock]' \
|
'--disable-drag-lock[Disable drag-lock]' \
|
||||||
+ '(dwt)' \
|
+ '(natural-scrolling)' \
|
||||||
'--enable-dwt[Enable disable-while-typing]' \
|
'--enable-natural-scrolling[Enable natural scrolling]' \
|
||||||
'--disable-dwt[Disable disable-while-typing]' \
|
'--disable-natural-scrolling[Disable natural scrolling]' \
|
||||||
+ '(dwtp)' \
|
|
||||||
'--enable-dwtp[Enable disable-while-trackpointing]' \
|
|
||||||
'--disable-dwtp[Disable disable-while-trackpointing]' \
|
|
||||||
+ '(left-handed)' \
|
+ '(left-handed)' \
|
||||||
'--enable-left-handed[Enable left handed button configuration]' \
|
'--enable-left-handed[Enable left handed button configuration]' \
|
||||||
'--disable-left-handed[Disable left handed button configuration]' \
|
'--disable-left-handed[Disable left handed button configuration]' \
|
||||||
+ '(middlebutton)' \
|
+ '(middlebutton)' \
|
||||||
'--enable-middlebutton[Enable middle button emulation]' \
|
'--enable-middlebutton[Enable middle button emulation]' \
|
||||||
'--disable-middlebutton[Disable middle button emulation]' \
|
'--disable-middlebutton[Disable middle button emulation]' \
|
||||||
+ '(natural-scrolling)' \
|
+ '(dwt)' \
|
||||||
'--enable-natural-scrolling[Enable natural scrolling]' \
|
'--enable-dwt[Enable disable-while-typing]' \
|
||||||
'--disable-natural-scrolling[Disable natural scrolling]' \
|
'--disable-dwt[Disable enable-while-typing]'
|
||||||
+ '(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()
|
(( $+functions[_libinput_debug-gui] )) || _libinput_debug-gui()
|
||||||
|
|
@ -112,15 +89,6 @@ __all_seats()
|
||||||
'--udev=[Listen for notifications on the given seat]:seat:_libinput_all_seats'
|
'--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()
|
(( $+functions[_libinput_measure] )) || _libinput_measure()
|
||||||
{
|
{
|
||||||
local curcontext=$curcontext state line ret=1
|
local curcontext=$curcontext state line ret=1
|
||||||
|
|
@ -180,71 +148,20 @@ __all_seats()
|
||||||
{
|
{
|
||||||
_arguments \
|
_arguments \
|
||||||
'--help[Show help message and exit]' \
|
'--help[Show help message and exit]' \
|
||||||
'--format=dat[Specify the data format to be printed. The default is "summary"]' \
|
'--format=dat[Specify the data format to be printed. The default is "summary"]'
|
||||||
':device:_files -W /dev/input/ -P /dev/input/'
|
':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()
|
(( $+functions[_libinput_record] )) || _libinput_record()
|
||||||
{
|
{
|
||||||
_arguments \
|
_arguments \
|
||||||
'--help[Show help message and exit]' \
|
'--help[Show help message and exit]' \
|
||||||
'--all[Record all /dev/input/event* devices available on the system]' \
|
'--all[Record all /dev/input/event* devices available on the system]' \
|
||||||
'--autorestart=[Terminate the current recording after s seconds of device inactivity]' \
|
'--autorestart=[Terminate the current recording after s seconds of device inactivity]' \
|
||||||
{-o+,--output=}'[Specify the output file to use]:file:_files -g "*.yml"' \
|
{-o+,--output=}'[Speficy the output file to use]:file:_files -g "*.yml"' \
|
||||||
'--multiple[Record multiple devices at once]' \
|
'--multiple[Record multiple devices at once]' \
|
||||||
'--show-keycodes[Show keycodes as-is in the recording]' \
|
'--show-keycodes[Show keycodes as-is in the recording]' \
|
||||||
'--with-libinput[Record libinput events alongside device events]' \
|
'--with-libinput[Record libinput events alongside device events]' \
|
||||||
'--with-hidraw[Record hidraw events alongside device events]' \
|
|
||||||
'*::device:_files -W /dev/input/ -P /dev/input/'
|
'*::device:_files -W /dev/input/ -P /dev/input/'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
zshcompletiondir = get_option('zshcompletiondir')
|
zshcompletiondir = get_option('zshcompletiondir')
|
||||||
if zshcompletiondir == ''
|
if zshcompletiondir == ''
|
||||||
zshcompletiondir = get_option('datadir') / 'zsh' / 'site-functions'
|
zshcompletiondir = join_paths(get_option('datadir'), 'zsh', 'site-functions')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if zshcompletiondir != 'no'
|
if zshcompletiondir != 'no'
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ MAX_INITIALIZER_LINES = 0
|
||||||
WARNINGS = YES
|
WARNINGS = YES
|
||||||
QUIET = YES
|
QUIET = YES
|
||||||
INPUT = "@builddir@"
|
INPUT = "@builddir@"
|
||||||
|
FILTER_PATTERNS = *.h *.dox
|
||||||
IMAGE_PATH = "@builddir@"
|
IMAGE_PATH = "@builddir@"
|
||||||
OUTPUT_DIRECTORY = doc
|
|
||||||
GENERATE_HTML = YES
|
GENERATE_HTML = YES
|
||||||
HTML_OUTPUT = html
|
HTML_OUTPUT = api
|
||||||
SEARCHENGINE = NO
|
SEARCHENGINE = NO
|
||||||
USE_MATHJAX = YES
|
USE_MATHJAX = YES
|
||||||
MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
|
MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
|
||||||
|
|
@ -25,7 +25,6 @@ PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
|
||||||
DOTFILE_DIRS = "@builddir@"
|
DOTFILE_DIRS = "@builddir@"
|
||||||
EXAMPLE_PATH = "@builddir@"
|
EXAMPLE_PATH = "@builddir@"
|
||||||
SHOW_NAMESPACES = NO
|
SHOW_NAMESPACES = NO
|
||||||
HAVE_DOT = YES
|
|
||||||
|
|
||||||
HTML_HEADER = "@builddir@/header.html"
|
HTML_HEADER = "@builddir@/header.html"
|
||||||
HTML_FOOTER = "@builddir@/footer.html"
|
HTML_FOOTER = "@builddir@/footer.html"
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,6 @@ release.
|
||||||
|
|
||||||
@section About
|
@section About
|
||||||
|
|
||||||
Documentation generated from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
Documentation generated by from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,26 @@ if not dot.found()
|
||||||
error('Program "dot" not found or not executable. Try building with -Ddocumentation=false')
|
error('Program "dot" not found or not executable. Try building with -Ddocumentation=false')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
doxygen_version_cmd = run_command(doxygen.path(), '--version')
|
||||||
|
if doxygen_version_cmd.returncode() != 0
|
||||||
|
error('Command "doxygen --version" failed.')
|
||||||
|
endif
|
||||||
|
doxygen_version = doxygen_version_cmd.stdout()
|
||||||
|
if doxygen_version.version_compare('< 1.8.3')
|
||||||
|
error('doxygen needs to be at least version 1.8.3 (have @0@)'.format(doxygen_version))
|
||||||
|
endif
|
||||||
|
grep = find_program('grep')
|
||||||
|
dot_version_cmd = run_command(dot.path(), '-V')
|
||||||
|
if dot_version_cmd.returncode() != 0
|
||||||
|
error('Command "dot -V" failed.')
|
||||||
|
endif
|
||||||
|
# dot -V output is (to stderr):
|
||||||
|
# dot - graphviz version 2.38.0 (20140413.2041)
|
||||||
|
dot_version = dot_version_cmd.stderr().split(' ')[4]
|
||||||
|
if dot_version.version_compare('< 2.26')
|
||||||
|
error('Graphviz dot needs to be at least version 2.26 (have @0@)'.format(dot_version))
|
||||||
|
endif
|
||||||
|
|
||||||
mainpage = vcs_tag(command : ['git', 'log', '-1', '--format=%h'],
|
mainpage = vcs_tag(command : ['git', 'log', '-1', '--format=%h'],
|
||||||
fallback : 'unknown',
|
fallback : 'unknown',
|
||||||
input : 'mainpage.dox',
|
input : 'mainpage.dox',
|
||||||
|
|
@ -17,7 +37,7 @@ mainpage = vcs_tag(command : ['git', 'log', '-1', '--format=%h'],
|
||||||
|
|
||||||
src_doxygen = files(
|
src_doxygen = files(
|
||||||
# source files
|
# source files
|
||||||
'../../src/libinput.h',
|
join_paths(meson.source_root(), 'src', 'libinput.h'),
|
||||||
# style files
|
# style files
|
||||||
'style/header.html',
|
'style/header.html',
|
||||||
'style/footer.html',
|
'style/footer.html',
|
||||||
|
|
@ -26,11 +46,19 @@ src_doxygen = files(
|
||||||
'style/libinputdoxygen.css',
|
'style/libinputdoxygen.css',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
config_noop = configuration_data()
|
||||||
|
# Set a dummy replacement to silence meson warnings:
|
||||||
|
# meson.build:487: WARNING: Got an empty configuration_data() object and
|
||||||
|
# found no substitutions in the input file 'foo'. If you
|
||||||
|
# want to copy a file to the build dir, use the 'copy:'
|
||||||
|
# keyword argument added in 0.47.0
|
||||||
|
config_noop.set('dummy', 'dummy')
|
||||||
|
|
||||||
doxyfiles = []
|
doxyfiles = []
|
||||||
foreach f : src_doxygen
|
foreach f : src_doxygen
|
||||||
df = configure_file(input: f,
|
df = configure_file(input: f,
|
||||||
output: '@PLAINNAME@',
|
output: '@PLAINNAME@',
|
||||||
copy : true)
|
configuration : config_noop)
|
||||||
doxyfiles += [ df ]
|
doxyfiles += [ df ]
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
|
@ -45,7 +73,7 @@ doxyfile = configure_file(input : 'libinput.doxygen.in',
|
||||||
|
|
||||||
custom_target('doxygen',
|
custom_target('doxygen',
|
||||||
input : [ doxyfiles, doxyfile, mainpage ] + src_doxygen,
|
input : [ doxyfiles, doxyfile, mainpage ] + src_doxygen,
|
||||||
output : [ 'html' ],
|
output : [ '.' ],
|
||||||
command : [ doxygen, doxyfile ],
|
command : [ doxygen, doxyfile ],
|
||||||
install : false,
|
install : false,
|
||||||
depends: [ mainpage ],
|
depends: [ mainpage ],
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 166 KiB |
|
|
@ -33,78 +33,59 @@ Measuring and fixing touchpad ranges
|
||||||
To fix the touchpad you need to:
|
To fix the touchpad you need to:
|
||||||
|
|
||||||
#. measure the physical size of your touchpad in mm
|
#. measure the physical size of your touchpad in mm
|
||||||
#. run the ``libinput measure touchpad-size`` tool
|
#. run touchpad-edge-detector
|
||||||
#. verify the hwdb entry provided by this tool
|
#. trim the udev match rule to something sensible
|
||||||
|
#. replace the resolution with the calculated resolution based on physical settings
|
||||||
#. test locally
|
#. test locally
|
||||||
#. send a patch to the `systemd project <https://github.com/systemd/systemd>`_.
|
#. send a patch to the systemd project
|
||||||
|
|
||||||
Detailed explanations are below.
|
Detailed explanations are below.
|
||||||
|
|
||||||
The ``libinput measure touchpad-size`` tool is an interactive tool. It must
|
`libevdev <http://freedesktop.org/wiki/Software/libevdev/>`_ provides a tool
|
||||||
be called with the physical dimensions of the touchpad in mm. In the example
|
called **touchpad-edge-detector** that allows measuring the touchpad's input
|
||||||
below, we use 100mm wide and 55mm high. The tool will find the touchpad device
|
ranges. Run the tool as root against the device node of your touchpad device
|
||||||
automatically.
|
and repeatedly move a finger around the whole outside area of the
|
||||||
|
touchpad. Then control+c the process and note the output.
|
||||||
|
An example output is below:
|
||||||
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$> sudo libinput measure touchpad-size 100x55
|
$> sudo touchpad-edge-detector /dev/input/event4
|
||||||
Using "Touchpad SynPS/2 Synaptics TouchPad": /dev/input/event4
|
Touchpad SynPS/2 Synaptics TouchPad on /dev/input/event4
|
||||||
|
Move one finger around the touchpad to detect the actual edges
|
||||||
|
Kernel says: x [1024..3112], y [2024..4832]
|
||||||
|
Touchpad sends: x [2445..4252], y [3464..4071]
|
||||||
|
|
||||||
Kernel specified touchpad size: 99.7x75.9mm
|
Touchpad size as listed by the kernel: 49x66mm
|
||||||
User specified touchpad size: 100.0x55.0mm
|
Calculate resolution as:
|
||||||
|
x axis: 2088/<width in mm>
|
||||||
|
y axis: 2808/<height in mm>
|
||||||
|
|
||||||
Kernel axis range: x [1024..5112], y [2024..4832]
|
Suggested udev rule:
|
||||||
Detected axis range: x [ 0.. 0], y [ 0.. 0]
|
# <Laptop model description goes here>
|
||||||
|
evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvnLENOVO:bvrGJET72WW(2.22):bd02/21/2014:svnLENOVO:pn20ARS25701:pvrThinkPadT440s:rvnLENOVO:rn20ARS25701:rvrSDK0E50512STD:cvnLENOVO:ct10:cvrNotAvailable:*
|
||||||
Move one finger along all edges of the touchpad
|
EVDEV_ABS_00=2445:4252:<x resolution>
|
||||||
until the detected axis range stops changing.
|
EVDEV_ABS_01=3464:4071:<y resolution>
|
||||||
|
EVDEV_ABS_35=2445:4252:<x resolution>
|
||||||
...
|
EVDEV_ABS_36=3464:4071:<y resolution>
|
||||||
|
|
||||||
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
|
Note the discrepancy between the coordinate range the kernels advertises vs.
|
||||||
``60-evdev.hwdb`` file provided by the `systemd project <https://github.com/systemd/systemd>`_.
|
what the touchpad sends.
|
||||||
|
To fix the advertised ranges, the udev rule should be taken and trimmed
|
||||||
|
before being sent to the `systemd project <https://github.com/systemd/systemd>`_.
|
||||||
An example commit can be found
|
An example commit can be found
|
||||||
`here <https://github.com/systemd/systemd/commit/26f667eac1c5e89b689aa0a1daef6a80f473e045>`_.
|
`here <https://github.com/systemd/systemd/commit/26f667eac1c5e89b689aa0a1daef6a80f473e045>`_.
|
||||||
|
|
||||||
The ``libinput measure touchpad-size`` tool attempts to provide the correct
|
In most cases the match can and should be trimmed to the system vendor (svn)
|
||||||
dmi match but it does require user verification.
|
and the product version (pvr), with everything else replaced by a wildcard
|
||||||
|
(*). In this case, a Lenovo T440s, a suitable match string would be:
|
||||||
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*
|
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
|
.. note:: hwdb match strings only allow for alphanumeric ascii characters. Use a
|
||||||
wildcard (* or ?, whichever appropriate) for special characters.
|
wildcard (* or ?, whichever appropriate) for special characters.
|
||||||
|
|
@ -114,19 +95,19 @@ The actual axis overrides are in the form:
|
||||||
::
|
::
|
||||||
|
|
||||||
# axis number=min:max:resolution
|
# axis number=min:max:resolution
|
||||||
EVDEV_ABS_00=2072:4880:28
|
EVDEV_ABS_00=2445:4252:42
|
||||||
|
|
||||||
or, if the range is correct but the resolution is wrong
|
or, if the range is correct but the resolution is wrong
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# axis number=::resolution
|
# axis number=::resolution
|
||||||
EVDEV_ABS_00=::28
|
EVDEV_ABS_00=::42
|
||||||
|
|
||||||
|
|
||||||
Note the leading single space. The axis numbers are in hex and can be found
|
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``,
|
in *linux/input-event-codes.h*. For touchpads ABS_X, ABS_Y,
|
||||||
``ABS_MT_POSITION_X`` and ``ABS_MT_POSITION_Y`` are required.
|
ABS_MT_POSITION_X and ABS_MT_POSITION_Y are required.
|
||||||
|
|
||||||
.. note:: The touchpad's ranges and/or resolution should only be fixed when
|
.. 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
|
there is a significant discrepancy. A few units do not make a
|
||||||
|
|
@ -135,7 +116,7 @@ in ``linux/input-event-codes.h``. For touchpads ``ABS_X``, ``ABS_Y``,
|
||||||
|
|
||||||
Once a match and override rule has been found, follow the instructions at
|
Once a match and override rule has been found, follow the instructions at
|
||||||
the top of the
|
the top of the
|
||||||
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`_
|
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/master/hwdb/60-evdev.hwdb>`_
|
||||||
file to save it locally and trigger the udev hwdb reload. Rebooting is
|
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
|
always a good idea. If the match string is correct, the new properties will
|
||||||
show up in the
|
show up in the
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,6 @@ 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
|
device-type-specific implementations in ``evdev-<type>.c``. It is not
|
||||||
necessary to understand all of libinput to contribute a patch.
|
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,
|
:ref:`architecture-contexts` is the only user-visible implementation detail,
|
||||||
everything else is purely internal implementation and may change when
|
everything else is purely internal implementation and may change when
|
||||||
required.
|
required.
|
||||||
|
|
@ -154,8 +150,10 @@ pointers to handle events. Four such dispatch methods are currently
|
||||||
implemented: touchpad, tablet, tablet pad, and the fallback dispatch which
|
implemented: touchpad, tablet, tablet pad, and the fallback dispatch which
|
||||||
handles mice, keyboards and touchscreens.
|
handles mice, keyboards and touchscreens.
|
||||||
|
|
||||||
|
|
||||||
.. graphviz::
|
.. graphviz::
|
||||||
|
|
||||||
|
|
||||||
digraph context
|
digraph context
|
||||||
{
|
{
|
||||||
compound=true;
|
compound=true;
|
||||||
|
|
@ -179,15 +177,13 @@ handles mice, keyboards and touchscreens.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
While ``evdev.c`` pulls the event out of libevdev, the actual handling of the
|
||||||
events is performed within the dispatch method.
|
events is performed within the dispatch method.
|
||||||
|
|
||||||
|
|
||||||
.. graphviz::
|
.. graphviz::
|
||||||
|
|
||||||
|
|
||||||
digraph context
|
digraph context
|
||||||
{
|
{
|
||||||
compound=true;
|
compound=true;
|
||||||
|
|
@ -198,107 +194,22 @@ events is performed within the dispatch method.
|
||||||
|
|
||||||
evdev [label="evdev_device_dispatch()"]
|
evdev [label="evdev_device_dispatch()"]
|
||||||
|
|
||||||
plugins [label="plugin pipline"]
|
|
||||||
|
|
||||||
fallback [label="fallback_interface_process()"];
|
fallback [label="fallback_interface_process()"];
|
||||||
touchpad [label="tp_interface_process()"]
|
touchpad [label="tp_interface_process()"]
|
||||||
tablet [label="tablet_process()"]
|
tablet [label="tablet_process()"]
|
||||||
pad [label="pad_process()"]
|
pad [label="pad_process()"]
|
||||||
|
|
||||||
evdev -> plugins;
|
evdev -> fallback;
|
||||||
plugins -> fallback;
|
evdev -> touchpad;
|
||||||
plugins -> touchpad;
|
evdev -> tablet;
|
||||||
plugins -> tablet;
|
evdev -> pad;
|
||||||
plugins -> pad;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
The dispatch methods then look at the ``struct evdev_frame`` and proceed to
|
The dispatch methods then look at the ``struct input_event`` and proceed to
|
||||||
update the state.
|
update the state. Note: the serialized nature of the kernel evdev protocol
|
||||||
|
requires that the device updates the state with each event but to delay
|
||||||
.. _architecture-plugins:
|
processing until the ``SYN_REPORT`` event is received.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
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:
|
.. _architecture-configuration:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,29 +16,6 @@ The build instruction on this page detail how to overwrite your
|
||||||
system-provided libinput with one from the git repository, see
|
system-provided libinput with one from the git repository, see
|
||||||
see :ref:`reverting_install` to revert to the previous state.
|
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:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -55,7 +32,7 @@ process below. A successful build requires the
|
||||||
|
|
||||||
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
||||||
$> cd libinput
|
$> cd libinput
|
||||||
$> meson setup --prefix=/usr builddir/
|
$> meson --prefix=/usr builddir/
|
||||||
$> ninja -C builddir/
|
$> ninja -C builddir/
|
||||||
$> sudo ninja -C builddir/ install
|
$> sudo ninja -C builddir/ install
|
||||||
|
|
||||||
|
|
@ -71,7 +48,7 @@ Additional options may also be specified. For example:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$> meson setup --prefix=/usr -Ddocumentation=false builddir/
|
$> meson --prefix=/usr -Ddocumentation=false builddir/
|
||||||
|
|
||||||
|
|
||||||
We recommend that users disable the documentation, it's not usually required
|
We recommend that users disable the documentation, it's not usually required
|
||||||
|
|
@ -96,7 +73,7 @@ again:
|
||||||
::
|
::
|
||||||
|
|
||||||
$> rm -r builddir/
|
$> rm -r builddir/
|
||||||
$> meson setup --prefix=....
|
$> meson --prefix=....
|
||||||
|
|
||||||
|
|
||||||
.. _verifying_install:
|
.. _verifying_install:
|
||||||
|
|
@ -110,10 +87,12 @@ the library path and that all symlinks point to the new library.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$> ldconfig -p | grep libinput | awk '{print $NF}' | xargs ls -l
|
$> ls -l /usr/lib64/libinput.*
|
||||||
lrwxrwxrwx 1 root root 14 lug 22 13:06 /usr/lib/x86_64-linux-gnu/libinput.so -> libinput.so.10
|
-rwxr-xr-x 1 root root 946 Apr 28 2015 /usr/lib64/libinput.la
|
||||||
lrwxrwxrwx 1 root root 19 lug 22 13:06 /usr/lib/x86_64-linux-gnu/libinput.so.10 -> libinput.so.10.13.0
|
lrwxrwxrwx 1 root root 19 Feb 1 15:12 /usr/lib64/libinput.so -> 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
|
lrwxrwxrwx 1 root root 19 Feb 1 15:12 /usr/lib64/libinput.so.10 -> libinput.so.10.13.0
|
||||||
|
-rwxr-xr-x 1 root root 204992 Feb 1 15:12 /usr/lib64/libinput.so.10.13.0
|
||||||
|
|
||||||
|
|
||||||
.. _reverting_install:
|
.. _reverting_install:
|
||||||
|
|
||||||
|
|
@ -142,7 +121,7 @@ overwriting manually installed files.
|
||||||
- **Fedora 22** and later: ``sudo dnf reinstall libinput``
|
- **Fedora 22** and later: ``sudo dnf reinstall libinput``
|
||||||
- **RHEL/CentOS/Fedora 21** and earlier: ``sudo yum reinstall libinput``
|
- **RHEL/CentOS/Fedora 21** and earlier: ``sudo yum reinstall libinput``
|
||||||
- **openSUSE**: ``sudo zypper install --force libinput10``
|
- **openSUSE**: ``sudo zypper install --force libinput10``
|
||||||
- **Arch**: ``sudo pacman -S libinput``
|
- **Arch**: ``sudo packman -S libinput``
|
||||||
|
|
||||||
.. _building_selinux:
|
.. _building_selinux:
|
||||||
|
|
||||||
|
|
@ -188,8 +167,8 @@ libinput has a few build-time dependencies that must be installed prior to
|
||||||
running meson.
|
running meson.
|
||||||
|
|
||||||
.. hint:: The build dependencies for some distributions can be found in the
|
.. 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>`_.
|
`GitLab Continuous Integration file <https://gitlab.freedesktop.org/libinput/libinput/blob/master/.gitlab-ci.yml>`_.
|
||||||
Search for **FEDORA_PACKAGES** in the **variables:** definition
|
Search for **FEDORA_RPMS** in the **variables:** definition
|
||||||
and check the list for an entry for your distribution.
|
and check the list for an entry for your distribution.
|
||||||
|
|
||||||
In most cases, it is sufficient to install the dependencies that your
|
In most cases, it is sufficient to install the dependencies that your
|
||||||
|
|
@ -222,14 +201,6 @@ found``. See
|
||||||
`this blog post here <https://who-t.blogspot.com/2018/07/meson-fails-with-native-dependency-not-found.html>`_
|
`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.
|
for instructions on how to fix it.
|
||||||
|
|
||||||
..............................................................................
|
|
||||||
Build dependencies per distribution
|
|
||||||
..............................................................................
|
|
||||||
|
|
||||||
|
|
||||||
.. include:: dependencies.rst
|
|
||||||
|
|
||||||
|
|
||||||
.. _building_conditional:
|
.. _building_conditional:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -242,7 +213,7 @@ available options. The default build enables most options and thus requires
|
||||||
more build dependencies. On systems where build dependencies are an issue,
|
more build dependencies. On systems where build dependencies are an issue,
|
||||||
options may be disabled with this meson command: ::
|
options may be disabled with this meson command: ::
|
||||||
|
|
||||||
meson setup --prefix=/usr -Dsomefeature=false builddir
|
meson --prefix=/usr -Dsomefeature=false builddir
|
||||||
|
|
||||||
Where ``-Dsomefeature=false`` may be one of:
|
Where ``-Dsomefeature=false`` may be one of:
|
||||||
|
|
||||||
|
|
@ -282,11 +253,6 @@ Software that uses meson should use the ``dependency()`` function: ::
|
||||||
pkgconfig = import('pkgconfig')
|
pkgconfig = import('pkgconfig')
|
||||||
dep_libinput = dependency('libinput')
|
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
|
Otherwise, the most rudimentary way to compile and link a program against
|
||||||
libinput is:
|
libinput is:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,12 +102,11 @@ ignores such button clicks, this behavior is intentional.
|
||||||
Clickfinger behavior
|
Clickfinger behavior
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This is the default behavior on Apple touchpads. Here, a left, right, middle
|
This is the default behavior on Apple touchpads.
|
||||||
button event is generated when one, two, or three fingers are held down on the
|
Here, a left, right, middle button event is generated when one, two, or
|
||||||
touchpad when a physical click is generated, given the default mapping. The
|
three fingers are held down on the touchpad when a physical click is
|
||||||
location of the fingers does not matter and there are no software-defined
|
generated. The location of the fingers does not matter and there are no
|
||||||
button areas. It is possible to swap right and middle buttons, the same way as
|
software-defined button areas.
|
||||||
with :ref:`tapping <tapping>`.
|
|
||||||
|
|
||||||
.. figure:: clickfinger.svg
|
.. figure:: clickfinger.svg
|
||||||
:align: center
|
:align: center
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
.. _clickpads_with_right_buttons:
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Clickpads with a fake right button
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
libinput relies on the kernel to label :ref:`Clickpads <touchpads_buttons_clickpads>`
|
|
||||||
with the ``INPUT_PROP_BUTTONPAD`` property so it can enable the correct
|
|
||||||
:ref:`clickpad_softbuttons`. Clickpads are not expected to have a right button
|
|
||||||
since the whole surface can be depressed.
|
|
||||||
|
|
||||||
A common bug encountered with :ref:`Clickpads <touchpads_buttons_clickpads>`
|
|
||||||
is that the device advertises a physical right button where no such button
|
|
||||||
exists. This is usually a bug in the firmware of the device and causes the
|
|
||||||
following warning to be emitted by libinput::
|
|
||||||
|
|
||||||
"<device name> clickpad advertising right button"
|
|
||||||
|
|
||||||
The user-visible effect of this is usually negligible since these devices
|
|
||||||
cannot actually trigger a right click and libinput's default behaviors for
|
|
||||||
clickpads work as expected.
|
|
||||||
|
|
||||||
However, we should nonetheless correct the device to get rid of this warning
|
|
||||||
and avoid potential issues with future features. The :ref:`device-quirks`
|
|
||||||
provide a simple way to disable the fake right button on the device. The
|
|
||||||
following quirk disables the right button on the MyModel laptop from the
|
|
||||||
MyVendor OEM::
|
|
||||||
|
|
||||||
[MyVendor MyModel Touchpad]
|
|
||||||
MatchName=Foo Bar Touchpad
|
|
||||||
MatchUdevtype=touchpad
|
|
||||||
MatchDMIModAlias=dmi:*:svnMyVendor:pnMyModel:*
|
|
||||||
AttrEventCode=-BTN_RIGHT
|
|
||||||
|
|
||||||
The name of the device can be obtained using :ref:`libinput record <libinput-record>`,
|
|
||||||
the modalias match is a shell-style glob against the value of ``/sys/class/dmi/id/modalias``.
|
|
||||||
In most cases, matching should be against ``svn`` (system vendor) and one of
|
|
||||||
``pn`` (product name) or ``pvr`` (product version), whichever provides a
|
|
||||||
useful description of the individual laptop model. See the
|
|
||||||
:ref:`device-quirks` documentation for details on testing local quirks.
|
|
||||||
|
|
||||||
For reference, some example commits that add such a quirk are:
|
|
||||||
|
|
||||||
- `bf61ab9bb0694d0ac3d60a7f815779abfe4886e6 <https://gitlab.freedesktop.org/libinput/libinput/-/commit/bf61ab9bb0694d0ac3d60a7f815779abfe4886e6>`__
|
|
||||||
- `74fac6d040ac62048882dfb6f73da567ace6a6f5 <https://gitlab.freedesktop.org/libinput/libinput/-/commit/74fac6d040ac62048882dfb6f73da567ace6a6f5>`__
|
|
||||||
- `89cd0f990e3bee9906754d6ca8484ed5aa392249 <https://gitlab.freedesktop.org/libinput/libinput/-/commit/89cd0f990e3bee9906754d6ca8484ed5aa392249>`__
|
|
||||||
|
|
@ -21,7 +21,7 @@ sys.path.insert(0, os.path.abspath('@BUILDDIR@'))
|
||||||
# -- Project information -----------------------------------------------------
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
project = '@PROJECT_NAME@'
|
project = '@PROJECT_NAME@'
|
||||||
copyright = '2019, the libinput authors'
|
copyright = '2018, the libinput authors'
|
||||||
author = 'the libinput authors'
|
author = 'the libinput authors'
|
||||||
|
|
||||||
# The short X.Y version
|
# The short X.Y version
|
||||||
|
|
@ -62,7 +62,7 @@ master_doc = 'index'
|
||||||
#
|
#
|
||||||
# This is also used if you do content translation via gettext catalogs.
|
# This is also used if you do content translation via gettext catalogs.
|
||||||
# Usually you set "language" from the command line for these cases.
|
# Usually you set "language" from the command line for these cases.
|
||||||
language = 'en'
|
language = None
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
|
|
@ -169,7 +169,7 @@ from recommonmark.parser import CommonMarkParser
|
||||||
|
|
||||||
extlinks = { 'commit' :
|
extlinks = { 'commit' :
|
||||||
('https://gitlab.freedesktop.org/libinput/libinput/commit/%s',
|
('https://gitlab.freedesktop.org/libinput/libinput/commit/%s',
|
||||||
'git commit %s')
|
'git commit ')
|
||||||
}
|
}
|
||||||
|
|
||||||
# -- git version hack -------------------------------------------------
|
# -- git version hack -------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -6,21 +6,15 @@ Configuration options
|
||||||
|
|
||||||
Below is a list of configurable options exposed to the users.
|
Below is a list of configurable options exposed to the users.
|
||||||
|
|
||||||
.. contents::
|
|
||||||
:depth: 1
|
|
||||||
:local:
|
|
||||||
|
|
||||||
|
|
||||||
.. hint:: Not all configuration options are available on all devices. Use
|
.. hint:: Not all configuration options are available on all devices. Use
|
||||||
:ref:`libinput list-devices <libinput-list-devices>` to show the
|
:ref:`libinput list-devices <libinput-list-devices>` to show the
|
||||||
configuration options for local devices.
|
configuration options for local devices.
|
||||||
|
|
||||||
libinput's configuration interface is available to the caller only, not
|
libinput's configuration interface is available to the caller only, not
|
||||||
directly to the user. Thus it is the responsibility of the caller to expose
|
directly to the user. Thus is is the responsibility of the caller to expose
|
||||||
the various options and how these options are exposed. For example, the
|
the various options and how these options are exposed. For example, the
|
||||||
`xf86-input-libinput driver <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/>`_
|
xf86-input-libinput driver exposes the options through X Input device
|
||||||
exposes the options through X Input device properties and `xorg.conf.d
|
properties and xorg.conf.d options. See the `libinput(4)
|
||||||
<https://linux.die.net/man/5/xorg.conf.d>`_ options. See the `libinput(4)
|
|
||||||
<https://www.mankier.com/4/libinput>`_ man page for more details.
|
<https://www.mankier.com/4/libinput>`_ man page for more details.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -34,7 +28,7 @@ options exposed by libinput are:
|
||||||
- how many tapping fingers are supported by this device
|
- how many tapping fingers are supported by this device
|
||||||
- a toggle to enable/disable tapping
|
- a toggle to enable/disable tapping
|
||||||
- a toggle to enable/disable tap-and-drag, see :ref:`tapndrag`.
|
- a toggle to enable/disable tap-and-drag, see :ref:`tapndrag`.
|
||||||
- a toggle to enable/disable tap-and-drag drag lock, see :ref:`tapndrag`
|
- a toggle to enable/disable tap-and-drag drag lock see :ref:`tapndrag`
|
||||||
- The default order is 1, 2, 3 finger tap mapping to left, right, middle
|
- The default order is 1, 2, 3 finger tap mapping to left, right, middle
|
||||||
click, respectively. This order can be changed to left, middle, right click,
|
click, respectively. This order can be changed to left, middle, right click,
|
||||||
respectively.
|
respectively.
|
||||||
|
|
@ -43,19 +37,6 @@ Tapping is usually available on touchpads and the touchpad part of external
|
||||||
graphics tablets. Tapping is usually **not** available on touch screens,
|
graphics tablets. Tapping is usually **not** available on touch screens,
|
||||||
for those devices it is expected to be implemented by the toolkit.
|
for those devices it is expected to be implemented by the toolkit.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Three-finger drag
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Three-finger drag allows emulates the mouse button down while three fingers
|
|
||||||
are down on a touchpad without the need to press a physical button or use
|
|
||||||
:ref:`tapndrag`. See :ref:`drag_3fg` for details on how this feature works.
|
|
||||||
|
|
||||||
Three-finger drag is usually available on touchpads and the touchpad part of
|
|
||||||
external graphics tablets. Three-finger drag is usually **not** available on
|
|
||||||
touch screens, for those devices it is expected to be implemented by the
|
|
||||||
toolkit.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Send Events Mode
|
Send Events Mode
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -154,25 +135,12 @@ Disable while typing
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
DWT is the most generic form of palm detection on touchpad. While the user
|
DWT is the most generic form of palm detection on touchpad. While the user
|
||||||
is typing on an internal keyboard the touchpad is disabled, the touchpad
|
is typing the touchpad is disabled, the touchpad is enabled after a timeout.
|
||||||
is enabled again after a timeout. See :ref:`disable-while-typing` for more
|
See :ref:`disable-while-typing` for more info.
|
||||||
info.
|
|
||||||
|
|
||||||
Disable-while-typing can be enabled or disabled, it is enabled by default on
|
Disable-while-typing can be enabled or disabled, it is enabled by default on
|
||||||
most touchpads.
|
most touchpads.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Disable while trackpointing
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DWTP is a form of palm detecion for devices that have a trackpoint (like
|
|
||||||
Thinkpads). While the user is using the trackpoint, the touchpad is disabled,
|
|
||||||
being enabled again after a timeout. See :ref:`disable-while-trackpointing` for
|
|
||||||
more info.
|
|
||||||
|
|
||||||
Disable-while-trackpointing can be enabled or disabled, it is enabled by
|
|
||||||
default.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Calibration
|
Calibration
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -187,51 +155,8 @@ environment should provide an interface for this.
|
||||||
Rotation
|
Rotation
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
The device rotation applies a corrective angle to relative input events,
|
The device rotation applies a corrective angle to relative input events.
|
||||||
allowing the device to be used e.g. sideways or upside-down. For example, a
|
This is currently only available on trackpoints which may be used sideways
|
||||||
trackball may be used in a 90° rotated position for accessibility reasons -
|
or upside-down. The angle can be freely chosen but not all devices support
|
||||||
such a rotated position allows triggering the buttons with the thumb or
|
rotation other than 0, 90, 180, or 270 degrees. Rotation is off (0 degrees)
|
||||||
the non-dominant hand.
|
by default.
|
||||||
|
|
||||||
Note that where a device rotation is higher than 160 but less than 200 degrees,
|
|
||||||
the direction of wheels is also inverted. For all other angles, the wheel
|
|
||||||
direction is left as-is.
|
|
||||||
|
|
||||||
.. _config-tablet-pressure-range:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet tool pressure range
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The pressure range on a :ref:`Tablet tool <tablet-tools>` can be reduced
|
|
||||||
from the full available hardware range to a subset of that range. The effect
|
|
||||||
of this is that the tablet will not register pressure below the given
|
|
||||||
the given threshold is met, and will reach the maximum logical pressure
|
|
||||||
before the maximum hardware-supported pressure is reached.
|
|
||||||
|
|
||||||
See :ref:`tablet-pressure-range` for more info.
|
|
||||||
|
|
||||||
.. _config-tablet-eraser-buttons:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet tool eraser buttons
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On many contemporary :ref:`Tablet tools <tablet-tools>` one button is hardcoded
|
|
||||||
in firmware to emulate an eraser. This button can be remapped to provide
|
|
||||||
a normal stylus button instead.
|
|
||||||
|
|
||||||
See :ref:`tablet-eraser-button` for more info.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Area configuration
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Area configuration is available for some indirect input devices such as
|
|
||||||
graphics tablets. This configuration allows reducing the active area of
|
|
||||||
such a device to a subset of the physically possible area.
|
|
||||||
|
|
||||||
An example use-case for this is to match the aspect ratio of the device to that
|
|
||||||
of the screen.
|
|
||||||
|
|
||||||
See :ref:`tablet-area` for more info.
|
|
||||||
|
|
|
||||||
|
|
@ -5,152 +5,18 @@
|
||||||
Contributing to libinput
|
Contributing to libinput
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
|
Contributions to libinput are always welcome. Please see the steps below for
|
||||||
So you want to contribute to libinput? Great! We'd love to help you be a part
|
details on how to create merge requests, correct git formatting and other
|
||||||
of our community. Here is some important information to help you.
|
topics:
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
:local:
|
:local:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
Questions regarding this process can be asked on ``#wayland-devel`` on
|
||||||
Code of Conduct
|
freenode or on the `wayland-devel@lists.freedesktop.org
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
As a freedesktop.org project, libinput follows the `freedesktop.org
|
|
||||||
Contributor Covenant <https://www.freedesktop.org/wiki/CodeOfConduct>`_.
|
|
||||||
|
|
||||||
Please conduct yourself in a respectful and civilised manner when
|
|
||||||
interacting with community members on mailing lists, IRC, or bug trackers.
|
|
||||||
The community represents the project as a whole, and abusive or bullying
|
|
||||||
behaviour is not tolerated by the project.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Contact
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Questions can be asked on ``#wayland`` on oftc or on the
|
|
||||||
`wayland-devel@lists.freedesktop.org
|
|
||||||
<https://lists.freedesktop.org/mailman/listinfo/wayland-devel>`_ mailing
|
<https://lists.freedesktop.org/mailman/listinfo/wayland-devel>`_ mailing
|
||||||
list.
|
list.
|
||||||
|
|
||||||
For IRC, ping user ``whot`` (Peter Hutterer, the libinput maintainer) though
|
|
||||||
note that he lives on UTC+10 and thus the rest of the world is out of sync
|
|
||||||
by default ;)
|
|
||||||
|
|
||||||
For anything that appears to be device specific and/or related to a new
|
|
||||||
feature, just file `an issue in our issue tracker
|
|
||||||
<https://gitlab.freedesktop.org/libinput/libinput/issues>`_. It's usually the
|
|
||||||
most efficient way to get answers.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
What to work on?
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
If you don't already know what you want to improve or fix with libinput,
|
|
||||||
then a good way of finding something is to search for the ``help needed``
|
|
||||||
tag in our `issue tracker <https://gitlab.freedesktop.org/libinput/libinput/issues?label_name%5B%5D=help+needed>`_.
|
|
||||||
These are issues that have been triaged to some degree and deemed to be a
|
|
||||||
possible future feature to libinput.
|
|
||||||
|
|
||||||
.. note:: Some of these issue may require specific hardware to reproduce.
|
|
||||||
|
|
||||||
Another good place to help out with is the documentation. For anything you
|
|
||||||
find in these pages that isn't clear enough please feel free to reword it
|
|
||||||
and add what is missing.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Getting the code
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The :ref:`building_libinput` have all the details but the short solution
|
|
||||||
will be:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
|
||||||
$> cd libinput
|
|
||||||
$> meson setup --prefix=/usr builddir/
|
|
||||||
$> ninja -C builddir/
|
|
||||||
$> sudo ninja -C builddir/ install
|
|
||||||
|
|
||||||
You can omit the last step if you only want to test locally.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Working on the code
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
If you are planning to send patches, it's a good idea to set up
|
|
||||||
`pre-commit <https://pre-commit.com/>`_ with these commands::
|
|
||||||
|
|
||||||
$> pre-commit install
|
|
||||||
$> pre-commit install --hook-type pre-push
|
|
||||||
|
|
||||||
This will check a few things before you commit and/or push to your repos to
|
|
||||||
reduce the turnaround time for some common mistakes.
|
|
||||||
|
|
||||||
libinput has a roughly three-parts architecture:
|
|
||||||
|
|
||||||
- the front-end code which handles the ``libinput_some_function()`` API calls in ``libinput.c``
|
|
||||||
- the generic evdev interface handling which maps those API calls to the
|
|
||||||
backend calls (``evdev.c``).
|
|
||||||
- there are device-specific backends which do most of the actual work -
|
|
||||||
``evdev-mt-touchpad.c`` is the one for touchpads for example.
|
|
||||||
|
|
||||||
In general, things that only affect the internal workings of a device only
|
|
||||||
get implemented in the device-specific backend. You only need to touch the
|
|
||||||
API when you are adding configuration options. For more details, please read
|
|
||||||
the :ref:`architecture` document. There's also a `blog post describing the
|
|
||||||
building blocks
|
|
||||||
<https://who-t.blogspot.com/2019/03/libinputs-internal-building-blocks.html>`_
|
|
||||||
that may help to understand how it all fits together.
|
|
||||||
|
|
||||||
Documentation is in ``/doc/api`` for the doxygen-generated API documentation.
|
|
||||||
These are extracted from the libinput source code directly. The
|
|
||||||
documentation you're reading right now is in ``/doc/user`` and generated with
|
|
||||||
sphinx. Simply running ``ninja -C builddir`` will rebuild it and the final
|
|
||||||
product ends up in ``builddir/Documentation``.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Testing the code
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput provides a bunch of :ref:`tools` to debug any changes - without
|
|
||||||
having to install libinput.
|
|
||||||
|
|
||||||
The two most useful ones are :ref:`libinput debug-events
|
|
||||||
<libinput-debug-events>` and :ref:`libinput debug-gui <libinput-debug-gui>`.
|
|
||||||
Both tools can be run from the build directory directly and are great for
|
|
||||||
quick test iterations::
|
|
||||||
|
|
||||||
$> sudo ./builddir/libinput-debug-events --verbose
|
|
||||||
$> sudo ./builddir/libinput-debug-gui --verbose
|
|
||||||
|
|
||||||
The former provides purely textual output and is useful for verifying event
|
|
||||||
streams from buttons, etc. The latter is particularly useful when you are
|
|
||||||
trying to debug pointer movement or placement. ``libinput debug-gui`` will
|
|
||||||
also visualize the raw data from the device so you can compare pointer
|
|
||||||
behavior with what comes from the kernel.
|
|
||||||
|
|
||||||
These tools create a new libinput context and will not affect your session's
|
|
||||||
behavior. Only once you've installed libinput and restarted your session
|
|
||||||
will your changes affect the X server/Wayland compositor.
|
|
||||||
|
|
||||||
Once everything seems to be correct, it's time to run the
|
|
||||||
:ref:`test-suite`::
|
|
||||||
|
|
||||||
$> sudo ./builddir/libinput-test-suite
|
|
||||||
|
|
||||||
This test suite can take test names etc. as arguments, have a look at
|
|
||||||
:ref:`test-suite` for more info. There are a bunch of other tests that are
|
|
||||||
run by the CI on merge requests, you can run those locally with ::
|
|
||||||
|
|
||||||
$> sudo ninja -C builddir check
|
|
||||||
|
|
||||||
So it always pays to run that before submitting. This will also run the code
|
|
||||||
through valgrind and pick up any memory leaks.
|
|
||||||
|
|
||||||
.. _contributing_submitting_code:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Submitting Code
|
Submitting Code
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -160,80 +26,32 @@ Any patches should be sent via a Merge Request (see the `GitLab docs
|
||||||
in the `libinput GitLab instance hosted by freedesktop.org
|
in the `libinput GitLab instance hosted by freedesktop.org
|
||||||
<https://gitlab.freedesktop.org/libinput/libinput>`_.
|
<https://gitlab.freedesktop.org/libinput/libinput>`_.
|
||||||
|
|
||||||
.. note:: freedesktop.org's GitLab instance has restrictions to prevent Spam
|
To submit a merge request, you need to
|
||||||
and you cannot fork libinput until you have successfully
|
|
||||||
`applied for fork permissions <https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home>`_.
|
|
||||||
|
|
||||||
Below are the steps required to submit a merge request. They do not
|
|
||||||
replace `learning git <https://git-scm.com/doc>`__ but they should be
|
|
||||||
sufficient to make some of the more confusing steps obvious.
|
|
||||||
|
|
||||||
- `Register an account <https://gitlab.freedesktop.org/users/sign_in>`_ in
|
- `Register an account <https://gitlab.freedesktop.org/users/sign_in>`_ in
|
||||||
the freedesktop.org GitLab instance and
|
the freedesktop.org GitLab instance.
|
||||||
`apply for fork permissions <https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home>`_.
|
- `Fork libinput <https://gitlab.freedesktop.org/libinput/libinput/forks/new>`_
|
||||||
- `Fork libinput <https://gitlab.freedesktop.org/libinput/libinput/-/forks/new>`_
|
into your username's namespace
|
||||||
into your username's namespace. Select public visibility.
|
- Get libinput's main repository: ::
|
||||||
- Get libinput's main repository. git will call this repository ``origin``. ::
|
|
||||||
|
|
||||||
git clone https://gitlab.freedesktop.org/libinput/libinput.git
|
git clone https://gitlab.freedesktop.org/libinput/libinput.git
|
||||||
|
|
||||||
- Add the forked git repository to your remotes (replace ``USERNAME``
|
- Add the forked git repository to your remotes (replace ``USERNAME``
|
||||||
with your username). git will call this repository ``gitlab``. ::
|
with your username): ::
|
||||||
|
|
||||||
cd /path/to/libinput.git
|
cd /path/to/libinput.git
|
||||||
git remote add gitlab git@ssh.gitlab.freedesktop.org:USERNAME/libinput.git
|
git remote add gitlab git@gitlab.freedesktop.org:USERNAME/libinput.git
|
||||||
git fetch gitlab
|
git fetch gitlab
|
||||||
|
|
||||||
- Create a new branch and commit your changes to that branch. ::
|
- Push your changes to your fork: ::
|
||||||
|
|
||||||
git switch -C mynewbranch
|
git push gitlab BRANCHNAME
|
||||||
# edit files, make changes
|
|
||||||
git add file1 file2
|
|
||||||
git commit -s
|
|
||||||
# edit commit message in the editor
|
|
||||||
|
|
||||||
Replace ``mynewbranch`` (here and in the commands below) with a meaningful
|
- Submit a merge request. The URL for a merge request is: ::
|
||||||
name. See :ref:`contributing_commit_messages` for details on the commit
|
|
||||||
message format.
|
|
||||||
|
|
||||||
- Push your changes to your fork and submit a merge request ::
|
|
||||||
|
|
||||||
git push gitlab mynewbranch
|
|
||||||
|
|
||||||
This command will print the URL to file a merge request, you then only
|
|
||||||
have to click through. Alternatively you can go to:
|
|
||||||
|
|
||||||
https://gitlab.freedesktop.org/USERNAME/libinput/merge_requests
|
https://gitlab.freedesktop.org/USERNAME/libinput/merge_requests
|
||||||
|
|
||||||
Select your branch name to merge and ``libinput/libinput`` ``main`` as target branch.
|
Select your branch name to merge and ``libinput/libinput`` ``master`` as target branch.
|
||||||
|
|
||||||
- Verify that the CI completes successfully by visiting the merge request
|
|
||||||
page. A successful pipeline shows only green ticks, failure is indicated
|
|
||||||
by a red cross or a yellow exclamation mark (see
|
|
||||||
the `GitLab Docs
|
|
||||||
<https://docs.gitlab.com/ee/ci/pipelines/#pipeline-mini-graphs>`__). For
|
|
||||||
details about the failures, click on the failed jobs in the pipelines
|
|
||||||
and/or click the ``Expand`` button in the box for the test summaries.
|
|
||||||
|
|
||||||
A merge request without a successful pipeline may never be looked at by a
|
|
||||||
maintainer.
|
|
||||||
|
|
||||||
- If changes are requested by the maintainers, please **amend** the
|
|
||||||
commit(s) and **force-push** the updated branch. ::
|
|
||||||
|
|
||||||
# edits in file foo.c
|
|
||||||
git add foo.c
|
|
||||||
git commit --amend
|
|
||||||
git push -f gitlab mynewbranch
|
|
||||||
|
|
||||||
A force-push will re-trigger the CI and notify the merge request that new
|
|
||||||
changes are available.
|
|
||||||
|
|
||||||
If the branch contains more than one commit, please look at
|
|
||||||
`git interactive rebases
|
|
||||||
<https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History>`__
|
|
||||||
to learn how to change multiple commits, or squash new changes into older
|
|
||||||
commits.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Commit History
|
Commit History
|
||||||
|
|
@ -274,12 +92,23 @@ describes the change. For example: ::
|
||||||
If in doubt what prefix to use, look at other commits that change the
|
If in doubt what prefix to use, look at other commits that change the
|
||||||
same file(s) as the patch being sent.
|
same file(s) as the patch being sent.
|
||||||
|
|
||||||
.. _contributing_commit_messages:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Commit Messages
|
Commit Messages
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Read `on commit messages <http://who-t.blogspot.de/2009/12/on-commit-messages.html>`_
|
||||||
|
as a general guideline on what commit messages should contain.
|
||||||
|
|
||||||
|
Commit messages **should** contain a **Signed-off-by** line with your name
|
||||||
|
and email address. If you're not the patch's original author, you should
|
||||||
|
also gather S-o-b's by them (and/or whomever gave the patch to you.) The
|
||||||
|
significance of this is that it certifies that you created the patch, that
|
||||||
|
it was created under an appropriate open source license, or provided to you
|
||||||
|
under those terms. This lets us indicate a chain of responsibility for the
|
||||||
|
copyright status of the code.
|
||||||
|
|
||||||
|
We won't reject patches that lack S-o-b, but it is strongly recommended.
|
||||||
|
|
||||||
When you re-send patches, revised or not, it would be very good to document the
|
When you re-send patches, revised or not, it would be very good to document the
|
||||||
changes compared to the previous revision in the commit message and/or the
|
changes compared to the previous revision in the commit message and/or the
|
||||||
merge request. If you have already received Reviewed-by or Acked-by tags, you
|
merge request. If you have already received Reviewed-by or Acked-by tags, you
|
||||||
|
|
@ -287,27 +116,12 @@ should evaluate whether they still apply and include them in the respective
|
||||||
commit messages. Otherwise the tags may be lost, reviewers miss the credit they
|
commit messages. Otherwise the tags may be lost, reviewers miss the credit they
|
||||||
deserve, and the patches may cause redundant review effort.
|
deserve, and the patches may cause redundant review effort.
|
||||||
|
|
||||||
If your commit solves a GitLab issue, add a ``Closes:`` tag followed by the
|
|
||||||
issue number at the end of your commit message. For example: ::
|
|
||||||
|
|
||||||
Closes: #974
|
|
||||||
|
|
||||||
If your commit fixes an issue introduced by another commit, use a ``Fixes`` tag
|
|
||||||
followed by the first 12 characters of the SHA-1 ID and the commit one line
|
|
||||||
summary at the end of your commit message. For example: ::
|
|
||||||
|
|
||||||
Fixes: 123456789012 ("The commit that caused the issue")
|
|
||||||
|
|
||||||
For further reading, please see
|
|
||||||
`'on commit messages' <http://who-t.blogspot.de/2009/12/on-commit-messages.html>`_
|
|
||||||
as a general guideline on what commit messages should contain.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Coding Style
|
Coding Style
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Please see the `CODING_STYLE.md
|
Please see the `CODING_STYLE.md
|
||||||
<https://gitlab.freedesktop.org/libinput/libinput/blob/main/CODING_STYLE.md>`_
|
<https://gitlab.freedesktop.org/libinput/libinput/blob/master/CODING_STYLE.md>`_
|
||||||
document in the source tree.
|
document in the source tree.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -347,75 +161,13 @@ process, even if you use other clients to track the list of available
|
||||||
patches.
|
patches.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Failed pipeline errors
|
Code of Conduct
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
After submitting your merge request to GitLab, you might receive an email
|
As a freedesktop.org project, libinput follows the `freedesktop.org
|
||||||
informing you that your pipeline failed.
|
Contributor Covenant <https://www.freedesktop.org/wiki/CodeOfConduct>`_.
|
||||||
|
|
||||||
Visit your merge request page and check the `pipeline mini graph
|
Please conduct yourself in a respectful and civilised manner when
|
||||||
<https://docs.gitlab.com/ee/ci/pipelines/#pipeline-mini-graphs>`_ to know which
|
interacting with community members on mailing lists, IRC, or bug trackers.
|
||||||
step failed.
|
The community represents the project as a whole, and abusive or bullying
|
||||||
|
behaviour is not tolerated by the project.
|
||||||
Follow the appropriate section to fix the errors.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
When your merge request modifies the CI templates, you might see this error
|
|
||||||
mainly due two reasons: the wrong file was modified and/or
|
|
||||||
``ci-fairy generate-template`` wasn't run.
|
|
||||||
|
|
||||||
``.gitlab-ci.yaml`` is auto generated, changes should be made in:
|
|
||||||
|
|
||||||
- ``.gitlab-ci/ci.template``
|
|
||||||
|
|
||||||
- ``.gitlab-ci/config.yaml``
|
|
||||||
|
|
||||||
Once the changes are ready, run
|
|
||||||
`ci-fairy <https://freedesktop.pages.freedesktop.org/ci-templates/ci-fairy.html#templating-gitlab-ci-yml>`_
|
|
||||||
to update ``.gitlab-ci.yaml``: ::
|
|
||||||
|
|
||||||
ci-fairy generate-template
|
|
||||||
|
|
||||||
Finally, force-push you changes. See :ref:`contributing_submitting_code` for
|
|
||||||
more details.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Build errors
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Usually, checking the CI log is enough to catch this errors. However, your merge
|
|
||||||
request is built using different configurations you might have not tested.
|
|
||||||
|
|
||||||
In order to fix this kind of problems, you can compile libinput using the same
|
|
||||||
flags used by the CI.
|
|
||||||
|
|
||||||
For example, if an error is found in the ``build-no-libwacom`` step, open the
|
|
||||||
log and search the build options: ::
|
|
||||||
|
|
||||||
[...]
|
|
||||||
+ rm -rf 'build dir'
|
|
||||||
+ meson 'build dir' -Dlibwacom=false
|
|
||||||
The Meson build system
|
|
||||||
[...]
|
|
||||||
|
|
||||||
Use the same flags to fix the issue and force-push you changes. See
|
|
||||||
:ref:`contributing_submitting_code` for more details.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Test errors
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The test suite is run for your merge request to check for bugs, regressions and
|
|
||||||
memory leaks among other issues.
|
|
||||||
|
|
||||||
Open the CI error log and search for a message similar to: ::
|
|
||||||
|
|
||||||
:: Failure: ../test/test-touchpad.c:465: touchpad_2fg_scroll_slow_distance(synaptics-t440)
|
|
||||||
|
|
||||||
See :ref:`test-suite` to learn how to run the failing tests.
|
|
||||||
|
|
||||||
Once the tests are fixed, force-push you changes. See
|
|
||||||
:ref:`contributing_submitting_code` for more details.
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
.. warning:: The package lists are autogenerated from the `CI <https://gitlab.freedesktop.org/libinput/libinput/-/tree/master/.gitlab-ci.yml>`_.
|
|
||||||
|
|
||||||
- Fedora: ::
|
|
||||||
|
|
||||||
dnf install @FEDORA_PACKAGES@
|
|
||||||
|
|
||||||
- Ubuntu: ::
|
|
||||||
|
|
||||||
apt install @UBUNTU_PACKAGES@
|
|
||||||
|
|
||||||
- Debian: ::
|
|
||||||
|
|
||||||
apt install @DEBIAN_PACKAGES@
|
|
||||||
|
|
||||||
- Arch: ::
|
|
||||||
|
|
||||||
pacman -S @ARCH_PACKAGES@
|
|
||||||
|
|
||||||
- Alpine: ::
|
|
||||||
|
|
||||||
apk add @ALPINE_PACKAGES@
|
|
||||||
|
|
@ -36,7 +36,6 @@ Topics below explain some behaviors of libinput.
|
||||||
normalization-of-relative-motion.rst
|
normalization-of-relative-motion.rst
|
||||||
seats.rst
|
seats.rst
|
||||||
timestamps.rst
|
timestamps.rst
|
||||||
wheel-api.rst
|
|
||||||
|
|
||||||
.. _hacking_on_libinput:
|
.. _hacking_on_libinput:
|
||||||
|
|
||||||
|
|
@ -47,6 +46,7 @@ Hacking on libinput
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
contributing.rst
|
||||||
architecture
|
architecture
|
||||||
test-suite.rst
|
test-suite.rst
|
||||||
pointer-acceleration.rst
|
pointer-acceleration.rst
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,10 @@ MOUSE_WHEEL_CLICK_ANGLE
|
||||||
|
|
||||||
|
|
||||||
Below is an example udev rule to assign "seat1" to a device from vendor
|
Below is an example udev rule to assign "seat1" to a device from vendor
|
||||||
``0x012a`` with the model ID of ``0x034b``. ::
|
0x012a with the model ID of 0x034b. ::
|
||||||
|
|
||||||
$ cat /etc/udev/rules.d/99-my-device-is-on-seat1.rules
|
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||||
ACTION!="remove", KERNEL=="event[0-9]*", \
|
ENV{ID_MODEL_ID}=="034b", ENV{ID_SEAT}="seat1"
|
||||||
ENV{ID_VENDOR_ID}=="012a", \
|
|
||||||
ENV{ID_MODEL_ID}=="034b", \
|
|
||||||
ENV{ID_SEAT}="seat1"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -99,13 +96,37 @@ handle some combinations for historical reasons.
|
||||||
|
|
||||||
Below is an example udev rule to remove an **ID_INPUT_TOUCHPAD** setting
|
Below is an example udev rule to remove an **ID_INPUT_TOUCHPAD** setting
|
||||||
and change it into an **ID_INPUT_TABLET** setting. This rule would apply
|
and change it into an **ID_INPUT_TABLET** setting. This rule would apply
|
||||||
for a device with the vendor/model ID of ``012a``/``034b``. ::
|
for a device with the vendor/model ID of 012a/034b. ::
|
||||||
|
|
||||||
$ cat /etc/udev/rules.d/99-my-device-is-a-tablet.rules
|
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||||
ACTION!="remove", KERNEL=="event[0-9]*", \
|
ENV{ID_MODEL_ID}=="034b", ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
|
||||||
ENV{ID_VENDOR_ID}=="012a", \
|
|
||||||
ENV{ID_MODEL_ID}=="034b", \
|
|
||||||
ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
|
|
||||||
|
.. _ignoring_devices:
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
Ignoring specific devices
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
If a device has the **LIBINPUT_IGNORE_DEVICE** udev property set to any
|
||||||
|
value but "0", that device is not initialized by libinput. For a context
|
||||||
|
created with **libinput_udev_create_context()**, the device is silently ignored
|
||||||
|
and never shows up. If the device is added with **libinput_path_add_device()**
|
||||||
|
to a context created with **libinput_path_create_context()**, adding the device
|
||||||
|
will fail and return NULL (see that function's documentation for more
|
||||||
|
information).
|
||||||
|
|
||||||
|
If the property value is exactly "0", then the property is considered unset
|
||||||
|
and libinput initializes the device normally.
|
||||||
|
|
||||||
|
This property should be used for devices that are correctly detected as
|
||||||
|
input devices (see :ref:`udev_device_type`) but that should not be used by
|
||||||
|
libinput. It is recommended that devices that should not be handled as input
|
||||||
|
devices at all unset the **ID_INPUT** and related properties instead. The
|
||||||
|
**LIBINPUT_IGNORE_DEVICE** property signals that only libinput should
|
||||||
|
ignore this property but other parts of the stack (if any) should continue
|
||||||
|
treating this device normally.
|
||||||
|
|
||||||
|
|
||||||
.. _model_specific_configuration:
|
.. _model_specific_configuration:
|
||||||
|
|
@ -129,7 +150,7 @@ The property **LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81** may be set by a
|
||||||
user in a local hwdb file. This property designates the touchpad on a Lenovo
|
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
|
x220 with a touchpad firmware version 8.1. When this firmware version is
|
||||||
installed, the touchpad is imprecise. The touchpad device does not send
|
installed, the touchpad is imprecise. The touchpad device does not send
|
||||||
continuous x/y axis position updates, a behavior also observed on its
|
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
|
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
|
above property is set, libinput adjusts its behavior to better suit this
|
||||||
particular model.
|
particular model.
|
||||||
|
|
@ -242,4 +263,4 @@ Modifying the hwdb
|
||||||
device-specific quirks must go in to the :ref:`device-quirks` system.
|
device-specific quirks must go in to the :ref:`device-quirks` system.
|
||||||
|
|
||||||
For information about older libinput versions, please see the documentation
|
For information about older libinput versions, please see the documentation
|
||||||
for your version available in: https://wayland.freedesktop.org/libinput/doc/
|
for your version avaialable in: https://wayland.freedesktop.org/libinput/doc/
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ Device quirks
|
||||||
|
|
||||||
libinput requires extra information from devices that is not always readily
|
libinput requires extra information from devices that is not always readily
|
||||||
available. For example, some touchpads are known to have jumping cursors
|
available. For example, some touchpads are known to have jumping cursors
|
||||||
under specific conditions. libinput ships a set of files containing the
|
under specific conditions. libinput ships a set of files containting the
|
||||||
so-called model quirks to provide that information. Model quirks are usually
|
so-called model quirks to provide that information. Model quirks are usually
|
||||||
installed under ``/usr/share/libinput/<filename>.quirks`` and are standard
|
installed under ``/usr/share/libinput/<filename>.quirks`` and are standard
|
||||||
``.ini`` files. A file may contain multiple section headers (``[some
|
``.ini`` files. A file may contain multiple section headers (``[some
|
||||||
identifier]``) followed by one or more :ref:`MatchFoo=Bar <device-quirks-matches>`
|
identifier]``) followed by one or more ``MatchFoo=Bar`` directives, followed by
|
||||||
directives, followed by at least one of ``ModelFoo=1`` or ``AttrFoo=bar`` directive.
|
at least one of ``ModelFoo=1`` or ``AttrFoo=bar`` directive. See the
|
||||||
See the ``quirks/README.md`` file in the libinput source repository for more
|
``quirks/README.md`` file in the libinput source repository for more details on
|
||||||
details on their contents.
|
their contents.
|
||||||
|
|
||||||
.. warning:: Model quirks are internal API and may change at any time. No
|
.. warning:: Model quirks are internal API and may change at any time. No
|
||||||
backwards-compatibility is guaranteed.
|
backwards-compatibility is guaranteed.
|
||||||
|
|
@ -71,7 +71,7 @@ devices. ::
|
||||||
|
|
||||||
$ libinput quirks list /dev/input/event19
|
$ libinput quirks list /dev/input/event19
|
||||||
$ libinput quirks list /dev/input/event0
|
$ libinput quirks list /dev/input/event0
|
||||||
AttrLidSwitchReliability=unreliable
|
AttrLidSwitchReliability=reliable
|
||||||
|
|
||||||
The device `event19` does not have any quirks assigned.
|
The device `event19` does not have any quirks assigned.
|
||||||
|
|
||||||
|
|
@ -112,11 +112,11 @@ output.
|
||||||
.. _device-quirks-list:
|
.. _device-quirks-list:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
List of currently available device quirks
|
List of supported device quirks
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This list is a guide for developers to ease the process of submitting
|
This list is a guide for developers to ease the process of submitting
|
||||||
patches upstream. This section shows device quirks currently available in
|
patches upstream. This section shows device quirks supported in
|
||||||
|git_version|.
|
|git_version|.
|
||||||
|
|
||||||
.. warning:: Quirks are internal API and may change at any time for any reason.
|
.. warning:: Quirks are internal API and may change at any time for any reason.
|
||||||
|
|
@ -147,21 +147,6 @@ ModelBouncingKeys
|
||||||
timestamps can not be relied upon.
|
timestamps can not be relied upon.
|
||||||
ModelSynapticsSerialTouchpad
|
ModelSynapticsSerialTouchpad
|
||||||
Reserved for touchpads made by Synaptics on the serial bus
|
Reserved for touchpads made by Synaptics on the serial bus
|
||||||
ModelPressurePad
|
|
||||||
.. warning:: This quirk is no longer in use. Use
|
|
||||||
``AttrInputProp=+INPUT_PROP_PRESSUREPAD`` instead.
|
|
||||||
|
|
||||||
Unlike in traditional touchpads, whose pressure value equals contact size,
|
|
||||||
on pressure pads pressure is a real physical axis.
|
|
||||||
Indicates that the device is a pressure pad.
|
|
||||||
ModelTouchpadPhantomClicks
|
|
||||||
Some laptops are prone to registering touchpad clicks when the case is
|
|
||||||
bent. Indicates that clicks should be ignored if no fingers are on the
|
|
||||||
touchpad.
|
|
||||||
ModelScrollOnMiddleClick
|
|
||||||
Some mice can generate unwanted high-resolution scroll events when the wheel
|
|
||||||
is pressed. Increases the scroll threshold required to start scrolling to
|
|
||||||
avoid accidentally scrolling when middle clicking.
|
|
||||||
AttrSizeHint=NxM, AttrResolutionHint=N
|
AttrSizeHint=NxM, AttrResolutionHint=N
|
||||||
Hints at the width x height of the device in mm, or the resolution
|
Hints at the width x height of the device in mm, or the resolution
|
||||||
of the x/y axis in units/mm. These may only be used where they apply to
|
of the x/y axis in units/mm. These may only be used where they apply to
|
||||||
|
|
@ -172,20 +157,15 @@ AttrTouchSizeRange=N:M, AttrPalmSizeThreshold=O
|
||||||
Specifies the touch size required to trigger a press (N) and to trigger
|
Specifies the touch size required to trigger a press (N) and to trigger
|
||||||
a release (M). O > N > M. See :ref:`touchpad_touch_size_hwdb` for more
|
a release (M). O > N > M. See :ref:`touchpad_touch_size_hwdb` for more
|
||||||
details.
|
details.
|
||||||
An AttrPalmSizeThreshold of zero unsets any threshold that has been
|
AttrTouchPressureRange=N:M, AttrPalmPressureThreshold=O, AttrThumbPressureThreshold=P
|
||||||
inherited from another quirk.
|
|
||||||
AttrPressureRange=N:M, AttrPalmPressureThreshold=O, AttrThumbPressureThreshold=P
|
|
||||||
Specifies the touch pressure required to trigger a press (N) and to
|
Specifies the touch pressure required to trigger a press (N) and to
|
||||||
trigger a release (M), when a palm touch is triggered (O) and when a
|
trigger a release (M), when a palm touch is triggered (O) and when a
|
||||||
thumb touch is triggered (P). O > P > N > M. See
|
thumb touch is triggered (P). O > P > N > M. See
|
||||||
:ref:`touchpad_pressure_hwdb` for more details.
|
:ref:`touchpad_pressure_hwdb` for more details.
|
||||||
An AttrPalmPressureThreshold of zero unsets any threshold that has been
|
AttrLidSwitchReliability=reliable|write_open
|
||||||
inherited from another quirk.
|
Indicates the reliability of the lid switch. This is a string enum. Do not
|
||||||
AttrLidSwitchReliability=reliable|unreliable|write_open
|
use "reliable" for any specific device. Very few devices need this, if in
|
||||||
Indicates the reliability of the lid switch. This is a string enum.
|
doubt do not set. See :ref:`switches_lid` for details.
|
||||||
Very few devices need this, if in doubt do not set. See :ref:`switches_lid`
|
|
||||||
for details. libinput 1.21.0 changed the default from unreliable to
|
|
||||||
reliable, which may be removed from local overrides.
|
|
||||||
AttrKeyboardIntegration=internal|external
|
AttrKeyboardIntegration=internal|external
|
||||||
Indicates the integration of the keyboard. This is a string enum.
|
Indicates the integration of the keyboard. This is a string enum.
|
||||||
Generally only needed for USB keyboards.
|
Generally only needed for USB keyboards.
|
||||||
|
|
@ -193,52 +173,10 @@ AttrTPKComboLayout=below
|
||||||
Indicates the position of the touchpad on an external touchpad+keyboard
|
Indicates the position of the touchpad on an external touchpad+keyboard
|
||||||
combination device. This is a string enum. Don't specify it unless the
|
combination device. This is a string enum. Don't specify it unless the
|
||||||
touchpad is below.
|
touchpad is below.
|
||||||
AttrEventCode=+EV_ABS;-BTN_STYLUS;+EV_KEY:0x123;
|
AttrEventCodeDisable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
||||||
Enables or disables the evdev event type/code tuples on the device. The prefix
|
Disables the evdev event type/code tuples on the device. Entries may be
|
||||||
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
|
||||||
a named event type, or a named event code, or a named event type with a
|
a named event type, or a named event code, or a named event type with a
|
||||||
hexadecimal event code, separated by a single colon.
|
hexadecimal event code, separated by a single colon.
|
||||||
AttrInputProp=+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER;
|
|
||||||
Enables or disables the evdev input property on the device. The prefix
|
|
||||||
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
|
||||||
a named input property or the hexadecimal value of that property.
|
|
||||||
|
|
||||||
The most common use of this is ``AttrInputProp=+INPUT_PROP_PRESSUREPAD``
|
|
||||||
which marks a touchpad as a :ref:`forcepad or pressurepad <touchpads_buttons_forcepads>`.
|
|
||||||
AttrPointingStickIntegration=internal|external
|
AttrPointingStickIntegration=internal|external
|
||||||
Indicates the integration of the pointing stick. This is a string enum.
|
Indicates the integration of the pointing stick. This is a string enum.
|
||||||
Only needed for external pointing sticks. These are rare.
|
Only needed for external pointing sticks. These are rare.
|
||||||
AttrTabletSmoothing=1|0
|
|
||||||
Enables (1) or disables (0) input smoothing for tablet devices. Smoothing is enabled
|
|
||||||
by default, except on AES devices.
|
|
||||||
|
|
||||||
.. _device-quirks-matches:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
List of currently available matches
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
``Match*`` statements are how quirks are assigned to a device. Quirks with multiple
|
|
||||||
match statements must match all of those to apply.
|
|
||||||
|
|
||||||
.. warning:: Quirks are internal API and may change at any time for any reason.
|
|
||||||
No guarantee is given that any ``Match`` statement below works on
|
|
||||||
your version of libinput.
|
|
||||||
|
|
||||||
MatchName, MatchUniq
|
|
||||||
Match on the ``NAME`` or ``UNIQ`` udev property on this device. These properties
|
|
||||||
are typically derived from the device's kernel name or uniq but may be overridden
|
|
||||||
by a udev rule. These matches use ``fnmatch()`` globs.
|
|
||||||
MatchBus
|
|
||||||
A lower-case bus name. Currently supported are ``usb``, ``bluetooth``, ``ps2``,
|
|
||||||
``rmi``, ``i2c``, and ``spi``.
|
|
||||||
MatchVendor, MatchProduct, MatchVersion
|
|
||||||
The hexadecimal 4-digit vendor ID, product ID or driver version as
|
|
||||||
exported, uppercase with a ``0x`` prefix, e.g. ``0x12AB```.
|
|
||||||
MatchDMIModalias, MatchDeviceTree
|
|
||||||
An ``fnmatch()`` glob for the DMI modalias or the DeviceTree ``compatible`` string.
|
|
||||||
See ``/sys/class/dmi/id/modalias`` and ``/sys/firmware/devicetree/base/compatible``.
|
|
||||||
MatchUdevType
|
|
||||||
One of ``touchpad``, ``mouse``, ``pointingstick``, ``keyboard``, ``joystick``,
|
|
||||||
``tablet``, ``tablet-pad``. Matches the corresponding ``ID_INPUT_*`` udev
|
|
||||||
property.
|
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
digraph stack
|
|
||||||
{
|
|
||||||
compound=true;
|
|
||||||
splines=line;
|
|
||||||
rankdir="LR";
|
|
||||||
node [
|
|
||||||
shape="box";
|
|
||||||
]
|
|
||||||
|
|
||||||
subgraph cluster_2 {
|
|
||||||
label="Kernel";
|
|
||||||
event0 [label="/dev/input/event0"];
|
|
||||||
event1 [label="/dev/input/event1"];
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_0 {
|
|
||||||
label="Compositor process";
|
|
||||||
libinput [label="libinput context 1"];
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_1 {
|
|
||||||
label="libinput debug-events";
|
|
||||||
libinput2 [label="libinput context 2"];
|
|
||||||
}
|
|
||||||
|
|
||||||
stdout;
|
|
||||||
|
|
||||||
client [label="Wayland client"];
|
|
||||||
|
|
||||||
event0:e -> libinput:w;
|
|
||||||
event1:e -> libinput:w;
|
|
||||||
event0:e -> libinput2:w;
|
|
||||||
event1:e -> libinput2:w;
|
|
||||||
libinput -> client [ltail=cluster_0 label="Wayland protocol"];
|
|
||||||
libinput2 -> stdout [ltail=cluster_1];
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
digraph stack
|
|
||||||
{
|
|
||||||
compound=true;
|
|
||||||
rankdir="LR";
|
|
||||||
node [
|
|
||||||
shape="box";
|
|
||||||
]
|
|
||||||
|
|
||||||
subgraph cluster_2 {
|
|
||||||
label="Kernel";
|
|
||||||
event0 [label="/dev/input/event0"]
|
|
||||||
}
|
|
||||||
|
|
||||||
subgraph cluster_1 {
|
|
||||||
label="libinput";
|
|
||||||
subgraph cluster_0 {
|
|
||||||
label="Plugin pipeline";
|
|
||||||
p1 [label="00-foo.lua"];
|
|
||||||
p2 [label="10-bar.lua"];
|
|
||||||
}
|
|
||||||
libinput [label="libinput core"];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
compositor [label="Compositor"];
|
|
||||||
|
|
||||||
event0 -> p1;
|
|
||||||
p1 -> p2;
|
|
||||||
p2 -> libinput;
|
|
||||||
libinput -> compositor [ltail=cluster_1 label="libinput API"];
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
.. _drag_3fg:
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Three-finger drag
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Three-finger drag is a feature available on touchpads that emulates logical
|
|
||||||
button presses if three fingers are moving on the touchpad.
|
|
||||||
|
|
||||||
Three-finger drag is independent from :ref:`tapping` though some specific
|
|
||||||
behaviors may change when both features are enabled. For example, with
|
|
||||||
tapping *disabled* a three-finger gesture will virtually always be a three-finger
|
|
||||||
drag. With tapping *enabled* a three finger gesture may be a three finger drag
|
|
||||||
and a short delay is required to disambiguate between the two.
|
|
||||||
|
|
||||||
|
|
||||||
The exact behavior of three-finger drag is implementation defined and may
|
|
||||||
subtly change. As a general rule, the following constraints can be expected:
|
|
||||||
|
|
||||||
- three fingers down and movement trigger a button down and subsequent motion
|
|
||||||
events (i.e. a drag)
|
|
||||||
- releasing one finger while keeping two fingers down will keep the drag
|
|
||||||
and *not* switch to :ref:`twofinger_scrolling`.
|
|
||||||
- releasing two fingers while keeping one finger down will end the drag
|
|
||||||
(and thus release the button) and switch to normal pointer motion
|
|
||||||
- releasing all three fingers and putting three fingers back on the touchpad
|
|
||||||
immediately will keep the drag (i.e. behave as if the fingers were
|
|
||||||
never lifted)
|
|
||||||
|
|
||||||
- if tapping is enabled: a three finger tap immediately after a three-finger
|
|
||||||
drag will *not* tap, the user needs to wait past the timeout to
|
|
||||||
three-finger tap
|
|
||||||
|
|
||||||
- releasing all three fingers and putting one or two fingers back on
|
|
||||||
the touchpad will end the drag (and thus release the button)
|
|
||||||
and proceed with pointer motion or two-finger scrolling, if applicable
|
|
||||||
|
|
||||||
- if tapping is enabled: a one or two finger tap immediately after a
|
|
||||||
three-finger drag will trigger a one or two finger tap. The user does
|
|
||||||
not have to wait past the drag release timeout
|
|
||||||
|
|
@ -42,18 +42,6 @@ This is a symptom of an invalid trackpoint multiplier. These devices need
|
||||||
pointer acceleration accordingly. See :ref:`trackpoint_range` for a detailed
|
pointer acceleration accordingly. See :ref:`trackpoint_range` for a detailed
|
||||||
explanation.
|
explanation.
|
||||||
|
|
||||||
.. _faq_pointer_acceleration:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Why is libinput's pointer acceleration worse than synaptics/evdev
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
This is a known problem affecting some devices and/or use-case but the exact
|
|
||||||
cause is still unknown. It may be a device-specific issue, it may be a bug
|
|
||||||
in libinput's acceleration code, it may be a disagreement about how pointer
|
|
||||||
acceleration should feel. Unfortunately this is something that affected
|
|
||||||
users need to investigate and analyze.
|
|
||||||
|
|
||||||
.. _faq_enable_tapping:
|
.. _faq_enable_tapping:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -218,7 +206,7 @@ Why don't synclient and syndaemon work with libinput?
|
||||||
|
|
||||||
Synclient and syndaemon rely on X input device properties that are specific
|
Synclient and syndaemon rely on X input device properties that are specific
|
||||||
to the xf86-input-synaptics X.Org input driver. Both were written when the
|
to the xf86-input-synaptics X.Org input driver. Both were written when the
|
||||||
synaptics driver was the only common touchpad driver in existence. They
|
synaptics driver was the only commmon touchpad driver in existence. They
|
||||||
assume that if the properties aren't available, no touchpad is available
|
assume that if the properties aren't available, no touchpad is available
|
||||||
either. The xf86-input-libinput X.Org input driver does not export these
|
either. The xf86-input-libinput X.Org input driver does not export these
|
||||||
driver-specific properties, synclient/syndaemon will thus not detect the
|
driver-specific properties, synclient/syndaemon will thus not detect the
|
||||||
|
|
@ -287,28 +275,28 @@ details on the hwdb and how to modify it locally.
|
||||||
.. _faq_timer_offset:
|
.. _faq_timer_offset:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
What causes the "your system is too slow" warning?
|
What causes the "timer offset negative" warning?
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
libinput relies on the caller to call **libinput_dispatch()** whenever data is
|
libinput relies on the caller to call **libinput_dispatch()** whenever data is
|
||||||
available. **libinput_dispatch()** will process the state of all devices,
|
available on the epoll-fd. Doing so will process the state of all devices
|
||||||
including some time-sensitive features (e.g. palm detection, tap-to-click,
|
and can trigger some timers to be set (e.g. palm detection, tap-to-click,
|
||||||
disable-while-typing, etc.).
|
disable-while-typing, etc.). Internally, libinput's time offsets are always
|
||||||
|
based on the event time of the triggering event.
|
||||||
|
|
||||||
If the time between the event and the call to **libinput_dispatch()**
|
For example, a touch event with time T may trigger a timer for the time T +
|
||||||
is excessive, those features may not work correctly. For example, a delay in
|
180ms. When setting a timer, libinput checks the wall clock time to ensure
|
||||||
touch event processing may cause wrong or missing tap-to-click events or
|
that this time T + offset is still in the future. If not, the warning is
|
||||||
a palm may not be detected correctly.
|
logged.
|
||||||
|
|
||||||
When this warning appears, it simply means that too much time has passed
|
When this warning appears, it simply means that too much time has passed
|
||||||
between the event occurring and the current time. In almost all cases this
|
between the event occurring (and the epoll-fd triggering) and the current
|
||||||
is an indication of the caller being overloaded and not handling events as
|
time. In almost all cases this is an indication of the caller being
|
||||||
speedily as required.
|
overloaded and not handling events as speedily as required.
|
||||||
|
|
||||||
The warning has no immediate effect on libinput's behavior but some of the
|
The warning has no immediate effect on libinput's behavior but some of the
|
||||||
functionality that relies on the timer may be impeded. This is not a bug in
|
functionality that relies on the timer may be impeded (e.g. palms are not
|
||||||
libinput. libinput does not control how quickly **libinput_dispatch()** is
|
detected as they should be).
|
||||||
called.
|
|
||||||
|
|
||||||
.. _faq_wayland:
|
.. _faq_wayland:
|
||||||
|
|
||||||
|
|
@ -324,67 +312,15 @@ direct connection. As a technical analogy, the question is similar to "is
|
||||||
glibc required for HTTP", or (stretching the analogy a bit further) "Is a
|
glibc required for HTTP", or (stretching the analogy a bit further) "Is a
|
||||||
pen required to write English". No, it isn't.
|
pen required to write English". No, it isn't.
|
||||||
|
|
||||||
You can use libinput without a Wayland compositor, you can write a Wayland
|
You can use libinput without a Wayland compositor, you can
|
||||||
compositor without libinput. On most major distributions, libinput is the
|
write a Wayland compositor without libinput. Until 2018 the most common use
|
||||||
standard input stack used with the X.Org X server through the
|
of libinput is with the X.Org X server through the xf86-input-libinput
|
||||||
xf86-input-libinput driver.
|
driver. As Wayland compositors become more commonplace they will eventually
|
||||||
|
overtake X.
|
||||||
|
|
||||||
So why "for your use-case - probably"? All general-purpose Wayland
|
So why "for your use-case - probably"? All general-purpose Wayland
|
||||||
compositors use libinput for their input stack. Wayland compositors that
|
compositors use libinput for their input stack. Wayland compositors that
|
||||||
are more specialized (e.g. in-vehicle infotainment or IVI) can handle input
|
are more specialized (e.g. in-vehicle infotainment or IVI) can handle input
|
||||||
devices directly but the compositor you want to use
|
devices directly but the compositor you want to use
|
||||||
on your desktop needs an input stack that is more complex. And right now,
|
on your desktop needs an input stack that is more complex. And right now,
|
||||||
libinput is the only input stack that exists for this use-case.
|
libinput is the only input stack that exists for this use-case.
|
||||||
|
|
||||||
.. _faq_separate_contexts:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Can I write a program to make libinput do $FOO
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A common question is whether it's possible to write a program that can change
|
|
||||||
libinput's behavior - specifically the libinput that is used inside the
|
|
||||||
compositor. This indicates a misunderstanding of how libinput works:
|
|
||||||
libinput is a library that converts kernel events into libinput events, much
|
|
||||||
like ``sed`` reads data in, modifies it, and provides it to stdout.
|
|
||||||
|
|
||||||
.. graphviz:: libinput-contexts.gv
|
|
||||||
|
|
||||||
A libinput context is private to the process and cannot be modified from the
|
|
||||||
outside. To use the ``sed`` analogy again: if ``sed`` is used by a
|
|
||||||
shell-script, that script has full control over how ``sed`` processes data. In
|
|
||||||
this analogy, ``sed`` is libinput and the shell script is the compositor. It is
|
|
||||||
not possible to write a program to modify the behavior of the ``sed`` instance
|
|
||||||
used inside that shell script.
|
|
||||||
|
|
||||||
Writing a program that uses libinput is akin to writing a new script that
|
|
||||||
invoke ``sed``. It will not have any effect on the original ``sed`` instance.
|
|
||||||
|
|
||||||
The only way to modify libinput's behavior is to use the configuration options
|
|
||||||
exposed by the respective compositor. Those affect the libinput context inside
|
|
||||||
the compositor and thus have an effect on the input device behavior.
|
|
||||||
|
|
||||||
.. _faq_debug_events_not_showing_configuration:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Why doesn't libinput debug-events show my configuration
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
See :ref:`faq_separate_contexts`.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Can I configure scroll speed?
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
No, or at least, not as a libinput option.
|
|
||||||
|
|
||||||
When using a mouse, libinput notifies callers about physical scroll wheel
|
|
||||||
movement. When using another device, libinput notifies scroll in scroll units.
|
|
||||||
|
|
||||||
It is up to the caller to transform those events into a number of pixels to
|
|
||||||
scroll and, if desired, provide a way to adjust scroll speed.
|
|
||||||
|
|
||||||
This transformation cannot be done in libinput because it may depend on context
|
|
||||||
only known by the caller. For example, a caller may want to scroll faster
|
|
||||||
depending on how many pages a document has or depending on the widget that
|
|
||||||
receives the scroll events.
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ libinput Features
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
Below is a list of features supported by libinput. The availability of
|
Below is a list of features supported by libinput. The availability of
|
||||||
features usually depends on the device type and a device's capabilities.
|
features usually depends on the device type and a device's capabilties.
|
||||||
Not all features are user-configurable, some rely on :ref:`device-quirks`
|
Not all features are user-configurable, some rely on :ref:`device-quirks`
|
||||||
to be useful.
|
to be useful.
|
||||||
|
|
||||||
|
|
@ -22,7 +22,6 @@ to be useful.
|
||||||
scrolling.rst
|
scrolling.rst
|
||||||
t440-support.rst
|
t440-support.rst
|
||||||
tapping.rst
|
tapping.rst
|
||||||
drag-3fg.rst
|
|
||||||
tablet-support.rst
|
tablet-support.rst
|
||||||
switches.rst
|
switches.rst
|
||||||
touchpad-pressure.rst
|
touchpad-pressure.rst
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,9 @@ finger belonging to this gesture is lifted.
|
||||||
|
|
||||||
A single gesture cannot change the finger count. For example, if a user
|
A single gesture cannot change the finger count. For example, if a user
|
||||||
puts down a fourth finger during a three-finger swipe gesture, libinput will
|
puts down a fourth finger during a three-finger swipe gesture, libinput will
|
||||||
end (cancel) the three-finger gesture and, if applicable, start a
|
end the three-finger gesture and, if applicable, start a four-finger swipe
|
||||||
four-finger swipe gesture. A caller may however decide that those gestures
|
gesture. A caller may however decide that those gestures are semantically
|
||||||
are semantically identical and continue the two gestures as one single
|
identical and continue the two gestures as one single gesture.
|
||||||
gesture.
|
|
||||||
|
|
||||||
.. _gestures_pinch:
|
.. _gestures_pinch:
|
||||||
|
|
||||||
|
|
@ -74,227 +73,6 @@ gesture into an action or limit a gesture to specific directions only.
|
||||||
The illustration above shows a vertical three-finger swipe. The coordinates
|
The illustration above shows a vertical three-finger swipe. The coordinates
|
||||||
provided during the gesture are the movements of the logical center.
|
provided during the gesture are the movements of the logical center.
|
||||||
|
|
||||||
.. _gestures_hold:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Hold gestures
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A hold gesture is one where the user places one or more fingers on the
|
|
||||||
device without significant movement. The exact conditions when a hold gesture
|
|
||||||
transitions to pointer motion, scrolling or other gestures
|
|
||||||
are implementation-defined.
|
|
||||||
|
|
||||||
The hold gesture is intended to allow for the implementation of two specific
|
|
||||||
features:
|
|
||||||
|
|
||||||
- where a two-finger scrolling starts kinetic scrolling in the caller, a
|
|
||||||
subsequent hold gesture can be used to stop that kinetic scroll motion,
|
|
||||||
and
|
|
||||||
- hold-to-trigger interactions where the interaction could be a click, a
|
|
||||||
context menu, or some other context-specific interaction.
|
|
||||||
|
|
||||||
Hold gestures have three potential logical states:
|
|
||||||
|
|
||||||
- **begin**: one or more fingers are placed on the device at the same time
|
|
||||||
- **end**: all fingers are removed and the device enters a neutral logical state
|
|
||||||
- **end(cancelled)**: all fingers are part of a known interaction and the
|
|
||||||
currenthold gesture is no longer active. This may also occurs when
|
|
||||||
switching between hold gestures with different finger counts.
|
|
||||||
|
|
||||||
.. note:: By definition, a hold gesture does not move and thus no coordinate
|
|
||||||
updates are available.
|
|
||||||
|
|
||||||
For example, a user that puts one finger, then a second finger down and
|
|
||||||
releases them later may trigger the following event sequence:
|
|
||||||
|
|
||||||
============= ============ ============
|
|
||||||
Action Event Finger count
|
|
||||||
============= ============ ============
|
|
||||||
Finger 1 down <no event>
|
|
||||||
Finger 2 down **begin** 2
|
|
||||||
Finger 2 up **end** 2
|
|
||||||
Finger 1 up <no event>
|
|
||||||
============= ============ ============
|
|
||||||
|
|
||||||
A hold gesture may by be **cancelled**. This occurs
|
|
||||||
when the hold gesture changes into some other interaction and should no
|
|
||||||
longer be considered the current hold gesture. A **end(cancelled)** event
|
|
||||||
applies to the whole gesture (all fingers). For example, a pointer motion on
|
|
||||||
a touchpad may trigger this sequence:
|
|
||||||
|
|
||||||
+-------------------+-----------------------+
|
|
||||||
| Action | Event |
|
|
||||||
+===================+=======================+
|
|
||||||
| | Finger 1 down | | **hold begin** |
|
|
||||||
+-------------------+-----------------------+
|
|
||||||
| | Finger 1 motion | | **hold cancel** |
|
|
||||||
| | | | **pointer motion** |
|
|
||||||
+-------------------+-----------------------+
|
|
||||||
| | Finger 1 motion | | **pointer motion** |
|
|
||||||
+-------------------+-----------------------+
|
|
||||||
| | Finger 1 up | | *no event* |
|
|
||||||
+-------------------+-----------------------+
|
|
||||||
|
|
||||||
.. note:: Many interactions with a touchpad will start with a hold
|
|
||||||
gesture that is then cancelled as that gesture turns into e.g.
|
|
||||||
pointer motion. A caller **must** handle hold gesture
|
|
||||||
cancellations correctly.
|
|
||||||
|
|
||||||
A two-finger scroll motion on a touchpad may trigger this sequence:
|
|
||||||
|
|
||||||
+------------------------+---------------------+--------------+
|
|
||||||
| Action | Event | Finger count |
|
|
||||||
+========================+=====================+==============+
|
|
||||||
| | Finger 1 down | | **hold begin** | | 1 |
|
|
||||||
+------------------------+---------------------+--------------+
|
|
||||||
| | Finger 2 down | | **hold cancel** | | 1 |
|
|
||||||
| | | | **hold begin** | | 2 |
|
|
||||||
+------------------------+---------------------+--------------+
|
|
||||||
| | Finger 1+2 motion | | **hold cancel** | | 2 |
|
|
||||||
| | | | **pointer axis** | | |
|
|
||||||
+------------------------+---------------------+--------------+
|
|
||||||
| | Finger 1+2 motion | | **pointer axis** | |
|
|
||||||
+------------------------+---------------------+--------------+
|
|
||||||
| | Finger 1 up | | **pointer axis** | |
|
|
||||||
| | Finger 2 up | | (scroll stop) | |
|
|
||||||
+------------------------+---------------------+--------------+
|
|
||||||
|
|
||||||
A three-finger-swipe on a touchpad may trigger this sequence:
|
|
||||||
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
| Action | Event | Finger count |
|
|
||||||
+=====================+=====================+==============+
|
|
||||||
| | Finger 1 down | | **hold begin** | | 1 |
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
| | Finger 2 down | | **hold cancel** | | 1 |
|
|
||||||
| | | | **hold begin** | | 2 |
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
| | Finger 3 down | | **hold cancel** | | 2 |
|
|
||||||
| | | | **hold begin** | | 3 |
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
| | Finger motion | | **hold cancel** | | 3 |
|
|
||||||
| | | | **swipe begin** | | 3 |
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
| | Finger motion | | **swipe update** | | 3 |
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
| | Finger 1 up | | **swipe end** | | 3 |
|
|
||||||
| | Finger 2 up | | | | |
|
|
||||||
| | Finger 3 up | | | | |
|
|
||||||
+---------------------+---------------------+--------------+
|
|
||||||
|
|
||||||
Single-finger hold gestures
|
|
||||||
...........................
|
|
||||||
|
|
||||||
libinput uses implementation-defined timeouts based on other interactions
|
|
||||||
to determine whether a single-finger hold gestures should start. In other
|
|
||||||
words, a caller **must not** rely on a hold gesture always being triggered
|
|
||||||
as soon as a single finger is placed on the touchpad. This is true for any
|
|
||||||
hold gesture but especially so for single-finger hold gestures.
|
|
||||||
|
|
||||||
Hold gestures with a single finger are prone to being extremely short-lived.
|
|
||||||
On many devices it is impossible to hold a finger still enough for there to
|
|
||||||
be no pointer motion events, even if those deltas are miniscule. Changing
|
|
||||||
movement thresholds to rely on hold gestures would reduce device
|
|
||||||
responsiveness.
|
|
||||||
|
|
||||||
It is thus the responsibility of the caller to determine where hold gestures
|
|
||||||
transition in and out of other interactions. For example, a two-finger hold
|
|
||||||
may produce a cancelled single-finger hold gesture first:
|
|
||||||
|
|
||||||
+--------------------+----------------------+--------------+--------------+
|
|
||||||
| Action | Event | Finger count | Notes |
|
|
||||||
+====================+======================+==============+==============+
|
|
||||||
| | Finger 1 down | | **hold begin** | | 1 | |
|
|
||||||
+--------------------+----------------------+--------------+--------------+
|
|
||||||
| | Finger 1 motion | | **hold cancel** | | 1 | | tiny deltas|
|
|
||||||
| | | | **pointer motion** | | | | |
|
|
||||||
+--------------------+----------------------+--------------+--------------+
|
|
||||||
| | Finger 2 down | | **hold begin** | | 2 | |
|
|
||||||
+--------------------+----------------------+--------------+--------------+
|
|
||||||
| | Finger 1 up | | **hold end** | | | |
|
|
||||||
| | Finger 2 up | | | | | |
|
|
||||||
+--------------------+----------------------+--------------+--------------+
|
|
||||||
|
|
||||||
Note how the second hold gesture started with a finger count of 2 - without
|
|
||||||
the user ever lifting the first finger. Cancellation of hold gesture does
|
|
||||||
not imply the user has lifted a finger.
|
|
||||||
|
|
||||||
A hold gesture may start after a previous gesture completed. For example, a
|
|
||||||
single finger move-and-hold may trigger different sequences for the same
|
|
||||||
user interaction:
|
|
||||||
|
|
||||||
+--------------------+---------------------+-------------------+--------------+
|
|
||||||
| Action | Device 1 | Device 2 | Notes |
|
|
||||||
+====================+=====================+===================+==============+
|
|
||||||
| | Finger 1 down | | **hold begin** | | **hold begin** | |
|
|
||||||
+--------------------+---------------------+-------------------+--------------+
|
|
||||||
| | Finger 1 motion | | **hold cancel** | | | tiny deltas|
|
|
||||||
| | | **pointer motion**| | | |
|
|
||||||
+--------------------+---------------------+-------------------+--------------+
|
|
||||||
| | | **hold begin** | | |
|
|
||||||
+--------------------+---------------------+-------------------+--------------+
|
|
||||||
| | Finger 1 up | | **hold end** | | **hold end** | |
|
|
||||||
+--------------------+---------------------+-------------------+--------------+
|
|
||||||
|
|
||||||
A caller that wants to use hold gestures must thus be able to infer the same
|
|
||||||
interaction based on a stream of pointer motion events with small deltas.
|
|
||||||
|
|
||||||
libinput may start a new hold begin gesture once the pointer stops moving.
|
|
||||||
The time between the last pointer motion event and the hold begin event is
|
|
||||||
implementation-defined.
|
|
||||||
|
|
||||||
|
|
||||||
Hold gestures and thumb/palm detection
|
|
||||||
......................................
|
|
||||||
|
|
||||||
Thumb and palm detection effectively remove touches from being counted
|
|
||||||
towards an interaction, see :ref:`thumb_detection` and
|
|
||||||
:ref:`palm_detection` for details.
|
|
||||||
|
|
||||||
In the context of hold gestures, thumbs and palms are treated by libinput as
|
|
||||||
if the finger was removed from the device. Where other non-thumb/non-palm
|
|
||||||
fingers remain on the device, an **hold update** event is sent. Otherwise,
|
|
||||||
the hold gesture terminates with a **hold cancel** event.
|
|
||||||
|
|
||||||
Notably, libinput's thumb and palm detection is not a simple boolean per
|
|
||||||
touch but specific to the state of that touch in the overall context. For
|
|
||||||
example, a touch may be a thumb for tapping but not for clickfinger
|
|
||||||
interactions. A caller must not infer the number of physical fingers from
|
|
||||||
the hold gesture.
|
|
||||||
|
|
||||||
Likewise, libinput may classify a finger as thumb in the same hardware event
|
|
||||||
as a new finger is placed on the touchpad. In that case, the hold gesture
|
|
||||||
**may** continue as one-finger gesture despite there being two physical
|
|
||||||
touch points.
|
|
||||||
|
|
||||||
Information to determine whether a touch is a thumb or a palm may not be
|
|
||||||
available until some time into an interaction. Thus very short brushes
|
|
||||||
of the touchpad by a palm may trigger a **hold begin** followed by an
|
|
||||||
immediate **hold end** as libinput lacks sufficient information to identify
|
|
||||||
the touch as thumb/palm and send the corresponding **hold cancel**
|
|
||||||
event. A caller must not assume that a hold gesture always represents a
|
|
||||||
valid finger down.
|
|
||||||
|
|
||||||
Hold gestures and tap-to-click
|
|
||||||
..............................
|
|
||||||
|
|
||||||
:ref:`tapping` is the feature that enables short-lived touches to trigger
|
|
||||||
button presses.
|
|
||||||
|
|
||||||
.. warning:: Summary: do not use hold gestures to do your own tap-to-click
|
|
||||||
implementation
|
|
||||||
|
|
||||||
In the context of hold gestures, tap-to-click cancels current hold gestures
|
|
||||||
and a finger dragging (see :ref:`tapndrag`) does not begin a hold
|
|
||||||
gesture. Where tap-to-click is disabled a tap-like gesture may create
|
|
||||||
**hold begin** followed by a **hold end** event. Callers **must not** use
|
|
||||||
hold gestures for their own tap-to-click implementation as the data is not
|
|
||||||
reliable enough. libinput may change internal timeouts and thresholds
|
|
||||||
depending on whether tap-to-click is enabled and the hold gesture event may
|
|
||||||
not match touch sequences that a user would expect to be a tap-to-click
|
|
||||||
interaction.
|
|
||||||
|
|
||||||
.. _gestures_touchscreens:
|
.. _gestures_touchscreens:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
.. _ignoring_devices:
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Ignoring specific devices
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
If a device has the **LIBINPUT_IGNORE_DEVICE** udev property set to any
|
|
||||||
value but "0", that device is not initialized by libinput.
|
|
||||||
For a context created with **libinput_udev_create_context()**, the device is
|
|
||||||
silently ignored and never shows up. If the device is added with
|
|
||||||
**libinput_path_add_device()** to a context created with
|
|
||||||
**libinput_path_create_context()**, adding the device will fail and return NULL
|
|
||||||
(see that function's documentation for more
|
|
||||||
information).
|
|
||||||
|
|
||||||
If the property value is exactly "0", then the property is considered unset
|
|
||||||
and libinput initializes the device normally.
|
|
||||||
|
|
||||||
This property should be used for devices that are correctly detected as
|
|
||||||
input devices (see :ref:`udev_device_type`) but that should not be used by
|
|
||||||
libinput. It is recommended that devices that should not be handled as input
|
|
||||||
devices at all unset the **ID_INPUT** and related properties instead. The
|
|
||||||
**LIBINPUT_IGNORE_DEVICE** property signals that only libinput should
|
|
||||||
ignore this property but other parts of the stack (if any) should continue
|
|
||||||
treating this device normally.
|
|
||||||
|
|
||||||
Below is an example udev rule to assign **LIBINPUT_IGNORE_DEVICE** to the
|
|
||||||
device with the vendor/model ID of ``012a``/``034b``. ::
|
|
||||||
|
|
||||||
$ cat /etc/udev/rules.d/99-ignore-my-device.rules
|
|
||||||
ACTION!="remove", KERNEL=="event[0-9]*", \
|
|
||||||
ENV{ID_VENDOR_ID}=="012a", \
|
|
||||||
ENV{ID_MODEL_ID}=="034b", \
|
|
||||||
ENV{LIBINPUT_IGNORE_DEVICE}="1"
|
|
||||||
|
|
||||||
See :ref:`udev_config` for more details on libinput's udev properties.
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
.. _incorrectly_enabled_hires:
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Incorrectly enabled high-resolution scroll
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Some devices might announce support for high-resolution scroll wheel by enabling
|
|
||||||
``REL_WHEEL_HI_RES`` and/or ``REL_HWHEEL_HI_RES`` but never send a
|
|
||||||
high-resolution scroll event.
|
|
||||||
|
|
||||||
When the first low-resolution scroll event is received without any previous
|
|
||||||
high-resolution event, libinput prints a bug warning with the text **"device
|
|
||||||
supports high-resolution scroll but only low-resolution events have been
|
|
||||||
received"** and a link to this page.
|
|
||||||
|
|
||||||
.. note:: This warning will be printed only once
|
|
||||||
|
|
||||||
In most cases this is a bug on the device firmware, the kernel driver or in a
|
|
||||||
software used to create user-space devices through uinput.
|
|
||||||
|
|
||||||
Once the bug is detected, libinput will start emulating high-resolution scroll
|
|
||||||
events.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Detecting and fixing the issue
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Events sent by a buggy device can be shown in the
|
|
||||||
:ref:`libinput record <libinput-record>` output for the device. Notice that
|
|
||||||
``REL_WHEEL_HI_RES`` and ``REL_HWHEEL_HI_RES`` are set but only ``REL_WHEEL``
|
|
||||||
events are sent: ::
|
|
||||||
|
|
||||||
# Supported Events:
|
|
||||||
# Event type 0 (EV_SYN)
|
|
||||||
# Event type 1 (EV_KEY)
|
|
||||||
# Event code 272 (BTN_LEFT)
|
|
||||||
# Event type 2 (EV_REL)
|
|
||||||
# Event code 0 (REL_X)
|
|
||||||
# Event code 1 (REL_Y)
|
|
||||||
# Event code 6 (REL_HWHEEL)
|
|
||||||
# Event code 8 (REL_WHEEL)
|
|
||||||
# Event code 11 (REL_WHEEL_HI_RES)
|
|
||||||
# Event code 12 (REL_HWHEEL_HI_RES)
|
|
||||||
[...]
|
|
||||||
quirks:
|
|
||||||
events:
|
|
||||||
- evdev:
|
|
||||||
- [ 0, 0, 2, 8, 1] # EV_REL / REL_WHEEL 1
|
|
||||||
- [ 0, 0, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +0ms
|
|
||||||
- evdev:
|
|
||||||
- [ 0, 15126, 2, 8, 1] # EV_REL / REL_WHEEL 1
|
|
||||||
- [ 0, 15126, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +15ms
|
|
||||||
- evdev:
|
|
||||||
- [ 0, 30250, 2, 8, 1] # EV_REL / REL_WHEEL 1
|
|
||||||
- [ 0, 30250, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +15ms
|
|
||||||
|
|
||||||
The issue can be fixed by adding a quirk to unset the ``REL_WHEEL_HI_RES`` and
|
|
||||||
``REL_HWHEEL_HI_RES`` event codes: ::
|
|
||||||
|
|
||||||
AttrEventCode=-REL_WHEEL_HI_RES;-REL_HWHEEL_HI_RES;
|
|
||||||
|
|
||||||
Please see :ref:`device-quirks` for details.
|
|
||||||
|
|
@ -10,10 +10,7 @@
|
||||||
faqs
|
faqs
|
||||||
reporting-bugs
|
reporting-bugs
|
||||||
troubleshooting
|
troubleshooting
|
||||||
contributing
|
|
||||||
development
|
development
|
||||||
lua-plugins
|
|
||||||
API documentation <@HTTP_DOC_LINK@/api/>
|
|
||||||
|
|
||||||
|
|
||||||
++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++
|
||||||
|
|
@ -24,7 +21,7 @@ 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
|
and other applications that need to handle input devices provided by the
|
||||||
kernel.
|
kernel.
|
||||||
|
|
||||||
libinput provides device detection, event handling and abstraction to
|
libinput provides device detection, event handling and abstraction so
|
||||||
minimize the amount of custom input code the user of libinput need to
|
minimize the amount of custom input code the user of libinput need to
|
||||||
provide the common set of functionality that users expect. Input event
|
provide the common set of functionality that users expect. Input event
|
||||||
processing includes scaling touch coordinates, generating
|
processing includes scaling touch coordinates, generating
|
||||||
|
|
@ -37,14 +34,14 @@ driver than an application library. See :ref:`what_is_libinput` for more details
|
||||||
Users and Developers
|
Users and Developers
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Please use the side-bar to navigate through the various documentation items.
|
Please use the side-bar to nagivate through the various documentation items.
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
API documentation
|
API documentation
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The API documentation is available here:
|
The API documentation is available here:
|
||||||
https://wayland.freedesktop.org/libinput/doc/latest/api/
|
http://wayland.freedesktop.org/libinput/doc/latest/api/
|
||||||
|
|
||||||
.. note:: This documentation is generally only needed by authors of Wayland
|
.. note:: This documentation is generally only needed by authors of Wayland
|
||||||
compositors or other developers dealing with input events directly.
|
compositors or other developers dealing with input events directly.
|
||||||
|
|
|
||||||
|
|
@ -1,661 +0,0 @@
|
||||||
.. _lua_plugins:
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Lua Plugins
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
libinput provides a plugin system that allows users to modify the behavior
|
|
||||||
of devices. For example, a plugin may add or remove axes and/or buttons on a
|
|
||||||
device and/or modify the event stream seen by this device before it is passed
|
|
||||||
to libinput.
|
|
||||||
|
|
||||||
Plugins are implemented in `Lua <https://www.lua.org/>`_ (version 5.4)
|
|
||||||
and are typically loaded from the following paths:
|
|
||||||
|
|
||||||
- ``/etc/libinput/plugins/*.lua``, and
|
|
||||||
- ``/usr/lib{64}/libinput/plugins/*.lua``
|
|
||||||
|
|
||||||
Plugins are loaded in alphabetical order and where
|
|
||||||
multiple plugins share the same file name, the one in the highest precedence
|
|
||||||
directory is used. Plugins in ``/etc`` take precedence over
|
|
||||||
plugins in ``/usr``.
|
|
||||||
|
|
||||||
.. note:: Plugins lookup paths and their order are decided by the compositor.
|
|
||||||
Some compositors may support more/fewer/other lookup paths than the
|
|
||||||
above defaults.
|
|
||||||
|
|
||||||
Plugins are run sequentially in ascending sort-order (i.e. ``00-foo.lua`` runs
|
|
||||||
before ``10-bar.lua``) and each plugin sees the state left by any previous
|
|
||||||
plugins. For example if ``00-foo.lua`` changes all left button events to right
|
|
||||||
button events, ``10-bar.lua`` only ever sees right button events.
|
|
||||||
|
|
||||||
See the `Lua Reference manual <https://www.lua.org/manual/5.4/manual.html>`_ for
|
|
||||||
details on the Lua language.
|
|
||||||
|
|
||||||
.. note:: Plugins are **not** loaded by default, it is up to the compositor
|
|
||||||
whether to allow plugins. An explicit call to
|
|
||||||
``libinput_plugin_system_load_plugins()`` is required.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Limitations
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Each script runs in its own sandbox and cannot communicate or share state with
|
|
||||||
other scripts.
|
|
||||||
|
|
||||||
Tables that hold API methods are not writable, i.e. it is not possible
|
|
||||||
to overwrite the default functionality of those APIs.
|
|
||||||
|
|
||||||
The Lua API available to plugins is limited to the following calls::
|
|
||||||
|
|
||||||
assert error ipairs next pairs tonumber
|
|
||||||
pcall select print tostring type xpcall
|
|
||||||
table string math _VERSION
|
|
||||||
|
|
||||||
It is not possible to e.g. use the ``io`` module from a script.
|
|
||||||
|
|
||||||
To use methods on instantiated objects, the ``object:method`` method call
|
|
||||||
syntax must be used. For example:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
libinput:register()
|
|
||||||
libinput.register() -- this will fail
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
When to use plugins
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput plugins are a relatively niche use-case that typically need to
|
|
||||||
address either once-off issues (e.g. those caused by worn-out hardware) or
|
|
||||||
user preferences that libinput does not and will not cater for.
|
|
||||||
|
|
||||||
Plugins should not be used for issues that can be fixed generically, for
|
|
||||||
example via :ref:`device-quirks`.
|
|
||||||
|
|
||||||
As a rule of thumb: a plugin should be a once-off that only works for one
|
|
||||||
user's hardware. If a plugin can be shared with many users then the plugin
|
|
||||||
implements functionality that should be integrated into libinput proper.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Testing plugins
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Our :ref:`tools` support plugins if passed the ``--enable-plugins`` commandline
|
|
||||||
option. For implementing and testing plugins the easiest commands to test are
|
|
||||||
|
|
||||||
- ``libinput debug-events --enable-plugins`` (see :ref:`libinput-debug-events` docs)
|
|
||||||
- ``libinput debug-gui --enable-plugins`` (see :ref:`libinput-debug-gui` docs)
|
|
||||||
|
|
||||||
Where libinput is built and run from git, the tools will also look for plugins
|
|
||||||
in the meson build directory. See the ``plugins/meson.build`` file for details.
|
|
||||||
|
|
||||||
.. _plugins_api_lua:
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
Lua Plugin API
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Lua plugins sit effectively below libinput and the API is not a
|
|
||||||
representation of the libinput API. Plugins modify the evdev event stream
|
|
||||||
received from the kernel.
|
|
||||||
|
|
||||||
.. graphviz:: plugin-stack.gv
|
|
||||||
|
|
||||||
The API revolves around two types: ``libinput`` and ``EvdevDevice``. The
|
|
||||||
``libinput`` type is used to register a plugin from a script, the
|
|
||||||
``EvdevDevice`` represents one device that is present in the system (but may
|
|
||||||
not have yet been added by libinput).
|
|
||||||
|
|
||||||
Typically a script does the following steps:
|
|
||||||
|
|
||||||
- register with libinput via ``libinput:register({versions})``
|
|
||||||
- connect to the ``"new-evdev-device"`` event
|
|
||||||
- receive an ``EvdevDevice`` object in the ``"new-evdev-device"`` callback
|
|
||||||
|
|
||||||
- check and/or modify the evdev event codes on the device
|
|
||||||
- connect to the device's ``"evdev-frame"`` event
|
|
||||||
|
|
||||||
- receive an :ref:`evdev frame <plugins_api_evdev_frame>` in the device's
|
|
||||||
``"evdev-frame"`` callback
|
|
||||||
|
|
||||||
- check and/or modify the events in that frame
|
|
||||||
|
|
||||||
Where multiple plugins are active, the evdev frame passed to the callback is
|
|
||||||
the combined frame as processed by all previous plugins in ascending sort order.
|
|
||||||
For example, if one plugin discards all button events subsequent plugins will
|
|
||||||
never see those button events in the frame.
|
|
||||||
|
|
||||||
.. _plugins_api_version_stability:
|
|
||||||
|
|
||||||
..............................................................................
|
|
||||||
Plugin version stability
|
|
||||||
..............................................................................
|
|
||||||
|
|
||||||
Plugin API version stability is provided on a best effort basis. We aim to provide
|
|
||||||
stable plugin versions for as long as feasible but may need to retire some older
|
|
||||||
versions over time. For this reason a plugin can select multiple versions it
|
|
||||||
implements, libinput will pick one supported version and adjust the plugin
|
|
||||||
behavior to match that version. See the ``libinput:register()`` call for details.
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
Lua Plugin API Reference
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
libinput provides the following globals and types:
|
|
||||||
|
|
||||||
.. _plugins_api_evdev_usage:
|
|
||||||
|
|
||||||
................................................................................
|
|
||||||
Evdev Usages
|
|
||||||
................................................................................
|
|
||||||
|
|
||||||
Evdev usages are a libinput-specific wrapper around the ``linux/input-event-codes.h``
|
|
||||||
evdev types and codes. They are used by libinput internally and are a 32-bit
|
|
||||||
combination of ``type << 16 | code``. Each usage carries the type and code and
|
|
||||||
is thus simpler to pass around and less prone to type confusion.
|
|
||||||
|
|
||||||
The :ref:`evdev global <plugins_api_evdev_global>` attempts to provide all
|
|
||||||
available usages but for the niche cases where it does not provide a named constant
|
|
||||||
the value can be crafted manually:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
evdev_type = 0x3 -- EV_REL
|
|
||||||
evdev_code = 0x1 -- REL_Y
|
|
||||||
evdev_usage = (evdev_type << 16) | evdev_code
|
|
||||||
|
|
||||||
assert(usage == evdev.REL_Y)
|
|
||||||
|
|
||||||
.. _plugins_api_evdev_global:
|
|
||||||
|
|
||||||
................................................................................
|
|
||||||
The ``evdev`` global
|
|
||||||
................................................................................
|
|
||||||
|
|
||||||
The ``evdev`` global represents all known :ref:`plugins_api_evdev_usage`,
|
|
||||||
effectively in the form:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
evdev = {
|
|
||||||
ABS_X = (3 << 16) | 0,
|
|
||||||
ABS_Y = (3 << 16) | 1,
|
|
||||||
...
|
|
||||||
REL_X = (2 << 16) | 0,
|
|
||||||
REL_Y = (2 << 16) | 1,
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
This global is provided for convenience to improve readability in the code.
|
|
||||||
Note that the name uses the event code name only (e.g. ``evdev.ABS_Y``) but the
|
|
||||||
value is an :ref:`Evdev Usage <plugins_api_evdev_usage>` (type and code).
|
|
||||||
|
|
||||||
See the ``linux/input-event-codes.h`` header file provided by your kernel
|
|
||||||
for a list of all evdev types and codes.
|
|
||||||
|
|
||||||
The evdev global also provides the bus type constants, e.g. ``evdev.BUS_USB``.
|
|
||||||
See the ``linux/input.h`` header file provided by your kernel
|
|
||||||
for a list of bus types.
|
|
||||||
|
|
||||||
|
|
||||||
.. _plugins_api_evdev_frame:
|
|
||||||
|
|
||||||
................................................................................
|
|
||||||
Evdev frames
|
|
||||||
................................................................................
|
|
||||||
|
|
||||||
Evdev frames represent a single frame of evdev events for a device. A frame
|
|
||||||
is a group of events that occurred at the same time. The frame usually only
|
|
||||||
contains state that has changed compared to the previous frame.
|
|
||||||
|
|
||||||
In our API a frame is exposed as a nested table with the following structure:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
frame1 = {
|
|
||||||
{ usage = evdev.ABS_X, value = 123 },
|
|
||||||
{ usage = evdev.ABS_Y, value = 456 },
|
|
||||||
{ usage = evdev.BTN_LEFT, value = 1 },
|
|
||||||
}
|
|
||||||
frame2 = {
|
|
||||||
{ usage = evdev.ABS_Y, value = 457 },
|
|
||||||
}
|
|
||||||
frame3 = {
|
|
||||||
{ usage = evdev.ABS_X, value = 124 },
|
|
||||||
{ usage = evdev.BTN_LEFT, value = 0 },
|
|
||||||
}
|
|
||||||
|
|
||||||
.. note:: This API does not use ``SYN_REPORT`` events, it is implied at the
|
|
||||||
end of the table. Where a plugin writes a ``SYN_REPORT`` into the
|
|
||||||
list of events, that ``SYN_REPORT`` terminates the event frame
|
|
||||||
(similar to writing a ``\0`` into the middle of a C string).
|
|
||||||
A frame containing only a ``SYN_REPORT`` is functionally equivalent
|
|
||||||
to an empty frame.
|
|
||||||
|
|
||||||
Events or frames do not have a timestamp. Where a timestamp is required, that
|
|
||||||
timestamp is passed as additional argument to the function or return value.
|
|
||||||
|
|
||||||
See :ref:`plugins_api_evdev_global` for a list of known usages.
|
|
||||||
|
|
||||||
.. warning:: Evdev frames have an implementation-defined size limit of how many
|
|
||||||
events can be added to a single frame. This limit should never be
|
|
||||||
hit by valid plugins.
|
|
||||||
|
|
||||||
.. _plugins_api_libinputglobal:
|
|
||||||
|
|
||||||
................................................................................
|
|
||||||
The ``libinput`` global object
|
|
||||||
................................................................................
|
|
||||||
|
|
||||||
The core of our plugin API is the ``libinput`` global object. A script must
|
|
||||||
immediately ``register()`` to be active, otherwise it is unloaded immediately.
|
|
||||||
|
|
||||||
All libinput-specific APIs can be accessed through the ``libinput`` object.
|
|
||||||
|
|
||||||
.. function:: libinput:register({1, 2, ...})
|
|
||||||
|
|
||||||
Register this plugin with the given table of supported version numbers and
|
|
||||||
returns the version number selected by libinput for this plugin. See
|
|
||||||
:ref:`plugins_api_version_stability` for details.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
-- this plugin can support versions 1, 4 and 5
|
|
||||||
version = libinput:register({1, 4, 5})
|
|
||||||
if version == 1 then
|
|
||||||
...
|
|
||||||
|
|
||||||
This function must be the first function called.
|
|
||||||
If the plugin calls any other functions before ``register()``, those functions
|
|
||||||
return the default zero value for the return type (``nil``, ``0``, an empty
|
|
||||||
table, etc.).
|
|
||||||
|
|
||||||
If the plugin does not call ``register()`` it will be removed immediately.
|
|
||||||
Once registered, any connected callbacks will be invoked whenever libinput
|
|
||||||
detects new devices, removes devices, etc.
|
|
||||||
|
|
||||||
This function must only be called once.
|
|
||||||
|
|
||||||
.. function:: libinput:unregister()
|
|
||||||
|
|
||||||
Unregister this plugin. This removes the plugin from libinput and releases
|
|
||||||
any resources associated with this plugin. This call must be the last call
|
|
||||||
in your plugin, it is effectively equivalent to Lua's
|
|
||||||
`os.exit() <https://www.lua.org/manual/5.4/manual.html#pdf-os.exit>`_.
|
|
||||||
|
|
||||||
.. function:: libinput:log_debug(message)
|
|
||||||
|
|
||||||
Log a message at the libinput debug log priority. See
|
|
||||||
``libinput:log_error()`` for details.
|
|
||||||
|
|
||||||
.. function:: libinput:log_info(message)
|
|
||||||
|
|
||||||
Log a message at the libinput info log priority. See
|
|
||||||
``libinput:log_error()`` for details.
|
|
||||||
|
|
||||||
.. function:: libinput:log_error(message)
|
|
||||||
|
|
||||||
Log a message at the libinput error log priority. Whether a message is
|
|
||||||
displayed in the log depends on libinput's log priority, set by the caller.
|
|
||||||
|
|
||||||
A compositor may disable stdout and stderr. Log messages should be preferred
|
|
||||||
over Lua's ``print()`` function to ensure the messages end up in the same
|
|
||||||
location as other libinput log messages and are not discarded.
|
|
||||||
|
|
||||||
.. function:: libinput:now()
|
|
||||||
|
|
||||||
Returns the current time in microseconds in ``CLOCK_MONOTONIC``. This is
|
|
||||||
the timestamp libinput uses internally. This timestamp cannot be mapped
|
|
||||||
to any particular time of day, see the
|
|
||||||
`clock_gettime() man page <https://man7.org/linux/man-pages/man3/clock_gettime.3.html>`_
|
|
||||||
for details.
|
|
||||||
|
|
||||||
.. function:: libinput:version()
|
|
||||||
|
|
||||||
Returns the agreed-on version of the plugin, see ``libinput:register()``.
|
|
||||||
If called before ``libinput:register()`` this function returns ``0``.
|
|
||||||
|
|
||||||
.. function:: libinput:connect(name, function)
|
|
||||||
|
|
||||||
Set the callback to the given event name. Only one callback
|
|
||||||
may be set for an event name at any time, subsequent callbacks
|
|
||||||
will replace any earlier callbacks for the same name.
|
|
||||||
|
|
||||||
Version 1 of the plugin API supports the following events and callback arguments:
|
|
||||||
|
|
||||||
- ``"new-evdev-device"``: A new :ref:`EvdevDevice <plugins_api_evdevdevice>`
|
|
||||||
has been seen by libinput but not yet added.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
libinput:connect("new-evdev-device", function (device) ... end)
|
|
||||||
|
|
||||||
- ``"timer-expired"``: The timer for this plugin has expired. This event is
|
|
||||||
only sent if the plugin has set a timer with ``timer_set()``.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
libinput:connect("timer-expired", function (now) ... end)
|
|
||||||
|
|
||||||
The ``now`` argument is the current time in microseconds in
|
|
||||||
``CLOCK_MONOTONIC`` (see ``libinput:now()``).
|
|
||||||
|
|
||||||
.. function:: libinput:timer_cancel()
|
|
||||||
|
|
||||||
Cancel the timer for this plugin. This is a no-op if the timer
|
|
||||||
has not been set or has already expired.
|
|
||||||
|
|
||||||
.. function:: libinput:timer_set_absolute(time)
|
|
||||||
|
|
||||||
Set a timer for this plugin, with the given time in microseconds.
|
|
||||||
The timeout specifies an absolute time in microseconds (see
|
|
||||||
``libinput:now()``) The timer will expire once and then call the
|
|
||||||
``"timer-expired"`` event handler (if any).
|
|
||||||
|
|
||||||
See ``libinput:timer_set_relative()`` for a relative timer.
|
|
||||||
|
|
||||||
The following two lines of code are equivalent:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
libinput:timer_set_relative(1000000) -- 1 second from now
|
|
||||||
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
|
|
||||||
|
|
||||||
Calling this function will cancel any existing (relative or absolute) timer.
|
|
||||||
|
|
||||||
.. function:: libinput:timer_set_relative(timeout)
|
|
||||||
|
|
||||||
Set a timer for this plugin, with the given timeout in microseconds from
|
|
||||||
the current time. The timer will expire once and then call the
|
|
||||||
``"timer-expired"`` event handler (if any).
|
|
||||||
|
|
||||||
See ``libinput:timer_set_absolute()`` for an absolute timer.
|
|
||||||
|
|
||||||
The following two lines of code are equivalent:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
libinput:timer_set_relative(1000000) -- 1 second from now
|
|
||||||
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
|
|
||||||
|
|
||||||
Calling this function will cancel any existing (relative or absolute) timer.
|
|
||||||
|
|
||||||
.. _plugins_api_evdevdevice:
|
|
||||||
|
|
||||||
................................................................................
|
|
||||||
The ``EvdevDevice`` type
|
|
||||||
................................................................................
|
|
||||||
|
|
||||||
The ``EvdevDevice`` type represents a device available in the system
|
|
||||||
but not (yet) added by libinput. This device may be used to modify
|
|
||||||
a device's capabilities before the device is processed by libinput.
|
|
||||||
|
|
||||||
A plugin should always ``connect()`` to the ``"device-removed"`` callback
|
|
||||||
to be notified when a device is removed. If the plugin keeps a reference
|
|
||||||
to this device but the device is discarded by libinput, the device's query
|
|
||||||
methods will return zero values (e.g. ``nil``, ``0``, an empty table) and
|
|
||||||
methods will be noops.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:info()
|
|
||||||
|
|
||||||
A table containing static information about the device, e.g.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
{
|
|
||||||
bustype = evdev.BUS_USB,
|
|
||||||
vid = 0x1234,
|
|
||||||
pid = 0x5678,
|
|
||||||
}
|
|
||||||
|
|
||||||
A plugin must ignore keys it does not know about.
|
|
||||||
|
|
||||||
Version 1 of the plugin API supports the following keys and values:
|
|
||||||
|
|
||||||
- ``bustype``: The numeric bustype of the device. See the
|
|
||||||
``BUS_*`` defines in ``linux/input.h`` for the list of possible values.
|
|
||||||
- ``vid``: The 16-bit vendor ID of the device
|
|
||||||
- ``pid``: The 16-bit product ID of the device
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function returns an
|
|
||||||
empty table.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:name()
|
|
||||||
|
|
||||||
The device name as set by the kernel
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:usages()
|
|
||||||
|
|
||||||
Returns a table of all usages that are currently enabled for this
|
|
||||||
device. Any type that exists on the device has a table assigned and in this
|
|
||||||
table any code that exists on the device is a boolean true.
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
{
|
|
||||||
evdev.REL_X = true,
|
|
||||||
evdev.REL_Y = true,
|
|
||||||
evdev.BTN_LEFT = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
All other usages are ``nil``, so that the following code is possible:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
local usages = device:usages()
|
|
||||||
if usages[evdev.REL_X] then
|
|
||||||
-- do something
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function returns an
|
|
||||||
empty table.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:absinfos()
|
|
||||||
|
|
||||||
Returns a table of all ``EV_ABS`` codes that are currently enabled for this device.
|
|
||||||
The event code is the key, each value is a table containing the following keys:
|
|
||||||
``minimum``, ``maximum``, ``fuzz``, ``flat``, ``resolution``.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
{
|
|
||||||
evdev.ABS_X = {
|
|
||||||
minimum = 0,
|
|
||||||
maximum = 1234,
|
|
||||||
fuzz = 0,
|
|
||||||
flat = 0,
|
|
||||||
resolution = 45,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function returns an
|
|
||||||
empty table.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:udev_properties()
|
|
||||||
|
|
||||||
Returns a table containing a filtered list of udev properties available on this device
|
|
||||||
in the form ``{ property_name = property_value, ... }``.
|
|
||||||
udev properties used as a boolean (e.g. ``ID_INPUT``) are only present if their
|
|
||||||
value is a logical true.
|
|
||||||
|
|
||||||
Version 1 of the plugin API supports the following udev properties:
|
|
||||||
|
|
||||||
- ``ID_INPUT`` and all of ``ID_INPUT_*`` that denote the device type as assigned
|
|
||||||
by udev. This information is usually used by libinput to determine a
|
|
||||||
device type. Note that for historical reasons these properties have
|
|
||||||
varying rules - some properties may be mutually exclusive, others are
|
|
||||||
independent, others may only be set if another property is set. Refer to
|
|
||||||
the udev documentation (if any) for details. ``ID_INPUT_WIDTH_MM`` and
|
|
||||||
``ID_INPUT_HEIGHT_MM`` are excluded from this set.
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function returns an
|
|
||||||
empty table.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:enable_evdev_usage(usage)
|
|
||||||
|
|
||||||
Enable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
|
|
||||||
Use :ref:`plugins_api_evdev_global` for better readability,
|
|
||||||
e.g. ``device:enable_evdev_usage(evdev.REL_X)``.
|
|
||||||
This function must not be used for ``ABS_*`` events, use ``set_absinfo()``
|
|
||||||
instead.
|
|
||||||
|
|
||||||
Once a usage is enabled, events for that usage may be added to a device's
|
|
||||||
frame.
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function does nothing.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:disable_evdev_usage(usage)
|
|
||||||
|
|
||||||
Disable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
|
|
||||||
Use :ref:`plugins_api_evdev_global` for better readability,
|
|
||||||
e.g. ``device:disable_evdev_usage(evdev.REL_X)``.
|
|
||||||
|
|
||||||
Once a usage is disabled, events for that usage are discarded from any
|
|
||||||
device frame.
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function does nothing.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:set_absinfo(usage, absinfo)
|
|
||||||
|
|
||||||
Set the absolute axis information for the given :ref:`evdev usage <plugins_api_evdev_usage>`
|
|
||||||
and enable it if it does not yet exist on the device. The ``absinfo`` argument is a table
|
|
||||||
containing zero or more of the following keys: ``minimum``, ``maximum``, ``fuzz``,
|
|
||||||
``flat``, ``resolution``. Any missing key defaults the corresponding
|
|
||||||
value from the device if the device already has this event usage or zero otherwise.
|
|
||||||
For example, the following code changes the resolution but leaves everything
|
|
||||||
else as-is:
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
local absinfo = {
|
|
||||||
resolution = 40,
|
|
||||||
}
|
|
||||||
device:set_absinfo(evdev.ABS_X, absinfo)
|
|
||||||
device:set_absinfo(evdev.ABS_Y, absinfo)
|
|
||||||
|
|
||||||
Use :ref:`plugins_api_evdev_global` for better readability as shown in the
|
|
||||||
example above.
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function does nothing.
|
|
||||||
|
|
||||||
.. note:: Overriding the absinfo values often indicates buggy firmware. This should
|
|
||||||
typically be fixed with an entry in the
|
|
||||||
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`_
|
|
||||||
or :ref:`device-quirks` instead of a plugin so all users of that
|
|
||||||
device can benefit from the fix.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:connect(name, function)
|
|
||||||
|
|
||||||
Set the callback to the given event name. Only one callback
|
|
||||||
may be set for an event name at any time, subsequent callbacks
|
|
||||||
will overwrite any earlier callbacks for the same name.
|
|
||||||
|
|
||||||
If the device has since been discarded by libinput, this function does nothing.
|
|
||||||
|
|
||||||
Version 1 of the plugin API supports the following events and callback arguments:
|
|
||||||
|
|
||||||
- ``"evdev-frame"``: A new :ref:`evdev frame <plugins_api_evdev_frame>` has
|
|
||||||
started for this device. If the callback returns a value other than
|
|
||||||
``nil``, that value is the frame with any modified events.
|
|
||||||
An empty frame (``{}``) causes libinput to drop the current event frame.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
|
||||||
-- change any event into a movement left by 1 pixel
|
|
||||||
move_left = {
|
|
||||||
{ usage = evdev.REL_X, value = -1, },
|
|
||||||
}
|
|
||||||
return move_left
|
|
||||||
end
|
|
||||||
|
|
||||||
The timestamp of an event frame is in microseconds in ``CLOCK_MONOTONIC``, see
|
|
||||||
``libinput:now()`` for details.
|
|
||||||
|
|
||||||
For performance reasons plugins that do not modify the event frame should
|
|
||||||
return ``nil`` (or nothing) instead of the event frame that was passed
|
|
||||||
as argument.
|
|
||||||
|
|
||||||
- ``"device-removed"``: This device was removed by libinput. This may happen
|
|
||||||
without the device ever becoming a libinput device as seen by libinput's
|
|
||||||
public API (e.g. if the device does not meet the requirements to be
|
|
||||||
added). Once this callback is invoked, the plugin should remove any
|
|
||||||
references to this device and stop using it.
|
|
||||||
|
|
||||||
.. code-block:: lua
|
|
||||||
|
|
||||||
device:connect("device-removed", function (device) ... end)
|
|
||||||
|
|
||||||
Functions to query the device's capabilities (e.g. ``usages()``) will
|
|
||||||
return an empty table.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:disconnect(name)
|
|
||||||
|
|
||||||
Disconnect the existing callback (if any) for the given event name. See
|
|
||||||
``EvdevDevice:connect()`` for a list of supported names.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:prepend_frame(frame)
|
|
||||||
|
|
||||||
Prepend an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
|
|
||||||
**before** the current frame (if any). The **next** plugin will see the
|
|
||||||
prepended frame first followed by the current frame.
|
|
||||||
|
|
||||||
This function can only be called from within a device's ``"evdev-frame"``
|
|
||||||
handler or from within the plugin's timer callback function.
|
|
||||||
|
|
||||||
For example, to change a single event into a drag, prepend a button
|
|
||||||
down and append a button up before each event:
|
|
||||||
|
|
||||||
.. code:: lua
|
|
||||||
|
|
||||||
function frame_handler(device, frame, timestamp)
|
|
||||||
device:prepend_frame({
|
|
||||||
{ usage = evdev.BTN_LEFT, value = 1}
|
|
||||||
})
|
|
||||||
device:append_frame({
|
|
||||||
{ usage = evdev.BTN_LEFT, value = 0}
|
|
||||||
})
|
|
||||||
return nil -- return the current frame unmodified
|
|
||||||
|
|
||||||
-- The next plugin sees the event sequence:
|
|
||||||
-- button down, frame, button up
|
|
||||||
end
|
|
||||||
|
|
||||||
If called from within the plugin's timer there is no current frame and this
|
|
||||||
function is identical to ``append_frame()``.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:append_frame(frame)
|
|
||||||
|
|
||||||
Appends an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
|
|
||||||
**after** the current frame (if any). This function can only be called from
|
|
||||||
within a device's ``"evdev-frame"`` handler or from within the plugin's timer
|
|
||||||
callback function.
|
|
||||||
|
|
||||||
If called from within the plugin's timer there is no current frame and this
|
|
||||||
function is identical to ``prepend_frame()``.
|
|
||||||
|
|
||||||
See ``prepend_frame()`` for more details.
|
|
||||||
|
|
||||||
.. function:: EvdevDevice:disable_feature(feature_name)
|
|
||||||
|
|
||||||
Disable the given libinput-internal feature for this device. This should be used
|
|
||||||
by plugins that replace that feature with a custom implementation for this device.
|
|
||||||
|
|
||||||
libinput may have multiple internal implementations for any given feature, disabling
|
|
||||||
it via this API disables any and all of those implementations, causing the feature to
|
|
||||||
no longer work at all. It is up to the plugin implementation to re-implement that
|
|
||||||
feature to match the user's expectation.
|
|
||||||
|
|
||||||
Version 1 of the plugin API supports the following features:
|
|
||||||
|
|
||||||
- ``"button-debouncing"``: see :ref:`button_debouncing`
|
|
||||||
- ``"touchpad-hysteresis"``: see :ref:`touchpad_jitter`
|
|
||||||
- ``"touchpad-jump-detection"``: see :ref:`touchpad_jumping_cursor`
|
|
||||||
- ``"touchpad-palm-detection"``: see :ref:`palm_detection`
|
|
||||||
- ``"wheel-debouncing"``: some high-resolution mouse wheel movements inside libinput
|
|
||||||
are delayed and/or modified
|
|
||||||
|
|
@ -4,16 +4,10 @@ if not sphinx.found()
|
||||||
error('Program "sphinx-build" not found or not executable. Try building with -Ddocumentation=false')
|
error('Program "sphinx-build" not found or not executable. Try building with -Ddocumentation=false')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
yq = find_program('yq', required : false)
|
|
||||||
if not yq.found()
|
|
||||||
warning('Program "yq" not found or not executable. Dependency list will not be built.')
|
|
||||||
endif
|
|
||||||
|
|
||||||
sphinx_config = configuration_data()
|
sphinx_config = configuration_data()
|
||||||
sphinx_config.set('PROJECT_NAME', meson.project_name())
|
sphinx_config.set('PROJECT_NAME', meson.project_name())
|
||||||
sphinx_config.set('PROJECT_VERSION', meson.project_version())
|
sphinx_config.set('PROJECT_VERSION', meson.project_version())
|
||||||
sphinx_config.set('BUILDDIR', meson.current_build_dir())
|
sphinx_config.set('BUILDDIR', meson.current_build_dir())
|
||||||
sphinx_config.set('HTTP_DOC_LINK', doc_url)
|
|
||||||
|
|
||||||
git_version_page = vcs_tag(command : ['git', 'log', '-1', '--format=%H'],
|
git_version_page = vcs_tag(command : ['git', 'log', '-1', '--format=%H'],
|
||||||
fallback : 'unknown',
|
fallback : 'unknown',
|
||||||
|
|
@ -50,7 +44,6 @@ src_404s = [
|
||||||
[ 'faqs.rst', 'faq.html'],
|
[ 'faqs.rst', 'faq.html'],
|
||||||
[ 'features.rst', 'features.html'],
|
[ 'features.rst', 'features.html'],
|
||||||
[ 'gestures.rst', 'gestures.html'],
|
[ 'gestures.rst', 'gestures.html'],
|
||||||
[ 'incorrectly-enabled-hires.rst', 'incorrectly-enabled-hires.html'],
|
|
||||||
[ 'middle-button-emulation.rst', 'middle_button_emulation.html'],
|
[ 'middle-button-emulation.rst', 'middle_button_emulation.html'],
|
||||||
[ 'normalization-of-relative-motion.rst', 'motion_normalization.html'],
|
[ 'normalization-of-relative-motion.rst', 'motion_normalization.html'],
|
||||||
[ 'palm-detection.rst', 'palm_detection.html'],
|
[ 'palm-detection.rst', 'palm_detection.html'],
|
||||||
|
|
@ -95,13 +88,11 @@ src_rst = files(
|
||||||
# dot drawings
|
# dot drawings
|
||||||
'dot/seats-sketch.gv',
|
'dot/seats-sketch.gv',
|
||||||
'dot/seats-sketch-libinput.gv',
|
'dot/seats-sketch-libinput.gv',
|
||||||
'dot/libinput-contexts.gv',
|
|
||||||
'dot/libinput-stack-wayland.gv',
|
'dot/libinput-stack-wayland.gv',
|
||||||
'dot/libinput-stack-xorg.gv',
|
'dot/libinput-stack-xorg.gv',
|
||||||
'dot/libinput-stack-gnome.gv',
|
'dot/libinput-stack-gnome.gv',
|
||||||
'dot/evemu.gv',
|
'dot/evemu.gv',
|
||||||
'dot/libinput-record.gv',
|
'dot/libinput-record.gv',
|
||||||
'dot/plugin-stack.gv',
|
|
||||||
# svgs
|
# svgs
|
||||||
'svg/button-debouncing-wave-diagram.svg',
|
'svg/button-debouncing-wave-diagram.svg',
|
||||||
'svg/button-scrolling.svg',
|
'svg/button-scrolling.svg',
|
||||||
|
|
@ -112,7 +103,6 @@ src_rst = files(
|
||||||
'svg/palm-detection.svg',
|
'svg/palm-detection.svg',
|
||||||
'svg/pinch-gestures.svg',
|
'svg/pinch-gestures.svg',
|
||||||
'svg/pinch-gestures-softbuttons.svg',
|
'svg/pinch-gestures-softbuttons.svg',
|
||||||
'svg/ptraccel-custom.svg',
|
|
||||||
'svg/ptraccel-linear.svg',
|
'svg/ptraccel-linear.svg',
|
||||||
'svg/ptraccel-low-dpi.svg',
|
'svg/ptraccel-low-dpi.svg',
|
||||||
'svg/ptraccel-touchpad.svg',
|
'svg/ptraccel-touchpad.svg',
|
||||||
|
|
@ -122,11 +112,8 @@ src_rst = files(
|
||||||
'svg/software-buttons-thumbpress.svg',
|
'svg/software-buttons-thumbpress.svg',
|
||||||
'svg/software-buttons-visualized.svg',
|
'svg/software-buttons-visualized.svg',
|
||||||
'svg/swipe-gestures.svg',
|
'svg/swipe-gestures.svg',
|
||||||
'svg/tablet-area.svg',
|
|
||||||
'svg/tablet-axes.svg',
|
'svg/tablet-axes.svg',
|
||||||
'svg/tablet-cintiq24hd-modes.svg',
|
'svg/tablet-cintiq24hd-modes.svg',
|
||||||
'svg/tablet-eraser-invert.svg',
|
|
||||||
'svg/tablet-eraser-button.svg',
|
|
||||||
'svg/tablet-interfaces.svg',
|
'svg/tablet-interfaces.svg',
|
||||||
'svg/tablet-intuos-modes.svg',
|
'svg/tablet-intuos-modes.svg',
|
||||||
'svg/tablet-left-handed.svg',
|
'svg/tablet-left-handed.svg',
|
||||||
|
|
@ -145,19 +132,15 @@ src_rst = files(
|
||||||
'building.rst',
|
'building.rst',
|
||||||
'button-debouncing.rst',
|
'button-debouncing.rst',
|
||||||
'clickpad-softbuttons.rst',
|
'clickpad-softbuttons.rst',
|
||||||
'clickpad-with-right-button.rst',
|
|
||||||
'contributing.rst',
|
'contributing.rst',
|
||||||
'device-configuration-via-udev.rst',
|
'device-configuration-via-udev.rst',
|
||||||
'device-quirks.rst',
|
'device-quirks.rst',
|
||||||
'drag-3fg.rst',
|
|
||||||
'faqs.rst',
|
'faqs.rst',
|
||||||
'gestures.rst',
|
'gestures.rst',
|
||||||
'incorrectly-enabled-hires.rst',
|
'index.rst',
|
||||||
'ignoring-devices.rst',
|
|
||||||
'middle-button-emulation.rst',
|
'middle-button-emulation.rst',
|
||||||
'normalization-of-relative-motion.rst',
|
'normalization-of-relative-motion.rst',
|
||||||
'palm-detection.rst',
|
'palm-detection.rst',
|
||||||
'lua-plugins.rst',
|
|
||||||
'pointer-acceleration.rst',
|
'pointer-acceleration.rst',
|
||||||
'reporting-bugs.rst',
|
'reporting-bugs.rst',
|
||||||
'scrolling.rst',
|
'scrolling.rst',
|
||||||
|
|
@ -179,39 +162,27 @@ src_rst = files(
|
||||||
'trackpoints.rst',
|
'trackpoints.rst',
|
||||||
'trackpoint-configuration.rst',
|
'trackpoint-configuration.rst',
|
||||||
'what-is-libinput.rst',
|
'what-is-libinput.rst',
|
||||||
'wheel-api.rst',
|
|
||||||
'features.rst',
|
'features.rst',
|
||||||
'development.rst',
|
'development.rst',
|
||||||
'troubleshooting.rst',
|
'troubleshooting.rst',
|
||||||
'configuration.rst',
|
'configuration.rst',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
config_noop = configuration_data()
|
||||||
|
# Set a dummy replacement to silence meson warnings:
|
||||||
|
# meson.build:487: WARNING: Got an empty configuration_data() object and
|
||||||
|
# found no substitutions in the input file 'foo'. If you
|
||||||
|
# want to copy a file to the build dir, use the 'copy:'
|
||||||
|
# keyword argument added in 0.47.0
|
||||||
|
config_noop.set('dummy', 'dummy')
|
||||||
src_sphinx = []
|
src_sphinx = []
|
||||||
foreach f : src_rst
|
foreach f : src_rst
|
||||||
sf = configure_file(input: f,
|
sf = configure_file(input: f,
|
||||||
output: '@PLAINNAME@',
|
output: '@PLAINNAME@',
|
||||||
copy : true)
|
configuration : config_noop)
|
||||||
src_sphinx += [ sf ]
|
src_sphinx += [ sf ]
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
configure_file(input: 'index.rst',
|
|
||||||
output: 'index.rst',
|
|
||||||
configuration: sphinx_config)
|
|
||||||
|
|
||||||
dependencies_config = configuration_data()
|
|
||||||
if yq.found()
|
|
||||||
distributions = ['fedora', 'ubuntu', 'debian', 'arch', 'alpine']
|
|
||||||
foreach distro : distributions
|
|
||||||
yq_filter = '.distributions[] | select(.name == "@0@") | .packages | join(" ")'.format(distro)
|
|
||||||
deps = run_command(yq, '-r', yq_filter,
|
|
||||||
dir_gitlab_ci / 'config.yml',
|
|
||||||
check: true).stdout()
|
|
||||||
dependencies_config.set('@0@_PACKAGES'.format(distro.to_upper()), deps)
|
|
||||||
endforeach
|
|
||||||
endif
|
|
||||||
configure_file(input: 'dependencies.rst',
|
|
||||||
output: 'dependencies.rst',
|
|
||||||
configuration: dependencies_config)
|
|
||||||
|
|
||||||
# do not use -j, it breaks on Ubuntu
|
# do not use -j, it breaks on Ubuntu
|
||||||
sphinx_output_dir = 'Documentation'
|
sphinx_output_dir = 'Documentation'
|
||||||
|
|
@ -219,6 +190,5 @@ custom_target('sphinx',
|
||||||
input : [ sphinx_conf_py, git_version_page ] + src_sphinx + dst_404s,
|
input : [ sphinx_conf_py, git_version_page ] + src_sphinx + dst_404s,
|
||||||
output : [ sphinx_output_dir ],
|
output : [ sphinx_output_dir ],
|
||||||
command : [ sphinx, '-q', '-b', 'html',
|
command : [ sphinx, '-q', '-b', 'html',
|
||||||
'-d', meson.current_build_dir() / 'doctrees',
|
|
||||||
meson.current_build_dir(), sphinx_output_dir],
|
meson.current_build_dir(), sphinx_output_dir],
|
||||||
build_by_default : true)
|
build_by_default : true)
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,6 @@ libinput applies a dpi-dependent acceleration function. At low speeds, a
|
||||||
movement speed increases, acceleration is applied - at high speeds a low-dpi
|
movement speed increases, acceleration is applied - at high speeds a low-dpi
|
||||||
device will roughly feel the same as a higher-dpi mouse.
|
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
|
This normalization only applies to accelerated coordinates, unaccelerated
|
||||||
coordinates are left in device-units. It is up to the caller to interpret
|
coordinates are left in device-units. It is up to the caller to interpret
|
||||||
those coordinates correctly.
|
those coordinates correctly.
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ hardware-specific capabilities.
|
||||||
- :ref:`palm_exclusion_zones`
|
- :ref:`palm_exclusion_zones`
|
||||||
- :ref:`trackpoint-disabling`
|
- :ref:`trackpoint-disabling`
|
||||||
- :ref:`disable-while-typing`
|
- :ref:`disable-while-typing`
|
||||||
- :ref:`disable-while-trackpointing`
|
|
||||||
- :ref:`stylus-touch-arbitration`
|
- :ref:`stylus-touch-arbitration`
|
||||||
|
|
||||||
Palm detection is always enabled, with the exception of
|
Palm detection is always enabled, with the exception of
|
||||||
|
|
@ -92,8 +91,9 @@ Another exclusion zone is defined on the top edge of the touchpad. As with
|
||||||
the edge zones, libinput detects vertical movements out of the edge zone and
|
the edge zones, libinput detects vertical movements out of the edge zone and
|
||||||
avoids palm detection on such touch sequences.
|
avoids palm detection on such touch sequences.
|
||||||
|
|
||||||
A touch starting in the exclusion zone does not trigger a tap (see
|
Each side edge exclusion zone is divided into a top part and a bottom part.
|
||||||
:ref:`tapping`).
|
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.
|
In the diagram below, the exclusion zones are painted red.
|
||||||
Touch 'A' starts inside the exclusion zone and moves
|
Touch 'A' starts inside the exclusion zone and moves
|
||||||
|
|
@ -103,8 +103,10 @@ despite moving out of the exclusion zone.
|
||||||
Touch 'B' starts inside the exclusion zone but moves horizontally out of the
|
Touch 'B' starts inside the exclusion zone but moves horizontally out of the
|
||||||
zone. It is considered a valid touch and controls the cursor.
|
zone. It is considered a valid touch and controls the cursor.
|
||||||
|
|
||||||
Touch 'C' occurs in the exclusion zone. Despite being a tapping motion, it does
|
Touch 'C' occurs in the top part of the exclusion zone. Despite being a
|
||||||
not generate an emulated button event.
|
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.
|
||||||
|
|
||||||
.. figure:: palm-detection.svg
|
.. figure:: palm-detection.svg
|
||||||
:align: center
|
:align: center
|
||||||
|
|
@ -155,29 +157,10 @@ Notable behaviors of libinput's disable-while-typing feature:
|
||||||
typing.
|
typing.
|
||||||
- Physical buttons work even while the touchpad is disabled. This includes
|
- Physical buttons work even while the touchpad is disabled. This includes
|
||||||
:ref:`software-emulated buttons <t440_support>`.
|
:ref:`software-emulated buttons <t440_support>`.
|
||||||
- libinput pairs touchpads and keyboards for the disable-while-typing
|
|
||||||
feature. In the most common case, the internal touchpad is paired only
|
|
||||||
with the internal keyboard. Typing on an external keyboard will thus not
|
|
||||||
disable the touchpad. Some devices require a :ref:`quirk <device-quirks>`
|
|
||||||
to be correctly paired.
|
|
||||||
|
|
||||||
Disable-while-typing can be enabled and disabled by calling
|
Disable-while-typing can be enabled and disabled by calling
|
||||||
**libinput_device_config_dwt_set_enabled()**.
|
**libinput_device_config_dwt_set_enabled()**.
|
||||||
|
|
||||||
.. _disable-while-trackpointing:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Disable-while-trackpointing
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput automatically disables the touchpad for a timeout after the trackpoint
|
|
||||||
is moved, a feature referred to as "disable while trackpointing". libinput does
|
|
||||||
not require an external command and the feature is currently enabled for all
|
|
||||||
touchpads.
|
|
||||||
|
|
||||||
Disable-while-trackpointing can be enabled and disabled by calling
|
|
||||||
**libinput_device_config_dwtp_set_enabled()**.
|
|
||||||
|
|
||||||
.. _stylus-touch-arbitration:
|
.. _stylus-touch-arbitration:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,12 @@ Pointer acceleration profiles
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
The profile decides the general method of pointer acceleration.
|
The profile decides the general method of pointer acceleration.
|
||||||
libinput currently supports three profiles: **"adaptive"**, **"flat"** and
|
libinput currently supports two profiles: "adaptive" and "flat". The adaptive
|
||||||
**"custom"**.
|
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
|
||||||
- The **adaptive** profile is the default profile for all devices and takes the
|
is simply a constant factor applied to all device deltas, regardless of the
|
||||||
current speed of the device into account when deciding on acceleration.
|
speed of motion (see :ref:`ptraccel-profile-flat`). Most of this document
|
||||||
- The **flat** profile is simply a constant factor applied to all device deltas,
|
describes the adaptive pointer acceleration.
|
||||||
regardless of the speed of motion (see :ref:`ptraccel-profile-flat`).
|
|
||||||
- The **custom** profile allows the user to define a custom acceleration
|
|
||||||
function, giving full control over accelerations behavior at different speed
|
|
||||||
(see :ref:`ptraccel-profile-custom`).
|
|
||||||
|
|
||||||
Most of this document describes the adaptive pointer acceleration.
|
|
||||||
|
|
||||||
.. _ptraccel-velocity:
|
.. _ptraccel-velocity:
|
||||||
|
|
||||||
|
|
@ -172,7 +166,7 @@ what is a unit again.
|
||||||
|
|
||||||
libinput attempts to normalize unit data to the best of its abilities, see
|
libinput attempts to normalize unit data to the best of its abilities, see
|
||||||
:ref:`trackpoint_multiplier`. Beyond this, it is not possible to have
|
:ref:`trackpoint_multiplier`. Beyond this, it is not possible to have
|
||||||
consistent behavior across different trackpoint devices.
|
consistent behavior across different touchpad devices.
|
||||||
|
|
||||||
.. figure:: ptraccel-trackpoint.svg
|
.. figure:: ptraccel-trackpoint.svg
|
||||||
:align: center
|
:align: center
|
||||||
|
|
@ -202,95 +196,3 @@ Pointer acceleration on tablets
|
||||||
Pointer acceleration for relative motion on tablet devices is a flat
|
Pointer acceleration for relative motion on tablet devices is a flat
|
||||||
acceleration, with the speed setting slowing down or speeding up the pointer
|
acceleration, with the speed setting slowing down or speeding up the pointer
|
||||||
motion by a constant factor. Tablets do not allow for switchable profiles.
|
motion by a constant factor. Tablets do not allow for switchable profiles.
|
||||||
|
|
||||||
.. _ptraccel-profile-custom:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
The custom acceleration profile
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput supports a user-defined custom acceleration profile, which can be
|
|
||||||
adjusted for different movement types supported by a device. Movement types
|
|
||||||
include pointer movement, scrolling, etc. but the set of supported
|
|
||||||
movement types depends on the device.
|
|
||||||
|
|
||||||
The custom pointer acceleration profile gives users full control over the
|
|
||||||
acceleration behavior at different speeds. libinput exposes
|
|
||||||
an acceleration function ``f(x)`` where the x axis is the device speed in
|
|
||||||
device units per millisecond and the y axis is the pointer speed. By
|
|
||||||
supplying the y axis values for this function, users can control the
|
|
||||||
behavior of the device.
|
|
||||||
|
|
||||||
The user should take into account the native device dpi and screen dpi in
|
|
||||||
order to achieve the desired behavior/feel.
|
|
||||||
|
|
||||||
The custom acceleration function is defined using ``n`` points which are spaced
|
|
||||||
uniformly along the x axis, starting from 0 and continuing in constant steps.
|
|
||||||
At least two points must be defined and there is an implementation-defined
|
|
||||||
limit on how many points may be added.
|
|
||||||
|
|
||||||
Thus the points defining the custom function are:
|
|
||||||
``(0 * step, f[0]), (1 * step, f[1]), ..., ((n-1) * step, f[n-1])``
|
|
||||||
where ``f`` is a list of ``n`` values defining the output velocity for each
|
|
||||||
input velocity.
|
|
||||||
The acceleration factor is defined by the ratio of the output velocity to the
|
|
||||||
input velocity.
|
|
||||||
When a velocity value does not lie exactly on those points, a linear
|
|
||||||
interpolation of the two closest points will be calculated.
|
|
||||||
When a velocity value is greater than the max point defined, a linear
|
|
||||||
extrapolation of the two biggest points will be calculated.
|
|
||||||
|
|
||||||
the calculation made by libinput: ::
|
|
||||||
|
|
||||||
input_delta = device delta units
|
|
||||||
delta_time = time in ms since last input_delta
|
|
||||||
input_speed = hypot(input_delta) / delta_time
|
|
||||||
output_speed = user_custom_function(input_speed)
|
|
||||||
acceleration_factor = output_speed / input_speed
|
|
||||||
output_delta = input_delta * acceleration_factor
|
|
||||||
|
|
||||||
An example is the curve of ``0.0, 1.0`` with a step of ``1.0``. This curve
|
|
||||||
is the equivalent of the flat acceleration profile with any input speed ``N``
|
|
||||||
mapped to the same pointer speed ``N``. The curve ``1.0, 1.0`` neutralizes
|
|
||||||
any input speed differences and results in a fixed pointer speed.
|
|
||||||
|
|
||||||
Another example is the custom acceleration function ``x**2``,
|
|
||||||
sampling the function at ``4`` points up to
|
|
||||||
a maximum input speed of ``9`` will give us a custom function with
|
|
||||||
a step of ``3`` and points ``[0.0, 9.0, 36.0, 81.0]``:
|
|
||||||
|
|
||||||
.. figure:: ptraccel-custom.svg
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
More sampled points can be added to improve the accuracy of the user custom
|
|
||||||
function.
|
|
||||||
|
|
||||||
Supported Movement types:
|
|
||||||
|
|
||||||
+---------------+---------------------------------+----------------------+
|
|
||||||
| Movement type | Uses | supported by |
|
|
||||||
+===============+=================================+======================+
|
|
||||||
| Fallback | Catch-all default movement type | All devices |
|
|
||||||
+---------------+---------------------------------+----------------------+
|
|
||||||
| Motion | Used for pointer motion | All devices |
|
|
||||||
+---------------+---------------------------------+----------------------+
|
|
||||||
| Scroll | Used for scroll movement | Mouse, Touchpad |
|
|
||||||
+---------------+---------------------------------+----------------------+
|
|
||||||
|
|
||||||
If a user does not provide the fallback custom acceleration function, a
|
|
||||||
flat acceleration function is used, i.e. no acceleration.
|
|
||||||
|
|
||||||
The fallback acceleration may be used for different types of movements, it is
|
|
||||||
strongly recommended that this acceleration function is a constant function.
|
|
||||||
|
|
||||||
For example, a touchpad has multiple movement types: pointer
|
|
||||||
movement, scroll movement, zoom movement (pinch), etc. As there is no separate
|
|
||||||
movement type for zoom yet, zoom movement is accelerated using the Fallback
|
|
||||||
acceleration function. Pointer movement is accelerated using the Motion
|
|
||||||
acceleration function, and Scroll movement is accelerated using the Scroll
|
|
||||||
acceleration function. If no Motion/Scroll acceleration function is set, the
|
|
||||||
Fallback acceleration function is used.
|
|
||||||
|
|
||||||
When using custom acceleration profile, any calls to set the speed have no
|
|
||||||
effect on the behavior of the custom acceleration function, but any future calls to
|
|
||||||
get the speed will reflect the requested speed setting.
|
|
||||||
|
|
|
||||||
|
|
@ -64,11 +64,7 @@ For the vast majority of bugs you should not take longer than 5 seconds or
|
||||||
three interactions (clicks, touches, taps, ...) with the device to
|
three interactions (clicks, touches, taps, ...) with the device to
|
||||||
reproduce. If it takes longer than that, you can narrow it down further.
|
reproduce. If it takes longer than that, you can narrow it down further.
|
||||||
|
|
||||||
Once you can reproduce it, use the :ref:`libinput-debug-events` helper
|
Once you can reproduce it, use the :ref:`libinput-debug-events` helper tool.
|
||||||
tool::
|
|
||||||
|
|
||||||
$> libinput debug-events --verbose
|
|
||||||
|
|
||||||
The output is textual and can help identify whether the bug is in libinput
|
The output is textual and can help identify whether the bug is in libinput
|
||||||
at all. Note that any configuration options you have set must be specified
|
at all. Note that any configuration options you have set must be specified
|
||||||
on the commandline, see the :ref:`libinput-debug-events`
|
on the commandline, see the :ref:`libinput-debug-events`
|
||||||
|
|
@ -113,8 +109,8 @@ When you file a bug, please attach the following information:
|
||||||
- the output from udevadm info, see :ref:`udev_info`.
|
- the output from udevadm info, see :ref:`udev_info`.
|
||||||
- the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s")
|
- the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s")
|
||||||
- and the content of ``/sys/class/dmi/id/modalias``.
|
- and the content of ``/sys/class/dmi/id/modalias``.
|
||||||
- run ``libinput measure touchpad-size`` tool (see :ref:`absolute_coordinate_ranges_fix`)
|
- run the ``touchpad-edge-detector`` tool (provided by libevdev) and verify
|
||||||
and verify that the ranges and sizes it prints match the touchpad (up to 5mm
|
that the ranges and sizes it prints match the touchpad (up to 5mm
|
||||||
difference is ok)
|
difference is ok)
|
||||||
|
|
||||||
If you are reporting a bug related to button event generation:
|
If you are reporting a bug related to button event generation:
|
||||||
|
|
@ -170,7 +166,8 @@ When you file a bug, please attach the following information:
|
||||||
This is the most important piece of information, do not forget it!
|
This is the most important piece of information, do not forget it!
|
||||||
- the vendor model number of the device (e.g. "Logitech M325")
|
- the vendor model number of the device (e.g. "Logitech M325")
|
||||||
- the output from udevadm info, see :ref:`udev_info`.
|
- the output from udevadm info, see :ref:`udev_info`.
|
||||||
- the sensitivity of the trackpoint if it exists (adjust the event node number as needed): ::
|
- the output of ``libinput measure trackpoint-range``
|
||||||
|
- the sensitivity of the trackpoint (adjust the event node number as needed): ::
|
||||||
|
|
||||||
$ cat /sys/class/input/event17/device/device/sensitivity
|
$ cat /sys/class/input/event17/device/device/sensitivity
|
||||||
|
|
||||||
|
|
@ -304,7 +301,7 @@ updated its package accordingly.
|
||||||
|
|
||||||
Whether the bug fix ends up in your distribution depends on a number of
|
Whether the bug fix ends up in your distribution depends on a number of
|
||||||
things. Any given bug fix **may** be cherry-picked into the current stable
|
things. Any given bug fix **may** be cherry-picked into the current stable
|
||||||
branch, depending on its severity, impact, and likelihood to cause
|
branch, depending on its severity, impact, and likelyhood to cause
|
||||||
regressions. Once cherry-picked it will land in the next stable branch
|
regressions. Once cherry-picked it will land in the next stable branch
|
||||||
release. These are usually a few weeks apart.
|
release. These are usually a few weeks apart.
|
||||||
|
|
||||||
|
|
@ -345,51 +342,3 @@ However, if the regression is in behavior unrelated to the fix itself it is
|
||||||
usually better to file a new bug to reduce the noise. For example, if a fix
|
usually better to file a new bug to reduce the noise. For example, if a fix
|
||||||
to improve tapping breaks two-finger scrolling behavior, you should file a
|
to improve tapping breaks two-finger scrolling behavior, you should file a
|
||||||
new bug but reference the original bug.
|
new bug but reference the original bug.
|
||||||
|
|
||||||
.. _reporting_bugs_tags:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Gitlab issue tracker tags
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The gitlab issue tracker allows developers to add tags to bugs to classify
|
|
||||||
them.
|
|
||||||
|
|
||||||
- **being worked on**: someone is currently working on this feature. This
|
|
||||||
tag is used for features that will take a long time to implement fully and
|
|
||||||
prevents others from having to duplicate the work. Do reach out and ask if
|
|
||||||
help and/or further testing is needed.
|
|
||||||
- **bug**: issue is confirmed to be a bug
|
|
||||||
- **cantfix**: for technical reasons, this bug cannot be fixed, or at least
|
|
||||||
it cannot be fixed in libinput.
|
|
||||||
- **enhancement**: this issue describes a future feature, not a bug.
|
|
||||||
- **help needed**: this issue requires someone outside the libinput core
|
|
||||||
developer team to implement it. It is unlikely to be implemented
|
|
||||||
without someone stepping up to do the work. If you do see this tag, do ask
|
|
||||||
for guidance on how to implement it.
|
|
||||||
- **hw issue**: an issue that affects a specific device and is a hardware
|
|
||||||
bug, not a software bug. Often these needs to be worked around in libinput
|
|
||||||
but there are cases where a hw issue ends up as *cantfix*.
|
|
||||||
- **janitor**: a cleanup task that does not substantially affect how
|
|
||||||
libinput works. These are usually good bugs for newcomers to start on.
|
|
||||||
- **kernel**: this issue is a kernel bug, not a libinput bug. Often closed
|
|
||||||
as *cantfix* of *wontfix* as we wait for the kernel to address the issue
|
|
||||||
instead.
|
|
||||||
- **needs triage**: bug has not yet been confirmed by a core developer.
|
|
||||||
- **not our bug**: the issue is in some other component of the stack and
|
|
||||||
needs to be addressed there.
|
|
||||||
- **please test**: a fix is available but not yet merged and should be
|
|
||||||
tested by the reporter or others affected by the issue.
|
|
||||||
- **quirk**: this is issue needs :ref:`device-quirks` to be fixed
|
|
||||||
- **regression**: the issue is a regression to previous versions of
|
|
||||||
libinput. These issues get priorities.
|
|
||||||
- **waiting on reporter**: some more information is required from the
|
|
||||||
reporter and the issue cannot be fixed until the issue has been provided.
|
|
||||||
Where a bug is left in this state for too long, the bug will be closed as
|
|
||||||
*cantfix*.
|
|
||||||
- **wontfix**: this issue will not get fixed. This tag is usually assigned
|
|
||||||
to feature requests that are outside the scope of libinput or would put an
|
|
||||||
unreasonable maintenance burdern on the maintainers.
|
|
||||||
|
|
||||||
These tags are high-level categories only, always look for the comments in
|
|
||||||
the issue to get further details.
|
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,9 @@ vertically or horizontally.
|
||||||
|
|
||||||
Vertical and horizontal two-finger scrolling
|
Vertical and horizontal two-finger scrolling
|
||||||
|
|
||||||
For scrolling to trigger, a built-in distance threshold has to be met, but once
|
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
|
engaged any movement will scroll. In other words, to start scrolling a
|
||||||
sufficiently large movement is required; once scrolling, tiny amounts of
|
sufficiently large movement is required, once scrolling tiny amounts of
|
||||||
movements will translate into tiny scroll movements.
|
movements will translate into tiny scroll movements.
|
||||||
Scrolling in both directions at once is possible by meeting the required
|
Scrolling in both directions at once is possible by meeting the required
|
||||||
distance thresholds to enable each direction separately.
|
distance thresholds to enable each direction separately.
|
||||||
|
|
@ -117,28 +117,12 @@ the motion events. Cross-device scrolling is not supported but
|
||||||
for one exception: libinput's :ref:`t440_support` enables the use of the middle
|
for one exception: libinput's :ref:`t440_support` enables the use of the middle
|
||||||
button for button scrolling (even when the touchpad is disabled).
|
button for button scrolling (even when the touchpad is disabled).
|
||||||
|
|
||||||
If the scroll button lock is enabled (see
|
|
||||||
**libinput_device_config_scroll_set_button_lock()**), the button does not
|
|
||||||
need to be held down. Pressing and releasing the button once enables the
|
|
||||||
button lock, the button is now considered logically held down. Pressing and
|
|
||||||
releasing the button a second time logically releases the button. While the
|
|
||||||
button is logically held down, motion events are converted to scroll events.
|
|
||||||
|
|
||||||
If the button is held and used to scroll for longer than a short grace
|
|
||||||
period, releasing the button does not engage the lock. This allows
|
|
||||||
hold-to-scroll for short, precise adjustments without accidentally toggling
|
|
||||||
the lock. A quick click or a brief scroll within the grace period still
|
|
||||||
engages the lock as normal.
|
|
||||||
|
|
||||||
.. _scroll_sources:
|
.. _scroll_sources:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Scroll sources
|
Scroll sources
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
.. note:: Scroll sources are deprecated with libinput 1.19. The scroll
|
|
||||||
source is now encoded in the event type.
|
|
||||||
|
|
||||||
libinput provides a pointer axis *source* for each scroll event. The
|
libinput provides a pointer axis *source* for each scroll event. The
|
||||||
source can be obtained with the **libinput_event_pointer_get_axis_source()**
|
source can be obtained with the **libinput_event_pointer_get_axis_source()**
|
||||||
function and is one of **wheel**, **finger**, or **continuous**. The source
|
function and is one of **wheel**, **finger**, or **continuous**. The source
|
||||||
|
|
@ -156,23 +140,3 @@ See the **libinput_event_pointer_get_axis_source()** for details on the
|
||||||
behavior of each scroll source.
|
behavior of each scroll source.
|
||||||
|
|
||||||
See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
|
See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
|
||||||
|
|
||||||
.. _natural_scrolling:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Natural scrolling vs. traditional scrolling
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Natural scrolling is the term (probably) coined by Apple for matching
|
|
||||||
the motion of the scroll device with the direction of the **content**.
|
|
||||||
|
|
||||||
In traditional scrolling, moving the wheel down causes the scroll bar
|
|
||||||
indicators to move down and the content to move up. In natural scrolling,
|
|
||||||
moving the wheel down causes the content to move down and the scroll bar
|
|
||||||
indicators to move up. This method of scrolling matches the interaction
|
|
||||||
with content on touch screens where a movement down also moves the content
|
|
||||||
down.
|
|
||||||
|
|
||||||
libinput supports natural scrolling for all its scroll methods; it can
|
|
||||||
be enabled with the
|
|
||||||
**libinput_device_config_scroll_set_natural_scroll_enabled()** function.
|
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,13 @@
|
||||||
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)"
|
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"
|
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" />
|
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.30510259px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="rect3490"
|
||||||
|
width="65.310997"
|
||||||
|
height="136.12065"
|
||||||
|
x="7.0411549"
|
||||||
|
y="7.1355872" />
|
||||||
<text
|
<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"
|
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"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
|
|
@ -148,6 +155,13 @@
|
||||||
id="tspan13876"
|
id="tspan13876"
|
||||||
y="63.628628"
|
y="63.628628"
|
||||||
x="33.214291">A</tspan></text>
|
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.22849"
|
||||||
|
y="6.8830237" />
|
||||||
<text
|
<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"
|
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"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
|
|
@ -177,6 +191,16 @@
|
||||||
id="tspan13876-7-9"
|
id="tspan13876-7-9"
|
||||||
y="46.009491"
|
y="46.009491"
|
||||||
x="342.27759">C</tspan></text>
|
x="342.27759">C</tspan></text>
|
||||||
|
<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"
|
||||||
|
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
|
<circle
|
||||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
id="path4401"
|
id="path4401"
|
||||||
|
|
@ -184,6 +208,13 @@
|
||||||
cy="24.53549"
|
cy="24.53549"
|
||||||
r="4.0658817"
|
r="4.0658817"
|
||||||
transform="scale(-1,1)" />
|
transform="scale(-1,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)" />
|
||||||
<rect
|
<rect
|
||||||
width="248.87633"
|
width="248.87633"
|
||||||
height="6.8111157"
|
height="6.8111157"
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
|
@ -208,3 +208,4 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
|
@ -1,228 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="229.5488mm"
|
|
||||||
height="86.66362mm"
|
|
||||||
viewBox="0 0 813.36188 307.07582"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
|
||||||
sodipodi:docname="tablet-area.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<defs
|
|
||||||
id="defs4">
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient4294"
|
|
||||||
id="linearGradient4300"
|
|
||||||
x1="465.81339"
|
|
||||||
y1="666.13727"
|
|
||||||
x2="454.82117"
|
|
||||||
y2="658.65521"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
id="linearGradient4294">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#1a1a1a;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop4296" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#808080;stop-opacity:1"
|
|
||||||
offset="1"
|
|
||||||
id="stop4298" />
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="2.8"
|
|
||||||
inkscape:cx="410.53571"
|
|
||||||
inkscape:cy="188.39286"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer3"
|
|
||||||
showgrid="false"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:guide-bbox="true"
|
|
||||||
inkscape:window-width="3072"
|
|
||||||
inkscape:window-height="1659"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1" />
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="tablet"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
style="display:inline"
|
|
||||||
transform="translate(67.109152,-133.63374)">
|
|
||||||
<g
|
|
||||||
id="g4309"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90"
|
|
||||||
transform="translate(0,1.0715222)">
|
|
||||||
<rect
|
|
||||||
y="134.15933"
|
|
||||||
x="75.787216"
|
|
||||||
height="306.02466"
|
|
||||||
width="522.19733"
|
|
||||||
id="rect4136"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:1.05118;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:4.20473, 1.05118;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.748138;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.99255, 0.748138;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4140"
|
|
||||||
width="357.34042"
|
|
||||||
height="226.52563"
|
|
||||||
x="199.33878"
|
|
||||||
y="175.42407" />
|
|
||||||
<rect
|
|
||||||
y="175.72914"
|
|
||||||
x="103.10225"
|
|
||||||
height="22.142857"
|
|
||||||
width="65"
|
|
||||||
id="rect4142"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4148"
|
|
||||||
width="65"
|
|
||||||
height="22.142857"
|
|
||||||
x="103.10225"
|
|
||||||
y="203.72914" />
|
|
||||||
<rect
|
|
||||||
y="231.72913"
|
|
||||||
x="103.10225"
|
|
||||||
height="22.142857"
|
|
||||||
width="65"
|
|
||||||
id="rect4150"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
y="323.72913"
|
|
||||||
x="103.10225"
|
|
||||||
height="22.142857"
|
|
||||||
width="65"
|
|
||||||
id="rect4154"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect4156"
|
|
||||||
width="65"
|
|
||||||
height="22.142857"
|
|
||||||
x="103.10225"
|
|
||||||
y="351.72913" />
|
|
||||||
<circle
|
|
||||||
r="22.98097"
|
|
||||||
cy="287.06125"
|
|
||||||
cx="135.61298"
|
|
||||||
id="path4158"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<ellipse
|
|
||||||
ry="12.608653"
|
|
||||||
rx="11.5985"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.520431;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.08172, 0.520431;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="circle4160"
|
|
||||||
cx="135.61298"
|
|
||||||
cy="287.06125" />
|
|
||||||
<rect
|
|
||||||
y="379.72913"
|
|
||||||
x="103.10225"
|
|
||||||
height="22.142857"
|
|
||||||
width="65"
|
|
||||||
id="rect4162"
|
|
||||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer2"
|
|
||||||
inkscape:label="area">
|
|
||||||
<rect
|
|
||||||
style="display:inline;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.675728"
|
|
||||||
id="rect1"
|
|
||||||
width="131.51813"
|
|
||||||
height="126.57689"
|
|
||||||
x="326.15009"
|
|
||||||
y="97.775696" />
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="display:inline;font-size:11.25px;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.9375"
|
|
||||||
x="261.92404"
|
|
||||||
y="244.01244"
|
|
||||||
id="text1"
|
|
||||||
transform="translate(67.109152,-133.63374)"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan1"
|
|
||||||
style="fill:#000000;stroke-width:0.9375"
|
|
||||||
x="261.92404"
|
|
||||||
y="244.01244">0/0</tspan></text>
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.9375;stroke-linecap:round;stroke-dasharray:none"
|
|
||||||
d="m 259.17629,227.63135 v 7.63349"
|
|
||||||
id="path1"
|
|
||||||
transform="translate(67.109152,-133.63374)" />
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.9375;stroke-linecap:round;stroke-dasharray:none"
|
|
||||||
d="m 262.99304,231.44809 h -7.63349"
|
|
||||||
id="path2"
|
|
||||||
transform="translate(67.109152,-133.63374)" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer3"
|
|
||||||
inkscape:label="stylus"
|
|
||||||
style="display:inline"
|
|
||||||
transform="translate(67.109152,-133.63374)">
|
|
||||||
<g
|
|
||||||
id="g4304"
|
|
||||||
transform="matrix(0.37129971,0.09948946,-0.09618892,0.35898192,319.19555,24.123239)"
|
|
||||||
style="display:inline">
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="czcc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path4286"
|
|
||||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
|
||||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path4283"
|
|
||||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
|
||||||
style="display:inline;fill:#000000" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="scccs"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path4292"
|
|
||||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
|
||||||
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 9.8 KiB |
|
|
@ -1,198 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="104.05109mm"
|
|
||||||
height="64.88131mm"
|
|
||||||
viewBox="0 0 368.68495 229.89441"
|
|
||||||
id="svg4321"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
|
||||||
sodipodi:docname="tablet-eraser-button.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<defs
|
|
||||||
id="defs4323">
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient4294"
|
|
||||||
id="linearGradient4300"
|
|
||||||
x1="465.81339"
|
|
||||||
y1="666.13727"
|
|
||||||
x2="454.82117"
|
|
||||||
y2="658.65521"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
id="linearGradient4294">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#1a1a1a;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop4296" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#808080;stop-opacity:1"
|
|
||||||
offset="1"
|
|
||||||
id="stop4298" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient4294"
|
|
||||||
id="linearGradient3"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
x1="465.81339"
|
|
||||||
y1="666.13727"
|
|
||||||
x2="454.82117"
|
|
||||||
y2="658.65521" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="2.8"
|
|
||||||
inkscape:cx="330.71429"
|
|
||||||
inkscape:cy="144.28571"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:window-width="3072"
|
|
||||||
inkscape:window-height="1659"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1" />
|
|
||||||
<metadata
|
|
||||||
id="metadata4326">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-67.741956,-463.35919)">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.35596319,-0.1450925,0.14027908,0.34415419,-98.897559,452.82709)"
|
|
||||||
id="g4304"
|
|
||||||
style="display:inline">
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
|
||||||
id="path4286"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="czcc" />
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#000000"
|
|
||||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
|
||||||
id="path4283"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
|
||||||
<path
|
|
||||||
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
|
||||||
id="path4292"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="scccs" />
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
transform="scale(1,-1)"
|
|
||||||
y="-693.18524"
|
|
||||||
x="67.81031"
|
|
||||||
height="16.036251"
|
|
||||||
width="168.54825"
|
|
||||||
id="rect4136"
|
|
||||||
style="fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
transform="scale(1,-1)"
|
|
||||||
y="-693.18524"
|
|
||||||
x="267.8103"
|
|
||||||
height="16.036251"
|
|
||||||
width="168.54825"
|
|
||||||
id="rect5709"
|
|
||||||
style="opacity:1;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
id="text5713"
|
|
||||||
y="559.10828"
|
|
||||||
x="296.20877"
|
|
||||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="559.10828"
|
|
||||||
x="296.20877"
|
|
||||||
id="tspan5715"
|
|
||||||
sodipodi:role="line"
|
|
||||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Eraser</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text1"
|
|
||||||
y="559.10828"
|
|
||||||
x="109.0436"
|
|
||||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="559.10828"
|
|
||||||
x="109.0436"
|
|
||||||
id="tspan1"
|
|
||||||
sodipodi:role="line"
|
|
||||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Pen</tspan></text>
|
|
||||||
<g
|
|
||||||
transform="matrix(0.35596319,-0.1450925,0.14027908,0.34415419,117.39708,452.82709)"
|
|
||||||
id="g3"
|
|
||||||
style="display:inline">
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
|
||||||
id="path1"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="czcc" />
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#000000"
|
|
||||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
|
||||||
id="path2"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
|
||||||
<path
|
|
||||||
style="fill:url(#linearGradient3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
|
||||||
id="path3"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="scccs" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="matrix(-0.21797128,-0.07136846,0.05329769,-0.25512499,403.9107,823.07273)"
|
|
||||||
id="g3663-9-8">
|
|
||||||
<path
|
|
||||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 h -0.71428 z"
|
|
||||||
id="path2820-6-7"
|
|
||||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
|
||||||
id="path2824-1-6"
|
|
||||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
<path
|
|
||||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
|
||||||
id="path2824-7-1-7"
|
|
||||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
|
|
@ -1,179 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="104.05109mm"
|
|
||||||
height="64.88131mm"
|
|
||||||
viewBox="0 0 368.68495 229.89441"
|
|
||||||
id="svg4321"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
|
||||||
sodipodi:docname="tablet-eraser-invert.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
||||||
<defs
|
|
||||||
id="defs4323">
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient4294"
|
|
||||||
id="linearGradient4300"
|
|
||||||
x1="465.81339"
|
|
||||||
y1="666.13727"
|
|
||||||
x2="454.82117"
|
|
||||||
y2="658.65521"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
id="linearGradient4294">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#1a1a1a;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop4296" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#808080;stop-opacity:1"
|
|
||||||
offset="1"
|
|
||||||
id="stop4298" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient4294"
|
|
||||||
id="linearGradient5721"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
x1="465.81339"
|
|
||||||
y1="666.13727"
|
|
||||||
x2="454.82117"
|
|
||||||
y2="658.65521" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="2.8"
|
|
||||||
inkscape:cx="330.71429"
|
|
||||||
inkscape:cy="144.28571"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:window-width="3072"
|
|
||||||
inkscape:window-height="1659"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1" />
|
|
||||||
<metadata
|
|
||||||
id="metadata4326">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-67.741956,-463.35919)">
|
|
||||||
<g
|
|
||||||
transform="matrix(0.35596319,-0.1450925,0.14027908,0.34415419,-98.897559,452.82709)"
|
|
||||||
id="g4304"
|
|
||||||
style="display:inline">
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
|
||||||
id="path4286"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="czcc" />
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#000000"
|
|
||||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
|
||||||
id="path4283"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
|
||||||
<path
|
|
||||||
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
|
||||||
id="path4292"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="scccs" />
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
transform="scale(1,-1)"
|
|
||||||
y="-693.18524"
|
|
||||||
x="67.81031"
|
|
||||||
height="16.036251"
|
|
||||||
width="168.54825"
|
|
||||||
id="rect4136"
|
|
||||||
style="fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<g
|
|
||||||
transform="matrix(-0.36104723,0.13193379,-0.12755691,-0.34906957,644.73068,698.04111)"
|
|
||||||
id="g5701"
|
|
||||||
style="display:inline">
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
|
||||||
id="path5703"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="czcc" />
|
|
||||||
<path
|
|
||||||
style="display:inline;fill:#000000"
|
|
||||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
|
||||||
id="path5705"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
|
||||||
<path
|
|
||||||
style="fill:url(#linearGradient5721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
|
||||||
id="path5707"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="scccs" />
|
|
||||||
</g>
|
|
||||||
<rect
|
|
||||||
transform="scale(1,-1)"
|
|
||||||
y="-693.18524"
|
|
||||||
x="267.8103"
|
|
||||||
height="16.036251"
|
|
||||||
width="168.54825"
|
|
||||||
id="rect5709"
|
|
||||||
style="opacity:1;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<text
|
|
||||||
id="text5713"
|
|
||||||
y="559.10828"
|
|
||||||
x="296.20877"
|
|
||||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="559.10828"
|
|
||||||
x="296.20877"
|
|
||||||
id="tspan5715"
|
|
||||||
sodipodi:role="line"
|
|
||||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Eraser</tspan></text>
|
|
||||||
<text
|
|
||||||
id="text1"
|
|
||||||
y="559.10828"
|
|
||||||
x="109.0436"
|
|
||||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
y="559.10828"
|
|
||||||
x="109.0436"
|
|
||||||
id="tspan1"
|
|
||||||
sodipodi:role="line"
|
|
||||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Pen</tspan></text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 9.4 KiB |
|
|
@ -4,9 +4,9 @@
|
||||||
Switches
|
Switches
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
libinput supports the lid, tablet-mode, and keypad slide switches. Unlike
|
libinput supports the lid and tablet-mode switches. Unlike button events
|
||||||
button events that come in press and release pairs, switches are usually
|
that come in press and release pairs, switches are usually toggled once and
|
||||||
toggled once and left at the setting for an extended period of time.
|
left at the setting for an extended period of time.
|
||||||
|
|
||||||
Only some switches are handled by libinput, see **libinput_switch** for a
|
Only some switches are handled by libinput, see **libinput_switch** for a
|
||||||
list of supported switches. Switch events are exposed to the caller, but
|
list of supported switches. Switch events are exposed to the caller, but
|
||||||
|
|
@ -28,17 +28,15 @@ The evdev event code ``EV_SW`` ``SW_LID`` is provided as
|
||||||
the device is disabled while the lid is logically closed. This is to avoid
|
the device is disabled while the lid is logically closed. This is to avoid
|
||||||
ghost touches that can be caused by interference with touchpads and the
|
ghost touches that can be caused by interference with touchpads and the
|
||||||
closed lid. The touchpad is automatically re-enabled whenever the lid is
|
closed lid. The touchpad is automatically re-enabled whenever the lid is
|
||||||
opened.
|
openend.
|
||||||
|
|
||||||
This handling of lid switches is transparent to the user, no notifications
|
This handling of lid switches is transparent to the user, no notifications
|
||||||
are sent and the device appears as enabled at all times.
|
are sent and the device appears as enabled at all times.
|
||||||
|
|
||||||
On some devices, the device's lid state does not always reflect the physical
|
On some devices, the device's lid state does not always reflect the physical
|
||||||
state and the lid state may report as closed even when the lid is physically
|
state and the lid state may report as closed even when the lid is physicall
|
||||||
open. libinput employs some heuristics to detect user input (specifically
|
open. libinput employs some heuristics to detect user input (specificially
|
||||||
typing) to re-enable the touchpad on those devices. Where input is detected,
|
typing) to re-enable the touchpad on those devices.
|
||||||
libinput updates the lid status of the kernel device so other consumers of
|
|
||||||
the kernel events also get the accurate state.
|
|
||||||
|
|
||||||
.. _switches_tablet_mode:
|
.. _switches_tablet_mode:
|
||||||
|
|
||||||
|
|
@ -59,20 +57,3 @@ tablet mode is disengaged.
|
||||||
|
|
||||||
This handling of tablet mode switches is transparent to the user, no
|
This handling of tablet mode switches is transparent to the user, no
|
||||||
notifications are sent and the device appears as enabled at all times.
|
notifications are sent and the device appears as enabled at all times.
|
||||||
|
|
||||||
.. _switches_keypad_slide:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Keypad slide switch handling
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Where available, libinput listens to devices providing a keypad slide switch.
|
|
||||||
This is usually available on devices that have an always-attached physical
|
|
||||||
keyboard which can slide under the screen. An example of such a device is the
|
|
||||||
Nokia N900.
|
|
||||||
|
|
||||||
The event sent by the kernel is ``EV_SW`` ``SW_KEYPAD_SLIDE`` and is provided
|
|
||||||
as **LIBINPUT_SWITCH_KEYPAD_SLIDE**. The keypad slide switch does not cause any
|
|
||||||
other input devices to be enabled nor disabled in response, since on some
|
|
||||||
devices the kernel event is sent while the keyboard is partially visible and
|
|
||||||
thus usable.
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,6 @@ the ``libinput record`` tool.
|
||||||
- **resolution** indicates that the device does not have a resolution set
|
- **resolution** indicates that the device does not have a resolution set
|
||||||
for the x and y axes. This can be fixed with a hwdb entry, locate and read
|
for the x and y axes. This can be fixed with a hwdb entry, locate and read
|
||||||
the `60-evdev.hwdb
|
the `60-evdev.hwdb
|
||||||
<https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`__ file
|
<https://github.com/systemd/systemd/tree/master/hwdb/60-evdev.hwdb>`__ file
|
||||||
on your machine and file a pull request with the fixes against
|
on your machine and file a pull request with the fixes against
|
||||||
`systemd <https://github.com/systemd/systemd/>`__.
|
`systemd <https://github.com/systemd/systemd/>`__.
|
||||||
|
|
|
||||||
|
|
@ -180,8 +180,8 @@ specifically:
|
||||||
capable of detection distances,
|
capable of detection distances,
|
||||||
- pressure offset is only detected if the distance between the tool and the
|
- pressure offset is only detected if the distance between the tool and the
|
||||||
tablet is high enough,
|
tablet is high enough,
|
||||||
- pressure offset is only used if it is 50% or less of the pressure range
|
- pressure offset is only used if it is 20% or less of the pressure range
|
||||||
available to the tool. A pressure offset higher than 50% indicates either
|
available to the tool. A pressure offset higher than 20% indicates either
|
||||||
a misdetection or a tool that should be replaced, and
|
a misdetection or a tool that should be replaced, and
|
||||||
- if a pressure value less than the current pressure offset is seen, the
|
- if a pressure value less than the current pressure offset is seen, the
|
||||||
offset resets to that value.
|
offset resets to that value.
|
||||||
|
|
@ -189,52 +189,6 @@ specifically:
|
||||||
Pressure offsets are not detected on **LIBINPUT_TABLET_TOOL_TYPE_MOUSE**
|
Pressure offsets are not detected on **LIBINPUT_TABLET_TOOL_TYPE_MOUSE**
|
||||||
and **LIBINPUT_TABLET_TOOL_TYPE_LENS** tools.
|
and **LIBINPUT_TABLET_TOOL_TYPE_LENS** tools.
|
||||||
|
|
||||||
|
|
||||||
.. _tablet-pressure-range:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Custom tablet tool pressure ranges
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On tablets supporting pressure, libinput provides that hardware pressure as
|
|
||||||
a logical range of ``0.0`` up to ``1.0`` for the maximum supported pressure.
|
|
||||||
By default, the hardware range thus maps into the following logical range::
|
|
||||||
|
|
||||||
|
|
||||||
hw minimum hw maximum
|
|
||||||
hw range: |------|-----------------------------------|
|
|
||||||
logical range: |----|-----------------------------------|
|
|
||||||
0.0 | 1.0
|
|
||||||
Tip
|
|
||||||
|
|
||||||
Note that libinput always has some built-in thresholds to filter out erroneous
|
|
||||||
touches with near-zero pressure but otherwise the hardware range maps as-is
|
|
||||||
into the logical range. The :ref:`tip event <tablet-tip>` threshold is defined
|
|
||||||
within this range.
|
|
||||||
|
|
||||||
For some use-cases the full hardware range is not suitable, it may require either
|
|
||||||
too light a pressure for the user to interact or it may require too hard a
|
|
||||||
pressure before the logical maximum is reached. libinput provides
|
|
||||||
the **libinput_tablet_tool_config_pressure_range_set()** function that allows
|
|
||||||
reducing the usable range of the tablet::
|
|
||||||
|
|
||||||
hw minimum hw maximum
|
|
||||||
hw range: |----------|-------------------------------|
|
|
||||||
adjusted range: |------|---------------------|
|
|
||||||
logical range: |----|---------------------|
|
|
||||||
0.0 | 1.0
|
|
||||||
Tip
|
|
||||||
|
|
||||||
A reduced range as shown above will result in
|
|
||||||
|
|
||||||
- all hw pressure below the new minimum to register as logical pressure ``0.0``
|
|
||||||
- all hw pressure above the new maximum to register as logical pressure ``1.0``
|
|
||||||
- the tip event threshold to be relative to the new minimum
|
|
||||||
|
|
||||||
In other words, adjusting the pressure range of a tablet tool is equivalent to
|
|
||||||
reducing the hardware range of said tool. Note that where a custom pressure
|
|
||||||
range is set, detection of :ref:`tablet-pressure-offset` is disabled.
|
|
||||||
|
|
||||||
.. _tablet-serial-numbers:
|
.. _tablet-serial-numbers:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -468,77 +422,3 @@ libinput uses the **libinput_device_group** to decide on touch arbitration
|
||||||
and automatically discards touch events whenever a tool is in proximity.
|
and automatically discards touch events whenever a tool is in proximity.
|
||||||
The exact behavior is device-dependent.
|
The exact behavior is device-dependent.
|
||||||
|
|
||||||
.. _tablet-area:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet area
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
External tablet devices such as e.g. the Wacom Intuos series can be configured
|
|
||||||
to reduce the available logical input area. Typically the logical input area
|
|
||||||
is equivalent to the physical input area but it can be reduced with the
|
|
||||||
**libinput_device_config_area_set_rectangle()** call. Once reduced, input
|
|
||||||
events outside the logical input area are ignored and the logical input area
|
|
||||||
acts as if it represented the extents of the physical tablet.
|
|
||||||
|
|
||||||
.. figure:: tablet-area.svg
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
Tablet area configuration example
|
|
||||||
|
|
||||||
In the image above, the area is set to the rectangle 0.25/0.25 to 0.5/0.75.
|
|
||||||
Even though the tool is roughly at the physical position ``0.5 * width`` and
|
|
||||||
``0.75 * height``, the return values of
|
|
||||||
**libinput_event_tablet_tool_get_x_transformed()** and
|
|
||||||
**libinput_event_tablet_tool_get_y_transformed()** would be close to the
|
|
||||||
maximum provided in this call.
|
|
||||||
|
|
||||||
The size of the tablet reported by **libinput_device_get_size()** always reflects
|
|
||||||
the physical area, not the logical area.
|
|
||||||
|
|
||||||
.. _tablet-eraser-button:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet eraser buttons
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Tablet tools come in a variety of forms but the most common one is a
|
|
||||||
pen-like tool. Some of these pen-like tools have a virtual eraser at the
|
|
||||||
tip of the tool - inverting the tool brings the eraser into proximity.
|
|
||||||
|
|
||||||
.. figure:: tablet-eraser-invert.svg
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
An pen-like tool used as pen and as eraser by inverting it
|
|
||||||
|
|
||||||
Having an eraser as a separate tool is beneficial in many applications as the
|
|
||||||
eraser tool can be assigned different functionality (colors, paint tools, etc.)
|
|
||||||
that is easily available.
|
|
||||||
|
|
||||||
However, a large proportion of tablet pens have an "eraser button". By
|
|
||||||
pressing the button the pen switches to be an eraser tool.
|
|
||||||
On the data level this is not done via a button event, instead the firmware
|
|
||||||
will pretend the pen tool going out of proximity and the eraser coming
|
|
||||||
into proximity immediately after - as if the tool was physically inverted.
|
|
||||||
|
|
||||||
.. figure:: tablet-eraser-button.svg
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
An pen-like tool used as pen and as eraser by pressing the eraser button
|
|
||||||
|
|
||||||
Microsoft mandates this behavior (see
|
|
||||||
`Windows Pen States <https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states>`_
|
|
||||||
for details) and thus the overwhelming majority of devices will have
|
|
||||||
an eraser button that virtually inverts the pen.
|
|
||||||
|
|
||||||
Enforcing an eraser button means that users have one button less on the
|
|
||||||
stylus that they would have otherwise. For some users the eraser button
|
|
||||||
is in an inconvenient location, others don't want an eraser button at all.
|
|
||||||
|
|
||||||
libinput provides an eraser button configuration that allows disabling the
|
|
||||||
eraser button and turning it into a normal button event. If the eraser button
|
|
||||||
is disabled, pressing that button will generate a normal tablet tool button
|
|
||||||
event.
|
|
||||||
|
|
||||||
This configuration is only available on pens with an eraser button, not on
|
|
||||||
with an invert-type eraser.
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,12 @@ Tap-to-click behaviour
|
||||||
finger touch down/up sequence maps into a button click. This is most
|
finger touch down/up sequence maps into a button click. This is most
|
||||||
commonly used on touchpads, but may be available on other devices.
|
commonly used on touchpads, but may be available on other devices.
|
||||||
|
|
||||||
libinput implements tapping for one, two, and three fingers, where supported by
|
libinput implements tapping for one, two, and three fingers, where supported
|
||||||
the hardware, and maps those taps into a left, right, and middle button click,
|
by the hardware, and maps those taps into a left, right, and middle button
|
||||||
respectively. This mapping can be switched to left, middle and right through
|
click, respectively. Not all devices support three fingers, libinput will
|
||||||
configuration. Not all devices support three fingers, libinput will support
|
support tapping up to whatever is supported by the hardware. libinput does
|
||||||
tapping up to whatever is supported by the hardware. libinput does not support
|
not support four-finger taps or any tapping with more than four fingers,
|
||||||
four-finger taps or any tapping with more than four fingers, even though some
|
even though some hardware can distinguish between that many fingers.
|
||||||
hardware can distinguish between that many fingers.
|
|
||||||
|
|
||||||
.. _tapping_default:
|
.. _tapping_default:
|
||||||
|
|
||||||
|
|
@ -34,10 +33,6 @@ Tapping is **enabled** by default on devices where tapping is the only
|
||||||
method to trigger button clicks. This includes devices without physical
|
method to trigger button clicks. This includes devices without physical
|
||||||
buttons such as touch-capable graphics tablets.
|
buttons such as touch-capable graphics tablets.
|
||||||
|
|
||||||
.. note:: Unfortunately due to the current API design, devices that require
|
|
||||||
tapping effectively prevent us from changing this default. For details see
|
|
||||||
`this comment <https://gitlab.freedesktop.org/libinput/libinput/-/issues/926#note_2056476>`_.
|
|
||||||
|
|
||||||
Tapping can be enabled/disabled on a per-device basis. See
|
Tapping can be enabled/disabled on a per-device basis. See
|
||||||
**libinput_device_config_tap_set_enabled()** for details.
|
**libinput_device_config_tap_set_enabled()** for details.
|
||||||
|
|
||||||
|
|
@ -54,19 +49,12 @@ Tap-and-drag is optional and can be enabled or disabled with
|
||||||
**libinput_device_config_tap_set_drag_enabled()**. Most devices have
|
**libinput_device_config_tap_set_drag_enabled()**. Most devices have
|
||||||
tap-and-drag enabled by default.
|
tap-and-drag enabled by default.
|
||||||
|
|
||||||
.. note:: Dragging is always done with one finger. The number of fingers on
|
|
||||||
the initial tap decide the type of button click. For example, to
|
|
||||||
middle-click drag, tap with three fingers followed by a
|
|
||||||
single-finger drag.
|
|
||||||
|
|
||||||
Also optional is a feature called "drag lock". With drag lock disabled, lifting
|
Also optional is a feature called "drag lock". With drag lock disabled, lifting
|
||||||
the finger will stop any drag process. When enabled, the drag
|
the finger will stop any drag process. When enabled, libinput will ignore a
|
||||||
process continues even after lifting a finger but can be ended
|
finger up event during a drag process, provided the finger is set down again
|
||||||
with an additional tap. If timeout-based drag-locks are enabled
|
within a implementation-specific timeout. Drag lock can be enabled and
|
||||||
the drag process will also automatically end once the finger has
|
disabled with **libinput_device_config_tap_set_drag_lock_enabled()**.
|
||||||
been lifted for an implementation-specific timeout. Drag lock can be
|
Note that drag lock only applies if tap-and-drag is be enabled.
|
||||||
enabled and disabled with **libinput_device_config_tap_set_drag_lock_enabled()**.
|
|
||||||
Note that drag lock only applies if tap-and-drag is enabled.
|
|
||||||
|
|
||||||
.. figure:: tap-n-drag.svg
|
.. figure:: tap-n-drag.svg
|
||||||
:align: center
|
:align: center
|
||||||
|
|
@ -84,9 +72,6 @@ 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,
|
release (e) is triggered by a timeout. To release the button immediately,
|
||||||
simply tap again (f).
|
simply tap again (f).
|
||||||
|
|
||||||
If drag lock is enabled in sticky mode there is no timeout after
|
|
||||||
releasing a finger and an extra tap is required to release the button.
|
|
||||||
|
|
||||||
If two fingers are supported by the hardware, a second finger can be used to
|
If two fingers are supported by the hardware, a second finger can be used to
|
||||||
drag while the first is held in-place.
|
drag while the first is held in-place.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ must pass for any merge request. These tests are invoked by calling
|
||||||
``meson test -C builddir`` (or ``ninja test``). The ``libinput-test-suite`` is
|
``meson test -C builddir`` (or ``ninja test``). The ``libinput-test-suite`` is
|
||||||
part of that test set by default.
|
part of that test set by default.
|
||||||
|
|
||||||
The upstream CI runs all these tests and is run for every merge request.
|
The upstream CI runs all these tests but not the ``libinput-test-suite``.
|
||||||
|
This CI is run for every merge request.
|
||||||
|
|
||||||
.. _test-job-control:
|
.. _test-job-control:
|
||||||
|
|
||||||
|
|
@ -207,7 +208,7 @@ verification of distribution composes.
|
||||||
To configure libinput to install the tests, use the ``-Dinstall-tests=true``
|
To configure libinput to install the tests, use the ``-Dinstall-tests=true``
|
||||||
meson option::
|
meson option::
|
||||||
|
|
||||||
$ meson setup builddir -Dtests=true -Dinstall-tests=true <other options>
|
$ meson builddir -Dtests=true -Dinstall-tests=true <other options>
|
||||||
|
|
||||||
.. _test-meson-suites:
|
.. _test-meson-suites:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,5 +42,3 @@ Once the timeout expires at t4, libinput generates an event of
|
||||||
|
|
||||||
Thus, the caller gets events with timestamps in the order t3, t1, t2,
|
Thus, the caller gets events with timestamps in the order t3, t1, t2,
|
||||||
despite t3 > t2 > t1.
|
despite t3 > t2 > t1.
|
||||||
|
|
||||||
libinput timestamps use **CLOCK_MONOTONIC**.
|
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ available in the **libinput(1)** man page.
|
||||||
|
|
||||||
The most common tools used are:
|
The most common tools used are:
|
||||||
|
|
||||||
- ``libinput list-devices``: to list locally available devices as seen by libinput,
|
- ``libinput list-devices``: to list locally available devices,
|
||||||
see :ref:`here <libinput-list-devices>`
|
see :ref:`here <libinput-list-devices>`
|
||||||
- ``libinput list-kernel-devices``: to list locally available devices as seen by the kernel,
|
|
||||||
see :ref:`here <libinput-list-kernel-devices>`
|
|
||||||
- ``libinput debug-events``: to monitor and debug events,
|
- ``libinput debug-events``: to monitor and debug events,
|
||||||
see :ref:`here <libinput-debug-events>`
|
see :ref:`here <libinput-debug-events>`
|
||||||
- ``libinput debug-gui``: to visualize events,
|
- ``libinput debug-gui``: to visualize events,
|
||||||
|
|
@ -23,8 +21,6 @@ The most common tools used are:
|
||||||
see :ref:`here <libinput-record>`
|
see :ref:`here <libinput-record>`
|
||||||
- ``libinput measure``: measure properties on a kernel device,
|
- ``libinput measure``: measure properties on a kernel device,
|
||||||
see :ref:`here <libinput-measure>`
|
see :ref:`here <libinput-measure>`
|
||||||
- ``libinput analyze``: analyse event recordings from a kernel device,
|
|
||||||
see :ref:`here <libinput-analyze>`
|
|
||||||
- ``libinput quirks``: show quirks assigned to a device, see
|
- ``libinput quirks``: show quirks assigned to a device, see
|
||||||
:ref:`here <libinput-quirks>`
|
:ref:`here <libinput-quirks>`
|
||||||
|
|
||||||
|
|
@ -75,55 +71,6 @@ binary state all available options are listed, with the default one prefixed
|
||||||
with an asterisk (``*``). In the example above, the default click method is
|
with an asterisk (``*``). In the example above, the default click method is
|
||||||
button-areas but clickfinger is available.
|
button-areas but clickfinger is available.
|
||||||
|
|
||||||
.. note:: This tool is intended for human-consumption and may change its output
|
|
||||||
at any time.
|
|
||||||
|
|
||||||
.. _libinput-list-kernel-devices:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
libinput list-kernel-devices
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The ``libinput list-kernel-devices`` command shows the devices known by **the
|
|
||||||
kernel**. This command can help identify issues when a device is not handled by
|
|
||||||
libinput.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ libinput list-kernel-devices
|
|
||||||
/dev/input/event0: Sleep Button
|
|
||||||
/dev/input/event1: Power Button
|
|
||||||
/dev/input/event2: Power Button
|
|
||||||
/dev/input/event3: Microsoft Microsoft® 2.4GHz Transceiver v9.0
|
|
||||||
/dev/input/event4: Microsoft Microsoft® 2.4GHz Transceiver v9.0 Mouse
|
|
||||||
[...]
|
|
||||||
|
|
||||||
|
|
||||||
In some cases, knowing about the HID devices behind the kernel's event nodes
|
|
||||||
can be useful. To list HID devices, supply the ``--hid`` commandline flag:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ libinput list-kernel-devices --hid
|
|
||||||
hid:
|
|
||||||
- name: 'Logitech Gaming Mouse G303'
|
|
||||||
id: '046d:c080'
|
|
||||||
driver: 'hid-generic'
|
|
||||||
hidraw: ['/dev/hidraw6']
|
|
||||||
evdev: ['/dev/input/event13']
|
|
||||||
|
|
||||||
- name: 'Logitech Gaming Mouse G303'
|
|
||||||
id: '046d:c080'
|
|
||||||
driver: 'hid-generic'
|
|
||||||
hidraw: ['/dev/hidraw7']
|
|
||||||
evdev: ['/dev/input/event14']
|
|
||||||
|
|
||||||
- name: 'Microsoft Microsoft® 2.4GHz Transceiver v9.0'
|
|
||||||
id: '045e:07a5'
|
|
||||||
driver: 'hid-generic'
|
|
||||||
hidraw: ['/dev/hidraw0']
|
|
||||||
evdev: ['/dev/input/event3']
|
|
||||||
|
|
||||||
.. note:: This tool is intended for human-consumption and may change its output
|
.. note:: This tool is intended for human-consumption and may change its output
|
||||||
at any time.
|
at any time.
|
||||||
|
|
||||||
|
|
@ -355,19 +302,6 @@ thing and one thing only and their usage is highly specific to the tool.
|
||||||
Please see the **libinput-measure(1)** man page for information about what
|
Please see the **libinput-measure(1)** man page for information about what
|
||||||
tools are available and the man page for each respective tool.
|
tools are available and the man page for each respective tool.
|
||||||
|
|
||||||
.. _libinput-analyze:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Analyzing device events with libinput analyze
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The ``libinput analyze`` tool is a multiplexer for various sub-tools that
|
|
||||||
can analyze input events previously recorded from a device.
|
|
||||||
|
|
||||||
Please see the **libinput-analyze(1)** man page for information about what
|
|
||||||
tools are available and the man page for each respective too.
|
|
||||||
|
|
||||||
|
|
||||||
.. _libinput-quirks:
|
.. _libinput-quirks:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -377,7 +311,7 @@ Listing quirks assigned to a device
|
||||||
The ``libinput quirks`` tool can show quirks applied for any given device. ::
|
The ``libinput quirks`` tool can show quirks applied for any given device. ::
|
||||||
|
|
||||||
$ libinput quirks list /dev/input/event0
|
$ libinput quirks list /dev/input/event0
|
||||||
AttrLidSwitchReliability=unreliable
|
AttrLidSwitchReliability=reliable
|
||||||
|
|
||||||
If the tool's output is empty, no quirk is applied. See :ref:`device-quirks`
|
If the tool's output is empty, no quirk is applied. See :ref:`device-quirks`
|
||||||
for more information.
|
for more information.
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,10 @@ position.
|
||||||
When libinput detects a cursor jump it prints a bug warning to the log with
|
When libinput detects a cursor jump it prints a bug warning to the log with
|
||||||
the text **"Touch jump detected and discarded."** and a link to this page.
|
the text **"Touch jump detected and discarded."** and a link to this page.
|
||||||
|
|
||||||
.. note:: This warning is ratelimited and will stop appearing after a few
|
In most cases, this is a bug in the kernel driver and to libinput it appears
|
||||||
times, even if the touchpad jumps continue.
|
that the touch point moves from its previous position. The pointer jump can
|
||||||
|
usually be seen in the :ref:`libinput record <libinput-record>` output for the device:
|
||||||
|
|
||||||
In most cases, this is a bug in the firmware (or 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 :ref:`libinput record
|
|
||||||
<libinput-record>` output for the device:
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -53,28 +50,9 @@ The pointer jump can usually be seen in the :ref:`libinput record
|
||||||
In this recording, the pointer jumps from its position 3752/2216 to
|
In this recording, the pointer jumps from its position 3752/2216 to
|
||||||
1640/4681 within a single frame. On this particular touchpad, this would
|
1640/4681 within a single frame. On this particular touchpad, this would
|
||||||
represent a physical move of almost 50mm. libinput detects some of these
|
represent a physical move of almost 50mm. libinput detects some of these
|
||||||
jumps and discards the movement but otherwise continues as usual.
|
jumps and discards the movement but otherwise continues as usual. However,
|
||||||
If your only encounter with these jumps is the warning printed to the log,
|
the bug should be fixed at the kernel level.
|
||||||
libinput functions as intended.
|
|
||||||
|
|
||||||
When you encounter the warning in the log, please generate a recording of
|
When you encounter the warning in the log, please generate a recording of
|
||||||
your touchpad with :ref:`libinput record <libinput-record>` and file a bug.
|
your touchpad with :ref:`libinput record <libinput-record>` and file a bug.
|
||||||
See :ref:`reporting_bugs` for more details.
|
See :ref:`reporting_bugs` for more details.
|
||||||
|
|
||||||
Note that it most cases, libinput cannot actually fix the issue. Filing a
|
|
||||||
bug is useful to figure out if there are other factors at play or whether
|
|
||||||
there are heuristics we can employ to reduce the impact.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AlpsPS/2 ALPS DualPoint TouchPad jumping to 4095/0
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A special case of pointer jumps happens on ``AlpsPS/2 ALPS DualPoint TouchPad``
|
|
||||||
devices found in the Lenovo ThinkPad E465 and E550 and likely others with
|
|
||||||
the same touchpad hardware. On those devices, the touchpad occasionally
|
|
||||||
sends an event for the second finger to move to position 4095/0 before
|
|
||||||
moving back to the original position. libinput detects this movement and
|
|
||||||
removes it but depending on the interaction this may cause a smaller jump
|
|
||||||
later when the coordinates reset to the new position of the finger.
|
|
||||||
|
|
||||||
Some more information is available in `Gitlab Issue #492 <https://gitlab.freedesktop.org/libinput/libinput/-/issues/492>`__.
|
|
||||||
|
|
|
||||||
|
|
@ -38,53 +38,30 @@ statistics, including whether a touch is/was considered logically down.
|
||||||
|
|
||||||
Example output of the tool is below: ::
|
Example output of the tool is below: ::
|
||||||
|
|
||||||
$ sudo libinput measure touchpad-pressure
|
$ sudo libinput measure touchpad-pressure
|
||||||
Using Synaptics TM2668-002: /dev/input/event21
|
Ready for recording data.
|
||||||
|
Pressure range used: 8:10
|
||||||
This is an interactive tool
|
Palm pressure range used: 65535
|
||||||
|
Place a single finger on the touchpad to measure pressure values.
|
||||||
Place a single finger on the touchpad to measure pressure values.
|
Ctrl+C to exit
|
||||||
Check that:
|
|
||||||
- touches subjectively perceived as down are tagged as down
|
Sequence 1190 pressure: min: 39 max: 48 avg: 43 median: 44 tags: down
|
||||||
- touches with a thumb are tagged as thumb
|
Sequence 1191 pressure: min: 49 max: 65 avg: 62 median: 64 tags: down
|
||||||
- touches with a palm are tagged as palm
|
Sequence 1192 pressure: min: 40 max: 78 avg: 64 median: 66 tags: down
|
||||||
|
Sequence 1193 pressure: min: 36 max: 83 avg: 70 median: 73 tags: down
|
||||||
If the touch states do not match the interaction, re-run
|
Sequence 1194 pressure: min: 43 max: 76 avg: 72 median: 74 tags: down
|
||||||
with --touch-thresholds=down:up using observed pressure values.
|
Touchpad pressure: 47 min: 47 max: 86 tags: down
|
||||||
See --help for more options.
|
|
||||||
|
|
||||||
Interactive keys:
|
|
||||||
q/a - decrease/increase down threshold
|
|
||||||
w/s - decrease/increase up threshold
|
|
||||||
e/d - decrease/increase palm threshold
|
|
||||||
r/f - decrease/increase thumb threshold
|
|
||||||
|
|
||||||
Press Ctrl+C to exit
|
|
||||||
|
|
||||||
┌───────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ Touch │ down │ up │ palm │ thumb │ min │ max │ p │ avg │ median │
|
|
||||||
├───────────────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ 178 │ x │ x │ │ │ 75 │ 75 │ 0 │ 75 │ 75 │
|
|
||||||
│ 179 │ x │ x │ │ │ 35 │ 88 │ 0 │ 77 │ 81 │
|
|
||||||
│ 180 │ x │ x │ │ x │ 65 │ 113 │ 0 │ 98 │ 98 │
|
|
||||||
│ 181 │ x │ x │ │ x │ 50 │ 101 │ 0 │ 86 │ 90 │
|
|
||||||
│ 182 │ x │ x │ │ │ 40 │ 80 │ 0 │ 66 │ 70 │
|
|
||||||
│ 183 │ x │ │ │ │ 43 │ 78 │ 78 │ │
|
|
||||||
│ Thresh │ 70 │ 60 │ 130 │ 100 │
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
The example output shows five completed touch sequences and one ongoing one.
|
The example output shows five completed touch sequences and one ongoing one.
|
||||||
For each, the respective minimum and maximum pressure values are printed as
|
For each, the respective minimum and maximum pressure values are printed as
|
||||||
well as some statistics. The ``down`` column show that each sequence was
|
well as some statistics. The ``tags`` show that sequence was considered
|
||||||
considered logically down at some point (see the threholds in the last line),
|
logically down at some point. This is an interactive tool and its output may
|
||||||
two of the sequences were considered thumbs. This is an interactive tool and
|
change frequently. Refer to the <i>libinput-measure-touchpad-pressure(1)</i> man
|
||||||
its output may change frequently. Refer to the
|
page for more details.
|
||||||
**libinput-measure-touchpad-pressure(1)** man page for more details.
|
|
||||||
|
|
||||||
By default, this tool uses the :ref:`device-quirks` for the pressure range. To
|
By default, this tool uses the :ref:`device-quirks` for the pressure range. To
|
||||||
narrow down on the best values for your device, adjust the thresholds using
|
narrow down on the best values for your device, specify the 'logically down'
|
||||||
the keys q/a, w/s, e/d and r/f or specify the 'logically down'
|
|
||||||
and 'logically up' pressure thresholds with the ``--touch-thresholds``
|
and 'logically up' pressure thresholds with the ``--touch-thresholds``
|
||||||
argument: ::
|
argument: ::
|
||||||
|
|
||||||
|
|
@ -107,10 +84,8 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
|
||||||
[Touchpad pressure override]
|
[Touchpad pressure override]
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchName=*SynPS/2 Synaptics TouchPad
|
MatchName=*SynPS/2 Synaptics TouchPad
|
||||||
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
|
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
|
||||||
AttrPressureRange=10:8
|
AttrPressureRange=10:8
|
||||||
AttrPalmPressureThreshold=150
|
|
||||||
AttrThumbPressureThreshold=100
|
|
||||||
|
|
||||||
The file name **must** be ``/etc/libinput/local-overrides.quirks``. The
|
The file name **must** be ``/etc/libinput/local-overrides.quirks``. The
|
||||||
The first line is the section name and can be free-form. The ``Match``
|
The first line is the section name and can be free-form. The ``Match``
|
||||||
|
|
@ -124,7 +99,7 @@ and product name (pn).
|
||||||
Once in place, run the following command to verify the quirk is valid and
|
Once in place, run the following command to verify the quirk is valid and
|
||||||
works for your device: ::
|
works for your device: ::
|
||||||
|
|
||||||
$ sudo libinput quirks list /dev/input/event10
|
$ sudo libinput list-quirks /dev/input/event10
|
||||||
AttrPressureRange=10:8
|
AttrPressureRange=10:8
|
||||||
|
|
||||||
Replace the event node with the one from your device. If the
|
Replace the event node with the one from your device. If the
|
||||||
|
|
@ -182,7 +157,7 @@ The example output shows five completed touch sequences. For each, the
|
||||||
respective minimum and maximum pressure values are printed as well as some
|
respective minimum and maximum pressure values are printed as well as some
|
||||||
statistics. The ``down`` and ``palm`` tags show that sequence was considered
|
statistics. The ``down`` and ``palm`` tags show that sequence was considered
|
||||||
logically down or a palm at some point. This is an interactive tool and its
|
logically down or a palm at some point. This is an interactive tool and its
|
||||||
output may change frequently. Refer to the **libinput-measure-touch-size(1)** man
|
output may change frequently. Refer to the <i>libinput-measure-touch-size(1)</i> man
|
||||||
page for more details.
|
page for more details.
|
||||||
|
|
||||||
By default, this tool uses the :ref:`device-quirks` for the touch size range. To
|
By default, this tool uses the :ref:`device-quirks` for the touch size range. To
|
||||||
|
|
@ -206,7 +181,7 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
|
||||||
[Touchpad touch size override]
|
[Touchpad touch size override]
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchName=*SynPS/2 Synaptics TouchPad
|
MatchName=*SynPS/2 Synaptics TouchPad
|
||||||
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
|
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
|
||||||
AttrTouchSizeRange=10:8
|
AttrTouchSizeRange=10:8
|
||||||
|
|
||||||
The first line is the match line and should be adjusted for the device name
|
The first line is the match line and should be adjusted for the device name
|
||||||
|
|
@ -218,7 +193,7 @@ and product name (pn).
|
||||||
Once in place, run the following command to verify the quirk is valid and
|
Once in place, run the following command to verify the quirk is valid and
|
||||||
works for your device: ::
|
works for your device: ::
|
||||||
|
|
||||||
$ sudo libinput quirks list /dev/input/event10
|
$ sudo libinput list-quirks /dev/input/event10
|
||||||
AttrTouchSizeRange=10:8
|
AttrTouchSizeRange=10:8
|
||||||
|
|
||||||
Replace the event node with the one from your device. If the
|
Replace the event node with the one from your device. If the
|
||||||
|
|
@ -232,3 +207,4 @@ the need for a restart.
|
||||||
|
|
||||||
Once the touch size ranges are deemed correct, :ref:`reporting_bugs` "report a
|
Once the touch size ranges are deemed correct, :ref:`reporting_bugs` "report a
|
||||||
bug" to get the thresholds into the repository.
|
bug" to get the thresholds into the repository.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,3 +56,4 @@ these axes are supposed to be mapped, few devices forward reliable
|
||||||
information. libinput uses these values together with a device-specific
|
information. libinput uses these values together with a device-specific
|
||||||
:ref:`device-quirks` entry. In other words, touch size detection does not work
|
:ref:`device-quirks` entry. In other words, touch size detection does not work
|
||||||
unless a device quirk is present for the device.
|
unless a device quirk is present for the device.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ other properties.
|
||||||
Number of buttons
|
Number of buttons
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
.. _touchpads_buttons_phys:
|
.. _touchapds_buttons_phys:
|
||||||
|
|
||||||
..............................................................................
|
..............................................................................
|
||||||
Physically separate buttons
|
Physically separate buttons
|
||||||
|
|
@ -57,7 +57,7 @@ property.
|
||||||
.. _touchpads_buttons_forcepads:
|
.. _touchpads_buttons_forcepads:
|
||||||
|
|
||||||
..............................................................................
|
..............................................................................
|
||||||
Forcepads/Pressurepads
|
Forcepads
|
||||||
..............................................................................
|
..............................................................................
|
||||||
|
|
||||||
Forcepads are Clickpads without a physical button underneath the hardware.
|
Forcepads are Clickpads without a physical button underneath the hardware.
|
||||||
|
|
@ -65,7 +65,6 @@ They provide pressure and may have a vibration element that is
|
||||||
software-controlled. This element can simulate the feel of a physical
|
software-controlled. This element can simulate the feel of a physical
|
||||||
click or be co-opted for other tasks.
|
click or be co-opted for other tasks.
|
||||||
|
|
||||||
Forcepads are also called pressurepads or haptic touchpads.
|
|
||||||
|
|
||||||
.. _touchpads_touch:
|
.. _touchpads_touch:
|
||||||
|
|
||||||
|
|
@ -80,7 +79,7 @@ device can **track**, i.e. provide reliable positional information for.
|
||||||
In the kernel each finger is tracked in a so-called "slot", the number of
|
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.
|
slots thus equals the number of simultaneous touches a device can track.
|
||||||
|
|
||||||
.. _touchpads_touch_st:
|
.. _touchapds_touch_st:
|
||||||
|
|
||||||
..............................................................................
|
..............................................................................
|
||||||
Single-touch touchpads
|
Single-touch touchpads
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ User-specific preferences can be adjusted with the
|
||||||
The magic trackpoint multiplier
|
The magic trackpoint multiplier
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
To accommodate for the wildly different input data on trackpoint, libinput
|
To accomodate for the wildly different input data on trackpoint, libinput
|
||||||
uses a multiplier that is applied to input deltas. Trackpoints that send
|
uses a multiplier that is applied to input deltas. Trackpoints that send
|
||||||
comparatively high deltas can be "slowed down", trackpoints that send low
|
comparatively high deltas can be "slowed down", trackpoints that send low
|
||||||
deltas can be "sped up" to match the expected range. The actual acceleration
|
deltas can be "sped up" to match the expected range. The actual acceleration
|
||||||
|
|
@ -78,7 +78,7 @@ installed.
|
||||||
$ cd path/to/libinput.git
|
$ cd path/to/libinput.git
|
||||||
|
|
||||||
# Use an approximate multiplier in the quirks file
|
# Use an approximate multiplier in the quirks file
|
||||||
$ cat > quirks/99-trackpoint-override.quirks <<EOF
|
$ cat > quirks/99-trackpont-override.quirks <<EOF
|
||||||
[Trackpoint Override]
|
[Trackpoint Override]
|
||||||
MatchUdevType=pointingstick
|
MatchUdevType=pointingstick
|
||||||
AttrTrackpointMultiplier=1.0
|
AttrTrackpointMultiplier=1.0
|
||||||
|
|
@ -131,7 +131,7 @@ variation of the following is sufficient:
|
||||||
[Trackpoint Override]
|
[Trackpoint Override]
|
||||||
MatchUdevType=pointingstick
|
MatchUdevType=pointingstick
|
||||||
MatchName=*TPPS/2 IBM TrackPoint*
|
MatchName=*TPPS/2 IBM TrackPoint*
|
||||||
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT440p:*
|
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p*
|
||||||
AttrTrackpointMultiplier=1.0
|
AttrTrackpointMultiplier=1.0
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -152,3 +152,4 @@ has been removed. See :ref:`trackpoint_multiplier` for versions 1.12.x and later
|
||||||
|
|
||||||
If using libinput version 1.11.x or earlier, please see
|
If using libinput version 1.11.x or earlier, please see
|
||||||
`the 1.11.0 documentation <https://wayland.freedesktop.org/libinput/doc/1.11.0/trackpoints.html#trackpoint_range_measure>`_
|
`the 1.11.0 documentation <https://wayland.freedesktop.org/libinput/doc/1.11.0/trackpoints.html#trackpoint_range_measure>`_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Trackpoints and Pointing Sticks
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
This page provides an overview of trackpoint handling in libinput, also
|
This page provides an overview of trackpoint handling in libinput, also
|
||||||
referred to as Pointing Stick or Trackstick. The device itself is usually a
|
refered to as Pointing Stick or Trackstick. The device itself is usually a
|
||||||
round plastic stick between the G, H and B keys with a set of buttons below
|
round plastic stick between the G, H and B keys with a set of buttons below
|
||||||
the space bar.
|
the space bar.
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ decreases, the delta decrease first, then the reporting rate until the
|
||||||
trackpoint is in a neutral state and no events are reported. Trackpoint data
|
trackpoint is in a neutral state and no events are reported. Trackpoint data
|
||||||
is hard to generalize, see
|
is hard to generalize, see
|
||||||
`Observations on trackpoint input data
|
`Observations on trackpoint input data
|
||||||
<https://who-t.blogspot.com/2018/06/observations-on-trackpoint-input-data.html>`_
|
<a href="https://who-t.blogspot.com/2018/06/observations-on-trackpoint-input-data.html">`_
|
||||||
for more details.
|
for more details.
|
||||||
|
|
||||||
.. figure:: trackpoint-delta-illustration.svg
|
.. figure:: trackpoint-delta-illustration.svg
|
||||||
|
|
@ -65,3 +65,4 @@ sufficient pressure to even get close to the maximum ranges.
|
||||||
|
|
||||||
libinput provides a :ref:`Magic Trackpoint Multiplier
|
libinput provides a :ref:`Magic Trackpoint Multiplier
|
||||||
<trackpoint_multiplier>` to normalize the trackpoint input data.
|
<trackpoint_multiplier>` to normalize the trackpoint input data.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,3 @@ Troubleshooting
|
||||||
touchpad-pressure-debugging.rst
|
touchpad-pressure-debugging.rst
|
||||||
trackpoint-configuration.rst
|
trackpoint-configuration.rst
|
||||||
tablet-debugging.rst
|
tablet-debugging.rst
|
||||||
incorrectly-enabled-hires.rst
|
|
||||||
clickpad-with-right-button.rst
|
|
||||||
ignoring-devices.rst
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ Handled device types
|
||||||
- Mice
|
- Mice
|
||||||
- Keyboards
|
- Keyboards
|
||||||
- Virtual absolute pointing devices such as those used by QEMU or VirtualBox
|
- Virtual absolute pointing devices such as those used by QEMU or VirtualBox
|
||||||
- Switches (Lid Switch, Tablet Mode switch, and Keypad Slide switch)
|
- Switches (Lid Switch and Tablet Mode switch)
|
||||||
- Graphics tablets
|
- Graphics tablets
|
||||||
- :ref:`Trackpoints`
|
- :ref:`Trackpoints`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
||||||
.. _wheel_scrolling:
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Wheel scrolling
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
libinput provides two events to handle wheel scrolling:
|
|
||||||
|
|
||||||
- ``LIBINPUT_EVENT_POINTER_AXIS`` events are sent for regular wheel clicks,
|
|
||||||
usually those representing one detent on the device. These wheel clicks
|
|
||||||
usually require a rotation of 15 or 20 degrees.
|
|
||||||
**This event is deprecated as of libinput 1.19.**
|
|
||||||
|
|
||||||
- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` events are sent for regular and/or
|
|
||||||
high resolution wheel movements. High-resolution events are often 4 or 8
|
|
||||||
times more frequent than wheel clicks and require the device to be switched
|
|
||||||
into high-resolution mode (Linux kernel 5.0 and later). Where
|
|
||||||
high-resolution wheels are not provided by the kernel, libinput emulates
|
|
||||||
these events for regular wheel clicks.
|
|
||||||
**This event is available since libinput 1.19.**
|
|
||||||
|
|
||||||
The events are separate for historical reasons. Both events are
|
|
||||||
generated for the same device but are independent event streams. Callers
|
|
||||||
must not assume any relation between the two, i.e. there is no guarantee
|
|
||||||
that an axis event is sent before or after any specific high-resolution
|
|
||||||
event and vice versa. Callers should not handle both events.
|
|
||||||
|
|
||||||
.. warning:: do not handle both ``LIBINPUT_EVENT_POINTER_AXIS`` and
|
|
||||||
``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``. Always use the latter where
|
|
||||||
possible, otherwise only use the former.
|
|
||||||
|
|
||||||
Both events have their own set of APIs to access the data within:
|
|
||||||
|
|
||||||
- ``LIBINPUT_EVENT_POINTER_AXIS``: Deprecated as of libinput 1.19, where
|
|
||||||
possible it is recommended to handle **only**
|
|
||||||
``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``.
|
|
||||||
|
|
||||||
* ``libinput_event_pointer_get_axis_value()`` returns the angle of movement
|
|
||||||
in degrees.
|
|
||||||
* ``libinput_event_pointer_get_axis_source()`` returns the source of the
|
|
||||||
event: wheel, finger or continuous.
|
|
||||||
* ``libinput_event_pointer_get_axis_value_discrete()`` returns the number of
|
|
||||||
logical wheel clicks.
|
|
||||||
|
|
||||||
- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` available since libinput 1.19.
|
|
||||||
|
|
||||||
* ``libinput_event_pointer_get_scroll_value_v120()`` returns a value
|
|
||||||
normalized into the 0..120 range, see below. Any multiple of 120 should
|
|
||||||
be treated as one full wheel click.
|
|
||||||
|
|
||||||
.. note:: Where possible, the ``libinput_event_pointer_get_axis_value()``,
|
|
||||||
``libinput_event_pointer_get_axis_source()`` and
|
|
||||||
``libinput_event_pointer_get_axis_value_discrete()`` API should be
|
|
||||||
avoided.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
The v120 Wheel API
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The ``v120`` value matches the Windows API for wheel scrolling. Wheel
|
|
||||||
movements are normalized into multiples (or fractions) of 120 with each
|
|
||||||
multiple of 120 representing one detent of movement. The ``v120`` API is the
|
|
||||||
recommended API for callers that do not care about the exact physical
|
|
||||||
motion and is the simplest API to handle high-resolution scrolling.
|
|
||||||
|
|
||||||
Most wheels provide 24 detents per 360 degree rotation (click angle of 15),
|
|
||||||
others provide 18 detents per 360 degree rotation (click angle 20). Mice
|
|
||||||
falling outside these two are rare but do exist. Below is a table showing
|
|
||||||
the various values for a single event, depending on the click angle of the
|
|
||||||
wheel:
|
|
||||||
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
| Click angle | Axis value | Discrete value| v120 |
|
|
||||||
+=============+============+===============+======+
|
|
||||||
| 15 | 15 | 1 | 120 |
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
| 20 | 20 | 1 | 120 |
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
|
|
||||||
Fast scrolling may trigger cover than one detent per event and thus each
|
|
||||||
event may contain multiples of the value, discrete or v120 value:
|
|
||||||
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
| Click angle | Axis value | Discrete value| v120 |
|
|
||||||
+=============+============+===============+======+
|
|
||||||
| 15 | 30 | 2 | 240 |
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
| 20 | 60 | 3 | 360 |
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
|
|
||||||
Scrolling on high-resolution wheels will produce fractions of 120, depending
|
|
||||||
on the resolution of the wheel. The example below shows a mouse with click
|
|
||||||
angle 15 and a resolution of 3 events per wheel click and a mouse with click
|
|
||||||
angle 20 and a resolution of 2 events per wheel click.
|
|
||||||
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
| Click angle | Axis value | Discrete value| v120 |
|
|
||||||
+=============+============+===============+======+
|
|
||||||
| 15 | 5 | 0 | 40 |
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
| 20 | 10 | 0 | 60 |
|
|
||||||
+-------------+------------+---------------+------+
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Event sequences for high-resolution wheel mice
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
High-resolution scroll wheels provide multiple events for each detent is
|
|
||||||
hit. For those mice, an event sequence covering two detents may look like
|
|
||||||
this:
|
|
||||||
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| Event number | Type | Axis value | Discrete value| v120 |
|
|
||||||
+==============+=========+============+===============+======+
|
|
||||||
| 1 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 2 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 3 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 4 | AXIS | 15 | 1 | 120 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 5 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 6 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 7 | AXIS | 15 | 1 | 120 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
|
|
||||||
The above assumes a click angle of 15 for the physical detents. Note how the
|
|
||||||
second set of high-resolution events do **not** add up to a multiple of
|
|
||||||
120 before the low-resolution event. A caller must not assume any relation
|
|
||||||
between ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` and
|
|
||||||
``LIBINPUT_EVENT_POINTER_AXIS``.
|
|
||||||
|
|
||||||
Fast-scrolling on a high-resolution mouse may trigger multiple fractions per
|
|
||||||
hardware scanout cycle and result in an event sequence like this:
|
|
||||||
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| Event number | Type | Axis value | Discrete value| v120 |
|
|
||||||
+===============+=========+============+===============+======+
|
|
||||||
| 1 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| 2 | WHEEL | 10 | n/a | 80 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| 3 | AXIS | 15 | 1 | 120 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| 4 | WHEEL | 10 | n/a | 80 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| 5 | WHEEL | 10 | n/a | 80 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| 6 | AXIS | 15 | 1 | 120 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
| 7 | WHEEL | 5 | n/a | 40 |
|
|
||||||
+---------------+---------+------------+---------------+------+
|
|
||||||
|
|
||||||
Note how the first low-resolution event is sent at an accumulated 15
|
|
||||||
degrees, the second at an accumulated 20 degrees. The libinput API does not
|
|
||||||
specify the smallest fraction a wheel supports.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Event sequences for regular wheel mice
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` for low-resolution mice are virtually
|
|
||||||
identical to ``LIBINPUT_EVENT_POINTER_AXIS`` events. Note that the discrete
|
|
||||||
value is always 0 for ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``.
|
|
||||||
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| Event number | Type | Axis value | Discrete value| v120 |
|
|
||||||
+==============+=========+============+===============+======+
|
|
||||||
| 1 | AXIS | 15 | 1 | 120 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 2 | WHEEL | 15 | n/a | 120 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 3 | WHEEL | 15 | n/a | 120 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
| 4 | AXIS | 15 | 1 | 120 |
|
|
||||||
+--------------+---------+------------+---------------+------+
|
|
||||||
|
|
||||||
Note that the order of ``LIBINPUT_EVENT_POINTER_AXIS`` vs
|
|
||||||
``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` events is not guaranteed, as shown in
|
|
||||||
the example above.
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||||
/*
|
/*
|
||||||
* Input event codes
|
* Input event codes
|
||||||
*
|
*
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||||
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||||
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
|
|
||||||
|
|
||||||
#define INPUT_PROP_MAX 0x1f
|
#define INPUT_PROP_MAX 0x1f
|
||||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||||
|
|
@ -279,8 +278,7 @@
|
||||||
#define KEY_PAUSECD 201
|
#define KEY_PAUSECD 201
|
||||||
#define KEY_PROG3 202
|
#define KEY_PROG3 202
|
||||||
#define KEY_PROG4 203
|
#define KEY_PROG4 203
|
||||||
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
#define KEY_DASHBOARD 204 /* AL Dashboard */
|
||||||
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
|
||||||
#define KEY_SUSPEND 205
|
#define KEY_SUSPEND 205
|
||||||
#define KEY_CLOSE 206 /* AC Close */
|
#define KEY_CLOSE 206 /* AC Close */
|
||||||
#define KEY_PLAY 207
|
#define KEY_PLAY 207
|
||||||
|
|
@ -441,12 +439,10 @@
|
||||||
#define KEY_TITLE 0x171
|
#define KEY_TITLE 0x171
|
||||||
#define KEY_SUBTITLE 0x172
|
#define KEY_SUBTITLE 0x172
|
||||||
#define KEY_ANGLE 0x173
|
#define KEY_ANGLE 0x173
|
||||||
#define KEY_FULL_SCREEN 0x174 /* AC View Toggle */
|
#define KEY_ZOOM 0x174
|
||||||
#define KEY_ZOOM KEY_FULL_SCREEN
|
|
||||||
#define KEY_MODE 0x175
|
#define KEY_MODE 0x175
|
||||||
#define KEY_KEYBOARD 0x176
|
#define KEY_KEYBOARD 0x176
|
||||||
#define KEY_ASPECT_RATIO 0x177 /* HUTRR37: Aspect */
|
#define KEY_SCREEN 0x177
|
||||||
#define KEY_SCREEN KEY_ASPECT_RATIO
|
|
||||||
#define KEY_PC 0x178 /* Media Select Computer */
|
#define KEY_PC 0x178 /* Media Select Computer */
|
||||||
#define KEY_TV 0x179 /* Media Select TV */
|
#define KEY_TV 0x179 /* Media Select TV */
|
||||||
#define KEY_TV2 0x17a /* Media Select Cable */
|
#define KEY_TV2 0x17a /* Media Select Cable */
|
||||||
|
|
@ -517,10 +513,6 @@
|
||||||
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
||||||
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
||||||
#define KEY_IMAGES 0x1ba /* AL Image Browser */
|
#define KEY_IMAGES 0x1ba /* AL Image Browser */
|
||||||
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
|
|
||||||
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
|
|
||||||
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
|
|
||||||
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
|
|
||||||
|
|
||||||
#define KEY_DEL_EOL 0x1c0
|
#define KEY_DEL_EOL 0x1c0
|
||||||
#define KEY_DEL_EOS 0x1c1
|
#define KEY_DEL_EOS 0x1c1
|
||||||
|
|
@ -548,7 +540,6 @@
|
||||||
#define KEY_FN_F 0x1e2
|
#define KEY_FN_F 0x1e2
|
||||||
#define KEY_FN_S 0x1e3
|
#define KEY_FN_S 0x1e3
|
||||||
#define KEY_FN_B 0x1e4
|
#define KEY_FN_B 0x1e4
|
||||||
#define KEY_FN_RIGHT_SHIFT 0x1e5
|
|
||||||
|
|
||||||
#define KEY_BRL_DOT1 0x1f1
|
#define KEY_BRL_DOT1 0x1f1
|
||||||
#define KEY_BRL_DOT2 0x1f2
|
#define KEY_BRL_DOT2 0x1f2
|
||||||
|
|
@ -602,14 +593,8 @@
|
||||||
#define BTN_DPAD_LEFT 0x222
|
#define BTN_DPAD_LEFT 0x222
|
||||||
#define BTN_DPAD_RIGHT 0x223
|
#define BTN_DPAD_RIGHT 0x223
|
||||||
|
|
||||||
#define BTN_GRIPL 0x224
|
|
||||||
#define BTN_GRIPR 0x225
|
|
||||||
#define BTN_GRIPL2 0x226
|
|
||||||
#define BTN_GRIPR2 0x227
|
|
||||||
|
|
||||||
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
||||||
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
|
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
|
||||||
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
|
|
||||||
|
|
||||||
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
|
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
|
||||||
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
||||||
|
|
@ -619,30 +604,10 @@
|
||||||
#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
|
#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
|
||||||
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
||||||
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
||||||
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
|
||||||
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
|
||||||
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
|
||||||
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
|
|
||||||
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
|
|
||||||
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
|
|
||||||
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
|
|
||||||
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
|
|
||||||
|
|
||||||
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
||||||
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
||||||
|
|
||||||
/*
|
|
||||||
* Keycodes for hotkeys toggling the electronic privacy screen found on some
|
|
||||||
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
|
|
||||||
* screen itself then the state should be reported through drm connecter props:
|
|
||||||
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
|
|
||||||
* Except when implementing the drm connecter properties API is not possible
|
|
||||||
* because e.g. the firmware does not allow querying the presence and/or status
|
|
||||||
* of the eprivacy screen at boot.
|
|
||||||
*/
|
|
||||||
#define KEY_EPRIVACY_SCREEN_ON 0x252
|
|
||||||
#define KEY_EPRIVACY_SCREEN_OFF 0x253
|
|
||||||
|
|
||||||
#define KEY_KBDINPUTASSIST_PREV 0x260
|
#define KEY_KBDINPUTASSIST_PREV 0x260
|
||||||
#define KEY_KBDINPUTASSIST_NEXT 0x261
|
#define KEY_KBDINPUTASSIST_NEXT 0x261
|
||||||
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
||||||
|
|
@ -681,110 +646,6 @@
|
||||||
*/
|
*/
|
||||||
#define KEY_DATA 0x277
|
#define KEY_DATA 0x277
|
||||||
#define KEY_ONSCREEN_KEYBOARD 0x278
|
#define KEY_ONSCREEN_KEYBOARD 0x278
|
||||||
/* Electronic privacy screen control */
|
|
||||||
#define KEY_PRIVACY_SCREEN_TOGGLE 0x279
|
|
||||||
|
|
||||||
/* Select an area of screen to be copied */
|
|
||||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
|
||||||
|
|
||||||
/* Move the focus to the next or previous user controllable element within a UI container */
|
|
||||||
#define KEY_NEXT_ELEMENT 0x27b
|
|
||||||
#define KEY_PREVIOUS_ELEMENT 0x27c
|
|
||||||
|
|
||||||
/* Toggle Autopilot engagement */
|
|
||||||
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
|
|
||||||
|
|
||||||
/* Shortcut Keys */
|
|
||||||
#define KEY_MARK_WAYPOINT 0x27e
|
|
||||||
#define KEY_SOS 0x27f
|
|
||||||
#define KEY_NAV_CHART 0x280
|
|
||||||
#define KEY_FISHING_CHART 0x281
|
|
||||||
#define KEY_SINGLE_RANGE_RADAR 0x282
|
|
||||||
#define KEY_DUAL_RANGE_RADAR 0x283
|
|
||||||
#define KEY_RADAR_OVERLAY 0x284
|
|
||||||
#define KEY_TRADITIONAL_SONAR 0x285
|
|
||||||
#define KEY_CLEARVU_SONAR 0x286
|
|
||||||
#define KEY_SIDEVU_SONAR 0x287
|
|
||||||
#define KEY_NAV_INFO 0x288
|
|
||||||
#define KEY_BRIGHTNESS_MENU 0x289
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some keyboards have keys which do not have a defined meaning, these keys
|
|
||||||
* are intended to be programmed / bound to macros by the user. For most
|
|
||||||
* keyboards with these macro-keys the key-sequence to inject, or action to
|
|
||||||
* take, is all handled by software on the host side. So from the kernel's
|
|
||||||
* point of view these are just normal keys.
|
|
||||||
*
|
|
||||||
* The KEY_MACRO# codes below are intended for such keys, which may be labeled
|
|
||||||
* e.g. G1-G18, or S1 - S30. The KEY_MACRO# codes MUST NOT be used for keys
|
|
||||||
* where the marking on the key does indicate a defined meaning / purpose.
|
|
||||||
*
|
|
||||||
* The KEY_MACRO# codes MUST also NOT be used as fallback for when no existing
|
|
||||||
* KEY_FOO define matches the marking / purpose. In this case a new KEY_FOO
|
|
||||||
* define MUST be added.
|
|
||||||
*/
|
|
||||||
#define KEY_MACRO1 0x290
|
|
||||||
#define KEY_MACRO2 0x291
|
|
||||||
#define KEY_MACRO3 0x292
|
|
||||||
#define KEY_MACRO4 0x293
|
|
||||||
#define KEY_MACRO5 0x294
|
|
||||||
#define KEY_MACRO6 0x295
|
|
||||||
#define KEY_MACRO7 0x296
|
|
||||||
#define KEY_MACRO8 0x297
|
|
||||||
#define KEY_MACRO9 0x298
|
|
||||||
#define KEY_MACRO10 0x299
|
|
||||||
#define KEY_MACRO11 0x29a
|
|
||||||
#define KEY_MACRO12 0x29b
|
|
||||||
#define KEY_MACRO13 0x29c
|
|
||||||
#define KEY_MACRO14 0x29d
|
|
||||||
#define KEY_MACRO15 0x29e
|
|
||||||
#define KEY_MACRO16 0x29f
|
|
||||||
#define KEY_MACRO17 0x2a0
|
|
||||||
#define KEY_MACRO18 0x2a1
|
|
||||||
#define KEY_MACRO19 0x2a2
|
|
||||||
#define KEY_MACRO20 0x2a3
|
|
||||||
#define KEY_MACRO21 0x2a4
|
|
||||||
#define KEY_MACRO22 0x2a5
|
|
||||||
#define KEY_MACRO23 0x2a6
|
|
||||||
#define KEY_MACRO24 0x2a7
|
|
||||||
#define KEY_MACRO25 0x2a8
|
|
||||||
#define KEY_MACRO26 0x2a9
|
|
||||||
#define KEY_MACRO27 0x2aa
|
|
||||||
#define KEY_MACRO28 0x2ab
|
|
||||||
#define KEY_MACRO29 0x2ac
|
|
||||||
#define KEY_MACRO30 0x2ad
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some keyboards with the macro-keys described above have some extra keys
|
|
||||||
* for controlling the host-side software responsible for the macro handling:
|
|
||||||
* -A macro recording start/stop key. Note that not all keyboards which emit
|
|
||||||
* KEY_MACRO_RECORD_START will also emit KEY_MACRO_RECORD_STOP if
|
|
||||||
* KEY_MACRO_RECORD_STOP is not advertised, then KEY_MACRO_RECORD_START
|
|
||||||
* should be interpreted as a recording start/stop toggle;
|
|
||||||
* -Keys for switching between different macro (pre)sets, either a key for
|
|
||||||
* cycling through the configured presets or keys to directly select a preset.
|
|
||||||
*/
|
|
||||||
#define KEY_MACRO_RECORD_START 0x2b0
|
|
||||||
#define KEY_MACRO_RECORD_STOP 0x2b1
|
|
||||||
#define KEY_MACRO_PRESET_CYCLE 0x2b2
|
|
||||||
#define KEY_MACRO_PRESET1 0x2b3
|
|
||||||
#define KEY_MACRO_PRESET2 0x2b4
|
|
||||||
#define KEY_MACRO_PRESET3 0x2b5
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some keyboards have a buildin LCD panel where the contents are controlled
|
|
||||||
* by the host. Often these have a number of keys directly below the LCD
|
|
||||||
* intended for controlling a menu shown on the LCD. These keys often don't
|
|
||||||
* have any labeling so we just name them KEY_KBD_LCD_MENU#
|
|
||||||
*/
|
|
||||||
#define KEY_KBD_LCD_MENU1 0x2b8
|
|
||||||
#define KEY_KBD_LCD_MENU2 0x2b9
|
|
||||||
#define KEY_KBD_LCD_MENU3 0x2ba
|
|
||||||
#define KEY_KBD_LCD_MENU4 0x2bb
|
|
||||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
|
||||||
|
|
||||||
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
|
|
||||||
#define KEY_PERFORMANCE 0x2bd
|
|
||||||
|
|
||||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||||
|
|
@ -890,7 +751,6 @@
|
||||||
#define ABS_TOOL_WIDTH 0x1c
|
#define ABS_TOOL_WIDTH 0x1c
|
||||||
|
|
||||||
#define ABS_VOLUME 0x20
|
#define ABS_VOLUME 0x20
|
||||||
#define ABS_PROFILE 0x21
|
|
||||||
|
|
||||||
#define ABS_MISC 0x28
|
#define ABS_MISC 0x28
|
||||||
|
|
||||||
|
|
@ -945,9 +805,7 @@
|
||||||
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
||||||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||||
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
|
#define SW_MAX 0x0f
|
||||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
|
||||||
#define SW_MAX 0x11
|
|
||||||
#define SW_CNT (SW_MAX+1)
|
#define SW_CNT (SW_MAX+1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||||
/*
|
/*
|
||||||
* Input event codes
|
* Input event codes
|
||||||
*
|
*
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||||
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||||
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
|
|
||||||
|
|
||||||
#define INPUT_PROP_MAX 0x1f
|
#define INPUT_PROP_MAX 0x1f
|
||||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||||
|
|
@ -279,8 +278,7 @@
|
||||||
#define KEY_PAUSECD 201
|
#define KEY_PAUSECD 201
|
||||||
#define KEY_PROG3 202
|
#define KEY_PROG3 202
|
||||||
#define KEY_PROG4 203
|
#define KEY_PROG4 203
|
||||||
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
#define KEY_DASHBOARD 204 /* AL Dashboard */
|
||||||
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
|
||||||
#define KEY_SUSPEND 205
|
#define KEY_SUSPEND 205
|
||||||
#define KEY_CLOSE 206 /* AC Close */
|
#define KEY_CLOSE 206 /* AC Close */
|
||||||
#define KEY_PLAY 207
|
#define KEY_PLAY 207
|
||||||
|
|
@ -441,12 +439,10 @@
|
||||||
#define KEY_TITLE 0x171
|
#define KEY_TITLE 0x171
|
||||||
#define KEY_SUBTITLE 0x172
|
#define KEY_SUBTITLE 0x172
|
||||||
#define KEY_ANGLE 0x173
|
#define KEY_ANGLE 0x173
|
||||||
#define KEY_FULL_SCREEN 0x174 /* AC View Toggle */
|
#define KEY_ZOOM 0x174
|
||||||
#define KEY_ZOOM KEY_FULL_SCREEN
|
|
||||||
#define KEY_MODE 0x175
|
#define KEY_MODE 0x175
|
||||||
#define KEY_KEYBOARD 0x176
|
#define KEY_KEYBOARD 0x176
|
||||||
#define KEY_ASPECT_RATIO 0x177 /* HUTRR37: Aspect */
|
#define KEY_SCREEN 0x177
|
||||||
#define KEY_SCREEN KEY_ASPECT_RATIO
|
|
||||||
#define KEY_PC 0x178 /* Media Select Computer */
|
#define KEY_PC 0x178 /* Media Select Computer */
|
||||||
#define KEY_TV 0x179 /* Media Select TV */
|
#define KEY_TV 0x179 /* Media Select TV */
|
||||||
#define KEY_TV2 0x17a /* Media Select Cable */
|
#define KEY_TV2 0x17a /* Media Select Cable */
|
||||||
|
|
@ -517,10 +513,6 @@
|
||||||
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
||||||
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
||||||
#define KEY_IMAGES 0x1ba /* AL Image Browser */
|
#define KEY_IMAGES 0x1ba /* AL Image Browser */
|
||||||
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
|
|
||||||
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
|
|
||||||
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
|
|
||||||
#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
|
|
||||||
|
|
||||||
#define KEY_DEL_EOL 0x1c0
|
#define KEY_DEL_EOL 0x1c0
|
||||||
#define KEY_DEL_EOS 0x1c1
|
#define KEY_DEL_EOS 0x1c1
|
||||||
|
|
@ -548,7 +540,6 @@
|
||||||
#define KEY_FN_F 0x1e2
|
#define KEY_FN_F 0x1e2
|
||||||
#define KEY_FN_S 0x1e3
|
#define KEY_FN_S 0x1e3
|
||||||
#define KEY_FN_B 0x1e4
|
#define KEY_FN_B 0x1e4
|
||||||
#define KEY_FN_RIGHT_SHIFT 0x1e5
|
|
||||||
|
|
||||||
#define KEY_BRL_DOT1 0x1f1
|
#define KEY_BRL_DOT1 0x1f1
|
||||||
#define KEY_BRL_DOT2 0x1f2
|
#define KEY_BRL_DOT2 0x1f2
|
||||||
|
|
@ -602,14 +593,8 @@
|
||||||
#define BTN_DPAD_LEFT 0x222
|
#define BTN_DPAD_LEFT 0x222
|
||||||
#define BTN_DPAD_RIGHT 0x223
|
#define BTN_DPAD_RIGHT 0x223
|
||||||
|
|
||||||
#define BTN_GRIPL 0x224
|
|
||||||
#define BTN_GRIPR 0x225
|
|
||||||
#define BTN_GRIPL2 0x226
|
|
||||||
#define BTN_GRIPR2 0x227
|
|
||||||
|
|
||||||
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
|
||||||
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
|
#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
|
||||||
#define KEY_REFRESH_RATE_TOGGLE 0x232 /* Display refresh rate toggle */
|
|
||||||
|
|
||||||
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
|
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
|
||||||
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
||||||
|
|
@ -619,30 +604,10 @@
|
||||||
#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
|
#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
|
||||||
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
||||||
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
||||||
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
|
||||||
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
|
||||||
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
|
||||||
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
|
|
||||||
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
|
|
||||||
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
|
|
||||||
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
|
|
||||||
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
|
|
||||||
|
|
||||||
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
||||||
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
|
||||||
|
|
||||||
/*
|
|
||||||
* Keycodes for hotkeys toggling the electronic privacy screen found on some
|
|
||||||
* laptops on/off. Note when the embedded-controller turns on/off the eprivacy
|
|
||||||
* screen itself then the state should be reported through drm connecter props:
|
|
||||||
* https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#standard-connector-properties
|
|
||||||
* Except when implementing the drm connecter properties API is not possible
|
|
||||||
* because e.g. the firmware does not allow querying the presence and/or status
|
|
||||||
* of the eprivacy screen at boot.
|
|
||||||
*/
|
|
||||||
#define KEY_EPRIVACY_SCREEN_ON 0x252
|
|
||||||
#define KEY_EPRIVACY_SCREEN_OFF 0x253
|
|
||||||
|
|
||||||
#define KEY_KBDINPUTASSIST_PREV 0x260
|
#define KEY_KBDINPUTASSIST_PREV 0x260
|
||||||
#define KEY_KBDINPUTASSIST_NEXT 0x261
|
#define KEY_KBDINPUTASSIST_NEXT 0x261
|
||||||
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
||||||
|
|
@ -681,110 +646,6 @@
|
||||||
*/
|
*/
|
||||||
#define KEY_DATA 0x277
|
#define KEY_DATA 0x277
|
||||||
#define KEY_ONSCREEN_KEYBOARD 0x278
|
#define KEY_ONSCREEN_KEYBOARD 0x278
|
||||||
/* Electronic privacy screen control */
|
|
||||||
#define KEY_PRIVACY_SCREEN_TOGGLE 0x279
|
|
||||||
|
|
||||||
/* Select an area of screen to be copied */
|
|
||||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
|
||||||
|
|
||||||
/* Move the focus to the next or previous user controllable element within a UI container */
|
|
||||||
#define KEY_NEXT_ELEMENT 0x27b
|
|
||||||
#define KEY_PREVIOUS_ELEMENT 0x27c
|
|
||||||
|
|
||||||
/* Toggle Autopilot engagement */
|
|
||||||
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
|
|
||||||
|
|
||||||
/* Shortcut Keys */
|
|
||||||
#define KEY_MARK_WAYPOINT 0x27e
|
|
||||||
#define KEY_SOS 0x27f
|
|
||||||
#define KEY_NAV_CHART 0x280
|
|
||||||
#define KEY_FISHING_CHART 0x281
|
|
||||||
#define KEY_SINGLE_RANGE_RADAR 0x282
|
|
||||||
#define KEY_DUAL_RANGE_RADAR 0x283
|
|
||||||
#define KEY_RADAR_OVERLAY 0x284
|
|
||||||
#define KEY_TRADITIONAL_SONAR 0x285
|
|
||||||
#define KEY_CLEARVU_SONAR 0x286
|
|
||||||
#define KEY_SIDEVU_SONAR 0x287
|
|
||||||
#define KEY_NAV_INFO 0x288
|
|
||||||
#define KEY_BRIGHTNESS_MENU 0x289
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some keyboards have keys which do not have a defined meaning, these keys
|
|
||||||
* are intended to be programmed / bound to macros by the user. For most
|
|
||||||
* keyboards with these macro-keys the key-sequence to inject, or action to
|
|
||||||
* take, is all handled by software on the host side. So from the kernel's
|
|
||||||
* point of view these are just normal keys.
|
|
||||||
*
|
|
||||||
* The KEY_MACRO# codes below are intended for such keys, which may be labeled
|
|
||||||
* e.g. G1-G18, or S1 - S30. The KEY_MACRO# codes MUST NOT be used for keys
|
|
||||||
* where the marking on the key does indicate a defined meaning / purpose.
|
|
||||||
*
|
|
||||||
* The KEY_MACRO# codes MUST also NOT be used as fallback for when no existing
|
|
||||||
* KEY_FOO define matches the marking / purpose. In this case a new KEY_FOO
|
|
||||||
* define MUST be added.
|
|
||||||
*/
|
|
||||||
#define KEY_MACRO1 0x290
|
|
||||||
#define KEY_MACRO2 0x291
|
|
||||||
#define KEY_MACRO3 0x292
|
|
||||||
#define KEY_MACRO4 0x293
|
|
||||||
#define KEY_MACRO5 0x294
|
|
||||||
#define KEY_MACRO6 0x295
|
|
||||||
#define KEY_MACRO7 0x296
|
|
||||||
#define KEY_MACRO8 0x297
|
|
||||||
#define KEY_MACRO9 0x298
|
|
||||||
#define KEY_MACRO10 0x299
|
|
||||||
#define KEY_MACRO11 0x29a
|
|
||||||
#define KEY_MACRO12 0x29b
|
|
||||||
#define KEY_MACRO13 0x29c
|
|
||||||
#define KEY_MACRO14 0x29d
|
|
||||||
#define KEY_MACRO15 0x29e
|
|
||||||
#define KEY_MACRO16 0x29f
|
|
||||||
#define KEY_MACRO17 0x2a0
|
|
||||||
#define KEY_MACRO18 0x2a1
|
|
||||||
#define KEY_MACRO19 0x2a2
|
|
||||||
#define KEY_MACRO20 0x2a3
|
|
||||||
#define KEY_MACRO21 0x2a4
|
|
||||||
#define KEY_MACRO22 0x2a5
|
|
||||||
#define KEY_MACRO23 0x2a6
|
|
||||||
#define KEY_MACRO24 0x2a7
|
|
||||||
#define KEY_MACRO25 0x2a8
|
|
||||||
#define KEY_MACRO26 0x2a9
|
|
||||||
#define KEY_MACRO27 0x2aa
|
|
||||||
#define KEY_MACRO28 0x2ab
|
|
||||||
#define KEY_MACRO29 0x2ac
|
|
||||||
#define KEY_MACRO30 0x2ad
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some keyboards with the macro-keys described above have some extra keys
|
|
||||||
* for controlling the host-side software responsible for the macro handling:
|
|
||||||
* -A macro recording start/stop key. Note that not all keyboards which emit
|
|
||||||
* KEY_MACRO_RECORD_START will also emit KEY_MACRO_RECORD_STOP if
|
|
||||||
* KEY_MACRO_RECORD_STOP is not advertised, then KEY_MACRO_RECORD_START
|
|
||||||
* should be interpreted as a recording start/stop toggle;
|
|
||||||
* -Keys for switching between different macro (pre)sets, either a key for
|
|
||||||
* cycling through the configured presets or keys to directly select a preset.
|
|
||||||
*/
|
|
||||||
#define KEY_MACRO_RECORD_START 0x2b0
|
|
||||||
#define KEY_MACRO_RECORD_STOP 0x2b1
|
|
||||||
#define KEY_MACRO_PRESET_CYCLE 0x2b2
|
|
||||||
#define KEY_MACRO_PRESET1 0x2b3
|
|
||||||
#define KEY_MACRO_PRESET2 0x2b4
|
|
||||||
#define KEY_MACRO_PRESET3 0x2b5
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some keyboards have a buildin LCD panel where the contents are controlled
|
|
||||||
* by the host. Often these have a number of keys directly below the LCD
|
|
||||||
* intended for controlling a menu shown on the LCD. These keys often don't
|
|
||||||
* have any labeling so we just name them KEY_KBD_LCD_MENU#
|
|
||||||
*/
|
|
||||||
#define KEY_KBD_LCD_MENU1 0x2b8
|
|
||||||
#define KEY_KBD_LCD_MENU2 0x2b9
|
|
||||||
#define KEY_KBD_LCD_MENU3 0x2ba
|
|
||||||
#define KEY_KBD_LCD_MENU4 0x2bb
|
|
||||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
|
||||||
|
|
||||||
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
|
|
||||||
#define KEY_PERFORMANCE 0x2bd
|
|
||||||
|
|
||||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||||
|
|
@ -890,7 +751,6 @@
|
||||||
#define ABS_TOOL_WIDTH 0x1c
|
#define ABS_TOOL_WIDTH 0x1c
|
||||||
|
|
||||||
#define ABS_VOLUME 0x20
|
#define ABS_VOLUME 0x20
|
||||||
#define ABS_PROFILE 0x21
|
|
||||||
|
|
||||||
#define ABS_MISC 0x28
|
#define ABS_MISC 0x28
|
||||||
|
|
||||||
|
|
@ -945,9 +805,7 @@
|
||||||
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
||||||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||||
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
|
#define SW_MAX 0x0f
|
||||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
|
||||||
#define SW_MAX 0x11
|
|
||||||
#define SW_CNT (SW_MAX+1)
|
#define SW_CNT (SW_MAX+1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
|| (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
|
|| (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
|
||||||
*/
|
*/
|
||||||
#define __VALGRIND_MAJOR__ 3
|
#define __VALGRIND_MAJOR__ 3
|
||||||
#define __VALGRIND_MINOR__ 18
|
#define __VALGRIND_MINOR__ 15
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -110,8 +110,6 @@
|
||||||
*/
|
*/
|
||||||
#undef PLAT_x86_darwin
|
#undef PLAT_x86_darwin
|
||||||
#undef PLAT_amd64_darwin
|
#undef PLAT_amd64_darwin
|
||||||
#undef PLAT_x86_freebsd
|
|
||||||
#undef PLAT_amd64_freebsd
|
|
||||||
#undef PLAT_x86_win32
|
#undef PLAT_x86_win32
|
||||||
#undef PLAT_amd64_win64
|
#undef PLAT_amd64_win64
|
||||||
#undef PLAT_x86_linux
|
#undef PLAT_x86_linux
|
||||||
|
|
@ -124,7 +122,6 @@
|
||||||
#undef PLAT_s390x_linux
|
#undef PLAT_s390x_linux
|
||||||
#undef PLAT_mips32_linux
|
#undef PLAT_mips32_linux
|
||||||
#undef PLAT_mips64_linux
|
#undef PLAT_mips64_linux
|
||||||
#undef PLAT_nanomips_linux
|
|
||||||
#undef PLAT_x86_solaris
|
#undef PLAT_x86_solaris
|
||||||
#undef PLAT_amd64_solaris
|
#undef PLAT_amd64_solaris
|
||||||
|
|
||||||
|
|
@ -133,17 +130,12 @@
|
||||||
# define PLAT_x86_darwin 1
|
# define PLAT_x86_darwin 1
|
||||||
#elif defined(__APPLE__) && defined(__x86_64__)
|
#elif defined(__APPLE__) && defined(__x86_64__)
|
||||||
# define PLAT_amd64_darwin 1
|
# define PLAT_amd64_darwin 1
|
||||||
#elif defined(__FreeBSD__) && defined(__i386__)
|
#elif (defined(__MINGW32__) && !defined(__MINGW64__)) \
|
||||||
# define PLAT_x86_freebsd 1
|
|
||||||
#elif defined(__FreeBSD__) && defined(__amd64__)
|
|
||||||
# define PLAT_amd64_freebsd 1
|
|
||||||
#elif (defined(__MINGW32__) && defined(__i386__)) \
|
|
||||||
|| defined(__CYGWIN32__) \
|
|| defined(__CYGWIN32__) \
|
||||||
|| (defined(_WIN32) && defined(_M_IX86))
|
|| (defined(_WIN32) && defined(_M_IX86))
|
||||||
# define PLAT_x86_win32 1
|
# define PLAT_x86_win32 1
|
||||||
#elif (defined(__MINGW32__) && defined(__x86_64__)) \
|
#elif defined(__MINGW64__) \
|
||||||
|| (defined(_WIN32) && defined(_M_X64))
|
|| (defined(_WIN64) && defined(_M_X64))
|
||||||
/* __MINGW32__ and _WIN32 are defined in 64 bit mode as well. */
|
|
||||||
# define PLAT_amd64_win64 1
|
# define PLAT_amd64_win64 1
|
||||||
#elif defined(__linux__) && defined(__i386__)
|
#elif defined(__linux__) && defined(__i386__)
|
||||||
# define PLAT_x86_linux 1
|
# define PLAT_x86_linux 1
|
||||||
|
|
@ -165,10 +157,8 @@
|
||||||
# define PLAT_s390x_linux 1
|
# define PLAT_s390x_linux 1
|
||||||
#elif defined(__linux__) && defined(__mips__) && (__mips==64)
|
#elif defined(__linux__) && defined(__mips__) && (__mips==64)
|
||||||
# define PLAT_mips64_linux 1
|
# define PLAT_mips64_linux 1
|
||||||
#elif defined(__linux__) && defined(__mips__) && (__mips==32)
|
#elif defined(__linux__) && defined(__mips__) && (__mips!=64)
|
||||||
# define PLAT_mips32_linux 1
|
# define PLAT_mips32_linux 1
|
||||||
#elif defined(__linux__) && defined(__nanomips__)
|
|
||||||
# define PLAT_nanomips_linux 1
|
|
||||||
#elif defined(__sun) && defined(__i386__)
|
#elif defined(__sun) && defined(__i386__)
|
||||||
# define PLAT_x86_solaris 1
|
# define PLAT_x86_solaris 1
|
||||||
#elif defined(__sun) && defined(__x86_64__)
|
#elif defined(__sun) && defined(__x86_64__)
|
||||||
|
|
@ -264,7 +254,7 @@
|
||||||
|
|
||||||
#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
|
#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
|
||||||
|| (defined(PLAT_x86_win32) && defined(__GNUC__)) \
|
|| (defined(PLAT_x86_win32) && defined(__GNUC__)) \
|
||||||
|| defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd)
|
|| defined(PLAT_x86_solaris)
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -404,7 +394,6 @@ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
|
||||||
|
|
||||||
#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \
|
#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \
|
||||||
|| defined(PLAT_amd64_solaris) \
|
|| defined(PLAT_amd64_solaris) \
|
||||||
|| defined(PLAT_amd64_freebsd) \
|
|
||||||
|| (defined(PLAT_amd64_win64) && defined(__GNUC__))
|
|| (defined(PLAT_amd64_win64) && defined(__GNUC__))
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
|
|
@ -883,8 +872,7 @@ typedef
|
||||||
/* results = r3 */ \
|
/* results = r3 */ \
|
||||||
"lgr %0, 3\n\t" \
|
"lgr %0, 3\n\t" \
|
||||||
: "=d" (_zzq_result) \
|
: "=d" (_zzq_result) \
|
||||||
: "a" (&_zzq_args[0]), \
|
: "a" (&_zzq_args[0]), "0" (_zzq_default) \
|
||||||
"0" ((unsigned long int)_zzq_default) \
|
|
||||||
: "cc", "2", "3", "memory" \
|
: "cc", "2", "3", "memory" \
|
||||||
); \
|
); \
|
||||||
_zzq_result; \
|
_zzq_result; \
|
||||||
|
|
@ -1057,75 +1045,6 @@ typedef
|
||||||
|
|
||||||
#endif /* PLAT_mips64_linux */
|
#endif /* PLAT_mips64_linux */
|
||||||
|
|
||||||
#if defined(PLAT_nanomips_linux)
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct {
|
|
||||||
unsigned int nraddr; /* where's the code? */
|
|
||||||
}
|
|
||||||
OrigFn;
|
|
||||||
/*
|
|
||||||
8000 c04d srl zero, zero, 13
|
|
||||||
8000 c05d srl zero, zero, 29
|
|
||||||
8000 c043 srl zero, zero, 3
|
|
||||||
8000 c053 srl zero, zero, 19
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __SPECIAL_INSTRUCTION_PREAMBLE "srl[32] $zero, $zero, 13 \n\t" \
|
|
||||||
"srl[32] $zero, $zero, 29 \n\t" \
|
|
||||||
"srl[32] $zero, $zero, 3 \n\t" \
|
|
||||||
"srl[32] $zero, $zero, 19 \n\t"
|
|
||||||
|
|
||||||
#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
|
|
||||||
_zzq_default, _zzq_request, \
|
|
||||||
_zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
|
|
||||||
__extension__ \
|
|
||||||
({ volatile unsigned int _zzq_args[6]; \
|
|
||||||
volatile unsigned int _zzq_result; \
|
|
||||||
_zzq_args[0] = (unsigned int)(_zzq_request); \
|
|
||||||
_zzq_args[1] = (unsigned int)(_zzq_arg1); \
|
|
||||||
_zzq_args[2] = (unsigned int)(_zzq_arg2); \
|
|
||||||
_zzq_args[3] = (unsigned int)(_zzq_arg3); \
|
|
||||||
_zzq_args[4] = (unsigned int)(_zzq_arg4); \
|
|
||||||
_zzq_args[5] = (unsigned int)(_zzq_arg5); \
|
|
||||||
__asm__ volatile("move $a7, %1\n\t" /* default */ \
|
|
||||||
"move $t0, %2\n\t" /* ptr */ \
|
|
||||||
__SPECIAL_INSTRUCTION_PREAMBLE \
|
|
||||||
/* $a7 = client_request( $t0 ) */ \
|
|
||||||
"or[32] $t0, $t0, $t0\n\t" \
|
|
||||||
"move %0, $a7\n\t" /* result */ \
|
|
||||||
: "=r" (_zzq_result) \
|
|
||||||
: "r" (_zzq_default), "r" (&_zzq_args[0]) \
|
|
||||||
: "$a7", "$t0", "memory"); \
|
|
||||||
_zzq_result; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
|
|
||||||
{ volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
|
|
||||||
volatile unsigned long int __addr; \
|
|
||||||
__asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
|
|
||||||
/* $a7 = guest_NRADDR */ \
|
|
||||||
"or[32] $t1, $t1, $t1\n\t" \
|
|
||||||
"move %0, $a7" /*result*/ \
|
|
||||||
: "=r" (__addr) \
|
|
||||||
: \
|
|
||||||
: "$a7"); \
|
|
||||||
_zzq_orig->nraddr = __addr; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
__SPECIAL_INSTRUCTION_PREAMBLE \
|
|
||||||
/* call-noredir $25 */ \
|
|
||||||
"or[32] $t2, $t2, $t2\n\t"
|
|
||||||
|
|
||||||
#define VALGRIND_VEX_INJECT_IR() \
|
|
||||||
do { \
|
|
||||||
__asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
|
|
||||||
"or[32] $t3, $t3, $t3\n\t" \
|
|
||||||
); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* Insert assembly code for other platforms here... */
|
/* Insert assembly code for other platforms here... */
|
||||||
|
|
||||||
#endif /* NVALGRIND */
|
#endif /* NVALGRIND */
|
||||||
|
|
@ -1226,7 +1145,7 @@ typedef
|
||||||
/* ----------------- x86-{linux,darwin,solaris} ---------------- */
|
/* ----------------- x86-{linux,darwin,solaris} ---------------- */
|
||||||
|
|
||||||
#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
|
#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
|
||||||
|| defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd)
|
|| defined(PLAT_x86_solaris)
|
||||||
|
|
||||||
/* These regs are trashed by the hidden call. No need to mention eax
|
/* These regs are trashed by the hidden call. No need to mention eax
|
||||||
as gcc can already see that, plus causes gcc to bomb. */
|
as gcc can already see that, plus causes gcc to bomb. */
|
||||||
|
|
@ -1658,7 +1577,7 @@ typedef
|
||||||
/* ---------------- amd64-{linux,darwin,solaris} --------------- */
|
/* ---------------- amd64-{linux,darwin,solaris} --------------- */
|
||||||
|
|
||||||
#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \
|
#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \
|
||||||
|| defined(PLAT_amd64_solaris) || defined(PLAT_amd64_freebsd)
|
|| defined(PLAT_amd64_solaris)
|
||||||
|
|
||||||
/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
|
/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
|
||||||
|
|
||||||
|
|
@ -4768,16 +4687,8 @@ typedef
|
||||||
r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
|
r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
|
||||||
function a proper return address. All others are ABI defined call
|
function a proper return address. All others are ABI defined call
|
||||||
clobbers. */
|
clobbers. */
|
||||||
#if defined(__VX__) || defined(__S390_VX__)
|
#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
|
||||||
#define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \
|
"f0","f1","f2","f3","f4","f5","f6","f7"
|
||||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
|
|
||||||
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
|
|
||||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
|
|
||||||
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
|
|
||||||
#else
|
|
||||||
#define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \
|
|
||||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Nb: Although r11 is modified in the asm snippets below (inside
|
/* Nb: Although r11 is modified in the asm snippets below (inside
|
||||||
VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
|
VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
|
||||||
|
|
@ -4799,9 +4710,9 @@ typedef
|
||||||
"aghi 15,-160\n\t" \
|
"aghi 15,-160\n\t" \
|
||||||
"lg 1, 0(1)\n\t" /* target->r1 */ \
|
"lg 1, 0(1)\n\t" /* target->r1 */ \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,160\n\t" \
|
"aghi 15,160\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||||
|
|
@ -4823,9 +4734,9 @@ typedef
|
||||||
"lg 2, 8(1)\n\t" \
|
"lg 2, 8(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,160\n\t" \
|
"aghi 15,160\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||||
|
|
@ -4848,9 +4759,9 @@ typedef
|
||||||
"lg 3,16(1)\n\t" \
|
"lg 3,16(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,160\n\t" \
|
"aghi 15,160\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||||
|
|
@ -4875,9 +4786,9 @@ typedef
|
||||||
"lg 4,24(1)\n\t" \
|
"lg 4,24(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,160\n\t" \
|
"aghi 15,160\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||||
|
|
@ -4904,9 +4815,9 @@ typedef
|
||||||
"lg 5,32(1)\n\t" \
|
"lg 5,32(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,160\n\t" \
|
"aghi 15,160\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||||
|
|
@ -4935,9 +4846,9 @@ typedef
|
||||||
"lg 6,40(1)\n\t" \
|
"lg 6,40(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,160\n\t" \
|
"aghi 15,160\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -4969,9 +4880,9 @@ typedef
|
||||||
"mvc 160(8,15), 48(1)\n\t" \
|
"mvc 160(8,15), 48(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,168\n\t" \
|
"aghi 15,168\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5005,9 +4916,9 @@ typedef
|
||||||
"mvc 168(8,15), 56(1)\n\t" \
|
"mvc 168(8,15), 56(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,176\n\t" \
|
"aghi 15,176\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5043,9 +4954,9 @@ typedef
|
||||||
"mvc 176(8,15), 64(1)\n\t" \
|
"mvc 176(8,15), 64(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,184\n\t" \
|
"aghi 15,184\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5083,9 +4994,9 @@ typedef
|
||||||
"mvc 184(8,15), 72(1)\n\t" \
|
"mvc 184(8,15), 72(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,192\n\t" \
|
"aghi 15,192\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5125,9 +5036,9 @@ typedef
|
||||||
"mvc 192(8,15), 80(1)\n\t" \
|
"mvc 192(8,15), 80(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,200\n\t" \
|
"aghi 15,200\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5169,9 +5080,9 @@ typedef
|
||||||
"mvc 200(8,15), 88(1)\n\t" \
|
"mvc 200(8,15), 88(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,208\n\t" \
|
"aghi 15,208\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5215,9 +5126,9 @@ typedef
|
||||||
"mvc 208(8,15), 96(1)\n\t" \
|
"mvc 208(8,15), 96(1)\n\t" \
|
||||||
"lg 1, 0(1)\n\t" \
|
"lg 1, 0(1)\n\t" \
|
||||||
VALGRIND_CALL_NOREDIR_R1 \
|
VALGRIND_CALL_NOREDIR_R1 \
|
||||||
|
"lgr %0, 2\n\t" \
|
||||||
"aghi 15,216\n\t" \
|
"aghi 15,216\n\t" \
|
||||||
VALGRIND_CFI_EPILOGUE \
|
VALGRIND_CFI_EPILOGUE \
|
||||||
"lgr %0, 2\n\t" \
|
|
||||||
: /*out*/ "=d" (_res) \
|
: /*out*/ "=d" (_res) \
|
||||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||||
|
|
@ -5767,422 +5678,6 @@ typedef
|
||||||
|
|
||||||
#endif /* PLAT_mips32_linux */
|
#endif /* PLAT_mips32_linux */
|
||||||
|
|
||||||
/* ------------------------- nanomips-linux -------------------- */
|
|
||||||
|
|
||||||
#if defined(PLAT_nanomips_linux)
|
|
||||||
|
|
||||||
/* These regs are trashed by the hidden call. */
|
|
||||||
#define __CALLER_SAVED_REGS "$t4", "$t5", "$a0", "$a1", "$a2", \
|
|
||||||
"$a3", "$a4", "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3", \
|
|
||||||
"$t8","$t9", "$at"
|
|
||||||
|
|
||||||
/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
|
|
||||||
long) == 4. */
|
|
||||||
|
|
||||||
#define CALL_FN_W_v(lval, orig) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[1]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_W(lval, orig, arg1) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[2]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[3]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[4]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
"lw $a2,12(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[5]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
"lw $a2,12(%1)\n\t" \
|
|
||||||
"lw $a3,16(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[6]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
"lw $a2,12(%1)\n\t" \
|
|
||||||
"lw $a3,16(%1)\n\t" \
|
|
||||||
"lw $a4,20(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[7]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
"lw $a2,12(%1)\n\t" \
|
|
||||||
"lw $a3,16(%1)\n\t" \
|
|
||||||
"lw $a4,20(%1)\n\t" \
|
|
||||||
"lw $a5,24(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
|
|
||||||
arg7) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[8]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
_argvec[7] = (unsigned long)(arg7); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
"lw $a2,12(%1)\n\t" \
|
|
||||||
"lw $a3,16(%1)\n\t" \
|
|
||||||
"lw $a4,20(%1)\n\t" \
|
|
||||||
"lw $a5,24(%1)\n\t" \
|
|
||||||
"lw $a6,28(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
|
|
||||||
arg7,arg8) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[9]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
_argvec[7] = (unsigned long)(arg7); \
|
|
||||||
_argvec[8] = (unsigned long)(arg8); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"lw $t9, 0(%1)\n\t" \
|
|
||||||
"lw $a0, 4(%1)\n\t" \
|
|
||||||
"lw $a1, 8(%1)\n\t" \
|
|
||||||
"lw $a2,12(%1)\n\t" \
|
|
||||||
"lw $a3,16(%1)\n\t" \
|
|
||||||
"lw $a4,20(%1)\n\t" \
|
|
||||||
"lw $a5,24(%1)\n\t" \
|
|
||||||
"lw $a6,28(%1)\n\t" \
|
|
||||||
"lw $a7,32(%1)\n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0\n" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
|
|
||||||
arg7,arg8,arg9) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[10]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
_argvec[7] = (unsigned long)(arg7); \
|
|
||||||
_argvec[8] = (unsigned long)(arg8); \
|
|
||||||
_argvec[9] = (unsigned long)(arg9); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"addiu $sp, $sp, -16 \n\t" \
|
|
||||||
"lw $t9,36(%1) \n\t" \
|
|
||||||
"sw $t9, 0($sp) \n\t" \
|
|
||||||
"lw $t9, 0(%1) \n\t" \
|
|
||||||
"lw $a0, 4(%1) \n\t" \
|
|
||||||
"lw $a1, 8(%1) \n\t" \
|
|
||||||
"lw $a2,12(%1) \n\t" \
|
|
||||||
"lw $a3,16(%1) \n\t" \
|
|
||||||
"lw $a4,20(%1) \n\t" \
|
|
||||||
"lw $a5,24(%1) \n\t" \
|
|
||||||
"lw $a6,28(%1) \n\t" \
|
|
||||||
"lw $a7,32(%1) \n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0 \n\t" \
|
|
||||||
"addiu $sp, $sp, 16 \n\t" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
|
|
||||||
arg7,arg8,arg9,arg10) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[11]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
_argvec[7] = (unsigned long)(arg7); \
|
|
||||||
_argvec[8] = (unsigned long)(arg8); \
|
|
||||||
_argvec[9] = (unsigned long)(arg9); \
|
|
||||||
_argvec[10] = (unsigned long)(arg10); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"addiu $sp, $sp, -16 \n\t" \
|
|
||||||
"lw $t9,36(%1) \n\t" \
|
|
||||||
"sw $t9, 0($sp) \n\t" \
|
|
||||||
"lw $t9,40(%1) \n\t" \
|
|
||||||
"sw $t9, 4($sp) \n\t" \
|
|
||||||
"lw $t9, 0(%1) \n\t" \
|
|
||||||
"lw $a0, 4(%1) \n\t" \
|
|
||||||
"lw $a1, 8(%1) \n\t" \
|
|
||||||
"lw $a2,12(%1) \n\t" \
|
|
||||||
"lw $a3,16(%1) \n\t" \
|
|
||||||
"lw $a4,20(%1) \n\t" \
|
|
||||||
"lw $a5,24(%1) \n\t" \
|
|
||||||
"lw $a6,28(%1) \n\t" \
|
|
||||||
"lw $a7,32(%1) \n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0 \n\t" \
|
|
||||||
"addiu $sp, $sp, 16 \n\t" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
|
|
||||||
arg6,arg7,arg8,arg9,arg10, \
|
|
||||||
arg11) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[12]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
_argvec[7] = (unsigned long)(arg7); \
|
|
||||||
_argvec[8] = (unsigned long)(arg8); \
|
|
||||||
_argvec[9] = (unsigned long)(arg9); \
|
|
||||||
_argvec[10] = (unsigned long)(arg10); \
|
|
||||||
_argvec[11] = (unsigned long)(arg11); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"addiu $sp, $sp, -16 \n\t" \
|
|
||||||
"lw $t9,36(%1) \n\t" \
|
|
||||||
"sw $t9, 0($sp) \n\t" \
|
|
||||||
"lw $t9,40(%1) \n\t" \
|
|
||||||
"sw $t9, 4($sp) \n\t" \
|
|
||||||
"lw $t9,44(%1) \n\t" \
|
|
||||||
"sw $t9, 8($sp) \n\t" \
|
|
||||||
"lw $t9, 0(%1) \n\t" \
|
|
||||||
"lw $a0, 4(%1) \n\t" \
|
|
||||||
"lw $a1, 8(%1) \n\t" \
|
|
||||||
"lw $a2,12(%1) \n\t" \
|
|
||||||
"lw $a3,16(%1) \n\t" \
|
|
||||||
"lw $a4,20(%1) \n\t" \
|
|
||||||
"lw $a5,24(%1) \n\t" \
|
|
||||||
"lw $a6,28(%1) \n\t" \
|
|
||||||
"lw $a7,32(%1) \n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0 \n\t" \
|
|
||||||
"addiu $sp, $sp, 16 \n\t" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
|
|
||||||
arg6,arg7,arg8,arg9,arg10, \
|
|
||||||
arg11,arg12) \
|
|
||||||
do { \
|
|
||||||
volatile OrigFn _orig = (orig); \
|
|
||||||
volatile unsigned long _argvec[13]; \
|
|
||||||
volatile unsigned long _res; \
|
|
||||||
_argvec[0] = (unsigned long)_orig.nraddr; \
|
|
||||||
_argvec[1] = (unsigned long)(arg1); \
|
|
||||||
_argvec[2] = (unsigned long)(arg2); \
|
|
||||||
_argvec[3] = (unsigned long)(arg3); \
|
|
||||||
_argvec[4] = (unsigned long)(arg4); \
|
|
||||||
_argvec[5] = (unsigned long)(arg5); \
|
|
||||||
_argvec[6] = (unsigned long)(arg6); \
|
|
||||||
_argvec[7] = (unsigned long)(arg7); \
|
|
||||||
_argvec[8] = (unsigned long)(arg8); \
|
|
||||||
_argvec[9] = (unsigned long)(arg9); \
|
|
||||||
_argvec[10] = (unsigned long)(arg10); \
|
|
||||||
_argvec[11] = (unsigned long)(arg11); \
|
|
||||||
_argvec[12] = (unsigned long)(arg12); \
|
|
||||||
__asm__ volatile( \
|
|
||||||
"addiu $sp, $sp, -16 \n\t" \
|
|
||||||
"lw $t9,36(%1) \n\t" \
|
|
||||||
"sw $t9, 0($sp) \n\t" \
|
|
||||||
"lw $t9,40(%1) \n\t" \
|
|
||||||
"sw $t9, 4($sp) \n\t" \
|
|
||||||
"lw $t9,44(%1) \n\t" \
|
|
||||||
"sw $t9, 8($sp) \n\t" \
|
|
||||||
"lw $t9,48(%1) \n\t" \
|
|
||||||
"sw $t9,12($sp) \n\t" \
|
|
||||||
"lw $t9, 0(%1) \n\t" \
|
|
||||||
"lw $a0, 4(%1) \n\t" \
|
|
||||||
"lw $a1, 8(%1) \n\t" \
|
|
||||||
"lw $a2,12(%1) \n\t" \
|
|
||||||
"lw $a3,16(%1) \n\t" \
|
|
||||||
"lw $a4,20(%1) \n\t" \
|
|
||||||
"lw $a5,24(%1) \n\t" \
|
|
||||||
"lw $a6,28(%1) \n\t" \
|
|
||||||
"lw $a7,32(%1) \n\t" \
|
|
||||||
VALGRIND_CALL_NOREDIR_T9 \
|
|
||||||
"move %0, $a0 \n\t" \
|
|
||||||
"addiu $sp, $sp, 16 \n\t" \
|
|
||||||
: /*out*/ "=r" (_res) \
|
|
||||||
: /*in*/ "r" (&_argvec[0]) \
|
|
||||||
: /*trash*/ "memory", __CALLER_SAVED_REGS \
|
|
||||||
); \
|
|
||||||
lval = (__typeof__(lval)) _res; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif /* PLAT_nanomips_linux */
|
|
||||||
|
|
||||||
/* ------------------------- mips64-linux ------------------------- */
|
/* ------------------------- mips64-linux ------------------------- */
|
||||||
|
|
||||||
#if defined(PLAT_mips64_linux)
|
#if defined(PLAT_mips64_linux)
|
||||||
|
|
@ -6651,10 +6146,6 @@ typedef
|
||||||
command. */
|
command. */
|
||||||
VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
|
VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
|
||||||
|
|
||||||
/* Allows the client program to change a dynamic command line
|
|
||||||
option. */
|
|
||||||
VG_USERREQ__CLO_CHANGE = 0x1203,
|
|
||||||
|
|
||||||
/* These are useful and can be interpreted by any tool that
|
/* These are useful and can be interpreted by any tool that
|
||||||
tracks malloc() et al, by using vg_replace_malloc.c. */
|
tracks malloc() et al, by using vg_replace_malloc.c. */
|
||||||
VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
|
VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
|
||||||
|
|
@ -7137,14 +6628,6 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
|
||||||
command, 0, 0, 0, 0)
|
command, 0, 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
/* Change the value of a dynamic command line option.
|
|
||||||
Note that unknown or not dynamically changeable options
|
|
||||||
will cause a warning message to be output. */
|
|
||||||
#define VALGRIND_CLO_CHANGE(option) \
|
|
||||||
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CLO_CHANGE, \
|
|
||||||
option, 0, 0, 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
#undef PLAT_x86_darwin
|
#undef PLAT_x86_darwin
|
||||||
#undef PLAT_amd64_darwin
|
#undef PLAT_amd64_darwin
|
||||||
#undef PLAT_x86_win32
|
#undef PLAT_x86_win32
|
||||||
|
|
@ -7158,7 +6641,6 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
|
||||||
#undef PLAT_s390x_linux
|
#undef PLAT_s390x_linux
|
||||||
#undef PLAT_mips32_linux
|
#undef PLAT_mips32_linux
|
||||||
#undef PLAT_mips64_linux
|
#undef PLAT_mips64_linux
|
||||||
#undef PLAT_nanomips_linux
|
|
||||||
#undef PLAT_x86_solaris
|
#undef PLAT_x86_solaris
|
||||||
#undef PLAT_amd64_solaris
|
#undef PLAT_amd64_solaris
|
||||||
|
|
||||||
|
|
|
||||||
820
meson.build
|
|
@ -10,10 +10,6 @@ option('libwacom',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: true,
|
value: true,
|
||||||
description: 'Use libwacom for tablet identification (default=true)')
|
description: 'Use libwacom for tablet identification (default=true)')
|
||||||
option('mtdev',
|
|
||||||
type: 'boolean',
|
|
||||||
value: true,
|
|
||||||
description: 'Use mtdev for multitouch protocol A devices (default=true)')
|
|
||||||
option('debug-gui',
|
option('debug-gui',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: true,
|
value: true,
|
||||||
|
|
@ -28,8 +24,8 @@ option('install-tests',
|
||||||
description: 'Install the libinput test command [default=false]')
|
description: 'Install the libinput test command [default=false]')
|
||||||
option('documentation',
|
option('documentation',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: false,
|
value: true,
|
||||||
description: 'Build the documentation [default=false]')
|
description: 'Build the documentation [default=true]')
|
||||||
option('coverity',
|
option('coverity',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
value: false,
|
value: false,
|
||||||
|
|
@ -38,15 +34,3 @@ option('zshcompletiondir',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
value: '',
|
value: '',
|
||||||
description: 'Directory for zsh completion scripts ["no" disables]')
|
description: 'Directory for zsh completion scripts ["no" disables]')
|
||||||
option('internal-event-debugging',
|
|
||||||
type: 'boolean',
|
|
||||||
value: false,
|
|
||||||
description: 'Enable additional internal event debug tracing. This will print key values to the logs and thus must never be enabled in a release build')
|
|
||||||
option('autoload-plugins',
|
|
||||||
type: 'boolean',
|
|
||||||
value: false,
|
|
||||||
description: 'Always load plugins from default plugin paths (only if the caller does not do so)')
|
|
||||||
option('lua-plugins',
|
|
||||||
type: 'feature',
|
|
||||||
value: 'auto',
|
|
||||||
description: 'Enable support for Lua plugins')
|
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This is an example libinput plugin
|
|
||||||
--
|
|
||||||
-- This plugin detects the Copilot key on the keyboard with
|
|
||||||
-- the given VID/PID and replaces it with a different key (sequence).
|
|
||||||
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
|
|
||||||
-- Replace this with your keyboard's VID/PID
|
|
||||||
KEYBOARD_VID = 0x046d
|
|
||||||
KEYBOARD_PID = 0x4088
|
|
||||||
|
|
||||||
meta_is_down = false
|
|
||||||
shift_is_down = false
|
|
||||||
|
|
||||||
-- shift-A, because you can never have enough screaming
|
|
||||||
replacement_sequence = { evdev.KEY_LEFTSHIFT, evdev.KEY_A }
|
|
||||||
|
|
||||||
function frame(device, frame, _)
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
if v.value ~= 2 then -- ignore key repeats
|
|
||||||
if v.usage == evdev.KEY_LEFTMETA then
|
|
||||||
meta_is_down = v.value == 1
|
|
||||||
elseif v.usage == evdev.KEY_LEFTSHIFT then
|
|
||||||
shift_is_down = v.value == 1
|
|
||||||
elseif v.usage == evdev.KEY_F23 and meta_is_down and shift_is_down then
|
|
||||||
-- We know from the MS requirements that F23 for copilot is
|
|
||||||
-- either last key (on press) or the first key (on release)
|
|
||||||
-- of the three-key sequence, and no other keys are
|
|
||||||
-- within this frame.
|
|
||||||
if v.value == 1 then
|
|
||||||
-- Release our modifiers first
|
|
||||||
device:prepend_frame({
|
|
||||||
{ usage = evdev.KEY_LEFTSHIFT, value = 0 },
|
|
||||||
{ usage = evdev.KEY_LEFTMETA, value = 0 },
|
|
||||||
})
|
|
||||||
-- Insert our replacement press sequence
|
|
||||||
local replacement_frame = {}
|
|
||||||
for _, rv in ipairs(replacement_sequence) do
|
|
||||||
table.insert(replacement_frame, { usage = rv, value = 1 })
|
|
||||||
end
|
|
||||||
device:append_frame(replacement_frame)
|
|
||||||
else
|
|
||||||
-- Insert our replacement release sequence
|
|
||||||
local replacement_frame = {}
|
|
||||||
for idx = #replacement_sequence, 1, -1 do
|
|
||||||
table.insert(replacement_frame, { usage = replacement_sequence[idx], value = 0 })
|
|
||||||
end
|
|
||||||
device:append_frame(replacement_frame)
|
|
||||||
|
|
||||||
-- we don't care about re-pressing shift/meta because the
|
|
||||||
-- rest of the stack will filter the release for an
|
|
||||||
-- unpressed key anyway.
|
|
||||||
end
|
|
||||||
|
|
||||||
return {} -- discard this frame
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function device_new(device)
|
|
||||||
local info = device:info()
|
|
||||||
if info.vid == KEYBOARD_VID and info.pid == KEYBOARD_PID then
|
|
||||||
device:connect("evdev-frame", frame)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
libinput:connect("new-evdev-device", device_new)
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This is an example libinput plugin
|
|
||||||
--
|
|
||||||
-- This plugin delays any event with relative motion by the given DELAY
|
|
||||||
-- by storing it in a table and replaying it via a timer callback later.
|
|
||||||
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
|
|
||||||
DELAY = 1500 * 1000 -- 1.5s
|
|
||||||
next_timer_expiry = 0
|
|
||||||
devices = {}
|
|
||||||
|
|
||||||
function timer_expired(time_in_microseconds)
|
|
||||||
next_timer_expiry = 0
|
|
||||||
for device, frames in pairs(devices) do
|
|
||||||
while #frames > 0 and frames[1].time <= time_in_microseconds do
|
|
||||||
--- we don't have a current frame so it doesn't matter
|
|
||||||
--- whether we prepend or append
|
|
||||||
device:prepend_frame(frames[1].frame)
|
|
||||||
table.remove(frames, 1)
|
|
||||||
end
|
|
||||||
local next_frame = frames[1]
|
|
||||||
if next_frame and (next_timer_expiry == 0 or next_frame.time < next_timer_expiry) then
|
|
||||||
next_timer_expiry = next_frame.time
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if next_timer_expiry ~= 0 then
|
|
||||||
libinput:timer_set_absolute(next_timer_expiry)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function frame(device, frame, timestamp)
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
|
|
||||||
local next_time = timestamp + DELAY
|
|
||||||
table.insert(devices[device], {
|
|
||||||
time = next_time,
|
|
||||||
frame = frame
|
|
||||||
})
|
|
||||||
if next_timer_expiry == 0 then
|
|
||||||
next_timer_expiry = next_time
|
|
||||||
libinput:timer_set_absolute(next_timer_expiry)
|
|
||||||
end
|
|
||||||
return {} -- discard frame
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function device_new(device)
|
|
||||||
local usages = device:usages()
|
|
||||||
if usages[evdev.REL_X] then
|
|
||||||
devices[device] = {}
|
|
||||||
device:connect("evdev-frame", frame)
|
|
||||||
device:connect("device-removed", function(dev)
|
|
||||||
devices[dev] = nil
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
libinput:connect("new-evdev-device", device_new)
|
|
||||||
libinput:connect("timer-expired", timer_expired)
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- An example plugin to show how to disable an internal feature.
|
|
||||||
--
|
|
||||||
-- Typically one would expect the plugin to re-implement the feature
|
|
||||||
-- in a more device-specific manner but that's not done here.
|
|
||||||
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
libinput:connect("new-evdev-device", function(device)
|
|
||||||
local udev_info = device:udev_properties()
|
|
||||||
if udev_info["ID_INPUT_TOUCHPAD"] then
|
|
||||||
libinput:log_info("Disabling palm detection on " .. device:name())
|
|
||||||
device:disable_feature("touchpad-palm-detection")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This plugin implements a very simple version of disable-while-typing.
|
|
||||||
-- It monitors all keyboard devices and if any of them send an event,
|
|
||||||
-- any touchpad device is disabled for 2 seconds.
|
|
||||||
-- And "disabled" means any event from that touchpad is simply
|
|
||||||
-- discarded.
|
|
||||||
--
|
|
||||||
-- Install this file in /etc/libinput/plugins and
|
|
||||||
--
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
|
|
||||||
tp_enabled = true
|
|
||||||
|
|
||||||
libinput:connect("timer-expired", function(now)
|
|
||||||
libinput:log_debug("touchpad enabled")
|
|
||||||
tp_enabled = true
|
|
||||||
end)
|
|
||||||
|
|
||||||
libinput:connect("new-evdev-device", function (device)
|
|
||||||
local props = device:udev_properties()
|
|
||||||
if props.ID_INPUT_KEYBOARD then
|
|
||||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
|
||||||
libinput:timer_set_relative(2000000)
|
|
||||||
if tp_enabled then
|
|
||||||
libinput:log_debug("touchpad disabled")
|
|
||||||
tp_enabled = false
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
elseif props.ID_INPUT_TOUCHPAD then
|
|
||||||
libinput:log_debug("Touchpad detected: " .. device:name())
|
|
||||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
|
||||||
if not tp_enabled then
|
|
||||||
-- Returning an empty table discards the event.
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This is an example libinput plugin
|
|
||||||
--
|
|
||||||
-- This plugin swaps left and right buttons on any device that has both buttons.
|
|
||||||
|
|
||||||
-- Let's create a plugin. A single Lua script may create more than one
|
|
||||||
-- plugin instance but that's a bit of a nice use-case. Most scripts
|
|
||||||
-- should be a single plugin.
|
|
||||||
|
|
||||||
-- A plugin needs to be registered to activate. If it isn't, it is
|
|
||||||
-- cleaned up immediately. In the register call we supply
|
|
||||||
-- the list of plugin versions we support. Currently we only
|
|
||||||
-- have version 1.
|
|
||||||
--
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
|
|
||||||
-- Note to the reader: it will be easier to understand this example
|
|
||||||
-- if you read it bottom-up from here on.
|
|
||||||
|
|
||||||
-- The callback for our "evdev-frame" signal.
|
|
||||||
-- These frames are sent *before* libinput gets to handle them so
|
|
||||||
-- any modifications will affect libinput.
|
|
||||||
function frame(device, frame, time_in_microseconds)
|
|
||||||
-- Frame is a table in the form
|
|
||||||
-- { { usage: 123, value: 3 }, ... }
|
|
||||||
-- Let's use the evdev module to make it more readable, evdev.KEY_A
|
|
||||||
-- is simply the value (0x1 << 16) | 0x1 (see linux/input-event-codes.h)
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
-- If we get a right button event, change it to left, and
|
|
||||||
-- vice versa. Because this happens before libinput (or the next
|
|
||||||
-- plugin in the precedence order) sees the
|
|
||||||
-- frame it doesn't know that the swap happened.
|
|
||||||
if v.usage == evdev.BTN_RIGHT then
|
|
||||||
v.usage = evdev.BTN_LEFT
|
|
||||||
elseif v.usage == evdev.BTN_LEFT then
|
|
||||||
v.usage = evdev.BTN_RIGHT
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- We changed the frame, let's return it. If we return nil
|
|
||||||
-- the original frame is being used as-is.
|
|
||||||
return frame
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This is a timer callback. It is invoked after one second
|
|
||||||
-- (see below) but only once - re-set the timer so
|
|
||||||
-- it goes off every second.
|
|
||||||
function timer_expired(time_in_microseconds)
|
|
||||||
libinput:timer_set_absolute(time_in_microseconds + 1000000)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Callback for the "new-evdev-device" signal, see below
|
|
||||||
-- The argument is the EvdevDevice object, see the documentation.
|
|
||||||
function device_new(device)
|
|
||||||
-- A table of evdev usages available on our device.
|
|
||||||
-- Using the evdev module makes it more readable but you can
|
|
||||||
-- use numbers (which is what evdev.EV_KEY and
|
|
||||||
-- friends resolve to anyway).
|
|
||||||
local usages = device:usages()
|
|
||||||
if usages[evdev.BTN_LEFT] and usages[evdev.BTN_RIGHT] then
|
|
||||||
-- The "evdev-frame" callback is invoked whenever the device
|
|
||||||
-- provided us with one evdev frame, i.e. a bunch of events up
|
|
||||||
-- to excluding EV_SYN SYN_REPORT.
|
|
||||||
device:connect("evdev-frame", frame)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- The device has udev information, let's print it out. Right
|
|
||||||
-- now all we get are the ID_INPUT_ bits.
|
|
||||||
-- If this is empty we know libinput will ignore this device anyway
|
|
||||||
local udev_info = device:udev_properties()
|
|
||||||
for k, v in pairs(udev_info) do
|
|
||||||
libinput:log_debug(k .. "=" .. v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Let's connect to the "new-evdev-device" signal. This function
|
|
||||||
-- is invoked when libinput detects a new evdev device (but before
|
|
||||||
-- that device is actually available to libinput as libinput device).
|
|
||||||
-- This allows us to e.g. change properties on the device.
|
|
||||||
libinput:connect("new-evdev-device", device_new)
|
|
||||||
|
|
||||||
-- Set our timer to expire 1s from now (in microseconds).
|
|
||||||
-- Timers are absolute, so they need to be added to the
|
|
||||||
-- current time
|
|
||||||
libinput:connect("timer-expired", timer_expired)
|
|
||||||
libinput:timer_set_relative(1000000)
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This plugin inverts the horizontal scroll direction of
|
|
||||||
-- the Logitech MX Master mouse. OOTB the mouse scrolls
|
|
||||||
-- in the opposite direction to all other mice out there.
|
|
||||||
--
|
|
||||||
-- This plugin is only needed when the mouse is connected
|
|
||||||
-- to the Logitech Bolt receiver - on that receiver we cannot
|
|
||||||
-- tell which device is connected.
|
|
||||||
--
|
|
||||||
-- For the Logitech Unifying receiver and Bluetooth please
|
|
||||||
-- add the ModelInvertHorizontalScrolling=1 quirk
|
|
||||||
-- in quirks/30-vendor-logitech.quirks.
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- Install this file in /etc/libinput/plugins and
|
|
||||||
--
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
libinput:connect("new-evdev-device", function (device)
|
|
||||||
local info = device:info()
|
|
||||||
if info.vid == 0x046D and info.pid == 0xC548 then
|
|
||||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
|
||||||
for _, event in ipairs(frame) do
|
|
||||||
if event.usage == evdev.REL_HWHEEL or event.usage == evdev.REL_HWHEEL_HI_RES then
|
|
||||||
event.value = -event.value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return frame
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- An example plugin to make the pointer go three times as fast
|
|
||||||
--
|
|
||||||
-- Install this file in /etc/libinput/plugins and
|
|
||||||
--
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
libinput:connect("new-evdev-device", function(device)
|
|
||||||
local usages = device:usages()
|
|
||||||
if usages[evdev.REL_X] then
|
|
||||||
device:connect("evdev-frame", function(device, frame, timestamp)
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
|
|
||||||
-- Multiply the relative motion by 3
|
|
||||||
v.value = v.value * 3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return frame
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- An example plugin to make the pointer go three times as slow
|
|
||||||
--
|
|
||||||
-- Install this file in /etc/libinput/plugins and
|
|
||||||
--
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
remainders = {}
|
|
||||||
|
|
||||||
function split(v)
|
|
||||||
if math.abs(v) >= 1.0 then
|
|
||||||
local i = math.floor(math.abs(v))
|
|
||||||
local r = math.abs(v) % 1.0
|
|
||||||
if v < 0.0 then
|
|
||||||
i = -i
|
|
||||||
r = -r
|
|
||||||
end
|
|
||||||
return i, r
|
|
||||||
else
|
|
||||||
return 0, v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function decelerate(device, x, y)
|
|
||||||
local remainder = remainders[device]
|
|
||||||
local rx, ry = 0, 0
|
|
||||||
if x ~= 0.0 then
|
|
||||||
rx, remainder.x = split(remainder.x + x/3.0)
|
|
||||||
end
|
|
||||||
if y ~= 0.0 then
|
|
||||||
ry, remainder.y = split(remainder.y + y/3.0)
|
|
||||||
end
|
|
||||||
|
|
||||||
return rx, ry
|
|
||||||
end
|
|
||||||
|
|
||||||
libinput:connect("new-evdev-device", function(device)
|
|
||||||
local usages = device:usages()
|
|
||||||
if usages[evdev.REL_X] then
|
|
||||||
remainders[device] = { x = 0.0, y = 0.0 }
|
|
||||||
device:connect("evdev-frame", function(device, frame, timestamp)
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
if v.usage == evdev.REL_X then
|
|
||||||
v.value, _ = decelerate(device, v.value, 0.0)
|
|
||||||
elseif v.usage == evdev.REL_Y then
|
|
||||||
_, v.value = decelerate(device, 0.0, v.value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return frame
|
|
||||||
end)
|
|
||||||
device:connect("device-removed", function(dev)
|
|
||||||
remainders[dev] = nil
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This is an example libinput plugin
|
|
||||||
--
|
|
||||||
-- This plugin controls a mouse/pointer from a tablet device. This
|
|
||||||
-- effectively hides stylus interactions and sends pointer events
|
|
||||||
-- instead. In other words: mouse emulation for tablets, implemented
|
|
||||||
-- by (remote) controlling a mouse device. This allows using a
|
|
||||||
-- tablet stylus as a mouse replacement without tablet limitations
|
|
||||||
-- from compositors or clients. Note that axis usually needed for
|
|
||||||
-- drawing (like pressure, tilt or distance) are no longer emitted
|
|
||||||
-- when this plugin is active and a mouse is connected. When no
|
|
||||||
-- mouse is connected, this plugin doesn't change tablet events,
|
|
||||||
-- thus the stylus works like a normal stylus.
|
|
||||||
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
|
|
||||||
-- globals
|
|
||||||
pointer_device = nil
|
|
||||||
tablet_device = nil
|
|
||||||
maximum_x = nil
|
|
||||||
maximum_y = nil
|
|
||||||
|
|
||||||
function adjust_for_aspect_ratio(y)
|
|
||||||
-- adjust y to match monitor 21:9 aspect ratio
|
|
||||||
local adj_maximum_y = maximum_x * 1440 / 3440
|
|
||||||
return math.floor(math.min(y * maximum_y / adj_maximum_y, maximum_y + 1))
|
|
||||||
end
|
|
||||||
|
|
||||||
function on_tablet_frame(device, frame, time_in_microseconds)
|
|
||||||
-- emit tablet frame when there is no pointer device
|
|
||||||
if not pointer_device then return nil end
|
|
||||||
|
|
||||||
-- map tablet frame to pointer frame
|
|
||||||
local events = {}
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
if v.usage == evdev.ABS_MISC then
|
|
||||||
-- save a few cycles on Wacom tablets by discarding a
|
|
||||||
-- proximity in / out frame early, non-Wacom tablets should
|
|
||||||
-- use BTN_TOOL_PEN/RUBBER/... instead
|
|
||||||
return {}
|
|
||||||
elseif v.usage == evdev.ABS_X then
|
|
||||||
table.insert(events, { usage = evdev.ABS_X, value = v.value })
|
|
||||||
elseif v.usage == evdev.ABS_Y then
|
|
||||||
-- uncomment the next two lines and comment the original line
|
|
||||||
-- for configuring aspect correction, see
|
|
||||||
-- adjust_for_aspect_ratio() for details and configuration
|
|
||||||
|
|
||||||
-- local adj_value = adjust_for_aspect_ratio(v.value)
|
|
||||||
-- table.insert(events, { usage = evdev.ABS_Y, value = adj_value })
|
|
||||||
table.insert(events, { usage = evdev.ABS_Y, value = v.value })
|
|
||||||
elseif v.usage == evdev.BTN_TOUCH then
|
|
||||||
table.insert(events, { usage = evdev.BTN_LEFT, value = v.value })
|
|
||||||
elseif v.usage == evdev.BTN_STYLUS then
|
|
||||||
table.insert(events, { usage = evdev.BTN_RIGHT, value = v.value })
|
|
||||||
elseif v.usage == evdev.BTN_STYLUS2 then
|
|
||||||
table.insert(events, { usage = evdev.BTN_MIDDLE, value = v.value })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- emit pointer frame, if any
|
|
||||||
if #events > 0 then pointer_device:append_frame(events) end
|
|
||||||
|
|
||||||
-- discard tablet frame
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function on_tablet_removed(device)
|
|
||||||
libinput:log_info("Remove tablet device")
|
|
||||||
tablet_device = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function on_pointer_removed(device)
|
|
||||||
libinput:log_info("Remove pointer device")
|
|
||||||
pointer_device = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function setup()
|
|
||||||
if not pointer_device or not tablet_device then return end
|
|
||||||
|
|
||||||
libinput:log_info("Controlling '" .. pointer_device:name() .. "' with '" .. tablet_device:name() .. "'")
|
|
||||||
|
|
||||||
-- fetch absinfos from tablet
|
|
||||||
local absinfo_x = {}
|
|
||||||
local absinfo_y = {}
|
|
||||||
for a, b in pairs(tablet_device:absinfos()) do
|
|
||||||
if a == evdev.ABS_X then absinfo_x = b end
|
|
||||||
if a == evdev.ABS_Y then absinfo_y = b end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- copy max values for aspect ratio correction later on
|
|
||||||
maximum_x = absinfo_x.maximum
|
|
||||||
maximum_y = absinfo_y.maximum
|
|
||||||
|
|
||||||
-- copy absinfos to pointer device
|
|
||||||
pointer_device:set_absinfo(evdev.ABS_X, absinfo_x)
|
|
||||||
pointer_device:set_absinfo(evdev.ABS_Y, absinfo_y)
|
|
||||||
|
|
||||||
-- setup listeners
|
|
||||||
pointer_device:connect("device-removed", on_pointer_removed)
|
|
||||||
tablet_device:connect("device-removed", on_tablet_removed)
|
|
||||||
tablet_device:connect("evdev-frame", on_tablet_frame)
|
|
||||||
end
|
|
||||||
|
|
||||||
function on_new_device(device)
|
|
||||||
local udev = device:udev_properties()
|
|
||||||
if udev["ID_INPUT_TABLET"] and not udev["ID_INPUT_TABLET_PAD"] then
|
|
||||||
libinput:log_info("Found tablet device")
|
|
||||||
tablet_device = device
|
|
||||||
setup()
|
|
||||||
end
|
|
||||||
if udev["ID_INPUT_MOUSE"] then
|
|
||||||
libinput:log_info("Found pointer device")
|
|
||||||
pointer_device = device
|
|
||||||
setup()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- setup listener
|
|
||||||
libinput:connect("new-evdev-device", on_new_device)
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
-- SPDX-License-Identifier: MIT
|
|
||||||
--
|
|
||||||
-- This is an example libinput plugin
|
|
||||||
--
|
|
||||||
-- This plugin maps a downwards mouse wheel to a button down event and
|
|
||||||
-- an upwards wheel movement to a button up event.
|
|
||||||
|
|
||||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
|
||||||
-- libinput:register({1})
|
|
||||||
|
|
||||||
-- The button we want to press on wheel events
|
|
||||||
local wheel_button = evdev.BTN_EXTRA
|
|
||||||
local button_states = {}
|
|
||||||
|
|
||||||
local function evdev_frame(device, frame, timestamp)
|
|
||||||
local events = {}
|
|
||||||
local modified = false
|
|
||||||
|
|
||||||
for _, v in ipairs(frame) do
|
|
||||||
if v.usage == evdev.REL_WHEEL then
|
|
||||||
-- REL_WHEEL is inverted, neg value -> down, pos value -> up
|
|
||||||
if v.value < 0 then
|
|
||||||
if not button_states[device] then
|
|
||||||
table.insert(events, { usage = wheel_button, value = 1 })
|
|
||||||
button_states[device] = true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if button_states[device] then
|
|
||||||
table.insert(events, { usage = wheel_button, value = 0 })
|
|
||||||
button_states[device] = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
modified = true
|
|
||||||
-- Because REL_WHEEL is no longer a wheel, the high-res
|
|
||||||
-- events are dropped
|
|
||||||
elseif v.usage == evdev.REL_WHEEL_HI_RES then
|
|
||||||
modified = true
|
|
||||||
else
|
|
||||||
table.insert(events, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if modified then
|
|
||||||
return events
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function device_new(device)
|
|
||||||
local usages = device:usages()
|
|
||||||
if usages[evdev.REL_WHEEL] then
|
|
||||||
button_states[device] = false
|
|
||||||
if not usages[wheel_button] then
|
|
||||||
device:enable_evdev_usage(wheel_button)
|
|
||||||
end
|
|
||||||
device:connect("evdev-frame", evdev_frame)
|
|
||||||
device:connect("device-removed", function(dev)
|
|
||||||
button_states[dev] = nil
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
libinput:connect("new-evdev-device", device_new)
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
plugins = [
|
|
||||||
'10-example.lua',
|
|
||||||
'10-dwt.lua',
|
|
||||||
'10-logitech-mx-master-horiz-scroll.lua',
|
|
||||||
'10-pointer-go-faster.lua',
|
|
||||||
'10-pointer-go-slower.lua',
|
|
||||||
'10-delay-motion.lua',
|
|
||||||
'10-disable-feature.lua',
|
|
||||||
'10-copilot-key-override.lua',
|
|
||||||
'10-wheel-to-button.lua',
|
|
||||||
'10-tablet-mouse-control.lua',
|
|
||||||
]
|
|
||||||
|
|
||||||
fs = import('fs')
|
|
||||||
foreach plugin : plugins
|
|
||||||
fs.copyfile(plugin)
|
|
||||||
endforeach
|
|
||||||
|
|
@ -9,23 +9,3 @@ AttrKeyboardIntegration=internal
|
||||||
MatchUdevType=keyboard
|
MatchUdevType=keyboard
|
||||||
MatchBus=bluetooth
|
MatchBus=bluetooth
|
||||||
AttrKeyboardIntegration=external
|
AttrKeyboardIntegration=external
|
||||||
|
|
||||||
# Detachable devices usually have the tablet part buttons wired as ps2 keyboard,
|
|
||||||
# don't disable them when tablet-mode switch is in effect.
|
|
||||||
# DMI Chassis Type 20h (32 decimal) is Detachable as per SMBIOS specification.
|
|
||||||
[Detachable Device Buttons]
|
|
||||||
MatchBus=ps2
|
|
||||||
MatchUdevType=keyboard
|
|
||||||
MatchDMIModalias=dmi:*:ct32:*
|
|
||||||
ModelTabletModeNoSuspend=1
|
|
||||||
|
|
||||||
# Tablet devices usually have the tablet part buttons wired as ps2 keyboard,
|
|
||||||
# despite being tablets some of them, e.g. Microsoft Surface Laptop Studio,
|
|
||||||
# expose tablet-mode switch, so don't disable the ps2 keyboard.
|
|
||||||
# Tablets that don't expose tablet-mode switch won't have any diference.
|
|
||||||
# DMI Chassis Type 1Eh (30 decimal) is Tablet as per SMBIOS specification.
|
|
||||||
[Tablet Device Buttons]
|
|
||||||
MatchBus=ps2
|
|
||||||
MatchUdevType=keyboard
|
|
||||||
MatchDMIModalias=dmi:*:ct30:*
|
|
||||||
ModelTabletModeNoSuspend=1
|
|
||||||
|
|
|
||||||
11
quirks/10-generic-lid.quirks
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Do not edit this file, it will be overwritten on update
|
||||||
|
|
||||||
|
[Lid Switch Ct9]
|
||||||
|
MatchName=*Lid Switch*
|
||||||
|
MatchDMIModalias=dmi:*:ct9:*
|
||||||
|
AttrLidSwitchReliability=reliable
|
||||||
|
|
||||||
|
[Lid Switch Ct10]
|
||||||
|
MatchName=*Lid Switch*
|
||||||
|
MatchDMIModalias=dmi:*:ct10:*
|
||||||
|
AttrLidSwitchReliability=reliable
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
|
||||||
|
|
||||||
# https://gitlab.freedesktop.org/libinput/libinput/-/issues/656
|
|
||||||
[Emulated Mouse]
|
|
||||||
MatchName=ImPS/2 Generic Wheel Mouse
|
|
||||||
ModelBouncingKeys=1
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
|
||||||
|
|
||||||
[A4TECH USB X-710BK]
|
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x09DA
|
|
||||||
MatchProduct=0x9090
|
|
||||||
ModelBouncingKeys=1
|
|
||||||