Compare commits

..

No commits in common. "main" and "1.19.0" have entirely different histories.
main ... 1.19.0

425 changed files with 24603 additions and 58930 deletions

View file

@ -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;"]

View file

@ -1 +0,0 @@
include/**/*

View file

@ -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: '*'

View file

@ -1 +0,0 @@
include/*

View file

@ -19,7 +19,3 @@ indent_style = space
[{meson.build,meson_options.txt}] [{meson.build,meson_options.txt}]
indent_size = 8 indent_size = 8
indent_style = tab indent_style = tab
[*.sym]
indent_size = 8
indent_style = tab

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -36,39 +36,18 @@
# <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 007f3e2fe2235328e77d3cd4ce007ab41cd9ce6c
include: include:
{% for distro in distributions|sort(attribute="name") %}
# {{ 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'
{% 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,7 +69,7 @@ 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(' ')}}'
@ -103,6 +82,11 @@ 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 %}
{{"%-20s"| format(distro.name.upper() + '_QEMU_TAG:')}} '{{distro.name}}-qemu-vm-{{distro.tag}}'
{% endif %}
{% endfor %} {% endfor %}
FDO_UPSTREAM_REPO: libinput/libinput FDO_UPSTREAM_REPO: libinput/libinput
@ -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
@ -131,16 +110,6 @@ variables:
interruptible: true interruptible: true
dependencies: [] 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:
name: "meson-logs-$CI_JOB_NAME" name: "meson-logs-$CI_JOB_NAME"
@ -148,13 +117,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 +127,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,7 +134,6 @@ 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
@ -197,16 +144,15 @@ check-ci-script:
- 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 && exit 0 || true
- > - >
printf "%s\n" \ printf "%s\n" \
"Error checking commit format. Please verify" \ "Error checking commit format. Please verify" \
@ -220,56 +166,41 @@ check-commit:
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: ${{distro.name.upper()}}_QEMU_TAG
FDO_DISTRIBUTION_PACKAGES: ${{distro.name.upper()}}_PACKAGES
{% endfor %}
{% for distro in distributions %} {% for distro in distributions %}
{% if not distro.skip_container %}
{% 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
@ -278,6 +209,7 @@ pre-commit-hooks:
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
{% endfor %} {% endfor %}
{% endif %}
{% endfor %} {% endfor %}
@ -297,7 +229,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
@ -313,6 +244,7 @@ pre-commit-hooks:
- schedules - schedules
{% for distro in distributions %} {% for distro in distributions %}
{% if not distro.skip_container %}
{% for version in distro.versions %} {% for version in distro.versions %}
{{distro.name}}:{{version}}@container-clean: {{distro.name}}:{{version}}@container-clean:
extends: extends:
@ -325,6 +257,7 @@ pre-commit-hooks:
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
{% endfor %} {% endfor %}
{% endif %}
{% endfor %} {% endfor %}
################################################################# #################################################################
@ -337,41 +270,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
# 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
# #
@ -388,8 +290,9 @@ pre-commit-hooks:
.build-in-qemu@template: .build-in-qemu@template:
extends: extends:
- .policy - .policy
- .fdo.distribution-image@fedora
tags: tags:
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM - kvm
variables: variables:
MESON_BUILDDIR: build_dir MESON_BUILDDIR: build_dir
script: script:
@ -426,7 +329,7 @@ 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
# Run in a test suite. Special variables: # Run in a test suite. Special variables:
@ -435,30 +338,32 @@ pre-commit-hooks:
# Set one or the other, not both. # Set one or the other, not both.
.test-suite-vm: .test-suite-vm:
extends: extends:
- .build-in-vng@template - .build-in-qemu@template
stage: test-suite stage: test-suite
variables: variables:
# remove the global --no-suite=hardware # remove the global --no-suite=hardware
MESON_TEST_ARGS: '' MESON_TEST_ARGS: ''
LITEST_JOBS: 4
before_script: before_script:
- if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi - if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi
- echo "Testing $SUITES" - echo "Testing $SUITES"
- export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES" - export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES"
retry:
max: 2
when: script_failure
{# 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()) %}
{% if distro.use_for_custom_build_tests %}
.{{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: ${{distro.name.upper()}}_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 +387,18 @@ 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 %}
{% endif %}
{% endfor %}{# for if distro.use_for_qemu_tests #} {% endfor %}{# for if distro.want_qemu #}
{% 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 +414,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: ''
MESON_TEST_ARGS: '' MESON_TEST_ARGS: ''
CC: 'clang' before_script:
- dnf install -y clang-analyzer
script: script:
- .gitlab-ci/meson-build.sh - .gitlab-ci/meson-build.sh
- ninja -C "$MESON_BUILDDIR" clang-tidy - export SCANBUILD="$PWD/.gitlab-ci/scanbuild-wrapper.sh"
- ninja -C "$MESON_BUILDDIR" scan-build
after_script:
- .gitlab-ci/scanbuild-plist-to-junit.py "$MESON_BUILDDIR"/meson-logs/scanbuild/ > "$MESON_BUILDDIR"/junit-scan-build.xml
# 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,34 +447,6 @@ 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}}:
extends:
- .{{distro.name}}-build@template
variables:
MESON_ARGS: "-Dmtdev=false"
build-no-mtdev-nodeps@{{distro.name}}:{{version}}:
extends:
- .{{distro.name}}-build@template
variables:
MESON_ARGS: "-Dmtdev=false"
before_script:
- dnf remove -y mtdev mtdev-devel
build-no-lua@{{distro.name}}:{{version}}:
extends:
- .{{distro.name}}-build@template
variables:
MESON_ARGS: "-Dlua-plugins=disabled"
build-no-lua-nodeps@{{distro.name}}:{{version}}:
extends:
- .{{distro.name}}-build@template
variables:
MESON_ARGS: "-Dlua-plugins=disabled"
before_script:
- dnf remove -y lua lua-devel
build-docs@{{distro.name}}:{{version}}: build-docs@{{distro.name}}:{{version}}:
extends: extends:
- .{{distro.name}}-build@template - .{{distro.name}}-build@template
@ -598,7 +473,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 +494,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 +509,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 +560,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 +599,7 @@ coverity:
################################################################# #################################################################
{% for distro in distributions %} {% for distro in distributions %}
{% if not distro.qemu_based %} {% if not distro.skip_container %}
{% for version in distro.versions %} {% for version in distro.versions %}
{{distro.name}}:{{version}}@default-build: {{distro.name}}:{{version}}@default-build:
stage: distro stage: distro
@ -742,7 +629,7 @@ coverity:
- .fdo.distribution-image@{{distro.name}} - .fdo.distribution-image@{{distro.name}}
variables: variables:
FDO_DISTRIBUTION_VERSION: '{{version}}' FDO_DISTRIBUTION_VERSION: '{{version}}'
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_QEMU_TAG
{# Where we have extra_variables defined, add them to the list #} {# Where we have extra_variables defined, add them to the list #}
{% if distro.build is defined and distro.build.extra_variables is defined %} {% if distro.build is defined and distro.build.extra_variables is defined %}
{% for var in distro.build.extra_variables %} {% for var in distro.build.extra_variables %}
@ -750,7 +637,7 @@ coverity:
{% endfor %} {% endfor %}
{% endif %} {% endif %}
needs: needs:
- "{{distro.name}}:{{version}}@container-prep" - "{{distro.name}}:{{version}}@qemu-prep"
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@ -761,20 +648,35 @@ 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
- .policy
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 +688,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: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
MESON_BUILDDIR: 'builddir' MESON_BUILDDIR: 'builddir'
rules: only:
- if: '$CI_PIPELINE_SOURCE == "schedule"' refs:
when: never - main
- 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

View file

@ -3,14 +3,15 @@
# #
# 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-07-30.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 use_for_qemu_tests: true
packages: packages:
@ -34,23 +35,7 @@ distributions:
- 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 +61,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.10'
- '21.04'
packages: packages:
- git - git
- gcc - gcc
@ -101,7 +86,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 +98,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 - gtk4
- 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:
@ -140,7 +125,6 @@ distributions:
- gtk4.0-dev - gtk4.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 +132,48 @@ 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
want_qemu: true
skip_container: true
versions:
- '13.0'
packages:
- git
- pkgconf
- meson
- libepoll-shim
- libudev-devd
- libevdev
- libwacom
- gtk3
- libmtdev
- bash
- wayland
build:
extra_variables:
- "MESON_ARGS: '-Dtests=false -Ddocumentation=false' # doxygen drags down too many deps"
# We don't run the tests on FreeBSD, someone would have to fix the
# test suite to work on BSD first.
- "MESON_TEST_ARGS: '' # test suite doesn't work on BSD yet"
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 +183,6 @@ test_suites:
- log - log
- misc - misc
- quirks - quirks
- device
- name: other devices - name: other devices
suites: suites:
- keyboard - keyboard
@ -209,9 +195,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

View file

@ -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

View file

@ -1,43 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#
# This script is sourced from here:
# https://gitlab.freedesktop.org/whot/meson-helper
#
# SPDX-License-Identifier: MIT
set -x 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,17 +14,16 @@ 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 if [[ -n "$FDO_CI_CONCURRENT" ]]; then
jobcount="-j$FDO_CI_CONCURRENT" NINJA_ARGS="-j$FDO_CI_CONCURRENT $NINJA_ARGS"
export MESON_TESTTHREADS="$FDO_CI_CONCURRENT" MESON_TESTTHREADS="$FDO_CI_CONCURRENT"
fi fi
echo "*************************************************" echo "*************************************************"
@ -65,24 +31,31 @@ 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
View 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="main",
)
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)

View file

@ -0,0 +1,131 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: MIT
#
# Usage:
# $ scanbuild-plist-to-junit.py /path/to/meson-logs/scanbuild/ > junit-report.xml
#
# Converts the plist output from scan-build into a JUnit-compatible XML.
#
# For use with meson, use a wrapper script with this content:
# scan-build -v --status-bugs -plist-html "$@"
# then build with
# SCANBUILD="/abs/path/to/wrapper.sh" ninja -C builddir scan-build
#
# For file context, $PWD has to be the root source directory.
#
# Note that the XML format is tailored towards being useful in the gitlab
# CI, the JUnit format supports more features.
#
# This file is formatted with Python Black
import argparse
import plistlib
import re
import sys
from pathlib import Path
errors = []
class Error(object):
pass
parser = argparse.ArgumentParser(
description="This tool convers scan-build's plist format to JUnit XML"
)
parser.add_argument(
"directory", help="Path to a scan-build output directory", type=Path
)
args = parser.parse_args()
if not args.directory.exists():
print(f"Invalid directory: {args.directory}", file=sys.stderr)
sys.exit(1)
# Meson places scan-build runs into a timestamped directory. To make it
# easier to invoke this script, we just glob everything on the assumption
# that there's only one scanbuild/$timestamp/ directory anyway.
for file in Path(args.directory).glob("**/*.plist"):
with open(file, "rb") as fd:
plist = plistlib.load(fd, fmt=plistlib.FMT_XML)
try:
sources = plist["files"]
for elem in plist["diagnostics"]:
e = Error()
e.type = elem["type"] # Human-readable error type
e.description = elem["description"] # Longer description
e.func = elem["issue_context"] # function name
e.lineno = elem["location"]["line"]
filename = sources[elem["location"]["file"]]
# Remove the ../../../ prefix from the file
e.file = re.sub(r"^(\.\./)*", "", filename)
errors.append(e)
except KeyError:
print(
"Failed to access plist content, incompatible format?", file=sys.stderr
)
sys.exit(1)
# Add a few lines of context for each error that we can print in the xml
# output. Note that e.lineno is 1-indexed.
#
# If one of the files fail, we stop doing this, we're probably in the wrong
# directory.
try:
current_file = None
lines = []
for e in sorted(errors, key=lambda x: x.file):
if current_file != e.file:
current_file = e.file
lines = open(current_file).readlines()
# e.lineno is 1-indexed, lineno is our 0-indexed line number
lineno = e.lineno - 1
start = max(0, lineno - 4)
end = min(len(lines), lineno + 5) # end is exclusive
e.context = [
f"{'>' if line == e.lineno else ' '} {line}: {content}"
for line, content in zip(range(start + 1, end), lines[start:end])
]
except FileNotFoundError:
pass
print('<?xml version="1.0" encoding="utf-8"?>')
print("<testsuites>")
if errors:
suites = sorted(set([s.type for s in errors]))
# Use a counter to ensure test names are unique, otherwise the CI
# display ignores duplicates.
counter = 0
for suite in suites:
errs = [e for e in errors if e.type == suite]
# Note: the grouping by suites doesn't actually do anything in gitlab. Oh well
print(f'<testsuite name="{suite}" failures="{len(errs)}" tests="{len(errs)}">')
for error in errs:
print(
f"""\
<testcase name="{counter}. {error.type} - {error.file}:{error.lineno}" classname="{error.file}">
<failure message="{error.description}">
<![CDATA[
In function {error.func}(),
{error.description}
{error.file}:{error.lineno}
---
{"".join(error.context)}
]]>
</failure>
</testcase>"""
)
counter += 1
print("</testsuite>")
else:
# In case of success, add one test case so that registers in the UI
# properly
print('<testsuite name="scanbuild" failures="0" tests="1">')
print('<testcase name="scanbuild" classname="scanbuild"/>')
print("</testsuite>")
print("</testsuites>")

