Compare commits
20 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a4c30f546 | ||
|
|
57ad6e5994 | ||
|
|
9b4f50472f | ||
|
|
54451cb7a0 | ||
|
|
f42b8dd1ae | ||
|
|
4813e63f79 | ||
|
|
26c65758e9 | ||
|
|
a3103ded82 | ||
|
|
b8d79df696 | ||
|
|
eea702e30a | ||
|
|
0cfe00f493 | ||
|
|
0d3d885a1a | ||
|
|
6df5169229 | ||
|
|
4f2f1d29ec | ||
|
|
4c1862c1e4 | ||
|
|
a49826a7a8 | ||
|
|
f905054b5b | ||
|
|
b8f90d074e | ||
|
|
7624497df5 | ||
|
|
1ca2f11524 |
|
|
@ -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
|
|
||||||
878
.gitlab-ci.yml
|
|
@ -8,10 +8,6 @@
|
||||||
# #
|
# #
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
# 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:
|
# This is a bit complicated for two reasons:
|
||||||
# - we really want to run dnf/apt/... only once, updating on the test runner for
|
# - 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
|
# each job takes forever. So we create a container image for each distribution
|
||||||
|
|
@ -36,39 +32,20 @@
|
||||||
# <distribution>:<version>@activity:
|
# <distribution>:<version>@activity:
|
||||||
# e.g. fedora:31@build-default
|
# e.g. fedora:31@build-default
|
||||||
|
|
||||||
.templates_sha: &template_sha c6aeb16f86e32525fa630fb99c66c4f3e62fc3cb
|
.templates_sha: &template_sha 18194044f0f984c8815bc9a1a146582f6bf15d41 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
{% for distro in distributions|sort(attribute="name") %}
|
||||||
|
{% if not distro.does_not_have_ci_templates %}
|
||||||
|
# {{ distro.name.capitalize() }} container builder template
|
||||||
- project: 'freedesktop/ci-templates'
|
- project: 'freedesktop/ci-templates'
|
||||||
ref: *template_sha
|
ref: *template_sha
|
||||||
file:
|
file: '/templates/{{distro.name}}.yml'
|
||||||
- '/templates/ci-fairy.yml'
|
{% endif %}
|
||||||
{% for distro in distributions|sort(attribute="name") %}
|
|
||||||
# {{ distro.name.capitalize() }} container builder template
|
|
||||||
- '/templates/{{distro.name}}.yml'
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
- project: 'freedesktop/ci-templates'
|
||||||
workflow:
|
ref: *template_sha
|
||||||
rules:
|
file: '/templates/ci-fairy.yml'
|
||||||
# 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:
|
stages:
|
||||||
- sanity check # CI/commit checks
|
- sanity check # CI/commit checks
|
||||||
|
|
@ -90,11 +67,12 @@ variables:
|
||||||
# distribution #
|
# distribution #
|
||||||
# #
|
# #
|
||||||
# See the documentation here: #
|
# See the documentation here: #
|
||||||
# https://wayland.freedesktop.org/libinput/doc/latest/building.html #
|
# https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
{% for distro in distributions %}
|
{% for distro in distributions %}
|
||||||
{{"%-17s" | format(distro.name.upper() + '_PACKAGES:')}} '{{ distro.packages|join(' ')}}'
|
{{"%-17s" | format(distro.name.upper() + '_PACKAGES:')}} '{{ distro.packages|join(' ')}}'
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
FREEBSD_BUILD_PKGS: 'meson'
|
||||||
############################ end of package lists #############################
|
############################ end of package lists #############################
|
||||||
|
|
||||||
# these tags should be updated each time the list of packages is updated
|
# these tags should be updated each time the list of packages is updated
|
||||||
|
|
@ -103,8 +81,14 @@ variables:
|
||||||
# libinput version
|
# libinput version
|
||||||
{% for distro in distributions %}
|
{% for distro in distributions %}
|
||||||
{{"%-13s"| format(distro.name.upper() + '_TAG:')}}'{{distro.tag}}'
|
{{"%-13s"| format(distro.name.upper() + '_TAG:')}}'{{distro.tag}}'
|
||||||
|
{% endfor %}
|
||||||
|
{% for distro in distributions %}
|
||||||
|
{% if distro.want_qemu %}
|
||||||
|
QEMU_TAG: 'qemu-vm-{{distro.tag}}'
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
FREEBSD_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/freebsd/11.2:$FREEBSD_TAG
|
||||||
FDO_UPSTREAM_REPO: libinput/libinput
|
FDO_UPSTREAM_REPO: libinput/libinput
|
||||||
|
|
||||||
MESON_BUILDDIR: "build dir"
|
MESON_BUILDDIR: "build dir"
|
||||||
|
|
@ -116,11 +100,6 @@ variables:
|
||||||
UDEV_NOT_AVAILABLE: 1
|
UDEV_NOT_AVAILABLE: 1
|
||||||
GIT_DEPTH: 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:
|
.policy:
|
||||||
retry:
|
retry:
|
||||||
max: 2
|
max: 2
|
||||||
|
|
@ -129,17 +108,6 @@ variables:
|
||||||
- stuck_or_timeout_failure
|
- stuck_or_timeout_failure
|
||||||
# cancel run when a newer version is pushed to the branch
|
# cancel run when a newer version is pushed to the branch
|
||||||
interruptible: true
|
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:
|
.default_artifacts:
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
@ -148,13 +116,8 @@ variables:
|
||||||
expire_in: 1 week
|
expire_in: 1 week
|
||||||
paths:
|
paths:
|
||||||
- $MESON_BUILDDIR/meson-logs
|
- $MESON_BUILDDIR/meson-logs
|
||||||
- $MESON_BUILDDIR/valgrind.*.log
|
|
||||||
reports:
|
reports:
|
||||||
junit: $MESON_BUILDDIR/*junit*.xml
|
junit: $MESON_BUILDDIR/junit-*.xml
|
||||||
|
|
||||||
.fdo-runner-tags:
|
|
||||||
tags:
|
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
@ -163,22 +126,6 @@ variables:
|
||||||
# #
|
# #
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
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
|
# 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
|
# If this job fails, re-generate the gitlab-ci.yml script, see
|
||||||
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
|
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
|
||||||
|
|
@ -186,90 +133,63 @@ fail-if-fork-is-not-public:
|
||||||
check-ci-script:
|
check-ci-script:
|
||||||
extends:
|
extends:
|
||||||
- .fdo.ci-fairy
|
- .fdo.ci-fairy
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
stage: sanity check
|
||||||
script:
|
script:
|
||||||
- ci-fairy generate-template --verify && exit 0 || true
|
- ci-fairy generate-template --verify && exit 0 || true
|
||||||
- >
|
- echo "Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify"
|
||||||
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
|
- exit 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Verify that commit messages are as expected, etc.
|
# Verify that commit messages are as expected, signed-off, etc.
|
||||||
#
|
#
|
||||||
|
|
||||||
check-commit:
|
check-commit:
|
||||||
extends:
|
extends:
|
||||||
- .fdo.ci-fairy
|
- .fdo.ci-fairy
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
stage: sanity check
|
||||||
script:
|
script:
|
||||||
- ci-fairy -vv check-commits --junit-xml=results.xml && exit 0 || true
|
- ci-fairy check-commits --signed-off-by --junit-xml=results.xml
|
||||||
- >
|
|
||||||
printf "%s\n" \
|
|
||||||
"Error checking commit format. Please verify" \
|
|
||||||
"https://wayland.freedesktop.org/libinput/doc/latest/contributing.html"
|
|
||||||
- exit 1
|
|
||||||
except:
|
except:
|
||||||
- main@libinput/libinput
|
- master@libinput/libinput
|
||||||
variables:
|
variables:
|
||||||
GIT_DEPTH: 100
|
GIT_DEPTH: 100
|
||||||
artifacts:
|
artifacts:
|
||||||
reports:
|
reports:
|
||||||
junit: results.xml
|
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 #
|
# prep stage #
|
||||||
# #
|
# #
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Note: images are rebuilt weekly with a scheduled pipeline with FDO_FORCE_REBUILD set
|
||||||
|
#
|
||||||
|
#
|
||||||
|
{# qemu builds are only done for the latest version of any distribution #}
|
||||||
|
{% for distro in distributions if distro.want_qemu %}
|
||||||
|
{% set version = "{}".format(distro.versions|last()) %}
|
||||||
|
{{distro.name}}:{{version}}@qemu-prep:
|
||||||
|
extends:
|
||||||
|
- .fdo.qemu-build@{{distro.name}}
|
||||||
|
- .policy
|
||||||
|
stage: prep
|
||||||
|
tags:
|
||||||
|
- kvm
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
FDO_DISTRIBUTION_VERSION: {{version}}
|
||||||
|
FDO_DISTRIBUTION_TAG: $QEMU_TAG
|
||||||
|
FDO_DISTRIBUTION_PACKAGES: ${{distro.name.upper()}}_PACKAGES
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% for distro in distributions %}
|
{% for distro in distributions %}
|
||||||
{% for version in distro.versions %}
|
{% for version in distro.versions %}
|
||||||
{{distro.name}}:{{version}}@container-prep:
|
{{distro.name}}:{{version}}@container-prep:
|
||||||
extends:
|
extends:
|
||||||
{% if distro.qemu_based %}
|
|
||||||
- .fdo.qemu-build@{{distro.name}}
|
|
||||||
{% else %}
|
|
||||||
- .fdo.container-build@{{distro.name}}
|
- .fdo.container-build@{{distro.name}}
|
||||||
{% endif %}
|
|
||||||
- .policy
|
- .policy
|
||||||
- .fdo-runner-tags
|
|
||||||
{% if distro.qemu_based %}
|
|
||||||
tags:
|
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
|
||||||
{% endif %}
|
|
||||||
stage: prep
|
stage: prep
|
||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: none
|
GIT_STRATEGY: none
|
||||||
|
|
@ -281,6 +201,57 @@ pre-commit-hooks:
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
# Note that we want to use the latest buildah image, and for that
|
||||||
|
# we use one of the .fdo.container-build@distribution by replacing the
|
||||||
|
# `script`.
|
||||||
|
.freebsd@container-prep:
|
||||||
|
extends:
|
||||||
|
- .policy
|
||||||
|
- .fdo.container-build@fedora
|
||||||
|
stage: prep
|
||||||
|
script:
|
||||||
|
# log in to the registry
|
||||||
|
- podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||||
|
|
||||||
|
# get the full container image name
|
||||||
|
- export IMAGE=freebsd/$FREEBSD_VERSION:$FREEBSD_TAG
|
||||||
|
|
||||||
|
- if [[ x"$FDO_FORCE_REBUILD" != x ]] ; then touch .rebuild; fi
|
||||||
|
|
||||||
|
# pull the latest upstream image if it exists
|
||||||
|
- test -e .rebuild || skopeo copy --dest-creds $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD
|
||||||
|
docker://$CI_REGISTRY/$FDO_UPSTREAM_REPO/$IMAGE
|
||||||
|
docker://$CI_REGISTRY_IMAGE/$IMAGE && exit 0 || true ;
|
||||||
|
|
||||||
|
# check if our image is already in the current registry
|
||||||
|
- test -e .rebuild || skopeo inspect docker://$CI_REGISTRY_IMAGE/$IMAGE > /dev/null && exit 0 || true ;
|
||||||
|
|
||||||
|
- export BUILDAH_RUN="buildah run --isolation chroot"
|
||||||
|
- export BUILDAH_COMMIT="buildah commit --format docker"
|
||||||
|
- buildcntr=$(buildah from --quiet myfreeweb/freebsd-cross:latest)
|
||||||
|
- $BUILDAH_RUN $buildcntr apk add --no-cache $FREEBSD_BUILD_PKGS
|
||||||
|
- $BUILDAH_RUN $buildcntr pkg -r /freebsd update -f
|
||||||
|
- $BUILDAH_RUN $buildcntr pkg -r /freebsd install -y $FREEBSD_PACKAGES
|
||||||
|
- buildah config --workingdir /app $buildcntr
|
||||||
|
# tag the current container
|
||||||
|
- $BUILDAH_COMMIT $buildcntr $FREEBSD_CONTAINER_IMAGE
|
||||||
|
# clean up the working container
|
||||||
|
- buildah rm $buildcntr
|
||||||
|
|
||||||
|
# push the container image to the libinput registry
|
||||||
|
- podman push --quiet $FREEBSD_CONTAINER_IMAGE
|
||||||
|
- skopeo copy --dest-creds $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD
|
||||||
|
docker://$FREEBSD_CONTAINER_IMAGE
|
||||||
|
docker://$CI_REGISTRY_IMAGE/freebsd/$FREEBSD_VERSION:$CI_JOB_ID
|
||||||
|
|
||||||
|
freebsd:11.2@container-prep:
|
||||||
|
extends:
|
||||||
|
- .freebsd@container-prep
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
FREEBSD_VERSION: "11.2"
|
||||||
|
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
# #
|
# #
|
||||||
# container clean stage #
|
# container clean stage #
|
||||||
|
|
@ -297,7 +268,6 @@ pre-commit-hooks:
|
||||||
extends:
|
extends:
|
||||||
- .policy
|
- .policy
|
||||||
- .fdo.ci-fairy
|
- .fdo.ci-fairy
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: container_clean
|
stage: container_clean
|
||||||
script:
|
script:
|
||||||
# Go to your Profile, Settings, Access Tokens
|
# Go to your Profile, Settings, Access Tokens
|
||||||
|
|
@ -308,6 +278,7 @@ pre-commit-hooks:
|
||||||
- ci-fairy -v --authfile $AUTHFILE delete-image
|
- ci-fairy -v --authfile $AUTHFILE delete-image
|
||||||
--repository $FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION
|
--repository $FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION
|
||||||
--exclude-tag $FDO_DISTRIBUTION_TAG
|
--exclude-tag $FDO_DISTRIBUTION_TAG
|
||||||
|
dependencies: []
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
only:
|
only:
|
||||||
- schedules
|
- schedules
|
||||||
|
|
@ -316,7 +287,6 @@ pre-commit-hooks:
|
||||||
{% for version in distro.versions %}
|
{% for version in distro.versions %}
|
||||||
{{distro.name}}:{{version}}@container-clean:
|
{{distro.name}}:{{version}}@container-clean:
|
||||||
extends:
|
extends:
|
||||||
- .policy
|
|
||||||
- .container-clean
|
- .container-clean
|
||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: none
|
GIT_STRATEGY: none
|
||||||
|
|
@ -327,6 +297,13 @@ pre-commit-hooks:
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
freebsd:11.2@container-clean:
|
||||||
|
extends:
|
||||||
|
- .container-clean
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
CURRENT_CONTAINER_IMAGE: $FREEBSD_CONTAINER_IMAGE
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
# #
|
# #
|
||||||
# build stage #
|
# build stage #
|
||||||
|
|
@ -337,40 +314,10 @@ pre-commit-hooks:
|
||||||
extends:
|
extends:
|
||||||
- .policy
|
- .policy
|
||||||
- .default_artifacts
|
- .default_artifacts
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: build
|
stage: build
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/meson-build.sh
|
- .gitlab-ci/meson-build.sh
|
||||||
|
dependencies: []
|
||||||
|
|
||||||
# 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
|
# Fedora
|
||||||
|
|
@ -384,14 +331,24 @@ pre-commit-hooks:
|
||||||
exit 1 ;
|
exit 1 ;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run meson and meson test in the qemu image
|
# Run in a test suite. Special variables:
|
||||||
.build-in-qemu@template:
|
# - 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:
|
extends:
|
||||||
- .policy
|
- .policy
|
||||||
|
- .fdo.distribution-image@fedora
|
||||||
|
stage: test-suite
|
||||||
tags:
|
tags:
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
- kvm
|
||||||
variables:
|
variables:
|
||||||
MESON_BUILDDIR: build_dir
|
MESON_BUILDDIR: build_dir
|
||||||
|
# remove the global --no-suite=hardware
|
||||||
|
MESON_TEST_ARGS: ''
|
||||||
|
before_script:
|
||||||
|
- if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi
|
||||||
|
- echo "Testing $SUITES"
|
||||||
script:
|
script:
|
||||||
# start our vm, no args required
|
# start our vm, no args required
|
||||||
- /app/vmctl start || (echo "Error - Failed to start the VM." && exit 1)
|
- /app/vmctl start || (echo "Error - Failed to start the VM." && exit 1)
|
||||||
|
|
@ -403,7 +360,7 @@ pre-commit-hooks:
|
||||||
- echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
|
- echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
|
||||||
- echo "MESON_ARGS=\"$MESON_ARGS\"" >> sshenv
|
- echo "MESON_ARGS=\"$MESON_ARGS\"" >> sshenv
|
||||||
- echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
|
- echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
|
||||||
- echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS\"" >> sshenv
|
- echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS $SUITES\"" >> sshenv
|
||||||
- echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
|
- echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
|
||||||
- "scp sshenv vm:~/$CI_PROJECT_NAME/.meson_environment"
|
- "scp sshenv vm:~/$CI_PROJECT_NAME/.meson_environment"
|
||||||
- /app/vmctl exec "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
|
- /app/vmctl exec "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
|
||||||
|
|
@ -426,39 +383,24 @@ pre-commit-hooks:
|
||||||
- $MESON_BUILDDIR/meson-logs
|
- $MESON_BUILDDIR/meson-logs
|
||||||
- console.out
|
- console.out
|
||||||
reports:
|
reports:
|
||||||
junit: $MESON_BUILDDIR/*junit*.xml
|
junit: $MESON_BUILDDIR/junit-*.xml
|
||||||
|
|
||||||
|
retry:
|
||||||
# Run in a test suite. Special variables:
|
max: 2
|
||||||
# - SUITES: the meson test suites to run, or
|
when: script_failure
|
||||||
# - 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 #}
|
{# qemu tests are only done for the latest version of any distribution #}
|
||||||
{% for distro in distributions if distro.use_for_qemu_tests %}
|
{% for distro in distributions if distro.want_qemu %}
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
{% set version = "{}".format(distro.versions|last()) %}
|
||||||
.{{distro.name}}:{{version}}@test-suite-vm:
|
.{{distro.name}}:{{version}}@test-suite-vm:
|
||||||
extends:
|
extends:
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
|
||||||
- .test-suite-vm
|
- .test-suite-vm
|
||||||
variables:
|
variables:
|
||||||
FDO_DISTRIBUTION_VERSION: {{version}}
|
FDO_DISTRIBUTION_VERSION: {{version}}
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
FDO_DISTRIBUTION_TAG: $QEMU_TAG
|
||||||
needs:
|
needs:
|
||||||
- "{{distro.name}}:{{version}}@container-prep"
|
- "{{distro.name}}:{{version}}@qemu-prep"
|
||||||
|
|
||||||
|
|
||||||
{% for suite in test_suites %}
|
{% for suite in test_suites %}
|
||||||
|
|
@ -482,24 +424,17 @@ vm-valgrind-{{suite.name}}:
|
||||||
stage: valgrind
|
stage: valgrind
|
||||||
extends:
|
extends:
|
||||||
- vm-{{suite.name}}
|
- vm-{{suite.name}}
|
||||||
- .policy-retry-on-failure
|
|
||||||
variables:
|
variables:
|
||||||
MESON_TEST_ARGS: '--setup=valgrind'
|
MESON_TEST_ARGS: '--setup=valgrind'
|
||||||
LITEST_JOBS: 0
|
|
||||||
retry:
|
|
||||||
max: 2
|
|
||||||
rules:
|
|
||||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endfor %}{# for if distro.want_qemu #}
|
||||||
{% endfor %}{# for if distro.use_for_qemu_tests #}
|
|
||||||
|
|
||||||
{% for distro in distributions if distro.use_for_custom_build_tests %}
|
{% for distro in distributions if distro.use_for_custom_build_tests %}
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
{% set version = "{}".format(distro.versions|last()) %}
|
||||||
.{{distro.name}}-build@template:
|
.{{distro.name}}-build@template:
|
||||||
extends:
|
extends:
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
- .fdo.distribution-image@fedora
|
||||||
- .build@template
|
- .build@template
|
||||||
variables:
|
variables:
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||||
|
|
@ -515,16 +450,20 @@ default-build-release@{{distro.name}}:{{version}}:
|
||||||
MESON_ARGS: "-Dbuildtype=release"
|
MESON_ARGS: "-Dbuildtype=release"
|
||||||
CFLAGS: "-Werror"
|
CFLAGS: "-Werror"
|
||||||
|
|
||||||
clang-tidy@{{distro.name}}:{{version}}:
|
scan-build@{{distro.name}}:{{version}}:
|
||||||
extends:
|
extends:
|
||||||
- .{{distro.name}}-build@template
|
- .{{distro.name}}-build@template
|
||||||
variables:
|
variables:
|
||||||
NINJA_ARGS: ''
|
NINJA_ARGS: scan-build
|
||||||
MESON_TEST_ARGS: ''
|
MESON_TEST_ARGS: ''
|
||||||
CC: 'clang'
|
before_script:
|
||||||
|
- dnf install -y clang-analyzer findutils
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/meson-build.sh
|
- .gitlab-ci/meson-build.sh
|
||||||
- ninja -C "$MESON_BUILDDIR" clang-tidy
|
- test ! -d "$MESON_BUILDDIR"/meson-logs/scanbuild && exit 0
|
||||||
|
- test $(find "$MESON_BUILDDIR"/meson-logs/scanbuild -maxdepth 0 ! -empty -exec echo "not empty" \; | wc -l) -eq 0 && exit 0
|
||||||
|
- echo "Check scan-build results"
|
||||||
|
- /bin/false
|
||||||
|
|
||||||
# Below jobs are build option combinations. We only
|
# Below jobs are build option combinations. We only
|
||||||
# run them on one image, they shouldn't fail on one distro
|
# run them on one image, they shouldn't fail on one distro
|
||||||
|
|
@ -544,39 +483,11 @@ build-no-libwacom-nodeps@{{distro.name}}:{{version}}:
|
||||||
before_script:
|
before_script:
|
||||||
- dnf remove -y libwacom libwacom-devel
|
- dnf remove -y libwacom libwacom-devel
|
||||||
|
|
||||||
build-no-mtdev@{{distro.name}}:{{version}}:
|
build-no-docs@{{distro.name}}:{{version}}:
|
||||||
extends:
|
extends:
|
||||||
- .{{distro.name}}-build@template
|
- .{{distro.name}}-build@template
|
||||||
variables:
|
variables:
|
||||||
MESON_ARGS: "-Dmtdev=false"
|
MESON_ARGS: "-Ddocumentation=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}}:
|
build-no-docs-nodeps@{{distro.name}}:{{version}}:
|
||||||
extends:
|
extends:
|
||||||
|
|
@ -598,7 +509,7 @@ build-no-debuggui-nodeps@{{distro.name}}:{{version}}:
|
||||||
variables:
|
variables:
|
||||||
MESON_ARGS: "-Ddebug-gui=false"
|
MESON_ARGS: "-Ddebug-gui=false"
|
||||||
before_script:
|
before_script:
|
||||||
- dnf remove -y gtk3-devel gtk4-devel
|
- dnf remove -y gtk3-devel
|
||||||
|
|
||||||
build-no-tests@{{distro.name}}:{{version}}:
|
build-no-tests@{{distro.name}}:{{version}}:
|
||||||
extends:
|
extends:
|
||||||
|
|
@ -619,6 +530,8 @@ valgrind@{{distro.name}}:{{version}}:
|
||||||
- .{{distro.name}}-build@template
|
- .{{distro.name}}-build@template
|
||||||
variables:
|
variables:
|
||||||
MESON_TEST_ARGS: '--suite=valgrind --no-suite=hardware --setup=valgrind'
|
MESON_TEST_ARGS: '--suite=valgrind --no-suite=hardware --setup=valgrind'
|
||||||
|
before_script:
|
||||||
|
- dnf install -y valgrind
|
||||||
|
|
||||||
# Python checks, only run on Fedora
|
# Python checks, only run on Fedora
|
||||||
|
|
||||||
|
|
@ -632,12 +545,23 @@ usr-bin-env-python@{{distro.name}}:{{version}}:
|
||||||
/bin/false
|
/bin/false
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
python-format@{{distro.name}}:{{version}}:
|
||||||
|
extends:
|
||||||
|
- .{{distro.name}}-build@template
|
||||||
|
before_script:
|
||||||
|
- dnf install -y black
|
||||||
|
script:
|
||||||
|
- black $(git grep -l '^#!/usr/bin/env python3')
|
||||||
|
- git diff --exit-code || (echo "Please run Black against all Python files" && false)
|
||||||
|
|
||||||
# A job to check we're actually running all test suites in the CI
|
# A job to check we're actually running all test suites in the CI
|
||||||
check-test-suites:
|
check-test-suites:
|
||||||
extends:
|
extends:
|
||||||
- .{{distro.name}}-build@template
|
- .{{distro.name}}-build@template
|
||||||
|
before_script:
|
||||||
|
- dnf install -y jq
|
||||||
script:
|
script:
|
||||||
- meson setup builddir
|
- meson builddir
|
||||||
- meson introspect builddir --test | jq -r '.[].name' | grep 'libinput-test-suite' | sort > meson-testsuites
|
- meson introspect builddir --test | jq -r '.[].name' | grep 'libinput-test-suite' | sort > meson-testsuites
|
||||||
- |
|
- |
|
||||||
cat <<EOF > ci-testsuites ;
|
cat <<EOF > ci-testsuites ;
|
||||||
|
|
@ -672,7 +596,6 @@ coverity:
|
||||||
extends:
|
extends:
|
||||||
- .fdo.distribution-image@debian
|
- .fdo.distribution-image@debian
|
||||||
- .policy
|
- .policy
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
variables:
|
||||||
FDO_DISTRIBUTION_VERSION: 'stable'
|
FDO_DISTRIBUTION_VERSION: 'stable'
|
||||||
|
|
@ -712,7 +635,6 @@ coverity:
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
{% for distro in distributions %}
|
{% for distro in distributions %}
|
||||||
{% if not distro.qemu_based %}
|
|
||||||
{% for version in distro.versions %}
|
{% for version in distro.versions %}
|
||||||
{{distro.name}}:{{version}}@default-build:
|
{{distro.name}}:{{version}}@default-build:
|
||||||
stage: distro
|
stage: distro
|
||||||
|
|
@ -733,27 +655,26 @@ coverity:
|
||||||
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% endfor %}
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
|
||||||
{{distro.name}}:{{version}}@default-build:
|
#
|
||||||
|
# FreeBSD
|
||||||
|
#
|
||||||
|
.freebsd@template:
|
||||||
stage: distro
|
stage: distro
|
||||||
extends:
|
extends:
|
||||||
- .build-in-qemu@template
|
- .build@template
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
image: $FREEBSD_CONTAINER_IMAGE
|
||||||
variables:
|
variables:
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
MESON_ARGS: '--cross-file freebsd -Ddocumentation=false -Dtests=false -Depoll-dir=/freebsd/usr/local/'
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
# Can't run FreeBSD tests on Linux machine, so MESON_TEST_ARGS shouldn't be "test"
|
||||||
{# Where we have extra_variables defined, add them to the list #}
|
MESON_TEST_ARGS: ''
|
||||||
{% 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 %}
|
freebsd:11.2@default-build:
|
||||||
{% endfor %}
|
extends:
|
||||||
|
- .freebsd@template
|
||||||
|
needs:
|
||||||
|
- "freebsd:11.2@container-prep"
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
# #
|
# #
|
||||||
|
|
@ -761,20 +682,34 @@ coverity:
|
||||||
# #
|
# #
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
{% for distro in distributions if distro.name == "fedora" %}
|
#
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
# Verify that the merge request has the allow-collaboration checkbox ticked
|
||||||
|
#
|
||||||
|
|
||||||
|
check-merge-request:
|
||||||
|
extends:
|
||||||
|
- .fdo.ci-fairy
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
|
||||||
|
artifacts:
|
||||||
|
when: on_failure
|
||||||
|
reports:
|
||||||
|
junit: results.xml
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
build rpm:
|
build rpm:
|
||||||
extends:
|
extends:
|
||||||
- .fdo.distribution-image@fedora
|
- .fdo.distribution-image@fedora
|
||||||
- .policy
|
- .policy
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: deploy
|
stage: deploy
|
||||||
variables:
|
variables:
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
FDO_DISTRIBUTION_VERSION: '34'
|
||||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||||
needs:
|
needs:
|
||||||
- "fedora:{{version}}@container-prep"
|
- "fedora:33@container-prep"
|
||||||
script:
|
script:
|
||||||
|
- dnf install -y rpmdevtools jq
|
||||||
- meson "$MESON_BUILDDIR"
|
- meson "$MESON_BUILDDIR"
|
||||||
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
|
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
|
||||||
- sed -e "s/@PIPELINEID@/${CI_PIPELINE_ID}/"
|
- sed -e "s/@PIPELINEID@/${CI_PIPELINE_ID}/"
|
||||||
|
|
@ -786,18 +721,20 @@ build rpm:
|
||||||
- cd "$MESON_BUILDDIR"
|
- cd "$MESON_BUILDDIR"
|
||||||
- meson dist --no-test
|
- meson dist --no-test
|
||||||
- rpmbuild -ta meson-dist/libinput*.tar.xz
|
- rpmbuild -ta meson-dist/libinput*.tar.xz
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
wayland-web:
|
wayland-web:
|
||||||
stage: deploy
|
stage: deploy
|
||||||
trigger: wayland/wayland.freedesktop.org
|
trigger: wayland/wayland.freedesktop.org
|
||||||
|
except:
|
||||||
|
refs:
|
||||||
|
- schedules
|
||||||
variables:
|
variables:
|
||||||
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
MESON_ARGS: '-Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
||||||
MESON_BUILDDIR: 'builddir'
|
MESON_BUILDDIR: 'builddir'
|
||||||
rules:
|
only:
|
||||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
refs:
|
||||||
when: never
|
- master
|
||||||
- if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
|
variables:
|
||||||
when: on_success
|
- $CI_PROJECT_PATH == "libinput/libinput"
|
||||||
- when: never
|
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# We're happy to rebuild all containers when one changes.
|
# We're happy to rebuild all containers when one changes.
|
||||||
.default_tag: &default_tag '2026-01-09.0'
|
.default_tag: &default_tag '2021-05-12.0'
|
||||||
|
|
||||||
distributions:
|
distributions:
|
||||||
- name: fedora
|
- name: fedora
|
||||||
tag: *default_tag
|
tag: *default_tag
|
||||||
versions:
|
versions:
|
||||||
- '42'
|
- '33'
|
||||||
- '43'
|
- '34' # last is picked for qemu
|
||||||
|
want_qemu: true
|
||||||
use_for_custom_build_tests: true
|
use_for_custom_build_tests: true
|
||||||
use_for_qemu_tests: true
|
|
||||||
packages:
|
packages:
|
||||||
- git-core
|
- git-core
|
||||||
- gcc
|
- gcc
|
||||||
|
|
@ -30,27 +30,11 @@ distributions:
|
||||||
- python3-pytest-xdist
|
- python3-pytest-xdist
|
||||||
- libwacom-devel
|
- libwacom-devel
|
||||||
- cairo-devel
|
- cairo-devel
|
||||||
- gtk4-devel
|
- gtk3-devel
|
||||||
- glib2-devel
|
- glib2-devel
|
||||||
- mtdev-devel
|
- mtdev-devel
|
||||||
- diffutils
|
- 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
|
- 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
|
- name: debian
|
||||||
tag: *default_tag
|
tag: *default_tag
|
||||||
versions:
|
versions:
|
||||||
|
|
@ -76,11 +60,11 @@ distributions:
|
||||||
- libglib2.0-dev
|
- libglib2.0-dev
|
||||||
- libmtdev-dev
|
- libmtdev-dev
|
||||||
- curl # for the coverity job
|
- curl # for the coverity job
|
||||||
- lua5.4-dev
|
|
||||||
- name: ubuntu
|
- name: ubuntu
|
||||||
tag: *default_tag
|
tag: *default_tag
|
||||||
versions:
|
versions:
|
||||||
- '25.10'
|
- '20.04'
|
||||||
|
- '20.10'
|
||||||
packages:
|
packages:
|
||||||
- git
|
- git
|
||||||
- gcc
|
- gcc
|
||||||
|
|
@ -101,7 +85,6 @@ distributions:
|
||||||
- libgtk-3-dev
|
- libgtk-3-dev
|
||||||
- libglib2.0-dev
|
- libglib2.0-dev
|
||||||
- libmtdev-dev
|
- libmtdev-dev
|
||||||
- lua5.4-dev
|
|
||||||
- name: arch
|
- name: arch
|
||||||
tag: *default_tag
|
tag: *default_tag
|
||||||
versions:
|
versions:
|
||||||
|
|
@ -114,15 +97,16 @@ distributions:
|
||||||
- check
|
- check
|
||||||
- libsystemd
|
- libsystemd
|
||||||
- libevdev
|
- libevdev
|
||||||
|
- doxygen
|
||||||
|
- graphviz
|
||||||
|
- python-sphinx
|
||||||
|
- python-recommonmark
|
||||||
|
- python-sphinx_rtd_theme
|
||||||
- python-pytest-xdist
|
- python-pytest-xdist
|
||||||
- libwacom
|
- libwacom
|
||||||
- gtk4
|
- gtk3
|
||||||
- mtdev
|
- mtdev
|
||||||
- diffutils
|
- diffutils
|
||||||
- lua
|
|
||||||
build:
|
|
||||||
extra_variables:
|
|
||||||
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
|
|
||||||
- name: alpine
|
- name: alpine
|
||||||
tag: *default_tag
|
tag: *default_tag
|
||||||
versions:
|
versions:
|
||||||
|
|
@ -137,10 +121,9 @@ distributions:
|
||||||
- libevdev-dev
|
- libevdev-dev
|
||||||
- libwacom-dev
|
- libwacom-dev
|
||||||
- cairo-dev
|
- cairo-dev
|
||||||
- gtk4.0-dev
|
- gtk+3.0-dev
|
||||||
- mtdev-dev
|
- mtdev-dev
|
||||||
- bash
|
- bash
|
||||||
- lua5.4-dev
|
|
||||||
build:
|
build:
|
||||||
extra_variables:
|
extra_variables:
|
||||||
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"
|
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"
|
||||||
|
|
@ -148,45 +131,34 @@ distributions:
|
||||||
# for any tcase_add_exit_test/tcase_add_test_raise_signal
|
# for any tcase_add_exit_test/tcase_add_test_raise_signal
|
||||||
# but someone more invested in musl will have to figure that out.
|
# but someone more invested in musl will have to figure that out.
|
||||||
- "MESON_TEST_ARGS: '' # litest-selftest fails on musl"
|
- "MESON_TEST_ARGS: '' # litest-selftest fails on musl"
|
||||||
|
- name: freebsd
|
||||||
|
tag: *default_tag
|
||||||
|
packages:
|
||||||
|
- libepoll-shim
|
||||||
|
- libudev-devd
|
||||||
|
- libevdev
|
||||||
|
- libwacom
|
||||||
|
- gtk3
|
||||||
|
- libmtdev
|
||||||
|
does_not_have_ci_templates: true
|
||||||
|
|
||||||
test_suites:
|
test_suites:
|
||||||
- name: touchpad
|
- name: touchpad
|
||||||
suites:
|
suites:
|
||||||
- touchpad
|
- touchpad
|
||||||
- name: touchpad_palm
|
|
||||||
suites:
|
|
||||||
- touchpad_palm
|
|
||||||
- name: touchpad_dwt
|
|
||||||
suites:
|
|
||||||
- touchpad_dwt
|
|
||||||
- name: tap
|
- name: tap
|
||||||
suites:
|
suites:
|
||||||
- touchpad_tap
|
- touchpad-tap
|
||||||
- name: tap-drag
|
|
||||||
suites:
|
|
||||||
- touchpad_tap_drag
|
|
||||||
- name: tap-palm
|
|
||||||
suites:
|
|
||||||
- touchpad_tap_palm
|
|
||||||
- name: touchpad-buttons
|
- name: touchpad-buttons
|
||||||
suites:
|
suites:
|
||||||
- touchpad_buttons
|
- touchpad-buttons
|
||||||
- name: tablet
|
- name: tablet
|
||||||
suites:
|
suites:
|
||||||
- tablet
|
- tablet
|
||||||
- name: tablet_left_handed
|
- name: gestures-device
|
||||||
suites:
|
|
||||||
- tablet_left_handed
|
|
||||||
- name: tablet_proximity_tip
|
|
||||||
suites:
|
|
||||||
- tablet_proximity
|
|
||||||
- tablet_tip
|
|
||||||
- name: tablet_eraser
|
|
||||||
suites:
|
|
||||||
- tablet_eraser
|
|
||||||
- name: gestures
|
|
||||||
suites:
|
suites:
|
||||||
- gestures
|
- gestures
|
||||||
|
- device
|
||||||
- name: backends
|
- name: backends
|
||||||
suites:
|
suites:
|
||||||
- path
|
- path
|
||||||
|
|
@ -196,7 +168,6 @@ test_suites:
|
||||||
- log
|
- log
|
||||||
- misc
|
- misc
|
||||||
- quirks
|
- quirks
|
||||||
- device
|
|
||||||
- name: other devices
|
- name: other devices
|
||||||
suites:
|
suites:
|
||||||
- keyboard
|
- keyboard
|
||||||
|
|
@ -209,9 +180,3 @@ test_suites:
|
||||||
- name: pointer
|
- name: pointer
|
||||||
suites:
|
suites:
|
||||||
- pointer
|
- 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
|
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,6 @@ intended to be run by users.
|
||||||
%files utils
|
%files utils
|
||||||
%{_libexecdir}/libinput/libinput-debug-gui
|
%{_libexecdir}/libinput/libinput-debug-gui
|
||||||
%{_libexecdir}/libinput/libinput-debug-tablet
|
%{_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
|
||||||
%{_libexecdir}/libinput/libinput-measure-fuzz
|
%{_libexecdir}/libinput/libinput-measure-fuzz
|
||||||
%{_libexecdir}/libinput/libinput-measure-touchpad-tap
|
%{_libexecdir}/libinput/libinput-measure-touchpad-tap
|
||||||
|
|
@ -112,14 +110,11 @@ intended to be run by users.
|
||||||
%{_libexecdir}/libinput/libinput-record
|
%{_libexecdir}/libinput/libinput-record
|
||||||
%{_libexecdir}/libinput/libinput-replay
|
%{_libexecdir}/libinput/libinput-replay
|
||||||
%{_libexecdir}/libinput/libinput-analyze
|
%{_libexecdir}/libinput/libinput-analyze
|
||||||
%{_libexecdir}/libinput/libinput-analyze-buttons
|
|
||||||
%{_libexecdir}/libinput/libinput-analyze-per-slot-delta
|
%{_libexecdir}/libinput/libinput-analyze-per-slot-delta
|
||||||
%{_libexecdir}/libinput/libinput-analyze-recording
|
%{_libexecdir}/libinput/libinput-analyze-recording
|
||||||
%{_libexecdir}/libinput/libinput-analyze-touch-down-state
|
%{_libexecdir}/libinput/libinput-analyze-touch-down-state
|
||||||
%{_mandir}/man1/libinput-debug-gui.1*
|
%{_mandir}/man1/libinput-debug-gui.1*
|
||||||
%{_mandir}/man1/libinput-debug-tablet.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.1*
|
||||||
%{_mandir}/man1/libinput-measure-fuzz.1*
|
%{_mandir}/man1/libinput-measure-fuzz.1*
|
||||||
%{_mandir}/man1/libinput-measure-touchpad-tap.1*
|
%{_mandir}/man1/libinput-measure-touchpad-tap.1*
|
||||||
|
|
@ -132,16 +127,12 @@ intended to be run by users.
|
||||||
%{_mandir}/man1/libinput-record.1*
|
%{_mandir}/man1/libinput-record.1*
|
||||||
%{_mandir}/man1/libinput-replay.1*
|
%{_mandir}/man1/libinput-replay.1*
|
||||||
%{_mandir}/man1/libinput-analyze.1*
|
%{_mandir}/man1/libinput-analyze.1*
|
||||||
%{_mandir}/man1/libinput-analyze-buttons.1*
|
|
||||||
%{_mandir}/man1/libinput-analyze-per-slot-delta.1*
|
%{_mandir}/man1/libinput-analyze-per-slot-delta.1*
|
||||||
%{_mandir}/man1/libinput-analyze-recording.1*
|
%{_mandir}/man1/libinput-analyze-recording.1*
|
||||||
%{_mandir}/man1/libinput-analyze-touch-down-state.1*
|
%{_mandir}/man1/libinput-analyze-touch-down-state.1*
|
||||||
|
|
||||||
%files test
|
%files test
|
||||||
%{_libexecdir}/libinput/libinput-test
|
|
||||||
%{_libexecdir}/libinput/libinput-test-suite
|
%{_libexecdir}/libinput/libinput-test-suite
|
||||||
%{_libexecdir}/libinput/libinput-test-utils
|
|
||||||
%{_mandir}/man1/libinput-test.1*
|
|
||||||
%{_mandir}/man1/libinput-test-suite.1*
|
%{_mandir}/man1/libinput-test-suite.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,9 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/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
|
if [[ -f .meson_environment ]]; then
|
||||||
. .meson_environment
|
. .meson_environment
|
||||||
fi
|
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
|
if [[ -z "$MESON_BUILDDIR" ]]; then
|
||||||
echo "\$MESON_BUILDDIR undefined."
|
echo "\$MESON_BUILDDIR undefined."
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -47,42 +13,44 @@ fi
|
||||||
# run and debug locally.
|
# run and debug locally.
|
||||||
if [[ -z "$CI_JOB_ID" ]] || [[ -z "$CI_JOB_NAME" ]]; then
|
if [[ -z "$CI_JOB_ID" ]] || [[ -z "$CI_JOB_NAME" ]]; then
|
||||||
echo "Missing \$CI_JOB_ID or \$CI_JOB_NAME".
|
echo "Missing \$CI_JOB_ID or \$CI_JOB_NAME".
|
||||||
CI_PROJECT_NAME=$(basename "$PWD")
|
|
||||||
CI_JOB_ID=$(date +%s)
|
CI_JOB_ID=$(date +%s)
|
||||||
CI_JOB_NAME="$CI_PROJECT_NAME-job-local"
|
CI_JOB_NAME='libinput-job-local'
|
||||||
echo "Simulating gitlab environment: "
|
echo "Simulating gitlab environment: "
|
||||||
echo " CI_JOB_ID=$CI_JOB_ID"
|
echo " CI_JOB_ID=$CI_JOB_ID"
|
||||||
echo " CI_JOB_NAME=$CI_JOB_NAME"
|
echo " CI_JOB_NAME=$CI_JOB_NAME"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "$FDO_CI_CONCURRENT" ]]; then
|
|
||||||
jobcount="-j$FDO_CI_CONCURRENT"
|
|
||||||
export MESON_TESTTHREADS="$FDO_CI_CONCURRENT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "*************************************************"
|
echo "*************************************************"
|
||||||
echo "builddir: $MESON_BUILDDIR"
|
echo "builddir: $MESON_BUILDDIR"
|
||||||
echo "meson args: $MESON_ARGS"
|
echo "meson args: $MESON_ARGS"
|
||||||
echo "ninja args: $NINJA_ARGS"
|
echo "ninja args: $NINJA_ARGS"
|
||||||
echo "meson test args: $MESON_TEST_ARGS"
|
echo "meson test args: $MESON_TEST_ARGS"
|
||||||
echo "job count: ${jobcount-0}"
|
|
||||||
echo "*************************************************"
|
echo "*************************************************"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [[ -z "$MESON_SKIP_SETUP" ]]; then
|
rm -rf "$MESON_BUILDDIR"
|
||||||
rm -rf "$MESON_BUILDDIR"
|
meson "$MESON_BUILDDIR" $MESON_ARGS
|
||||||
meson setup "$MESON_BUILDDIR" $MESON_ARGS
|
|
||||||
fi
|
|
||||||
meson configure "$MESON_BUILDDIR"
|
meson configure "$MESON_BUILDDIR"
|
||||||
|
ninja -C "$MESON_BUILDDIR" $NINJA_ARGS
|
||||||
|
|
||||||
if [[ -z "$MESON_SKIP_BUILD" ]]; then
|
if [[ -z "$MESON_TEST_ARGS" ]]; then
|
||||||
if [[ -n "$NINJA_ARGS" ]]; then
|
exit 0
|
||||||
ninja_args="--ninja-args $NINJA_ARGS"
|
|
||||||
fi
|
|
||||||
meson compile -v -C "$MESON_BUILDDIR" $jobcount $ninja_args
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "$MESON_RUN_TEST" ]]; then
|
# we still want to generate the reports, even if meson test fails
|
||||||
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
|
set +e
|
||||||
fi
|
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
|
||||||
|
exit_code=$?
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# We need the glob for the testlog so that it picks up those suffixed by a
|
||||||
|
# suite (e.g. testlog-valgrind.json)
|
||||||
|
./.gitlab-ci/meson-junit-report.py \
|
||||||
|
--project-name=libinput \
|
||||||
|
--job-id="$CI_JOB_ID" \
|
||||||
|
--output="$MESON_BUILDDIR/junit-$CI_JOB_NAME-report.xml" \
|
||||||
|
"$MESON_BUILDDIR"/meson-logs/testlog*.json; \
|
||||||
|
|
||||||
|
exit $exit_code
|
||||||
|
|
|
||||||
117
.gitlab-ci/meson-junit-report.py
Executable file
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# meson-junit-report.py: Turns a Meson test log into a JUnit report
|
||||||
|
#
|
||||||
|
# Copyright 2019 GNOME Foundation
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
aparser = argparse.ArgumentParser(
|
||||||
|
description="Turns a Meson test log into a JUnit report"
|
||||||
|
)
|
||||||
|
aparser.add_argument(
|
||||||
|
"--project-name", metavar="NAME", help="The project name", default="unknown"
|
||||||
|
)
|
||||||
|
aparser.add_argument(
|
||||||
|
"--job-id", metavar="ID", help="The job ID for the report", default="Unknown"
|
||||||
|
)
|
||||||
|
aparser.add_argument(
|
||||||
|
"--branch",
|
||||||
|
metavar="NAME",
|
||||||
|
help="Branch of the project being tested",
|
||||||
|
default="master",
|
||||||
|
)
|
||||||
|
aparser.add_argument(
|
||||||
|
"--output",
|
||||||
|
metavar="FILE",
|
||||||
|
help="The output file, stdout by default",
|
||||||
|
type=argparse.FileType("w", encoding="UTF-8"),
|
||||||
|
default=sys.stdout,
|
||||||
|
)
|
||||||
|
aparser.add_argument(
|
||||||
|
"infile",
|
||||||
|
metavar="FILE",
|
||||||
|
help="The input testlog.json, stdin by default",
|
||||||
|
type=argparse.FileType("r", encoding="UTF-8"),
|
||||||
|
default=sys.stdin,
|
||||||
|
)
|
||||||
|
|
||||||
|
args = aparser.parse_args()
|
||||||
|
|
||||||
|
outfile = args.output
|
||||||
|
|
||||||
|
testsuites = ET.Element("testsuites")
|
||||||
|
testsuites.set("id", "{}/{}".format(args.job_id, args.branch))
|
||||||
|
testsuites.set("package", args.project_name)
|
||||||
|
testsuites.set("timestamp", datetime.datetime.utcnow().isoformat(timespec="minutes"))
|
||||||
|
|
||||||
|
suites = {}
|
||||||
|
for line in args.infile:
|
||||||
|
data = json.loads(line)
|
||||||
|
(full_suite, unit_name) = data["name"].split(" / ")
|
||||||
|
(project_name, suite_name) = full_suite.split(":")
|
||||||
|
|
||||||
|
duration = data["duration"]
|
||||||
|
return_code = data["returncode"]
|
||||||
|
log = data["stdout"]
|
||||||
|
|
||||||
|
unit = {
|
||||||
|
"suite": suite_name,
|
||||||
|
"name": unit_name,
|
||||||
|
"duration": duration,
|
||||||
|
"returncode": return_code,
|
||||||
|
"stdout": log,
|
||||||
|
}
|
||||||
|
|
||||||
|
units = suites.setdefault(suite_name, [])
|
||||||
|
units.append(unit)
|
||||||
|
|
||||||
|
for name, units in suites.items():
|
||||||
|
print("Processing suite {} (units: {})".format(name, len(units)))
|
||||||
|
|
||||||
|
def if_failed(unit):
|
||||||
|
if unit["returncode"] != 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def if_succeded(unit):
|
||||||
|
if unit["returncode"] == 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
successes = list(filter(if_succeded, units))
|
||||||
|
failures = list(filter(if_failed, units))
|
||||||
|
print(" - {}: {} pass, {} fail".format(name, len(successes), len(failures)))
|
||||||
|
|
||||||
|
testsuite = ET.SubElement(testsuites, "testsuite")
|
||||||
|
testsuite.set("name", "{}/{}".format(args.project_name, name))
|
||||||
|
testsuite.set("tests", str(len(units)))
|
||||||
|
testsuite.set("errors", str(len(failures)))
|
||||||
|
testsuite.set("failures", str(len(failures)))
|
||||||
|
|
||||||
|
for unit in successes:
|
||||||
|
testcase = ET.SubElement(testsuite, "testcase")
|
||||||
|
testcase.set("classname", "{}/{}".format(args.project_name, unit["suite"]))
|
||||||
|
testcase.set("name", unit["name"])
|
||||||
|
testcase.set("time", str(unit["duration"]))
|
||||||
|
|
||||||
|
for unit in failures:
|
||||||
|
testcase = ET.SubElement(testsuite, "testcase")
|
||||||
|
testcase.set("classname", "{}/{}".format(args.project_name, unit["suite"]))
|
||||||
|
testcase.set("name", unit["name"])
|
||||||
|
testcase.set("time", str(unit["duration"]))
|
||||||
|
|
||||||
|
failure = ET.SubElement(testcase, "failure")
|
||||||
|
failure.set("classname", "{}/{}".format(args.project_name, unit["suite"]))
|
||||||
|
failure.set("name", unit["name"])
|
||||||
|
failure.set("type", "error")
|
||||||
|
failure.text = unit["stdout"]
|
||||||
|
|
||||||
|
output = ET.tostring(testsuites, encoding="unicode")
|
||||||
|
outfile.write(output)
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
scan-build -v --status-bugs -plist-html "$@"
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import itertools
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class WhitespaceError:
|
|
||||||
message: str
|
|
||||||
lineno: int
|
|
||||||
nlines: int = 1
|
|
||||||
column: None | int = None
|
|
||||||
ncolumns: int = 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_duplicate_empty_lines(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx, (l1, l2) in enumerate(itertools.pairwise(lines)):
|
|
||||||
if not l1 and not l2:
|
|
||||||
errors.append(WhitespaceError("Duplicated empty lines", idx, nlines=2))
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def test_tab_after_space(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx, l in enumerate(lines):
|
|
||||||
index = l.find(" \t")
|
|
||||||
if index > -1:
|
|
||||||
errors.append(
|
|
||||||
WhitespaceError(
|
|
||||||
"Tab after space", idx, nlines=index, column=index, ncolumns=2
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def test_trailing_whitespace(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx, l in enumerate(lines):
|
|
||||||
if l.rstrip() != l:
|
|
||||||
errors.append(WhitespaceError("Trailing whitespace", idx))
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def test_empty_line_between_braces(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx in range(len(lines) - 3):
|
|
||||||
l1 = lines[idx]
|
|
||||||
l2 = lines[idx + 1]
|
|
||||||
l3 = lines[idx + 2]
|
|
||||||
if l1.strip() == "}" and l3.strip() == "}" and l2.strip() == "":
|
|
||||||
errors.append(WhitespaceError("Empty line between closing braces", idx + 1))
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description="Whitespace checker script")
|
|
||||||
parser.add_argument(
|
|
||||||
"files",
|
|
||||||
metavar="FILES",
|
|
||||||
type=Path,
|
|
||||||
nargs="+",
|
|
||||||
help="The files to check",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
have_errors: bool = False
|
|
||||||
|
|
||||||
if os.isatty(sys.stderr.fileno()):
|
|
||||||
red = "\x1b[0;31m"
|
|
||||||
reset = "\x1b[0m"
|
|
||||||
else:
|
|
||||||
red = ""
|
|
||||||
reset = ""
|
|
||||||
|
|
||||||
for file in args.files:
|
|
||||||
lines = [l.rstrip("\n") for l in file.open().readlines()]
|
|
||||||
|
|
||||||
errors = []
|
|
||||||
errors.extend(test_tab_after_space(lines))
|
|
||||||
errors.extend(test_trailing_whitespace(lines))
|
|
||||||
if any(file.name.endswith(suffix) for suffix in [".c", ".h"]):
|
|
||||||
if not file.parts[0] == "include":
|
|
||||||
errors.extend(test_duplicate_empty_lines(lines))
|
|
||||||
errors.extend(test_empty_line_between_braces(lines))
|
|
||||||
|
|
||||||
for e in errors:
|
|
||||||
print(f"{red}ERROR: {e.message} in {file}:{reset}", file=sys.stderr)
|
|
||||||
print(f"{'-' * 72}", file=sys.stderr)
|
|
||||||
lineno = max(0, e.lineno - 5)
|
|
||||||
for idx, l in enumerate(lines[lineno : lineno + 10]):
|
|
||||||
if e.lineno <= lineno + idx < e.lineno + e.nlines:
|
|
||||||
prefix = "->"
|
|
||||||
hl = red
|
|
||||||
nohl = reset
|
|
||||||
else:
|
|
||||||
prefix = " "
|
|
||||||
hl = ""
|
|
||||||
nohl = ""
|
|
||||||
print(f"{hl}{lineno + idx:3d}: {prefix} {l.rstrip()}{nohl}")
|
|
||||||
|
|
||||||
print(f"{'-' * 72}", file=sys.stderr)
|
|
||||||
|
|
||||||
if errors:
|
|
||||||
have_errors = True
|
|
||||||
|
|
||||||
if have_errors:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
@ -1,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
|
|
||||||
127
CODING_STYLE.md
|
|
@ -52,102 +52,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
|
||||||
|
|
@ -211,6 +160,38 @@ the approach chosen was correct. A good commit message also helps
|
||||||
maintainers to decide if a given patch is suitable for stable branches or
|
maintainers to decide if a given patch is suitable for stable branches or
|
||||||
inclusion in a distribution.
|
inclusion in a distribution.
|
||||||
|
|
||||||
|
## Developer Certificate of Origin
|
||||||
|
|
||||||
|
Your commit **must** be signed off with a line:
|
||||||
|
```
|
||||||
|
Signed-off-by: <your name> <your email address>
|
||||||
|
```
|
||||||
|
By signing off, you indicate the [developer certificate of origin](https://developercertificate.org/).
|
||||||
|
|
||||||
|
> By making a contribution to this project, I certify that:
|
||||||
|
>
|
||||||
|
> (a) The contribution was created in whole or in part by me and I
|
||||||
|
> have the right to submit it under the open source license
|
||||||
|
> indicated in the file; or
|
||||||
|
>
|
||||||
|
> (b) The contribution is based upon previous work that, to the best
|
||||||
|
> of my knowledge, is covered under an appropriate open source
|
||||||
|
> license and I have the right under that license to submit that
|
||||||
|
> work with modifications, whether created in whole or in part
|
||||||
|
> by me, under the same open source license (unless I am
|
||||||
|
> permitted to submit under a different license), as indicated
|
||||||
|
> in the file; or
|
||||||
|
>
|
||||||
|
> (c) The contribution was provided directly to me by some other
|
||||||
|
> person who certified (a), (b) or (c) and I have not modified
|
||||||
|
> it.
|
||||||
|
>
|
||||||
|
> (d) I understand and agree that this project and the contribution
|
||||||
|
> are public and that a record of the contribution (including all
|
||||||
|
> personal information I submit with it, including my sign-off) is
|
||||||
|
> maintained indefinitely and may be redistributed consistent with
|
||||||
|
> this project or the open source license(s) involved.
|
||||||
|
|
||||||
## Commit message format
|
## Commit message format
|
||||||
|
|
||||||
The canonical git commit message format is:
|
The canonical git commit message format is:
|
||||||
|
|
@ -225,6 +206,8 @@ supported.
|
||||||
You can include extra data where required like:
|
You can include extra data where required like:
|
||||||
- benchmark one says 10s
|
- benchmark one says 10s
|
||||||
- benchmark two says 12s
|
- benchmark two says 12s
|
||||||
|
|
||||||
|
Signed-off-by: <your name> <your email>
|
||||||
```
|
```
|
||||||
|
|
||||||
The subject line is the first thing everyone sees about this commit, so make
|
The subject line is the first thing everyone sees about this commit, so make
|
||||||
|
|
@ -236,8 +219,8 @@ sure it's on point.
|
||||||
"change foo to bar", not "changed foo to bar".
|
"change foo to bar", not "changed foo to bar".
|
||||||
- The text width of the commit should be 78 chars or less, especially the
|
- The text width of the commit should be 78 chars or less, especially the
|
||||||
subject line.
|
subject line.
|
||||||
- The author must be the name you usually identify as and email address. We do
|
- The author and signed-off-by must be your real name and email address. We
|
||||||
not accept the default `@users.noreply` gitlab addresses.
|
do not accept the default `@users.noreply` gitlab addresses.
|
||||||
```
|
```
|
||||||
git config --global user.name Your Name
|
git config --global user.name Your Name
|
||||||
git config --global user.email your@email
|
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,7 +75,7 @@ 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
|
||||||
|
|
|
||||||
|
|
@ -45,61 +45,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 disable-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()
|
||||||
|
|
@ -180,7 +159,7 @@ __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/'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +223,6 @@ __all_seats()
|
||||||
'--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'
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
|
@ -40,6 +40,11 @@ To fix the touchpad you need to:
|
||||||
|
|
||||||
Detailed explanations are below.
|
Detailed explanations are below.
|
||||||
|
|
||||||
|
.. note:: ``libinput measure touchpad-size`` was introduced in libinput
|
||||||
|
1.16. For earlier versions, use `libevdev <http://freedesktop.org/wiki/Software/libevdev/>`_'s
|
||||||
|
``touchpad-edge-detector`` tool.
|
||||||
|
|
||||||
|
|
||||||
The ``libinput measure touchpad-size`` tool is an interactive tool. It must
|
The ``libinput measure touchpad-size`` tool is an interactive tool. It must
|
||||||
be called with the physical dimensions of the touchpad in mm. In the example
|
be called with the physical dimensions of the touchpad in mm. In the example
|
||||||
below, we use 100mm wide and 55mm high. The tool will find the touchpad device
|
below, we use 100mm wide and 55mm high. The tool will find the touchpad device
|
||||||
|
|
@ -135,7 +140,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:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,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 +71,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 +96,7 @@ again:
|
||||||
::
|
::
|
||||||
|
|
||||||
$> rm -r builddir/
|
$> rm -r builddir/
|
||||||
$> meson setup --prefix=....
|
$> meson --prefix=....
|
||||||
|
|
||||||
|
|
||||||
.. _verifying_install:
|
.. _verifying_install:
|
||||||
|
|
@ -110,10 +110,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:
|
||||||
|
|
||||||
|
|
@ -188,8 +190,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
|
||||||
|
|
@ -242,7 +244,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 +284,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>`__
|
|
||||||
|
|
@ -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
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -161,18 +142,6 @@ 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 +156,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.
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ behaviour is not tolerated by the project.
|
||||||
Contact
|
Contact
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Questions can be asked on ``#wayland`` on oftc or on the
|
Questions can be asked on ``#wayland`` on freenode or on the
|
||||||
`wayland-devel@lists.freedesktop.org
|
`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.
|
||||||
|
|
@ -69,7 +69,7 @@ will be:
|
||||||
|
|
||||||
$> 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
|
||||||
|
|
||||||
|
|
@ -79,15 +79,6 @@ You can omit the last step if you only want to test locally.
|
||||||
Working on the code
|
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:
|
libinput has a roughly three-parts architecture:
|
||||||
|
|
||||||
- the front-end code which handles the ``libinput_some_function()`` API calls in ``libinput.c``
|
- the front-end code which handles the ``libinput_some_function()`` API calls in ``libinput.c``
|
||||||
|
|
@ -149,8 +140,6 @@ run by the CI on merge requests, you can run those locally with ::
|
||||||
So it always pays to run that before submitting. This will also run the code
|
So it always pays to run that before submitting. This will also run the code
|
||||||
through valgrind and pick up any memory leaks.
|
through valgrind and pick up any memory leaks.
|
||||||
|
|
||||||
.. _contributing_submitting_code:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Submitting Code
|
Submitting Code
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -160,19 +149,14 @@ 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
|
|
||||||
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
|
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
|
replace `learning git <https://git-scm.com/doc>`__ but they should be
|
||||||
sufficient to make some of the more confusing steps obvious.
|
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. git will call this repository ``origin``. ::
|
- 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
|
||||||
|
|
@ -181,7 +165,7 @@ sufficient to make some of the more confusing steps obvious.
|
||||||
with your username). git will call this repository ``gitlab``. ::
|
with your username). git will call this repository ``gitlab``. ::
|
||||||
|
|
||||||
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. ::
|
- Create a new branch and commit your changes to that branch. ::
|
||||||
|
|
@ -205,7 +189,7 @@ sufficient to make some of the more confusing steps obvious.
|
||||||
|
|
||||||
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
|
- Verify that the CI completes successfully by visiting the merge request
|
||||||
page. A successful pipeline shows only green ticks, failure is indicated
|
page. A successful pipeline shows only green ticks, failure is indicated
|
||||||
|
|
@ -280,6 +264,25 @@ same file(s) as the patch being sent.
|
||||||
Commit Messages
|
Commit Messages
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Commit messages **must** contain a **Signed-off-by** line with your name
|
||||||
|
and email address. An example is: ::
|
||||||
|
|
||||||
|
A description of this commit, and it's great work.
|
||||||
|
|
||||||
|
Signed-off-by: Claire Someone <name@domain>
|
||||||
|
|
||||||
|
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. An example is: ::
|
||||||
|
|
||||||
|
A description of this commit, and it's great work.
|
||||||
|
|
||||||
|
Signed-off-by: Claire Someone <name@domain>
|
||||||
|
Signed-off-by: Ferris Crab <name@domain>
|
||||||
|
|
||||||
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,17 +290,6 @@ 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
|
For further reading, please see
|
||||||
`'on commit messages' <http://who-t.blogspot.de/2009/12/on-commit-messages.html>`_
|
`'on commit messages' <http://who-t.blogspot.de/2009/12/on-commit-messages.html>`_
|
||||||
as a general guideline on what commit messages should contain.
|
as a general guideline on what commit messages should contain.
|
||||||
|
|
@ -307,7 +299,7 @@ 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.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
@ -346,76 +338,3 @@ web interface though, so we do recommend using this to go through the review
|
||||||
process, even if you use other clients to track the list of available
|
process, even if you use other clients to track the list of available
|
||||||
patches.
|
patches.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Failed pipeline errors
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
After submitting your merge request to GitLab, you might receive an email
|
|
||||||
informing you that your pipeline failed.
|
|
||||||
|
|
||||||
Visit your merge request page and check the `pipeline mini graph
|
|
||||||
<https://docs.gitlab.com/ee/ci/pipelines/#pipeline-mini-graphs>`_ to know which
|
|
||||||
step failed.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ under specific conditions. libinput ships a set of files containing 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
|
|
||||||
inherited from another quirk.
|
|
||||||
AttrPressureRange=N:M, AttrPalmPressureThreshold=O, AttrThumbPressureThreshold=P
|
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,20 @@ 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;
|
AttrEventCodeEnable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
||||||
Enables or disables the evdev input property on the device. The prefix
|
Enables 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
|
||||||
|
hexadecimal event code, separated by a single colon.
|
||||||
|
AttrInputPropDisable=INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER;
|
||||||
|
Disables the evdev input property on the device. Entries may be
|
||||||
|
a named input property or the hexadecimal value of that property.
|
||||||
|
AttrInputPropEnable=INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER;
|
||||||
|
Enables the evdev input property on the device. Entries may be
|
||||||
a named input property or the hexadecimal value of that property.
|
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
|
|
||||||
|
|
@ -335,56 +335,3 @@ 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.
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
troubleshooting
|
troubleshooting
|
||||||
contributing
|
contributing
|
||||||
development
|
development
|
||||||
lua-plugins
|
|
||||||
API documentation <@HTTP_DOC_LINK@/api/>
|
API documentation <@HTTP_DOC_LINK@/api/>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,7 +23,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,7 +36,7 @@ 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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -50,7 +50,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 +94,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 +109,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 +118,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 +138,14 @@ 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',
|
|
||||||
'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,7 +167,6 @@ 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',
|
||||||
|
|
@ -204,8 +191,7 @@ if yq.found()
|
||||||
foreach distro : distributions
|
foreach distro : distributions
|
||||||
yq_filter = '.distributions[] | select(.name == "@0@") | .packages | join(" ")'.format(distro)
|
yq_filter = '.distributions[] | select(.name == "@0@") | .packages | join(" ")'.format(distro)
|
||||||
deps = run_command(yq, '-r', yq_filter,
|
deps = run_command(yq, '-r', yq_filter,
|
||||||
dir_gitlab_ci / 'config.yml',
|
join_paths(meson.source_root(), '.gitlab-ci', 'config.yml')).stdout()
|
||||||
check: true).stdout()
|
|
||||||
dependencies_config.set('@0@_PACKAGES'.format(distro.to_upper()), deps)
|
dependencies_config.set('@0@_PACKAGES'.format(distro.to_upper()), deps)
|
||||||
endforeach
|
endforeach
|
||||||
endif
|
endif
|
||||||
|
|
@ -219,6 +205,6 @@ 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',
|
'-d', join_paths(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,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
|
||||||
|
|
@ -164,20 +166,6 @@ Notable behaviors of libinput's disable-while-typing feature:
|
||||||
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.
|
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,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 +170,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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,21 +124,12 @@ button lock, the button is now considered logically held down. Pressing and
|
||||||
releasing the button a second time logically releases the button. While the
|
releasing the button a second time logically releases the button. While the
|
||||||
button is logically held down, motion events are converted to scroll events.
|
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 +147,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
|
||||||
|
|
@ -59,20 +59,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.
|
||||||
|
|
||||||
|
|
@ -60,13 +55,11 @@ tap-and-drag enabled by default.
|
||||||
single-finger drag.
|
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 +77,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,
|
||||||
|
|
@ -75,55 +73,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.
|
||||||
|
|
||||||
|
|
@ -377,7 +326,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.
|
||||||
|
|
|
||||||
|
|
@ -53,38 +53,31 @@ Example output of the tool is below: ::
|
||||||
with --touch-thresholds=down:up using observed pressure values.
|
with --touch-thresholds=down:up using observed pressure values.
|
||||||
See --help for more options.
|
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
|
Press Ctrl+C to exit
|
||||||
|
|
||||||
┌───────────────────────────────────────────────────────────────────────────────┐
|
+-------------------------------------------------------------------------------+
|
||||||
│ Touch │ down │ up │ palm │ thumb │ min │ max │ p │ avg │ median │
|
| Thresh | 70 | 60 | 130 | 100 | |
|
||||||
├───────────────────────────────────────────────────────────────────────────────┤
|
+-------------------------------------------------------------------------------+
|
||||||
│ 178 │ x │ x │ │ │ 75 │ 75 │ 0 │ 75 │ 75 │
|
| Touch | down | up | palm | thumb | min | max | p | avg | median |
|
||||||
│ 179 │ x │ x │ │ │ 35 │ 88 │ 0 │ 77 │ 81 │
|
+-------------------------------------------------------------------------------+
|
||||||
│ 180 │ x │ x │ │ x │ 65 │ 113 │ 0 │ 98 │ 98 │
|
| 178 | x | x | | | 75 | 75 | 0 | 75 | 75 |
|
||||||
│ 181 │ x │ x │ │ x │ 50 │ 101 │ 0 │ 86 │ 90 │
|
| 179 | x | x | | | 35 | 88 | 0 | 77 | 81 |
|
||||||
│ 182 │ x │ x │ │ │ 40 │ 80 │ 0 │ 66 │ 70 │
|
| 180 | x | x | | x | 65 | 113 | 0 | 98 | 98 |
|
||||||
│ 183 │ x │ │ │ │ 43 │ 78 │ 78 │ │
|
| 181 | x | x | | x | 50 | 101 | 0 | 86 | 90 |
|
||||||
│ Thresh │ 70 │ 60 │ 130 │ 100 │
|
| 182 | x | x | | | 40 | 80 | 0 | 66 | 70 |
|
||||||
|
| 183 | x | | | | 43 | 78 | 78 | |
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
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 ``down`` column show that each sequence was
|
||||||
considered logically down at some point (see the threholds in the last line),
|
considered logically down at some point, two of the sequences were considered
|
||||||
two of the sequences were considered thumbs. This is an interactive tool and
|
thumbs. This is an interactive tool and its output may change frequently. Refer
|
||||||
its output may change frequently. Refer to the
|
to the **libinput-measure-touchpad-pressure(1)** man 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 +100,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 +115,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
|
||||||
|
|
@ -206,7 +197,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 +209,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 +223,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
|
||||||
|
|
|
||||||
|
|
@ -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>`_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -517,10 +515,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 +542,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 +595,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 */
|
||||||
|
|
@ -620,29 +607,10 @@
|
||||||
#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_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
|
||||||
|
|
@ -687,27 +655,6 @@
|
||||||
/* Select an area of screen to be copied */
|
/* Select an area of screen to be copied */
|
||||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
#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
|
* 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
|
* are intended to be programmed / bound to macros by the user. For most
|
||||||
|
|
@ -783,9 +730,6 @@
|
||||||
#define KEY_KBD_LCD_MENU4 0x2bb
|
#define KEY_KBD_LCD_MENU4 0x2bb
|
||||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
#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
|
||||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||||
|
|
@ -890,7 +834,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
|
||||||
|
|
||||||
|
|
@ -946,8 +889,7 @@
|
||||||
#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_MACHINE_COVER 0x10 /* set = cover closed */
|
||||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
#define SW_MAX 0x10
|
||||||
#define SW_MAX 0x11
|
|
||||||
#define SW_CNT (SW_MAX+1)
|
#define SW_CNT (SW_MAX+1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -517,10 +515,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 +542,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 +595,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 */
|
||||||
|
|
@ -620,29 +607,10 @@
|
||||||
#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_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
|
||||||
|
|
@ -687,27 +655,6 @@
|
||||||
/* Select an area of screen to be copied */
|
/* Select an area of screen to be copied */
|
||||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
#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
|
* 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
|
* are intended to be programmed / bound to macros by the user. For most
|
||||||
|
|
@ -783,9 +730,6 @@
|
||||||
#define KEY_KBD_LCD_MENU4 0x2bb
|
#define KEY_KBD_LCD_MENU4 0x2bb
|
||||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
#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
|
||||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||||
|
|
@ -890,7 +834,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
|
||||||
|
|
||||||
|
|
@ -946,8 +889,7 @@
|
||||||
#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_MACHINE_COVER 0x10 /* set = cover closed */
|
||||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
#define SW_MAX 0x10
|
||||||
#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
|
||||||
|
|
||||||
|
|
|
||||||
520
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
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
MatchUdevType=tablet
|
MatchUdevType=tablet
|
||||||
MatchBus=usb
|
MatchBus=usb
|
||||||
MatchVendor=0x08CA
|
MatchVendor=0x08CA
|
||||||
AttrEventCode=-ABS_TILT_X;-ABS_TILT_Y;
|
AttrEventCodeDisable=ABS_TILT_X;ABS_TILT_Y;
|
||||||
|
|
||||||
[Aiptek 8000U pressure threshold]
|
[Aiptek 8000U pressure threshold]
|
||||||
MatchUdevType=tablet
|
MatchUdevType=tablet
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,23 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
|
||||||
|
|
||||||
[Contour Design RollerMouse Free 2]
|
[Contour Design RollerMouse Free 2]
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x0B33
|
MatchVendor=0x0B33
|
||||||
MatchProduct=0x0401
|
MatchProduct=0x0401
|
||||||
|
MatchUdevType=mouse
|
||||||
ModelBouncingKeys=1
|
ModelBouncingKeys=1
|
||||||
|
|
||||||
[Contour Design RollerMouse Free 3]
|
[Contour Design RollerMouse Free 3]
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x0B33
|
MatchVendor=0x0B33
|
||||||
MatchProduct=0x0404
|
MatchProduct=0x0404
|
||||||
|
MatchUdevType=mouse
|
||||||
ModelBouncingKeys=1
|
ModelBouncingKeys=1
|
||||||
|
|
||||||
[Contour Design RollerMouse Re:d]
|
[Contour Design RollerMouse Re:d]
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x0B33
|
MatchVendor=0x0B33
|
||||||
MatchProduct=0x1000
|
MatchProduct=0x1000
|
||||||
|
MatchUdevType=mouse
|
||||||
ModelBouncingKeys=1
|
ModelBouncingKeys=1
|
||||||
|
|
||||||
[Contour Design RollerMouse Red v3]
|
[Contour Design RollerMouse Red v3]
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x0B33
|
MatchVendor=0x0B33
|
||||||
MatchProduct=0x1004
|
MatchProduct=0x1004
|
||||||
ModelBouncingKeys=1
|
|
||||||
|
|
||||||
[Contour Design RollerMouse Pro3]
|
|
||||||
MatchUdevType=mouse
|
MatchUdevType=mouse
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x0B33
|
|
||||||
MatchProduct=0x0703
|
|
||||||
ModelBouncingKeys=1
|
|
||||||
|
|
||||||
[Contour Design RollerMouse USB Receiver]
|
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x0B33
|
|
||||||
MatchProduct=0x2000
|
|
||||||
ModelBouncingKeys=1
|
ModelBouncingKeys=1
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
# Do not edit this file, it will be overwritten on update
|
||||||
|
|
||||||
[Cyapa Touchpads]
|
[Cyapa Touchpads]
|
||||||
MatchBus=i2c
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
MatchName=*Cypress APA Trackpad ?cyapa?
|
MatchName=*Cypress APA Trackpad ?cyapa?
|
||||||
AttrPressureRange=10:8
|
AttrPressureRange=10:8
|
||||||
|
|
||||||
[Cypress Touchpads]
|
[Cypress Touchpads]
|
||||||
MatchBus=ps2
|
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchName=*CyPS/2 Cypress Trackpad
|
MatchName=*CyPS/2 Cypress Trackpad
|
||||||
AttrPressureRange=10:8
|
AttrPressureRange=10:8
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,3 @@ AttrPressureRange=10:8
|
||||||
MatchName=*Elan Touchpad*
|
MatchName=*Elan Touchpad*
|
||||||
AttrResolutionHint=31x31
|
AttrResolutionHint=31x31
|
||||||
AttrPressureRange=10:8
|
AttrPressureRange=10:8
|
||||||
|
|
||||||
# Elan Hapticpad mostly used in Lenovo laptops.
|
|
||||||
[Elan Haptic Touchpad (04F3:3355)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x04F3
|
|
||||||
MatchProduct=0x3355
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
|
||||||
|
|
||||||
[Glorious Model O]
|
|
||||||
MatchUdevType=mouse
|
|
||||||
MatchBus=usb
|
|
||||||
MatchVendor=0x258A
|
|
||||||
MatchProduct=0x0036
|
|
||||||
ModelBouncingKeys=1
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
|
||||||
|
|
||||||
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
# Match vid and pid as it can have other names.
|
|
||||||
[Goodix Haptic Touchpad (27C6:01E7)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x01E7
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
||||||
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
# GXTP5100:00 27C6:01E8 Touchpad
|
|
||||||
[Goodix Haptic Touchpad (27C6:01E8)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x01E8
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
||||||
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
# GXTP5100:00 27C6:01E9 Touchpad
|
|
||||||
[Goodix Haptic Touchpad (27C6:01E9)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x01E9
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
||||||
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
# GXTP5100:00 27C6:01EA Touchpad
|
|
||||||
[Goodix Haptic Touchpad (27C6:01EA)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x01EA
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
||||||
# "GXTP5100 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
# GXTP5100:00 27C6:01EB Touchpad
|
|
||||||
[Goodix Haptic Touchpad (27C6:01EB)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x01EB
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
||||||
# "GXTP5420 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
# GXTP5420:00 27C6:0F95 Touchpad
|
|
||||||
[Goodix Haptic Touchpad (27C6:0F95)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x0F95
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
||||||
# "GXTP5420 Touchpad": pressure touchpad mostly used in Lenovo laptops.
|
|
||||||
[Goodix Haptic Touchpad (27C6:0F90)]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x27C6
|
|
||||||
MatchProduct=0x0F90
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
# Do not edit this file, it will be overwritten on update
|
|
||||||
|
|
||||||
# HTIX3602:00 0911:5288 touchpad, clickpad pretending it has a right button.
|
|
||||||
# Integrated into several systems, including
|
|
||||||
# Purism Librem 14v1
|
|
||||||
# Prestigio Smartbook 141 C2
|
|
||||||
# StarLite Mk II
|
|
||||||
# Iota IOTA2320
|
|
||||||
# with different names
|
|
||||||
# ALPS0001:00 0911:5288
|
|
||||||
# HTIX3602:00 0911:5288
|
|
||||||
# PCT2342:00 0911:5288
|
|
||||||
# SP3105FT:00 0911:5288
|
|
||||||
# SYNA3602:00 0911:5288
|
|
||||||
# Also exist FTSC1000:00 0911:5288 Mouse, so match in type
|
|
||||||
# is needed to leave mouse button untouched.
|
|
||||||
[Hantick 0911:5288 Touchpad]
|
|
||||||
MatchBus=i2c
|
|
||||||
MatchVendor=0x0911
|
|
||||||
MatchProduct=0x5288
|
|
||||||
MatchUdevType=touchpad
|
|
||||||
AttrEventCode=-BTN_RIGHT
|
|
||||||