0
.gitlab-ci/scanbuild-wrapper.sh Normal file → Executable file
View file

View file

@ -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()

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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).

View file

@ -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/'
} }

View file

@ -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"

3
doc/touchpad-gestures-state-machine.svg Normal file → Executable file

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View file

@ -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

View file

@ -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:

View file

@ -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:
@ -189,7 +189,7 @@ 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/main/.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 +242,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:

View file

@ -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

View file

@ -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>`__

View file

@ -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 -------------------------------------------------

View file

@ -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.

View file

@ -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``
@ -160,19 +151,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 +167,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. ::
@ -280,6 +266,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 +292,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.
@ -359,6 +353,26 @@ step failed.
Follow the appropriate section to fix the errors. Follow the appropriate section to fix the errors.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Missing "Signed-off-by: author information"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As explained in :ref:`contributing_commit_messages`, every commit must contain a
Signed-off-by line with your name and email address.
When this line is not present, it can be added to your commit afterwards: ::
git commit --amend -s
If the merge request contains more than one commit, it must be added to all of
them: ::
git rebase --interactive --exec 'git commit --amend -s' main
Once the problem is fixed, force-push your branch. See
:ref:`contributing_submitting_code` for more details about how to push your code
and interactive rebases.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -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:

View file

@ -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,23 @@ 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 AttrTabletSmoothing=1|0
Enables (1) or disables (0) input smoothing for tablet devices. Smoothing is enabled Enables (1) or disables (0) input smoothing for tablet devices. Smoothing is enabled
by default, except on AES devices. 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.

View file

@ -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];
}

View file

@ -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"];
}

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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',
@ -204,8 +192,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', 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

View file

@ -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:
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View file

@ -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.

View file

@ -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

View file

@ -124,12 +124,6 @@ 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:
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -156,23 +150,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.

View file

@ -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

File diff suppressed because it is too large Load diff

Before

Width:  |  Height:  |  Size: 27 KiB

View file

@ -208,3 +208,4 @@
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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/>`__.

View file

@ -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.

View file

@ -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.

View file

@ -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:

View file

@ -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**.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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>`_

View file

@ -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.

View file

@ -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

View file

@ -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`

View file

@ -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)
/* /*

View file

@ -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)
/* /*

View file

@ -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

View file

@ -1,8 +1,8 @@
project('libinput', 'c', project('libinput', 'c',
version : '1.31.0', version : '1.19.0',
license : 'MIT/Expat', license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ], default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.64.0') meson_version : '>= 0.49.0')
libinput_version = meson.project_version().split('.') libinput_version = meson.project_version().split('.')
@ -16,7 +16,6 @@ dir_system_udev = get_option('prefix') / 'lib' / 'udev'
dir_src_quirks = meson.current_source_dir() / 'quirks' dir_src_quirks = meson.current_source_dir() / 'quirks'
dir_src_test = meson.current_source_dir() / 'test' dir_src_test = meson.current_source_dir() / 'test'
dir_src = meson.current_source_dir() / 'src' dir_src = meson.current_source_dir() / 'src'
dir_gitlab_ci = meson.current_source_dir() / '.gitlab-ci'
dir_udev = get_option('udev-dir') dir_udev = get_option('udev-dir')
if dir_udev == '' if dir_udev == ''
@ -47,7 +46,6 @@ libinput_so_version = '@0@.@1@.@2@'.format((libinput_lt_c - libinput_lt_a),
# Compiler setup # Compiler setup
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
cflags = [ cflags = [
'-Wno-error=deprecated-declarations',
'-Wno-unused-parameter', '-Wno-unused-parameter',
'-Wmissing-prototypes', '-Wmissing-prototypes',
'-Wstrict-prototypes', '-Wstrict-prototypes',
@ -80,11 +78,10 @@ endif
config_h.set_quoted('HTTP_DOC_LINK', doc_url) config_h.set_quoted('HTTP_DOC_LINK', doc_url)
config_h.set('_GNU_SOURCE', '1') config_h.set('_GNU_SOURCE', '1')
if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
is_debug_build = get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
if is_debug_build
config_h.set('IS_DEBUG_BUILD', '1')
config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir()) config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir())
else
config_h.set_quoted('MESON_BUILD_ROOT', '')
endif endif
prefix = '''#define _GNU_SOURCE 1 prefix = '''#define _GNU_SOURCE 1
@ -117,14 +114,6 @@ if cc.has_header_symbol('dirent.h', 'versionsort', prefix : prefix)
config_h.set('HAVE_VERSIONSORT', '1') config_h.set('HAVE_VERSIONSORT', '1')
endif endif
if cc.get_define('SYS_pidfd_open', prefix: '#include <sys/syscall.h>') != ''
config_h.set('HAVE_PIDFD_OPEN', '1')
endif
if cc.has_function('sigabbrev_np', prefix: '#define _GNU_SOURCE 1\n#include <string.h>')
config_h.set('HAVE_SIGABBREV_NP', '1')
endif
if not cc.has_header_symbol('errno.h', 'program_invocation_short_name', prefix : prefix) if not cc.has_header_symbol('errno.h', 'program_invocation_short_name', prefix : prefix)
if cc.has_header_symbol('stdlib.h', 'getprogname') if cc.has_header_symbol('stdlib.h', 'getprogname')
config_h.set('program_invocation_short_name', 'getprogname()') config_h.set('program_invocation_short_name', 'getprogname()')
@ -135,15 +124,6 @@ if cc.has_header('xlocale.h')
config_h.set('HAVE_XLOCALE_H', '1') config_h.set('HAVE_XLOCALE_H', '1')
endif endif
code = '''
#include <time.h>
void func() { auto foo = gmtime(NULL); foo->tm_sec = 0; }
'''
if cc.compiles(code, name: 'has C23 auto keyword')
config_h.set('HAVE_C23_AUTO', '1')
endif
code = ''' code = '''
#include <locale.h> #include <locale.h>
void main(void) { newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); } void main(void) { newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); }
@ -157,76 +137,28 @@ if not cc.has_header_symbol('sys/ptrace.h', 'PTRACE_ATTACH', prefix : prefix)
config_h.set('PTRACE_CONT', 'PT_CONTINUE') config_h.set('PTRACE_CONT', 'PT_CONTINUE')
config_h.set('PTRACE_DETACH', 'PT_DETACH') config_h.set('PTRACE_DETACH', 'PT_DETACH')
endif endif
if get_option('install-tests')
config_h.set('HAVE_INSTALLED_TESTS', 1)
endif
# Dependencies # Dependencies
pkgconfig = import('pkgconfig') pkgconfig = import('pkgconfig')
dep_udev = dependency('libudev') dep_udev = dependency('libudev')
dep_libevdev = dependency('libevdev', version: '>= 1.10.0') dep_mtdev = dependency('mtdev', version : '>= 1.1.0')
dep_libevdev = dependency('libevdev')
config_h.set10('HAVE_LIBEVDEV_DISABLE_PROPERTY',
dep_libevdev.version().version_compare('>= 1.9.902'))
dep_lm = cc.find_library('m', required : false) dep_lm = cc.find_library('m', required : false)
dep_rt = cc.find_library('rt', required : false) dep_rt = cc.find_library('rt', required : false)
dep_lua = dependency('lua-5.4', 'lua5.4', 'lua',
version : '>= 5.4',
required : get_option('lua-plugins'))
have_lua = dep_lua.found()
if have_lua
config_h.set('HAVE_LUA', 1)
endif
have_plugins = dep_lua.found()
if have_plugins
config_h.set('HAVE_PLUGINS', 1)
endif
autoload_plugins = get_option('autoload-plugins')
if autoload_plugins
config_h.set('AUTOLOAD_PLUGINS', 1)
endif
summary({
'Plugins enabled' : have_plugins,
'Autoload plugins' : autoload_plugins,
'Lua Plugin support' : have_lua,
},
section : 'Plugins',
bool_yn : true)
# Include directories # Include directories
includes_include = include_directories('include') includes_include = include_directories('include')
includes_src = include_directories('src') includes_src = include_directories('src')
############ mtdev configuration ############
have_mtdev = get_option('mtdev')
if have_mtdev
config_h.set('HAVE_MTDEV', 1)
dep_mtdev = dependency('mtdev', version : '>= 1.1.0')
else
dep_mtdev = declare_dependency()
endif
############ libwacom configuration ############ ############ libwacom configuration ############
have_libwacom = get_option('libwacom') have_libwacom = get_option('libwacom')
config_h.set10('HAVE_LIBWACOM', have_libwacom)
if have_libwacom if have_libwacom
config_h.set('HAVE_LIBWACOM', 1)
dep_libwacom = dependency('libwacom', version : '>= 0.27') dep_libwacom = dependency('libwacom', version : '>= 0.27')
if cc.has_header_symbol('libwacom/libwacom.h', 'WACOM_BUTTON_DIAL_MODESWITCH',
dependencies : dep_libwacom)
config_h.set('HAVE_LIBWACOM_BUTTON_DIAL_MODESWITCH', '1')
endif
if cc.has_function('libwacom_get_button_modeswitch_mode',
dependencies: dep_libwacom)
config_h.set('HAVE_LIBWACOM_BUTTON_MODESWITCH_MODE', '1')
endif
if cc.has_function('libwacom_stylus_is_generic',
dependencies: dep_libwacom)
config_h.set('HAVE_LIBWACOM_STYLUS_IS_GENERIC', '1')
endif
else else
dep_libwacom = declare_dependency() dep_libwacom = declare_dependency()
endif endif
@ -238,7 +170,6 @@ executable('libinput-device-group',
dependencies : [dep_udev, dep_libwacom], dependencies : [dep_udev, dep_libwacom],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install : true, install : true,
install_tag : 'runtime',
install_dir : dir_udev_callouts) install_dir : dir_udev_callouts)
executable('libinput-fuzz-extract', executable('libinput-fuzz-extract',
'udev/libinput-fuzz-extract.c', 'udev/libinput-fuzz-extract.c',
@ -247,18 +178,16 @@ executable('libinput-fuzz-extract',
dependencies : [dep_udev, dep_libevdev, dep_lm], dependencies : [dep_udev, dep_libevdev, dep_lm],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install : true, install : true,
install_tag : 'runtime',
install_dir : dir_udev_callouts) install_dir : dir_udev_callouts)
executable('libinput-fuzz-to-zero', executable('libinput-fuzz-to-zero',
'udev/libinput-fuzz-to-zero.c', 'udev/libinput-fuzz-to-zero.c',
dependencies : [dep_udev, dep_libevdev], dependencies : [dep_udev, dep_libevdev],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install : true, install : true,
install_tag : 'runtime',
install_dir : dir_udev_callouts) install_dir : dir_udev_callouts)
udev_rules_config = configuration_data() udev_rules_config = configuration_data()
udev_rules_config.set('UDEV_TEST_PATH', dir_udev_callouts + '/') udev_rules_config.set('UDEV_TEST_PATH', '')
configure_file(input : 'udev/80-libinput-device-groups.rules.in', configure_file(input : 'udev/80-libinput-device-groups.rules.in',
output : '80-libinput-device-groups.rules', output : '80-libinput-device-groups.rules',
install_dir : dir_udev_rules, install_dir : dir_udev_rules,
@ -323,38 +252,42 @@ endif
# Basic compilation test to make sure the headers include and define all the # Basic compilation test to make sure the headers include and define all the
# necessary bits. # necessary bits.
util_headers = [ util_headers = [
'util-backtrace.h',
'util-bits.h', 'util-bits.h',
'util-input-event.h', 'util-input-event.h',
'util-list.h', 'util-list.h',
'util-files.h',
'util-macros.h', 'util-macros.h',
'util-matrix.h', 'util-matrix.h',
'util-prop-parsers.h', 'util-prop-parsers.h',
'util-ratelimit.h', 'util-ratelimit.h',
'util-stringbuf.h',
'util-strings.h', 'util-strings.h',
'util-time.h', 'util-time.h',
] ]
foreach h: util_headers foreach h: util_headers
c = configuration_data() c = configuration_data()
c.set_quoted('FILE', h) c.set_quoted('FILE', h)
testfile = configure_file(input : 'test/test-util-includes.c.in', testfile = configure_file(input : 'test/test-util-includes.c',
output : 'test-util-includes-@0@.c'.format(h), output : 'test-util-includes-@0@.c'.format(h),
configuration : c) configuration : c)
executable('test-build-@0@'.format(h), executable('test-build-@0@'.format(h),
testfile, testfile, dir_src / h,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
dependencies: [dep_libevdev],
install : false) install : false)
endforeach endforeach
src_libinput_util = [ src_libinput_util = [
'src/util-files.c', 'src/util-bits.h',
'src/util-list.c', 'src/util-list.c',
'src/util-list.h',
'src/util-macros.h',
'src/util-matrix.h',
'src/util-ratelimit.c', 'src/util-ratelimit.c',
'src/util-ratelimit.h',
'src/util-strings.h',
'src/util-strings.c', 'src/util-strings.c',
'src/util-time.h',
'src/util-prop-parsers.h',
'src/util-prop-parsers.c', 'src/util-prop-parsers.c',
'src/libinput-util.h',
] ]
libinput_util = static_library('libinput-util', libinput_util = static_library('libinput-util',
src_libinput_util, src_libinput_util,
@ -365,7 +298,6 @@ dep_libinput_util = declare_dependency(link_with : libinput_util)
############ libfilter.a ############ ############ libfilter.a ############
src_libfilter = [ src_libfilter = [
'src/filter.c', 'src/filter.c',
'src/filter-custom.c',
'src/filter-flat.c', 'src/filter-flat.c',
'src/filter-low-dpi.c', 'src/filter-low-dpi.c',
'src/filter-mouse.c', 'src/filter-mouse.c',
@ -374,10 +306,11 @@ src_libfilter = [
'src/filter-touchpad-x230.c', 'src/filter-touchpad-x230.c',
'src/filter-tablet.c', 'src/filter-tablet.c',
'src/filter-trackpoint.c', 'src/filter-trackpoint.c',
'src/filter-trackpoint-flat.c', 'src/filter.h',
'src/filter-private.h'
] ]
libfilter = static_library('filter', src_libfilter, libfilter = static_library('filter', src_libfilter,
dependencies : [dep_udev, dep_libwacom, dep_libevdev], dependencies : [dep_udev, dep_libwacom],
include_directories : includes_include) include_directories : includes_include)
dep_libfilter = declare_dependency(link_with : libfilter) dep_libfilter = declare_dependency(link_with : libfilter)
@ -395,6 +328,8 @@ install_subdir('quirks',
src_libquirks = [ src_libquirks = [
'src/quirks.c', 'src/quirks.c',
'src/quirks.h',
'src/builddir.h',
] ]
deps_libquirks = [dep_udev, dep_libwacom, dep_libinput_util] deps_libquirks = [dep_udev, dep_libwacom, dep_libinput_util]
@ -404,58 +339,43 @@ libquirks = static_library('quirks', src_libquirks,
dep_libquirks = declare_dependency(link_with : libquirks) dep_libquirks = declare_dependency(link_with : libquirks)
# Create /etc/libinput # Create /etc/libinput
install_emptydir(dir_etc / 'libinput') install_subdir('libinput', install_dir : dir_etc)
############ libinput.so ############ ############ libinput.so ############
if get_option('internal-event-debugging')
config_h.set('EVENT_DEBUGGING', 1)
endif
config_h.set_quoted('LIBINPUT_PLUGIN_LIBDIR', dir_lib / 'libinput' / 'plugins')
config_h.set_quoted('LIBINPUT_PLUGIN_ETCDIR', dir_etc / 'libinput' / 'plugins')
install_headers('src/libinput.h') install_headers('src/libinput.h')
src_libinput = src_libfilter + [ src_libinput = src_libfilter + [
'src/libinput.c', 'src/libinput.c',
'src/libinput-plugin.c', 'src/libinput.h',
'src/libinput-plugin-button-debounce.c',
'src/libinput-plugin-mouse-wheel.c',
'src/libinput-plugin-mouse-wheel-lowres.c',
'src/libinput-plugin-tablet-double-tool.c',
'src/libinput-plugin-tablet-eraser-button.c',
'src/libinput-plugin-tablet-forced-tool.c',
'src/libinput-plugin-tablet-proximity-timer.c',
'src/libinput-private-config.c', 'src/libinput-private-config.c',
'src/libinput-private-config.h',
'src/libinput-private.h',
'src/evdev.c', 'src/evdev.c',
'src/evdev.h',
'src/evdev-debounce.c',
'src/evdev-fallback.c', 'src/evdev-fallback.c',
'src/evdev-plugin.c', 'src/evdev-fallback.h',
'src/evdev-totem.c', 'src/evdev-totem.c',
'src/evdev-middle-button.c', 'src/evdev-middle-button.c',
'src/evdev-mt-touchpad.c', 'src/evdev-mt-touchpad.c',
'src/evdev-mt-touchpad.h',
'src/evdev-mt-touchpad-tap.c', 'src/evdev-mt-touchpad-tap.c',
'src/evdev-mt-touchpad-thumb.c', 'src/evdev-mt-touchpad-thumb.c',
'src/evdev-mt-touchpad-buttons.c', 'src/evdev-mt-touchpad-buttons.c',
'src/evdev-mt-touchpad-edge-scroll.c', 'src/evdev-mt-touchpad-edge-scroll.c',
'src/evdev-mt-touchpad-gestures.c', 'src/evdev-mt-touchpad-gestures.c',
'src/evdev-tablet.c', 'src/evdev-tablet.c',
'src/evdev-tablet.h',
'src/evdev-tablet-pad.c', 'src/evdev-tablet-pad.c',
'src/evdev-tablet-pad.h',
'src/evdev-tablet-pad-leds.c', 'src/evdev-tablet-pad-leds.c',
'src/path-seat.c', 'src/path-seat.c',
'src/udev-seat.c', 'src/udev-seat.c',
'src/udev-seat.h',
'src/timer.c', 'src/timer.c',
'src/util-libinput.c', 'src/timer.h',
'include/linux/input.h'
] ]
if have_mtdev
src_libinput += ['src/libinput-plugin-mtdev.c']
endif
if dep_lua.found()
src_libinput += [
'src/libinput-plugin-lua.c',
]
endif
deps_libinput = [ deps_libinput = [
dep_mtdev, dep_mtdev,
dep_udev, dep_udev,
@ -465,8 +385,7 @@ deps_libinput = [
dep_rt, dep_rt,
dep_libwacom, dep_libwacom,
dep_libinput_util, dep_libinput_util,
dep_libquirks, dep_libquirks
dep_lua,
] ]
libinput_version_h_config = configuration_data() libinput_version_h_config = configuration_data()
@ -497,18 +416,12 @@ dep_libinput = declare_dependency(
link_with : lib_libinput, link_with : lib_libinput,
dependencies : deps_libinput) dependencies : deps_libinput)
meson.override_dependency('libinput', dep_libinput)
pkgconfig.generate( pkgconfig.generate(
filebase : 'libinput', filebase : 'libinput',
name : 'Libinput', name : 'Libinput',
description : 'Input device library', description : 'Input device library',
version : meson.project_version(), version : meson.project_version(),
libraries : lib_libinput, libraries : lib_libinput
requires_private : dep_udev,
variables : [
'plugindir=${libdir}/libinput/plugins'
]
) )
git_version_h = vcs_tag(command : ['git', 'describe'], git_version_h = vcs_tag(command : ['git', 'describe'],
@ -516,8 +429,6 @@ git_version_h = vcs_tag(command : ['git', 'describe'],
input : 'src/libinput-git-version.h.in', input : 'src/libinput-git-version.h.in',
output :'libinput-git-version.h') output :'libinput-git-version.h')
subdir('plugins')
############ documentation ############ ############ documentation ############
if get_option('documentation') if get_option('documentation')
@ -529,23 +440,13 @@ endif
subdir('completion/zsh') subdir('completion/zsh')
############ libinput-util-libinput.a ############
# This one needs libinput itself
src_libinput_util_libinput = [
'src/util-libinput.c'
]
libinput_util_libinput = static_library('libinput-util-libinput',
src_libinput_util_libinput,
dependencies : [dep_libevdev, dep_libinput_util, dep_libinput],
include_directories : includes_include)
dep_libinput_util_libinput = declare_dependency(link_with : libinput_util_libinput)
############ tools ############ ############ tools ############
libinput_tool_path = dir_libexec libinput_tool_path = dir_libexec
config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path) config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path)
tools_shared_sources = [ 'tools/shared.c' ] tools_shared_sources = [ 'tools/shared.c',
deps_tools_shared = [ dep_libinput, dep_libevdev, dep_libinput_util_libinput ] 'tools/shared.h',
'src/builddir.h' ]
deps_tools_shared = [ dep_libinput, dep_libevdev ]
lib_tools_shared = static_library('tools_shared', lib_tools_shared = static_library('tools_shared',
tools_shared_sources, tools_shared_sources,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
@ -563,7 +464,6 @@ executable('libinput-debug-events',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true install : true
) )
@ -573,17 +473,8 @@ executable('libinput-debug-tablet',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true) install : true)
libinput_debug_tablet_pad_sources = [ 'tools/libinput-debug-tablet-pad.c' ]
executable('libinput-debug-tablet-pad',
libinput_debug_tablet_pad_sources,
dependencies : deps_tools,
include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path,
install_tag : 'bin',
install : true)
libinput_quirks_sources = [ 'tools/libinput-quirks.c' ] libinput_quirks_sources = [ 'tools/libinput-quirks.c' ]
libinput_quirks = executable('libinput-quirks', libinput_quirks = executable('libinput-quirks',
@ -591,7 +482,6 @@ libinput_quirks = executable('libinput-quirks',
dependencies : [dep_libquirks, dep_tools_shared, dep_libinput], dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true install : true
) )
test('validate-quirks', test('validate-quirks',
@ -600,20 +490,12 @@ test('validate-quirks',
suite : ['all'] suite : ['all']
) )
quirks_file_tester = find_program('test/test_quirks_files.py')
test('validate-quirks-files',
quirks_file_tester,
suite : ['all'],
env: ['MESON_SOURCE_ROOT=@0@'.format(meson.project_source_root())],
)
libinput_list_devices_sources = [ 'tools/libinput-list-devices.c' ] libinput_list_devices_sources = [ 'tools/libinput-list-devices.c' ]
libinput_list_devices = executable('libinput-list-devices', libinput_list_devices = executable('libinput-list-devices',
libinput_list_devices_sources, libinput_list_devices_sources,
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
test('list-devices', test('list-devices',
@ -626,7 +508,6 @@ executable('libinput-measure',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
@ -636,22 +517,19 @@ executable('libinput-analyze',
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
src_python_tools = files( src_python_tools = files(
'tools/libinput-analyze-buttons.py', 'tools/libinput-analyze-per-slot-delta.py',
'tools/libinput-analyze-per-slot-delta.py', 'tools/libinput-analyze-recording.py',
'tools/libinput-analyze-recording.py', 'tools/libinput-analyze-touch-down-state.py',
'tools/libinput-analyze-touch-down-state.py', 'tools/libinput-measure-fuzz.py',
'tools/libinput-list-kernel-devices.py', 'tools/libinput-measure-touchpad-size.py',
'tools/libinput-measure-fuzz.py', 'tools/libinput-measure-touchpad-tap.py',
'tools/libinput-measure-touchpad-size.py', 'tools/libinput-measure-touchpad-pressure.py',
'tools/libinput-measure-touchpad-tap.py', 'tools/libinput-measure-touch-size.py',
'tools/libinput-measure-touchpad-pressure.py', 'tools/libinput-replay.py'
'tools/libinput-measure-touch-size.py',
'tools/libinput-replay.py'
) )
foreach t : src_python_tools foreach t : src_python_tools
@ -668,42 +546,28 @@ executable('libinput-record',
dependencies : deps_tools + [dep_udev], dependencies : deps_tools + [dep_udev],
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true, install : true,
) )
if get_option('debug-gui') if get_option('debug-gui')
config_h.set('HAVE_DEBUG_GUI', 1)
dep_gtk = dependency('gtk4', version : '>= 4.0', required : false) dep_gtk = dependency('gtk4', version : '>= 4.0', required : false)
if dep_gtk.found() config_h.set10('HAVE_GTK4', dep_gtk.found())
config_h.set('HAVE_GTK4', 1) if not dep_gtk.found()
else
dep_gtk = dependency('gtk+-3.0', version : '>= 3.20') dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
if dep_gtk.found() config_h.set10('HAVE_GTK3', dep_gtk.found())
config_h.set('HAVE_GTK3', 1)
endif
endif endif
gtk_targets = dep_gtk.get_variable('targets')
have_gtk_wayland = gtk_targets.contains('wayland')
have_gtk_x11 = gtk_targets.contains('x11')
dep_cairo = dependency('cairo') dep_cairo = dependency('cairo')
dep_glib = dependency('glib-2.0') dep_glib = dependency('glib-2.0')
dep_x11 = dependency('x11', required : false)
dep_wayland_client = dependency('wayland-client', required : false) dep_wayland_client = dependency('wayland-client', required : false)
dep_wayland_protocols = dependency('wayland-protocols', required : false) dep_wayland_protocols = dependency('wayland-protocols', required : false)
dep_x11 = dependency('x11', required : false)
if have_gtk_x11 and dep_x11.found()
config_h.set('HAVE_GTK_X11', 1)
endif
debug_gui_sources = [ 'tools/libinput-debug-gui.c' ] debug_gui_sources = [ 'tools/libinput-debug-gui.c' ]
if have_gtk_wayland and dep_wayland_client.found() and dep_wayland_protocols.found() if dep_wayland_client.found() and dep_wayland_protocols.found()
wayland_scanner = find_program('wayland-scanner') wayland_scanner = find_program('wayland-scanner')
wlproto_dir = dep_wayland_protocols.get_variable('pkgdatadir') wlproto_dir = dep_wayland_protocols.get_pkgconfig_variable('pkgdatadir')
proto_name = 'pointer-constraints-unstable-v1' proto_name = 'pointer-constraints-unstable-v1'
input = files(wlproto_dir / 'unstable' / 'pointer-constraints' / '@0@.xml'.format(proto_name)) input = files(wlproto_dir / 'unstable' / 'pointer-constraints' / '@0@.xml'.format(proto_name))
@ -721,7 +585,6 @@ if get_option('debug-gui')
) )
debug_gui_sources += [ wayland_headers, wayland_sources ] debug_gui_sources += [ wayland_headers, wayland_sources ]
config_h.set('HAVE_GTK_WAYLAND', 1)
endif endif
deps_debug_gui = [ deps_debug_gui = [
@ -737,7 +600,6 @@ if get_option('debug-gui')
dependencies : deps_debug_gui, dependencies : deps_debug_gui,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path, install_dir : libinput_tool_path,
install_tag : 'bin',
install : true install : true
) )
src_man += files('tools/libinput-debug-gui.man') src_man += files('tools/libinput-debug-gui.man')
@ -749,7 +611,6 @@ libinput_tool = executable('libinput',
libinput_sources, libinput_sources,
dependencies : deps_tools, dependencies : deps_tools,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
install_tag : 'bin',
install : true install : true
) )
@ -763,10 +624,10 @@ executable('ptraccel-debug',
# Don't run the test during a release build because we rely on the magic # Don't run the test during a release build because we rely on the magic
# subtool lookup # subtool lookup
if is_debug_build if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
config_tool_option_test = configuration_data() config_tool_option_test = configuration_data()
config_tool_option_test.set('DISABLE_WARNING', 'yes') config_tool_option_test.set('DISABLE_WARNING', 'yes')
config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui').to_string()) config_tool_option_test.set('MESON_ENABLED_DEBUG_GUI', get_option('debug-gui'))
config_tool_option_test.set('MESON_BUILD_ROOT', meson.current_build_dir()) config_tool_option_test.set('MESON_BUILD_ROOT', meson.current_build_dir())
config_tool_option_test.set('TOOL_PATH', libinput_tool.full_path()) config_tool_option_test.set('TOOL_PATH', libinput_tool.full_path())
tool_option_test = configure_file(input: 'tools/test_tool_option_parsing.py', tool_option_test = configure_file(input: 'tools/test_tool_option_parsing.py',
@ -774,7 +635,7 @@ if is_debug_build
configuration : config_tool_option_test) configuration : config_tool_option_test)
test('tool-option-parsing', test('tool-option-parsing',
tool_option_test, tool_option_test,
args : [tool_option_test], args : [tool_option_test, '-n', 'auto'],
suite : ['all', 'root'], suite : ['all', 'root'],
timeout : 240) timeout : 240)
endif endif
@ -800,13 +661,6 @@ test('tools-builddir-lookup-installed',
############ tests ############ ############ tests ############
summary({
'Tests enabled' : get_option('tests'),
'Install tests' : get_option('install-tests'),
},
section : 'Tests',
bool_yn : true)
test('symbols-leak-test', test('symbols-leak-test',
find_program('test/symbols-leak-test'), find_program('test/symbols-leak-test'),
args : [ dir_src / 'libinput.sym', dir_src], args : [ dir_src / 'libinput.sym', dir_src],
@ -833,7 +687,7 @@ executable('test-build-linker',
dependencies : [ dep_libinput, dep_libinput_util ], dependencies : [ dep_libinput, dep_libinput_util ],
install : false) install : false)
# test including from C++ (in case CPP compiler is available) # test including from C++ (in case CPP compiler is available)
if add_languages('cpp', native: false, required: false) if add_languages('cpp', required: false)
executable('test-build-cxx', executable('test-build-cxx',
'test/build-cxx.cc', 'test/build-cxx.cc',
dependencies : [dep_udev], dependencies : [dep_udev],
@ -841,34 +695,23 @@ if add_languages('cpp', native: false, required: false)
install : false) install : false)
endif endif
libinput_test_sources = [ 'tools/libinput-test.c' ]
executable('libinput-test',
libinput_test_sources,
dependencies : deps_tools,
include_directories : [includes_src, includes_include],
install_dir : libinput_tool_path,
install_tag : 'tests',
install : true,
)
# This is the test suite runner, we allow disabling that one because of # This is the test suite runner, we allow disabling that one because of
# dependencies # dependencies
if get_option('tests') if get_option('tests')
dep_check = dependency('check', version : '>= 0.9.10', required: false) dep_check = dependency('check', version : '>= 0.9.10')
gstack = find_program('gstack', required : false) gstack = find_program('gstack', required : false)
if gstack.found() config_h.set10('HAVE_GSTACK', gstack.found())
config_h.set('HAVE_GSTACK', 1)
endif
# for inhibit support during test run # for inhibit support during test run
dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false) dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
if dep_libsystemd.found() config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
config_h.set('HAVE_LIBSYSTEMD', 1)
endif
litest_sources = [ litest_sources = [
'src/libinput-private-config.c', 'src/libinput-private-config.c',
'src/libinput-private-config.h',
'test/litest.h',
'test/litest-int.h',
'test/litest-device-absinfo-override.c', 'test/litest-device-absinfo-override.c',
'test/litest-device-acer-hawaii-keyboard.c', 'test/litest-device-acer-hawaii-keyboard.c',
'test/litest-device-acer-hawaii-touchpad.c', 'test/litest-device-acer-hawaii-touchpad.c',
@ -889,14 +732,10 @@ if get_option('tests')
'test/litest-device-dell-canvas-totem-touch.c', 'test/litest-device-dell-canvas-totem-touch.c',
'test/litest-device-elantech-touchpad.c', 'test/litest-device-elantech-touchpad.c',
'test/litest-device-elan-tablet.c', 'test/litest-device-elan-tablet.c',
'test/litest-device-format-string.c',
'test/litest-device-generic-pressurepad.c', 'test/litest-device-generic-pressurepad.c',
'test/litest-device-generic-singletouch.c', 'test/litest-device-generic-singletouch.c',
'test/litest-device-generic-usb-keyboard.c',
'test/litest-device-generic-usb-touchpad.c',
'test/litest-device-gpio-keys.c', 'test/litest-device-gpio-keys.c',
'test/litest-device-huion-pentablet.c', 'test/litest-device-huion-pentablet.c',
'test/litest-device-huion-q620m-dial.c',
'test/litest-device-hp-wmi-hotkeys.c', 'test/litest-device-hp-wmi-hotkeys.c',
'test/litest-device-ignored-mouse.c', 'test/litest-device-ignored-mouse.c',
'test/litest-device-keyboard.c', 'test/litest-device-keyboard.c',
@ -905,8 +744,6 @@ if get_option('tests')
'test/litest-device-keyboard-razer-blackwidow.c', 'test/litest-device-keyboard-razer-blackwidow.c',
'test/litest-device-keyboard-razer-blade-stealth.c', 'test/litest-device-keyboard-razer-blade-stealth.c',
'test/litest-device-keyboard-razer-blade-stealth-videoswitch.c', 'test/litest-device-keyboard-razer-blade-stealth-videoswitch.c',
'test/litest-device-keypad-slide-switch.c',
'test/litest-device-lenovo-scrollpoint.c',
'test/litest-device-lid-switch.c', 'test/litest-device-lid-switch.c',
'test/litest-device-lid-switch-surface3.c', 'test/litest-device-lid-switch-surface3.c',
'test/litest-device-logitech-media-keyboard-elite.c', 'test/litest-device-logitech-media-keyboard-elite.c',
@ -915,16 +752,13 @@ if get_option('tests')
'test/litest-device-magic-trackpad.c', 'test/litest-device-magic-trackpad.c',
'test/litest-device-mouse.c', 'test/litest-device-mouse.c',
'test/litest-device-mouse-wheel-tilt.c', 'test/litest-device-mouse-wheel-tilt.c',
'test/litest-device-mouse-wheel-hires-disabled.c',
'test/litest-device-mouse-ps2.c',
'test/litest-device-mouse-roccat.c', 'test/litest-device-mouse-roccat.c',
'test/litest-device-mouse-low-dpi.c', 'test/litest-device-mouse-low-dpi.c',
'test/litest-device-mouse-virtual.c',
'test/litest-device-mouse-wheel-click-angle.c', 'test/litest-device-mouse-wheel-click-angle.c',
'test/litest-device-mouse-wheel-click-count.c', 'test/litest-device-mouse-wheel-click-count.c',
'test/litest-device-ms-nano-transceiver-mouse.c', 'test/litest-device-ms-nano-transceiver-mouse.c',
'test/litest-device-ms-surface-cover.c', 'test/litest-device-ms-surface-cover.c',
'test/litest-device-ploopy-pavonis-stylus.c', 'test/litest-device-protocol-a-touch-screen.c',
'test/litest-device-qemu-usb-tablet.c', 'test/litest-device-qemu-usb-tablet.c',
'test/litest-device-sony-vaio-keys.c', 'test/litest-device-sony-vaio-keys.c',
'test/litest-device-synaptics-x220.c', 'test/litest-device-synaptics-x220.c',
@ -935,14 +769,10 @@ if get_option('tests')
'test/litest-device-synaptics-st.c', 'test/litest-device-synaptics-st.c',
'test/litest-device-synaptics-t440.c', 'test/litest-device-synaptics-t440.c',
'test/litest-device-synaptics-x1-carbon-3rd.c', 'test/litest-device-synaptics-x1-carbon-3rd.c',
'test/litest-device-synaptics-phantomclicks.c',
'test/litest-device-tablet-doubledial.c',
'test/litest-device-tablet-mode-switch.c', 'test/litest-device-tablet-mode-switch.c',
'test/litest-device-tablet-rel-dial.c',
'test/litest-device-thinkpad-extrabuttons.c', 'test/litest-device-thinkpad-extrabuttons.c',
'test/litest-device-trackpoint.c', 'test/litest-device-trackpoint.c',
'test/litest-device-touch-screen.c', 'test/litest-device-touch-screen.c',
'test/litest-device-touchpad-palm-threshold-zero.c',
'test/litest-device-touchscreen-invalid-range.c', 'test/litest-device-touchscreen-invalid-range.c',
'test/litest-device-touchscreen-fuzz.c', 'test/litest-device-touchscreen-fuzz.c',
'test/litest-device-touchscreen-mt-tool.c', 'test/litest-device-touchscreen-mt-tool.c',
@ -951,7 +781,6 @@ if get_option('tests')
'test/litest-device-wacom-bamboo-2fg-pad.c', 'test/litest-device-wacom-bamboo-2fg-pad.c',
'test/litest-device-wacom-bamboo-2fg-pen.c', 'test/litest-device-wacom-bamboo-2fg-pen.c',
'test/litest-device-wacom-bamboo-16fg-pen.c', 'test/litest-device-wacom-bamboo-16fg-pen.c',
'test/litest-device-wacom-calibrated-tablet.c',
'test/litest-device-wacom-cintiq-12wx-pen.c', 'test/litest-device-wacom-cintiq-12wx-pen.c',
'test/litest-device-wacom-cintiq-13hdt-finger.c', 'test/litest-device-wacom-cintiq-13hdt-finger.c',
'test/litest-device-wacom-cintiq-13hdt-pad.c', 'test/litest-device-wacom-cintiq-13hdt-pad.c',
@ -968,7 +797,6 @@ if get_option('tests')
'test/litest-device-wacom-intuos5-pad.c', 'test/litest-device-wacom-intuos5-pad.c',
'test/litest-device-wacom-intuos5-pen.c', 'test/litest-device-wacom-intuos5-pen.c',
'test/litest-device-wacom-isdv4-4200-pen.c', 'test/litest-device-wacom-isdv4-4200-pen.c',
'test/litest-device-wacom-isdv4-524c-pen.c',
'test/litest-device-wacom-isdv4-e6-pen.c', 'test/litest-device-wacom-isdv4-e6-pen.c',
'test/litest-device-wacom-isdv4-e6-finger.c', 'test/litest-device-wacom-isdv4-e6-finger.c',
'test/litest-device-wacom-mobilestudio-pro-pad.c', 'test/litest-device-wacom-mobilestudio-pro-pad.c',
@ -977,27 +805,20 @@ if get_option('tests')
'test/litest-device-xen-virtual-pointer.c', 'test/litest-device-xen-virtual-pointer.c',
'test/litest-device-vmware-virtual-usb-mouse.c', 'test/litest-device-vmware-virtual-usb-mouse.c',
'test/litest-device-yubikey.c', 'test/litest-device-yubikey.c',
'test/litest-runner.c',
'test/litest.c', 'test/litest.c',
'test/litest-main.c', 'include/valgrind/valgrind.h'
] ]
if have_mtdev
litest_sources += [
'test/litest-device-protocol-a-touch-screen.c',
]
endif
dep_dl = cc.find_library('dl') dep_dl = cc.find_library('dl')
deps_litest = [ deps_litest = [
dep_libinput, dep_libinput,
dep_check,
dep_udev, dep_udev,
dep_libevdev, dep_libevdev,
dep_dl, dep_dl,
dep_lm, dep_lm,
dep_libsystemd, dep_libsystemd,
dep_libquirks, dep_libquirks,
dep_libinput_util_libinput,
] ]
litest_config_h = configuration_data() litest_config_h = configuration_data()
@ -1008,28 +829,27 @@ if get_option('tests')
meson.current_build_dir() / meson.current_build_dir() /
'90-libinput-fuzz-override-litest.rules') '90-libinput-fuzz-override-litest.rules')
if dep_check.found() def_no_main = '-DLITEST_NO_MAIN'
def_disable_backtrace = '-DLITEST_DISABLE_BACKTRACE_LOGGING' def_disable_backtrace = '-DLITEST_DISABLE_BACKTRACE_LOGGING'
defs_litest_selftest = [ defs_litest_selftest = [
def_disable_backtrace, def_no_main,
'-Wno-unused', def_disable_backtrace
] ]
test_litest_selftest_sources = [ test_litest_selftest_sources = [
'test/litest-selftest.c', 'test/litest-selftest.c',
'test/litest-runner.c', 'test/litest.c',
'test/litest.c', 'test/litest.h'
] ]
test_litest_selftest = executable('test-litest-selftest', test_litest_selftest = executable('test-litest-selftest',
test_litest_selftest_sources, test_litest_selftest_sources,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
dependencies : [deps_litest, dep_check], dependencies : deps_litest,
c_args : defs_litest_selftest, c_args : defs_litest_selftest,
install : false) install : false)
test('test-litest-selftest', test('test-litest-selftest',
test_litest_selftest, test_litest_selftest,
suite : ['all'], suite : ['all'],
timeout : 100) timeout : 100)
endif
def_LT_VERSION = '-DLIBINPUT_LT_VERSION="@0@:@1@:@2@"'.format(libinput_lt_c, libinput_lt_r, libinput_lt_a) def_LT_VERSION = '-DLIBINPUT_LT_VERSION="@0@:@1@:@2@"'.format(libinput_lt_c, libinput_lt_r, libinput_lt_a)
test_library_version = executable('test-library-version', test_library_version = executable('test-library-version',
@ -1041,20 +861,19 @@ if get_option('tests')
suite : ['all']) suite : ['all'])
test_utils_sources = [ test_utils_sources = [
'src/libinput-util.h',
'test/test-utils.c', 'test/test-utils.c',
'test/litest-runner.c',
'test/litest.c',
] ]
test_utils = executable('libinput-test-utils', test_utils = executable('test-utils',
test_utils_sources, test_utils_sources,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
dependencies : deps_litest, dependencies : deps_litest,
install_dir : libinput_tool_path, install: false)
install : get_option('install-tests'))
test('test-utils', test('test-utils',
test_utils, test_utils,
suite : ['all']) suite : ['all'])
# When adding new files to this list, update the CI
tests_sources = [ tests_sources = [
'test/test-udev.c', 'test/test-udev.c',
'test/test-path.c', 'test/test-path.c',
@ -1076,11 +895,9 @@ if get_option('tests')
'test/test-switch.c', 'test/test-switch.c',
'test/test-quirks.c', 'test/test-quirks.c',
] ]
if have_plugins and have_lua libinput_test_runner_sources = litest_sources + tests_sources + [
tests_sources += ['test/test-plugins-lua.c'] 'src/libinput-util.h',
endif ]
libinput_test_runner_sources = litest_sources + tests_sources
libinput_test_runner = executable('libinput-test-suite', libinput_test_runner = executable('libinput-test-suite',
libinput_test_runner_sources, libinput_test_runner_sources,
include_directories : [includes_src, includes_include], include_directories : [includes_src, includes_include],
@ -1090,54 +907,23 @@ if get_option('tests')
src_man += 'test/libinput-test-suite.man' src_man += 'test/libinput-test-suite.man'
# When adding new TEST_COLLECTION() macros, add to this list and the CI foreach testfile : tests_sources
# $ git grep TEST_COLLECTION test/test-* | sed -e "s|.*TEST_COLLECTION(\(.*\))|\t\t'\1',|" | sort tfile = testfile.split('test/test-')[1]
collections = [ group = tfile.split('.c')[0]
'device',
'gestures',
'keyboard',
'log',
'misc',
'pad',
'path',
'pointer',
'quirks',
'switch',
'tablet',
'tablet_eraser',
'tablet_left_handed',
'tablet_proximity',
'tablet_tip',
'totem',
'touch',
'touchpad',
'touchpad_buttons',
'touchpad_dwt',
'touchpad_palm',
'touchpad_tap',
'touchpad_tap_drag',
'touchpad_tap_palm',
'trackball',
'trackpoint',
'udev',
]
if have_plugins and have_lua
collections += ['lua']
endif
foreach group : collections
test('libinput-test-suite-@0@'.format(group), test('libinput-test-suite-@0@'.format(group),
libinput_test_runner, libinput_test_runner,
suite : ['all', 'valgrind', 'root', 'hardware'], suite : ['all', 'valgrind', 'root', 'hardware'],
args : ['--filter-group=@0@'.format(group)], args : ['--filter-group=@0@'.format(group),
'--xml-output=junit-@0@-XXXXXX.xml'.format(group)],
is_parallel : false, is_parallel : false,
timeout : 1100) timeout : 1200)
endforeach endforeach
test('libinput-test-deviceless', test('libinput-test-deviceless',
libinput_test_runner, libinput_test_runner,
suite : ['all', 'valgrind'], suite : ['all', 'valgrind'],
args: ['--filter-deviceless']) args: ['--filter-deviceless',
'--xml-output=junit-deviceless-XXXXXX.xml'])
valgrind = find_program('valgrind', required : false) valgrind = find_program('valgrind', required : false)
if valgrind.found() if valgrind.found()
@ -1145,13 +931,12 @@ if get_option('tests')
valgrind_suppressions_file = dir_src_test / 'valgrind.suppressions' valgrind_suppressions_file = dir_src_test / 'valgrind.suppressions'
add_test_setup('valgrind', add_test_setup('valgrind',
exe_wrapper : [ valgrind, exe_wrapper : [ valgrind,
'--log-file=valgrind.%p.log',
'--leak-check=full', '--leak-check=full',
'--gen-suppressions=all', '--gen-suppressions=all',
'--error-exitcode=3', '--error-exitcode=3',
'--suppressions=' + valgrind_suppressions_file ], '--suppressions=' + valgrind_suppressions_file ],
env : valgrind_env, env : valgrind_env,
timeout_multiplier : 3) timeout_multiplier : 100)
else else
message('valgrind not found, disabling valgrind test suite') message('valgrind not found, disabling valgrind test suite')
endif endif
@ -1164,29 +949,15 @@ endif
man_config = configuration_data() man_config = configuration_data()
man_config.set('LIBINPUT_VERSION', meson.project_version()) man_config.set('LIBINPUT_VERSION', meson.project_version())
man_config.set('LIBINPUT_DATA_DIR', dir_data) man_config.set('LIBINPUT_DATA_DIR', dir_data)
if get_option('install-tests')
man_config.set('HAVE_INSTALLED_TESTS', '.\"')
else
man_config.set('HAVE_INSTALLED_TESTS', '')
endif
if get_option('debug-gui')
man_config.set('HAVE_DEBUG_GUI', '')
else
man_config.set('HAVE_DEBUG_GUI', '.\"')
endif
src_man += files( src_man += files(
'tools/libinput.man', 'tools/libinput.man',
'tools/libinput-analyze.man', 'tools/libinput-analyze.man',
'tools/libinput-analyze-buttons.man',
'tools/libinput-analyze-per-slot-delta.man', 'tools/libinput-analyze-per-slot-delta.man',
'tools/libinput-analyze-recording.man', 'tools/libinput-analyze-recording.man',
'tools/libinput-analyze-touch-down-state.man', 'tools/libinput-analyze-touch-down-state.man',
'tools/libinput-debug-events.man', 'tools/libinput-debug-events.man',
'tools/libinput-debug-tablet.man', 'tools/libinput-debug-tablet.man',
'tools/libinput-debug-tablet-pad.man',
'tools/libinput-list-devices.man', 'tools/libinput-list-devices.man',
'tools/libinput-list-kernel-devices.man',
'tools/libinput-measure.man', 'tools/libinput-measure.man',
'tools/libinput-measure-fuzz.man', 'tools/libinput-measure-fuzz.man',
'tools/libinput-measure-touchpad-size.man', 'tools/libinput-measure-touchpad-size.man',
@ -1196,7 +967,6 @@ src_man += files(
'tools/libinput-quirks.man', 'tools/libinput-quirks.man',
'tools/libinput-record.man', 'tools/libinput-record.man',
'tools/libinput-replay.man', 'tools/libinput-replay.man',
'tools/libinput-test.man',
) )
foreach m : src_man foreach m : src_man

View file

@ -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,
@ -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')

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,9 +0,0 @@
# Do not edit this file, it will be overwritten on update
# This will match several vendors that all
# re-use the same vendor ID 256C.
[Huion/Gaomon Tablets]
MatchUdevType=tablet
MatchBus=usb
MatchVendor=0x256C
AttrResolutionHint=205x328

View file

@ -0,0 +1,47 @@
# Do not edit this file, it will be overwritten on update
# IBM/Lenovo Scrollpoint mouse. Instead of a scroll wheel these mice
# feature trackpoint-like sticks which generate a huge amount of scroll
# events that need to be handled differently than scroll wheel events
[IBM ScrollPoint Mouse 3100]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3100
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3103]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3103
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3105]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3105
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3108]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3108
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 3109]
MatchUdevType=mouse
MatchVendor=0x04B3
MatchProduct=0x3109
ModelLenovoScrollPoint=1
[IBM ScrollPoint Mouse 6049]
MatchUdevType=mouse
MatchVendor=0x17EF
MatchProduct=0x6049
ModelLenovoScrollPoint=1
[IBM USB Travel Keyboard with Ultra Nav Mouse]
MatchUdevType=pointingstick
MatchVendor=0x04B3
MatchProduct=0x301E
AttrTrackpointMultiplier=1.50

View file

@ -1,41 +0,0 @@
# Do not edit this file, it will be overwritten on update
# ITE keyboards are usb keyboards mostly used in notebook and laptops,
# set as internal.
[ITE Device(8???) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
AttrKeyboardIntegration=internal
# Exception used in desktops (external)
[ITE Device(8595) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8295
AttrKeyboardIntegration=external
# Exception used in some desktops and few laptops (external)
[ITE Device(8911) Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8911
AttrKeyboardIntegration=external
# Exception used in desktops (external)
[IT8297 RGB LED Controller Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0x8297
AttrKeyboardIntegration=external
# Exception used in desktops (external)
[Corsair Gaming K95 RGB PLATINUM Keyboard]
MatchUdevType=keyboard
MatchBus=usb
MatchVendor=0x048D
MatchProduct=0xC935
AttrKeyboardIntegration=external

View file

@ -1,9 +1,7 @@
# Do not edit this file, it will be overwritten on update
# Kensington Orbit claims to have a middle button, same for # Kensington Orbit claims to have a middle button, same for
[Kensington Orbit Scroll Wheel] [Kensington Orbit Scroll Wheel]
MatchBus=usb MatchBus=usb
MatchVendor=0x047D MatchVendor=0x047D
MatchProduct=0x2048 MatchProduct=0x2048
ModelTrackball=1 ModelTrackball=1
AttrEventCode=-BTN_MIDDLE AttrEventCodeDisable=BTN_MIDDLE

View file

@ -4,18 +4,13 @@
MatchName=*Logitech M570* MatchName=*Logitech M570*
ModelTrackball=1 ModelTrackball=1
# This will also work for the newer 'S' version — Logitech ERGO M575S
[Logitech ERGO M575]
MatchName=*Logitech*M575*
ModelTrackball=1
# Logitech Marble Mouse claims to have a middle button # Logitech Marble Mouse claims to have a middle button
[Logitech Marble Mouse Trackball] [Logitech Marble Mouse Trackball]
MatchUdevType=mouse MatchUdevType=mouse
MatchBus=usb MatchBus=usb
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0xC408 MatchProduct=0xC408
AttrEventCode=-BTN_MIDDLE AttrEventCodeDisable=BTN_MIDDLE
[Logitech K400] [Logitech K400]
MatchUdevType=mouse MatchUdevType=mouse
@ -51,82 +46,51 @@ MatchVendor=0x046D
MatchProduct=0x4011 MatchProduct=0x4011
AttrPalmPressureThreshold=400 AttrPalmPressureThreshold=400
[Logitech MX Master (4041)] [Logitech MX Master]
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0x4041 MatchProduct=0x4041
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master]
[Logitech MX Master (4060)] MatchVendor=0x46D
MatchVendor=0x046D
MatchProduct=0x4060 MatchProduct=0x4060
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master]
[Logitech MX Master (4071)] MatchVendor=0x46D
MatchVendor=0x046D
MatchProduct=0x4071 MatchProduct=0x4071
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
# MX Master has a different PID on bluetooth # MX Master has a different PID on bluetooth
[Logitech MX Master (Bluetooth B012)] [Logitech MX Master]
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0xB012 MatchProduct=0xB012
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master]
[Logitech MX Master (Bluetooth B017)] MatchVendor=0x46D
MatchVendor=0x046D
MatchProduct=0xB017 MatchProduct=0xB017
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master]
[Logitech MX Master (Bluetooth B01E)] MatchVendor=0x46D
MatchVendor=0x046D
MatchProduct=0xB01E MatchProduct=0xB01E
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
[Logitech MX Master 2S USB] [Logitech MX Master 2S]
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0x4069 MatchProduct=0x4069
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
# MX Master 2S has a different PID on bluetooth # MX Master 2S has a different PID on bluetooth
[Logitech MX Master 2S Bluetooth] [Logitech MX Master 2S]
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0xB019 MatchProduct=0xB019
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
[Logitech MX Master 3 USB] [Logitech MX Master 3]
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0x4082 MatchProduct=0x4082
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
# MX Master 3 has a different PID on bluetooth # MX Master 3 has a different PID on bluetooth
[Logitech MX Master 3 Bluetooth] [Logitech MX Master 3]
MatchVendor=0x046D MatchVendor=0x46D
MatchProduct=0xB023 MatchProduct=0xB023
ModelInvertHorizontalScrolling=1 ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
[Logitech MX Master 3S]
MatchVendor=0x046D
MatchProduct=0xB034
ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
[Logitech MX Master 3B]
MatchVendor=0x046D
MatchProduct=0xB028
ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
[Logitech MX Master 4]
MatchVendor=0x046D
MatchProduct=0xB042
ModelInvertHorizontalScrolling=1
ModelScrollOnMiddleClick=1
# Don't add quirks for the Logitech Bolt Receiver:
# MatchVendor=0x046D
# MatchProduct=0xC548
# This receiver can be used with multiple mice.

View file

@ -21,7 +21,7 @@ MatchBus=usb
MatchVendor=0x0738 MatchVendor=0x0738
MatchProduct=0x1703 MatchProduct=0x1703
# EV_KEY 0x115, 0x116, 0x117 # EV_KEY 0x115, 0x116, 0x117
AttrEventCode=-EV_KEY:0x115;-EV_KEY:0x116;-EV_KEY:0x117 AttrEventCodeDisable=EV_KEY:0x115;EV_KEY:0x116;EV_KEY:0x117
# Like the Madcatz RAT3, but with different codes: # Like the Madcatz RAT3, but with different codes:
# event8 POINTER_BUTTON +0.488s ??? (280) pressed, seat count: 1 # event8 POINTER_BUTTON +0.488s ??? (280) pressed, seat count: 1
@ -37,4 +37,4 @@ MatchBus=usb
MatchVendor=0x0738 MatchVendor=0x0738
MatchProduct=0x1708 MatchProduct=0x1708
# EV_KEY 0x118, 0x119, 0x11A # EV_KEY 0x118, 0x119, 0x11A
AttrEventCode=-EV_KEY:0x118;-EV_KEY:0x119;-EV_KEY:0x11A AttrEventCodeDisable=EV_KEY:0x118;EV_KEY:0x119;EV_KEY:0x11A

View file

@ -2,7 +2,7 @@
[Microsoft Surface 3 Lid Switch] [Microsoft Surface 3 Lid Switch]
MatchName=*Lid Switch* MatchName=*Lid Switch*
MatchDMIModalias=dmi:*:svnMicrosoftCorporation:pnSurface3:* MatchDMIModalias=dmi:*svnMicrosoftCorporation:pnSurface3:*
AttrLidSwitchReliability=write_open AttrLidSwitchReliability=write_open
# Matches both Surface Laptop keyboards as well as type covers. # Matches both Surface Laptop keyboards as well as type covers.
@ -11,17 +11,14 @@ AttrLidSwitchReliability=write_open
# - Surface Laptop 3: Microsoft Surface 045E:09AE Keyboard # - Surface Laptop 3: Microsoft Surface 045E:09AE Keyboard
# - Surface Book 2: Microsoft Surface Keyboard # - Surface Book 2: Microsoft Surface Keyboard
[Microsoft Surface Keyboard] [Microsoft Surface Keyboard]
MatchName=Microsoft Surface *Keyboard MatchName=*Microsoft Surface *Keyboard*
MatchDMIModalias=dmi:*:svnMicrosoftCorporation:* MatchDMIModalias=dmi:*svnMicrosoftCorporation:*
AttrEventCode=-BTN_0;
AttrKeyboardIntegration=internal AttrKeyboardIntegration=internal
[Microsoft Surface Laptop Studio Touchpad] [Microsoft Surface Cover]
MatchVendor=0x045E MatchName=*Microsoft Surface *Cover*
MatchProduct=0x09AF MatchDMIModalias=dmi:*svnMicrosoftCorporation:*
MatchUdevType=touchpad AttrKeyboardIntegration=internal
AttrPressureRange=25:10
AttrPalmPressureThreshold=500
[Microsoft Nano Transceiver v2.0] [Microsoft Nano Transceiver v2.0]
MatchUdevType=mouse MatchUdevType=mouse
@ -29,9 +26,3 @@ MatchBus=usb
MatchVendor=0x045E MatchVendor=0x045E
MatchProduct=0x0800 MatchProduct=0x0800
ModelBouncingKeys=1 ModelBouncingKeys=1
[Microsoft Surface Pro 10 with Flex Keyboard Touchpad]
MatchVendor=0x045E
MatchProduct=0x0C8D
MatchUdevType=touchpad
AttrEventCode=-BTN_RIGHT

Some files were not shown because too many files have changed in this diff Show more