Compare commits
No commits in common. "main" and "1.19.0" have entirely different histories.
|
|
@ -1,82 +0,0 @@
|
|||
AlignAfterOpenBracket: Align
|
||||
# This option we want but it's frequently broken and causes bad
|
||||
# misalignment. The canary is wheel_click_count_parser, if that works
|
||||
# we can actually enable it.
|
||||
# AlignArrayOfStructures: Left
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: true
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: true
|
||||
AlignCaseColons: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: OnePerLine
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
BreakAfterReturnType: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 88
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: false
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^(<|")config\.h(>|")'
|
||||
Priority: 0
|
||||
SortPriority: 0
|
||||
- Regex: '^<.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
- Regex: '^"util-.*'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
IndentCaseLabels: false
|
||||
IndentGotoLabels: false
|
||||
IndentWidth: 8
|
||||
MaxEmptyLinesToKeep: 1
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
RemoveEmptyLinesInUnwrappedLines: true
|
||||
RemoveParentheses: MultipleParentheses
|
||||
RemoveSemicolon: true
|
||||
SkipMacroDefinitionBody: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInParens: Custom
|
||||
TabWidth: 8
|
||||
UseTab: ForContinuationAndIndentation
|
||||
|
||||
ForEachMacros:
|
||||
- ARRAY_FOR_EACH
|
||||
- list_for_each
|
||||
- list_for_each_safe
|
||||
- tp_for_each_touch
|
||||
- range_for_each
|
||||
- litest_log_group
|
||||
- litest_with_logcapture
|
||||
- litest_with_parameters
|
||||
- litest_with_event_frame
|
||||
- udev_list_entry_foreach
|
||||
# END_TEST is defined as something that enforces a line break
|
||||
Macros: [ "CASE_RETURN_STRING(s)=case s: return s", "START_TEST(s)=static void s(void)", "END_TEST=enum foo;"]
|
||||
|
|
@ -1 +0,0 @@
|
|||
include/**/*
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
# optin.core.unix.Malloc: disabled so we can use __attribute__((cleanup)) without leak complaints
|
||||
# optin.core.EnumCastOutOfRange: disabled because we use a lot of "wrong" enum values for testing
|
||||
# and internally and don't want those values leak into the public API
|
||||
Checks: >
|
||||
-clang-analyzer-unix.Malloc,
|
||||
-clang-analyzer-optin.core.EnumCastOutOfRange
|
||||
WarningsAsErrors: '*'
|
||||
|
|
@ -1 +0,0 @@
|
|||
include/*
|
||||
|
|
@ -19,7 +19,3 @@ indent_style = space
|
|||
[{meson.build,meson_options.txt}]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[*.sym]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
# This file contains revisions to be ignored by git blame.
|
||||
# These revisions are expected to be formatting-only changes.
|
||||
#
|
||||
# Calling `git blame --ignore-revs-file .git-blame-ignore-revs` will
|
||||
# tell git blame to ignore changes made by these revisions when assigning
|
||||
# assigning blame, as if the change never happened.
|
||||
#
|
||||
# You can enable this as a default for your local repository by running
|
||||
# `git config blame.ignoreRevsFile .git-blame-ignore-revs`
|
||||
# Important: if you do this, then switch to a branch without this file,
|
||||
# `git blame` will fail with an error.
|
||||
#
|
||||
|
||||
# Run clang-format over the code
|
||||
2a1095924b0be60f822bc0ff20d567e209a9db73
|
||||
|
||||
# Add trailing commas to prevent clang-format oddities
|
||||
aebf3cd4915adc576cf055926caa621e098ec32b
|
||||
|
||||
# Fix some inconsistent whitespace.
|
||||
60abf1575560cb8e2220ae48a67e7f74b5dc70dd
|
||||
771
.gitlab-ci.yml
|
|
@ -36,39 +36,18 @@
|
|||
# <distribution>:<version>@activity:
|
||||
# e.g. fedora:31@build-default
|
||||
|
||||
.templates_sha: &template_sha c6aeb16f86e32525fa630fb99c66c4f3e62fc3cb
|
||||
.templates_sha: &template_sha 007f3e2fe2235328e77d3cd4ce007ab41cd9ce6c
|
||||
|
||||
include:
|
||||
{% for distro in distributions|sort(attribute="name") %}
|
||||
# {{ distro.name.capitalize() }} container builder template
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: *template_sha
|
||||
file:
|
||||
- '/templates/ci-fairy.yml'
|
||||
{% for distro in distributions|sort(attribute="name") %}
|
||||
# {{ distro.name.capitalize() }} container builder template
|
||||
- '/templates/{{distro.name}}.yml'
|
||||
file: '/templates/{{distro.name}}.yml'
|
||||
{% endfor %}
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
# do not duplicate pipelines on merge pipelines
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
# merge pipeline
|
||||
- if: &is-merge-attempt $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
variables:
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: priority:high
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: priority:high-kvm
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: priority:high-aarch64
|
||||
# post-merge pipeline
|
||||
- if: &is-post-merge $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "push"
|
||||
variables:
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: priority:high
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: priority:high-kvm
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: priority:high-aarch64
|
||||
# Pre-merge pipeline
|
||||
- if: &is-pre-merge $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# Push to a branch on a fork
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: *template_sha
|
||||
file: '/templates/ci-fairy.yml'
|
||||
|
||||
stages:
|
||||
- sanity check # CI/commit checks
|
||||
|
|
@ -90,7 +69,7 @@ variables:
|
|||
# distribution #
|
||||
# #
|
||||
# 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 %}
|
||||
{{"%-17s" | format(distro.name.upper() + '_PACKAGES:')}} '{{ distro.packages|join(' ')}}'
|
||||
|
|
@ -103,6 +82,11 @@ variables:
|
|||
# libinput version
|
||||
{% for distro in distributions %}
|
||||
{{"%-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 %}
|
||||
|
||||
FDO_UPSTREAM_REPO: libinput/libinput
|
||||
|
|
@ -116,11 +100,6 @@ variables:
|
|||
UDEV_NOT_AVAILABLE: 1
|
||||
GIT_DEPTH: 1
|
||||
|
||||
# Default priority for non-merge pipelines
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: "" # Empty tags are ignored by gitlab
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: kvm
|
||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: aarch64
|
||||
|
||||
.policy:
|
||||
retry:
|
||||
max: 2
|
||||
|
|
@ -131,16 +110,6 @@ variables:
|
|||
interruptible: true
|
||||
dependencies: []
|
||||
|
||||
.policy-retry-on-failure:
|
||||
retry:
|
||||
max: 1
|
||||
when:
|
||||
- runner_system_failure
|
||||
- stuck_or_timeout_failure
|
||||
# cancel run when a newer version is pushed to the branch
|
||||
interruptible: true
|
||||
dependencies: []
|
||||
|
||||
.default_artifacts:
|
||||
artifacts:
|
||||
name: "meson-logs-$CI_JOB_NAME"
|
||||
|
|
@ -148,13 +117,8 @@ variables:
|
|||
expire_in: 1 week
|
||||
paths:
|
||||
- $MESON_BUILDDIR/meson-logs
|
||||
- $MESON_BUILDDIR/valgrind.*.log
|
||||
reports:
|
||||
junit: $MESON_BUILDDIR/*junit*.xml
|
||||
|
||||
.fdo-runner-tags:
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64
|
||||
junit: $MESON_BUILDDIR/junit-*.xml
|
||||
|
||||
|
||||
#################################################################
|
||||
|
|
@ -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
|
||||
# If this job fails, re-generate the gitlab-ci.yml script, see
|
||||
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
|
||||
|
|
@ -186,7 +134,6 @@ fail-if-fork-is-not-public:
|
|||
check-ci-script:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- ci-fairy generate-template --verify && exit 0 || true
|
||||
|
|
@ -197,16 +144,15 @@ check-ci-script:
|
|||
- exit 1
|
||||
|
||||
#
|
||||
# Verify that commit messages are as expected, etc.
|
||||
# Verify that commit messages are as expected, signed-off, etc.
|
||||
#
|
||||
|
||||
check-commit:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- ci-fairy -vv check-commits --junit-xml=results.xml && exit 0 || true
|
||||
- ci-fairy check-commits --signed-off-by --junit-xml=results.xml && exit 0 || true
|
||||
- >
|
||||
printf "%s\n" \
|
||||
"Error checking commit format. Please verify" \
|
||||
|
|
@ -220,56 +166,41 @@ check-commit:
|
|||
reports:
|
||||
junit: results.xml
|
||||
|
||||
|
||||
#
|
||||
# Check for trailing whitespaces
|
||||
#
|
||||
|
||||
check-whitespace:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- .gitlab-ci/whitespace-check.py $(git ls-files)
|
||||
|
||||
#
|
||||
# pre-commit hooks
|
||||
#
|
||||
|
||||
pre-commit-hooks:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: sanity check
|
||||
script:
|
||||
- python3 -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip3 install pre-commit
|
||||
- pre-commit run --all-files
|
||||
- git diff --exit-code || (echo "ERROR - Code style errors found, please fix" && false)
|
||||
|
||||
#################################################################
|
||||
# #
|
||||
# prep stage #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
#
|
||||
# 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 %}
|
||||
{% if not distro.skip_container %}
|
||||
{% for version in distro.versions %}
|
||||
{{distro.name}}:{{version}}@container-prep:
|
||||
extends:
|
||||
{% if distro.qemu_based %}
|
||||
- .fdo.qemu-build@{{distro.name}}
|
||||
{% else %}
|
||||
- .fdo.container-build@{{distro.name}}
|
||||
{% endif %}
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
{% if distro.qemu_based %}
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
||||
{% endif %}
|
||||
stage: prep
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
|
@ -278,6 +209,7 @@ pre-commit-hooks:
|
|||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
|
@ -297,7 +229,6 @@ pre-commit-hooks:
|
|||
extends:
|
||||
- .policy
|
||||
- .fdo.ci-fairy
|
||||
- .fdo-runner-tags
|
||||
stage: container_clean
|
||||
script:
|
||||
# Go to your Profile, Settings, Access Tokens
|
||||
|
|
@ -313,6 +244,7 @@ pre-commit-hooks:
|
|||
- schedules
|
||||
|
||||
{% for distro in distributions %}
|
||||
{% if not distro.skip_container %}
|
||||
{% for version in distro.versions %}
|
||||
{{distro.name}}:{{version}}@container-clean:
|
||||
extends:
|
||||
|
|
@ -325,6 +257,7 @@ pre-commit-hooks:
|
|||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
#################################################################
|
||||
|
|
@ -337,41 +270,10 @@ pre-commit-hooks:
|
|||
extends:
|
||||
- .policy
|
||||
- .default_artifacts
|
||||
- .fdo-runner-tags
|
||||
stage: build
|
||||
script:
|
||||
- .gitlab-ci/meson-build.sh
|
||||
|
||||
|
||||
# Run meson and meson test in the container image through qemu
|
||||
.build-in-vng@template:
|
||||
extends:
|
||||
- .policy
|
||||
- .default_artifacts
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
||||
variables:
|
||||
MESON_BUILDDIR: build_dir
|
||||
VNG_KERNEL: {{ vng.kernel }}
|
||||
script:
|
||||
# first build in the host container
|
||||
- .gitlab-ci/meson-build.sh --skip-test
|
||||
|
||||
- mkdir -p $MESON_BUILDDIR
|
||||
- curl -LO $VNG_KERNEL
|
||||
|
||||
- export -p > .vngenv
|
||||
|
||||
# runs the test suite only
|
||||
- |
|
||||
vng --run ./bzImage \
|
||||
--user root \
|
||||
--overlay-rwdir=$HOME \
|
||||
--append HOME=$HOME \
|
||||
--overlay-rwdir=$(pwd) \
|
||||
--rwdir=$MESON_BUILDDIR \
|
||||
--exec "source $PWD/.vngenv; rm $PWD/.vngenv; .gitlab-ci/meson-build.sh --skip-setup --skip-build --run-test"
|
||||
|
||||
#
|
||||
# Fedora
|
||||
#
|
||||
|
|
@ -388,8 +290,9 @@ pre-commit-hooks:
|
|||
.build-in-qemu@template:
|
||||
extends:
|
||||
- .policy
|
||||
- .fdo.distribution-image@fedora
|
||||
tags:
|
||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
||||
- kvm
|
||||
variables:
|
||||
MESON_BUILDDIR: build_dir
|
||||
script:
|
||||
|
|
@ -426,7 +329,7 @@ pre-commit-hooks:
|
|||
- $MESON_BUILDDIR/meson-logs
|
||||
- console.out
|
||||
reports:
|
||||
junit: $MESON_BUILDDIR/*junit*.xml
|
||||
junit: $MESON_BUILDDIR/junit-*.xml
|
||||
|
||||
|
||||
# Run in a test suite. Special variables:
|
||||
|
|
@ -435,30 +338,32 @@ pre-commit-hooks:
|
|||
# Set one or the other, not both.
|
||||
.test-suite-vm:
|
||||
extends:
|
||||
- .build-in-vng@template
|
||||
- .build-in-qemu@template
|
||||
stage: test-suite
|
||||
variables:
|
||||
# remove the global --no-suite=hardware
|
||||
MESON_TEST_ARGS: ''
|
||||
LITEST_JOBS: 4
|
||||
before_script:
|
||||
- if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi
|
||||
- echo "Testing $SUITES"
|
||||
- export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES"
|
||||
retry:
|
||||
max: 2
|
||||
when: script_failure
|
||||
|
||||
|
||||
{# 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()) %}
|
||||
{% if distro.use_for_custom_build_tests %}
|
||||
.{{distro.name}}:{{version}}@test-suite-vm:
|
||||
extends:
|
||||
- .fdo.distribution-image@{{distro.name}}
|
||||
- .test-suite-vm
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: {{version}}
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_QEMU_TAG
|
||||
needs:
|
||||
- "{{distro.name}}:{{version}}@container-prep"
|
||||
- "{{distro.name}}:{{version}}@qemu-prep"
|
||||
|
||||
|
||||
{% for suite in test_suites %}
|
||||
|
|
@ -482,24 +387,18 @@ vm-valgrind-{{suite.name}}:
|
|||
stage: valgrind
|
||||
extends:
|
||||
- vm-{{suite.name}}
|
||||
- .policy-retry-on-failure
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--setup=valgrind'
|
||||
LITEST_JOBS: 0
|
||||
retry:
|
||||
max: 2
|
||||
rules:
|
||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}{# for if distro.use_for_qemu_tests #}
|
||||
{% endif %}
|
||||
{% endfor %}{# for if distro.want_qemu #}
|
||||
|
||||
{% for distro in distributions if distro.use_for_custom_build_tests %}
|
||||
{% set version = "{}".format(distro.versions|last()) %}
|
||||
.{{distro.name}}-build@template:
|
||||
extends:
|
||||
- .fdo.distribution-image@{{distro.name}}
|
||||
- .fdo.distribution-image@fedora
|
||||
- .build@template
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
|
|
@ -515,16 +414,20 @@ default-build-release@{{distro.name}}:{{version}}:
|
|||
MESON_ARGS: "-Dbuildtype=release"
|
||||
CFLAGS: "-Werror"
|
||||
|
||||
clang-tidy@{{distro.name}}:{{version}}:
|
||||
scan-build@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
NINJA_ARGS: ''
|
||||
MESON_TEST_ARGS: ''
|
||||
CC: 'clang'
|
||||
before_script:
|
||||
- dnf install -y clang-analyzer
|
||||
script:
|
||||
- .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
|
||||
# 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:
|
||||
- dnf remove -y libwacom libwacom-devel
|
||||
|
||||
build-no-mtdev@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dmtdev=false"
|
||||
|
||||
build-no-mtdev-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dmtdev=false"
|
||||
before_script:
|
||||
- dnf remove -y mtdev mtdev-devel
|
||||
|
||||
build-no-lua@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
|
||||
build-no-lua-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
||||
before_script:
|
||||
- dnf remove -y lua lua-devel
|
||||
|
||||
build-docs@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
|
|
@ -598,7 +473,7 @@ build-no-debuggui-nodeps@{{distro.name}}:{{version}}:
|
|||
variables:
|
||||
MESON_ARGS: "-Ddebug-gui=false"
|
||||
before_script:
|
||||
- dnf remove -y gtk3-devel gtk4-devel
|
||||
- dnf remove -y gtk3-devel
|
||||
|
||||
build-no-tests@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
|
|
@ -619,6 +494,8 @@ valgrind@{{distro.name}}:{{version}}:
|
|||
- .{{distro.name}}-build@template
|
||||
variables:
|
||||
MESON_TEST_ARGS: '--suite=valgrind --no-suite=hardware --setup=valgrind'
|
||||
before_script:
|
||||
- dnf install -y valgrind
|
||||
|
||||
# Python checks, only run on Fedora
|
||||
|
||||
|
|
@ -632,12 +509,23 @@ usr-bin-env-python@{{distro.name}}:{{version}}:
|
|||
/bin/false
|
||||
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
|
||||
check-test-suites:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
before_script:
|
||||
- dnf install -y jq
|
||||
script:
|
||||
- meson setup builddir
|
||||
- meson builddir
|
||||
- meson introspect builddir --test | jq -r '.[].name' | grep 'libinput-test-suite' | sort > meson-testsuites
|
||||
- |
|
||||
cat <<EOF > ci-testsuites ;
|
||||
|
|
@ -672,7 +560,6 @@ coverity:
|
|||
extends:
|
||||
- .fdo.distribution-image@debian
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: build
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 'stable'
|
||||
|
|
@ -712,7 +599,7 @@ coverity:
|
|||
#################################################################
|
||||
|
||||
{% for distro in distributions %}
|
||||
{% if not distro.qemu_based %}
|
||||
{% if not distro.skip_container %}
|
||||
{% for version in distro.versions %}
|
||||
{{distro.name}}:{{version}}@default-build:
|
||||
stage: distro
|
||||
|
|
@ -742,7 +629,7 @@ coverity:
|
|||
- .fdo.distribution-image@{{distro.name}}
|
||||
variables:
|
||||
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 #}
|
||||
{% if distro.build is defined and distro.build.extra_variables is defined %}
|
||||
{% for var in distro.build.extra_variables %}
|
||||
|
|
@ -750,7 +637,7 @@ coverity:
|
|||
{% endfor %}
|
||||
{% endif %}
|
||||
needs:
|
||||
- "{{distro.name}}:{{version}}@container-prep"
|
||||
- "{{distro.name}}:{{version}}@qemu-prep"
|
||||
|
||||
{% endif %}
|
||||
{% 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:
|
||||
extends:
|
||||
- .fdo.distribution-image@fedora
|
||||
- .policy
|
||||
- .fdo-runner-tags
|
||||
stage: deploy
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
||||
FDO_DISTRIBUTION_VERSION: '34'
|
||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
||||
needs:
|
||||
- "fedora:{{version}}@container-prep"
|
||||
- "fedora:33@container-prep"
|
||||
script:
|
||||
- dnf install -y rpmdevtools jq
|
||||
- meson "$MESON_BUILDDIR"
|
||||
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
|
||||
- sed -e "s/@PIPELINEID@/${CI_PIPELINE_ID}/"
|
||||
|
|
@ -786,18 +688,20 @@ build rpm:
|
|||
- cd "$MESON_BUILDDIR"
|
||||
- meson dist --no-test
|
||||
- rpmbuild -ta meson-dist/libinput*.tar.xz
|
||||
{% endfor %}
|
||||
|
||||
|
||||
wayland-web:
|
||||
stage: deploy
|
||||
trigger: wayland/wayland.freedesktop.org
|
||||
except:
|
||||
refs:
|
||||
- schedules
|
||||
variables:
|
||||
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
||||
MESON_BUILDDIR: 'builddir'
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
when: never
|
||||
- if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
|
||||
when: on_success
|
||||
- when: never
|
||||
only:
|
||||
refs:
|
||||
- main
|
||||
variables:
|
||||
- $CI_PROJECT_PATH == "libinput/libinput"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
#
|
||||
|
||||
# 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:
|
||||
- name: fedora
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- '42'
|
||||
- '43'
|
||||
- '33'
|
||||
- '34' # last is picked for qemu
|
||||
want_qemu: true
|
||||
use_for_custom_build_tests: true
|
||||
use_for_qemu_tests: true
|
||||
packages:
|
||||
|
|
@ -34,23 +35,7 @@ distributions:
|
|||
- glib2-devel
|
||||
- mtdev-devel
|
||||
- diffutils
|
||||
- wayland-protocols-devel
|
||||
- black # for the Python black job, optional
|
||||
- clang # for the clang-tidy build, optional
|
||||
- clang-tools-extra # for clang-tidy, optional
|
||||
- jq # for the test suite check job, optional
|
||||
- rpmdevtools # for the rpm build job, optional
|
||||
- valgrind # for the valgrind run, optional
|
||||
# below packages are for the qemu runs, so optional
|
||||
- systemd-udev # for the qemu run
|
||||
- qemu-img
|
||||
- qemu-system-x86-core
|
||||
- qemu-system-aarch64-core
|
||||
- jq
|
||||
- python3-click
|
||||
- python3-rich
|
||||
- virtme-ng
|
||||
- lua-devel
|
||||
- name: debian
|
||||
tag: *default_tag
|
||||
versions:
|
||||
|
|
@ -76,11 +61,11 @@ distributions:
|
|||
- libglib2.0-dev
|
||||
- libmtdev-dev
|
||||
- curl # for the coverity job
|
||||
- lua5.4-dev
|
||||
- name: ubuntu
|
||||
tag: *default_tag
|
||||
versions:
|
||||
- '25.10'
|
||||
- '20.10'
|
||||
- '21.04'
|
||||
packages:
|
||||
- git
|
||||
- gcc
|
||||
|
|
@ -101,7 +86,6 @@ distributions:
|
|||
- libgtk-3-dev
|
||||
- libglib2.0-dev
|
||||
- libmtdev-dev
|
||||
- lua5.4-dev
|
||||
- name: arch
|
||||
tag: *default_tag
|
||||
versions:
|
||||
|
|
@ -114,15 +98,16 @@ distributions:
|
|||
- check
|
||||
- libsystemd
|
||||
- libevdev
|
||||
- doxygen
|
||||
- graphviz
|
||||
- python-sphinx
|
||||
- python-recommonmark
|
||||
- python-sphinx_rtd_theme
|
||||
- python-pytest-xdist
|
||||
- libwacom
|
||||
- gtk4
|
||||
- mtdev
|
||||
- diffutils
|
||||
- lua
|
||||
build:
|
||||
extra_variables:
|
||||
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
|
||||
- name: alpine
|
||||
tag: *default_tag
|
||||
versions:
|
||||
|
|
@ -140,7 +125,6 @@ distributions:
|
|||
- gtk4.0-dev
|
||||
- mtdev-dev
|
||||
- bash
|
||||
- lua5.4-dev
|
||||
build:
|
||||
extra_variables:
|
||||
- "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
|
||||
# but someone more invested in musl will have to figure that out.
|
||||
- "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:
|
||||
- name: touchpad
|
||||
suites:
|
||||
- touchpad
|
||||
- name: touchpad_palm
|
||||
suites:
|
||||
- touchpad_palm
|
||||
- name: touchpad_dwt
|
||||
suites:
|
||||
- touchpad_dwt
|
||||
- name: tap
|
||||
suites:
|
||||
- touchpad_tap
|
||||
- name: tap-drag
|
||||
suites:
|
||||
- touchpad_tap_drag
|
||||
- name: tap-palm
|
||||
suites:
|
||||
- touchpad_tap_palm
|
||||
- touchpad-tap
|
||||
- name: touchpad-buttons
|
||||
suites:
|
||||
- touchpad_buttons
|
||||
- touchpad-buttons
|
||||
- name: tablet
|
||||
suites:
|
||||
- tablet
|
||||
- name: tablet_left_handed
|
||||
suites:
|
||||
- tablet_left_handed
|
||||
- name: tablet_proximity_tip
|
||||
suites:
|
||||
- tablet_proximity
|
||||
- tablet_tip
|
||||
- name: tablet_eraser
|
||||
suites:
|
||||
- tablet_eraser
|
||||
- name: gestures
|
||||
- name: gestures-device
|
||||
suites:
|
||||
- gestures
|
||||
- device
|
||||
- name: backends
|
||||
suites:
|
||||
- path
|
||||
|
|
@ -196,7 +183,6 @@ test_suites:
|
|||
- log
|
||||
- misc
|
||||
- quirks
|
||||
- device
|
||||
- name: other devices
|
||||
suites:
|
||||
- keyboard
|
||||
|
|
@ -209,9 +195,3 @@ test_suites:
|
|||
- name: pointer
|
||||
suites:
|
||||
- pointer
|
||||
- name: lua
|
||||
suites:
|
||||
- lua
|
||||
|
||||
vng:
|
||||
kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.14/bzImage
|
||||
|
|
|
|||
|
|
@ -100,8 +100,6 @@ intended to be run by users.
|
|||
%files utils
|
||||
%{_libexecdir}/libinput/libinput-debug-gui
|
||||
%{_libexecdir}/libinput/libinput-debug-tablet
|
||||
%{_libexecdir}/libinput/libinput-debug-tablet-pad
|
||||
%{_libexecdir}/libinput/libinput-list-kernel-devices
|
||||
%{_libexecdir}/libinput/libinput-measure
|
||||
%{_libexecdir}/libinput/libinput-measure-fuzz
|
||||
%{_libexecdir}/libinput/libinput-measure-touchpad-tap
|
||||
|
|
@ -112,14 +110,11 @@ intended to be run by users.
|
|||
%{_libexecdir}/libinput/libinput-record
|
||||
%{_libexecdir}/libinput/libinput-replay
|
||||
%{_libexecdir}/libinput/libinput-analyze
|
||||
%{_libexecdir}/libinput/libinput-analyze-buttons
|
||||
%{_libexecdir}/libinput/libinput-analyze-per-slot-delta
|
||||
%{_libexecdir}/libinput/libinput-analyze-recording
|
||||
%{_libexecdir}/libinput/libinput-analyze-touch-down-state
|
||||
%{_mandir}/man1/libinput-debug-gui.1*
|
||||
%{_mandir}/man1/libinput-debug-tablet.1*
|
||||
%{_mandir}/man1/libinput-debug-tablet-pad.1*
|
||||
%{_mandir}/man1/libinput-list-kernel-devices.1*
|
||||
%{_mandir}/man1/libinput-measure.1*
|
||||
%{_mandir}/man1/libinput-measure-fuzz.1*
|
||||
%{_mandir}/man1/libinput-measure-touchpad-tap.1*
|
||||
|
|
@ -132,16 +127,12 @@ intended to be run by users.
|
|||
%{_mandir}/man1/libinput-record.1*
|
||||
%{_mandir}/man1/libinput-replay.1*
|
||||
%{_mandir}/man1/libinput-analyze.1*
|
||||
%{_mandir}/man1/libinput-analyze-buttons.1*
|
||||
%{_mandir}/man1/libinput-analyze-per-slot-delta.1*
|
||||
%{_mandir}/man1/libinput-analyze-recording.1*
|
||||
%{_mandir}/man1/libinput-analyze-touch-down-state.1*
|
||||
|
||||
%files test
|
||||
%{_libexecdir}/libinput/libinput-test
|
||||
%{_libexecdir}/libinput/libinput-test-suite
|
||||
%{_libexecdir}/libinput/libinput-test-utils
|
||||
%{_mandir}/man1/libinput-test.1*
|
||||
%{_mandir}/man1/libinput-test-suite.1*
|
||||
|
||||
%changelog
|
||||
|
|
|
|||
|
|
@ -1,43 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# This script is sourced from here:
|
||||
# https://gitlab.freedesktop.org/whot/meson-helper
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
set -x
|
||||
if [[ -f .meson_environment ]]; then
|
||||
. .meson_environment
|
||||
fi
|
||||
|
||||
# If test args are set, we assume we want to run the tests
|
||||
MESON_RUN_TEST="$MESON_TEST_ARGS"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--skip-setup)
|
||||
shift
|
||||
MESON_SKIP_SETUP="1"
|
||||
;;
|
||||
--skip-build)
|
||||
shift
|
||||
MESON_SKIP_BUILD="1"
|
||||
;;
|
||||
--skip-test)
|
||||
shift
|
||||
MESON_RUN_TEST=""
|
||||
;;
|
||||
--run-test)
|
||||
shift
|
||||
MESON_RUN_TEST="1"
|
||||
;;
|
||||
*)
|
||||
echo "Unknow commandline argument $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$MESON_BUILDDIR" ]]; then
|
||||
echo "\$MESON_BUILDDIR undefined."
|
||||
exit 1
|
||||
|
|
@ -47,17 +14,16 @@ fi
|
|||
# run and debug locally.
|
||||
if [[ -z "$CI_JOB_ID" ]] || [[ -z "$CI_JOB_NAME" ]]; then
|
||||
echo "Missing \$CI_JOB_ID or \$CI_JOB_NAME".
|
||||
CI_PROJECT_NAME=$(basename "$PWD")
|
||||
CI_JOB_ID=$(date +%s)
|
||||
CI_JOB_NAME="$CI_PROJECT_NAME-job-local"
|
||||
CI_JOB_NAME='libinput-job-local'
|
||||
echo "Simulating gitlab environment: "
|
||||
echo " CI_JOB_ID=$CI_JOB_ID"
|
||||
echo " CI_JOB_NAME=$CI_JOB_NAME"
|
||||
fi
|
||||
|
||||
if [[ -n "$FDO_CI_CONCURRENT" ]]; then
|
||||
jobcount="-j$FDO_CI_CONCURRENT"
|
||||
export MESON_TESTTHREADS="$FDO_CI_CONCURRENT"
|
||||
NINJA_ARGS="-j$FDO_CI_CONCURRENT $NINJA_ARGS"
|
||||
MESON_TESTTHREADS="$FDO_CI_CONCURRENT"
|
||||
fi
|
||||
|
||||
echo "*************************************************"
|
||||
|
|
@ -65,24 +31,31 @@ echo "builddir: $MESON_BUILDDIR"
|
|||
echo "meson args: $MESON_ARGS"
|
||||
echo "ninja args: $NINJA_ARGS"
|
||||
echo "meson test args: $MESON_TEST_ARGS"
|
||||
echo "job count: ${jobcount-0}"
|
||||
echo "*************************************************"
|
||||
|
||||
set -e
|
||||
|
||||
if [[ -z "$MESON_SKIP_SETUP" ]]; then
|
||||
rm -rf "$MESON_BUILDDIR"
|
||||
meson setup "$MESON_BUILDDIR" $MESON_ARGS
|
||||
fi
|
||||
rm -rf "$MESON_BUILDDIR"
|
||||
meson "$MESON_BUILDDIR" $MESON_ARGS
|
||||
meson configure "$MESON_BUILDDIR"
|
||||
ninja -C "$MESON_BUILDDIR" $NINJA_ARGS
|
||||
|
||||
if [[ -z "$MESON_SKIP_BUILD" ]]; then
|
||||
if [[ -n "$NINJA_ARGS" ]]; then
|
||||
ninja_args="--ninja-args $NINJA_ARGS"
|
||||
fi
|
||||
meson compile -v -C "$MESON_BUILDDIR" $jobcount $ninja_args
|
||||
if [[ -z "$MESON_TEST_ARGS" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "$MESON_RUN_TEST" ]]; then
|
||||
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
|
||||
fi
|
||||
# we still want to generate the reports, even if meson test fails
|
||||
set +e
|
||||
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
|
||||
exit_code=$?
|
||||
set -e
|
||||
|
||||
# We need the glob for the testlog so that it picks up those suffixed by a
|
||||
# suite (e.g. testlog-valgrind.json)
|
||||
./.gitlab-ci/meson-junit-report.py \
|
||||
--project-name=libinput \
|
||||
--job-id="$CI_JOB_ID" \
|
||||
--output="$MESON_BUILDDIR/junit-$CI_JOB_NAME-report.xml" \
|
||||
"$MESON_BUILDDIR"/meson-logs/testlog*.json; \
|
||||
|
||||
exit $exit_code
|
||||
|
|
|
|||
117
.gitlab-ci/meson-junit-report.py
Executable file
|
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# meson-junit-report.py: Turns a Meson test log into a JUnit report
|
||||
#
|
||||
# Copyright 2019 GNOME Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
aparser = argparse.ArgumentParser(
|
||||
description="Turns a Meson test log into a JUnit report"
|
||||
)
|
||||
aparser.add_argument(
|
||||
"--project-name", metavar="NAME", help="The project name", default="unknown"
|
||||
)
|
||||
aparser.add_argument(
|
||||
"--job-id", metavar="ID", help="The job ID for the report", default="Unknown"
|
||||
)
|
||||
aparser.add_argument(
|
||||
"--branch",
|
||||
metavar="NAME",
|
||||
help="Branch of the project being tested",
|
||||
default="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)
|
||||
131
.gitlab-ci/scanbuild-plist-to-junit.py
Executable 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
|
|
@ -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()
|
||||
|
|
@ -15,12 +15,12 @@ detailed instructions to report bugs
|
|||
<!-- Note: if your libinput version is older than the current stable version,
|
||||
please reproduce with a current version instead -->
|
||||
|
||||
- libinput version:
|
||||
- libinput version:
|
||||
- hardware information:
|
||||
- `libinput record` output: do not paste, **attach** the file
|
||||
- `libinput debug-events --verbose` output: do not paste, **attach the file**
|
||||
|
||||
<!--
|
||||
<!--
|
||||
|
||||
Paste any other relevant logs - please use code blocks (```) to format
|
||||
console output, logs, and code as it's very hard to read otherwise.)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- id: no-commit-to-branch
|
||||
args: ['--branch', 'main']
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.12.2
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
args: ['--ignore=E741,E501', '--extend-exclude=subprojects', '.']
|
||||
- id: ruff-format
|
||||
args: ['--check', '--diff']
|
||||
- repo: https://gitlab.freedesktop.org/freedesktop/ci-templates.git
|
||||
rev: e195d80f35b45cc73668be3767b923fd76c70ed5
|
||||
hooks:
|
||||
- id: check-commits
|
||||
- id: generate-template
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: run-sed-script
|
||||
name: Check for whitespace errors
|
||||
entry: ./.gitlab-ci/whitespace-check.py
|
||||
language: system
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v20.1.6
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c]
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
# This is a set of bugbot commands for issues and merge requests - setting any of the
|
||||
# bugbot::foo labels will trigger gitlab-triage to run with this ruleset (well, the
|
||||
# one we have on the main branch at the time)
|
||||
#
|
||||
# Note that for adding labels, the label must first created in the project.
|
||||
|
||||
# Re-used in issues and mrs
|
||||
.close_needinfo: &close_needinfo
|
||||
name: "Close stale needinfo bugs"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::needinfo-timeout"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::needinfo-timeout"
|
||||
comment: |
|
||||
I'm closing this bug because some information we requested a while ago was never supplied and
|
||||
we're not able to continue without this information.
|
||||
Please feel free to re-open.
|
||||
status: "close"
|
||||
|
||||
.remind_needinfo: &remind_needinfo
|
||||
name: "Remind users of needinfo bugs"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::needinfo-reminder"
|
||||
actions:
|
||||
labels:
|
||||
- "waiting on reporter"
|
||||
remove_labels:
|
||||
- "bugbot::needinfo-reminder"
|
||||
comment: |
|
||||
Hi. This is a friendly reminder that the maintainers are waiting on some information by
|
||||
you (or maybe someone cc'd on this bug). If the information is not provided we may not
|
||||
be able to proceed with this issue or merge request. Please check the recent comments, thanks.
|
||||
|
||||
.help_needed: &help_needed
|
||||
name: "Remind users help is needed"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::help-needed"
|
||||
actions:
|
||||
labels:
|
||||
- "help needed"
|
||||
remove_labels:
|
||||
- "bugbot::help-needed"
|
||||
comment: |
|
||||
Hi. This issue or merge request needs help. This simply means that for
|
||||
the foreseeable future, the maintainers will not have time to work on
|
||||
this.
|
||||
|
||||
If this is a request for a new feature, then the feature is unlikely to
|
||||
be implemented unless you or another contributor files a merge request.
|
||||
If a merge request already exists maybe it needs finishing which often
|
||||
involves adding documentation or tests.
|
||||
|
||||
If this is an issue affecting a specific device then it is unlikely to be
|
||||
fixed. This may be because it requires specific hardware to reproduce or
|
||||
it may be that the use case is niche enough that the maintainers do not
|
||||
have time to implement it.
|
||||
|
||||
In short, to resolve this issue or get this merge request into libinput
|
||||
help is needed.
|
||||
|
||||
.libinput_record: &libinput_record
|
||||
name: "Request libinput record output"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::libinput-record"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::libinput-record"
|
||||
comment: |
|
||||
Looks like we may need some extra information. Please **attach** (do not paste) the full output
|
||||
of `libinput record` and `libinput debug-events --verbose` (if you haven't yet).
|
||||
The [documentation](https://wayland.freedesktop.org/libinput/doc/latest/tools.html#libinput-record-and-libinput-replay)
|
||||
has some information on what we're looking for to be able to triage bugs.
|
||||
|
||||
.hid_recorder: &hid_recorder
|
||||
name: "Request hid-recorder output"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::hid-recorder"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::hid-recorder"
|
||||
comment: |
|
||||
Looks like we may need some extra information that isn't yet available in this issue.
|
||||
Please **attach** (do not paste) the output of [`hid-recorder`](https://github.com/hidutils/hid-recorder/)
|
||||
for this device (run `sudo hid-recorder` without argument and it will let you pick the device).
|
||||
This should show the data the kernel receives from the device and may provide a hint on what's going on here.
|
||||
|
||||
.udev_hid_bpf: &udev_hid_bpf
|
||||
name: "Punt to udev-hid-bpf"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::udev-hid-bpf"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::udev-hid-bpf"
|
||||
comment: |
|
||||
This issue looks like it could or should be fixed with [udev-hid-bpf](https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/).
|
||||
udev-hid-bpf is a collection of BPF programs that modify the HID Report Descriptor and/or HID Reports from the device,
|
||||
making it possible to change the properties of a device and/or the events to make them compatible with the
|
||||
expectations the kernel and userspace has of such devices.
|
||||
|
||||
Please see the [udev-hid-bpf documentation](https://libevdev.pages.freedesktop.org/udev-hid-bpf/) for details
|
||||
and/or in particular the [udev-hid-bpf tutorial](https://libevdev.pages.freedesktop.org/udev-hid-bpf/tutorial.html)
|
||||
if you need to enable a new device.
|
||||
status: "close"
|
||||
|
||||
resource_rules:
|
||||
issues:
|
||||
rules:
|
||||
- name: "Close kernel bugs"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::kernel"
|
||||
actions:
|
||||
labels:
|
||||
- "kernel"
|
||||
remove_labels:
|
||||
- "bugbot::kernel"
|
||||
comment: |
|
||||
This bug looks like a kernel issue and it cannot be fixed
|
||||
in libinput directly. I'm closing this bug but do feel free
|
||||
to continue discussing the issue here.
|
||||
|
||||
Kernel bugs are usually best sent to the [`linux-input` list](https://lore.kernel.org/linux-input/).
|
||||
status: "close"
|
||||
- name: "Expect a merge request"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::expect-mr"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::expect-mr"
|
||||
comment: |
|
||||
I'm closing this bug in anticipation of a merge request that fixes this issue.
|
||||
|
||||
If you are a new contributor, please see
|
||||
[the freedesktop.org wiki](https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home)
|
||||
on how to get permissions to fork a project and file a merge request.
|
||||
|
||||
The [libinput documentation](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html)
|
||||
also has more details on how to get started.
|
||||
status: "close"
|
||||
- name: "Point to 60-evdev.hwdb"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::evdev-hwdb"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::evdev-hwdb"
|
||||
comment: |
|
||||
Looks like this issue may be solved with a device-specific entry in systemd's hwdb.
|
||||
|
||||
You should have a /usr/lib/udev/hwdb.d/60-evdev.hwdb file which includes those quirks. Please see
|
||||
the top of the file for instructions and follow those. Once the quirk is confirmed working
|
||||
this issue (or parts thereof) should be fixed and you can submit a pull request to the
|
||||
[systemd](https://github.com/systemd/systemd/) repository to get that quirk included.
|
||||
Please link to the systemd issue here, thanks.
|
||||
|
||||
I'm closing this issue now, if the hwdb entry does not fix this issue here, please re-open.
|
||||
status: "close"
|
||||
- name: "Close bug for reopening"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::close"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::close"
|
||||
comment: |
|
||||
I'm temporarily closing this bug. The bug may not be fixed yet (see any comments above)
|
||||
and we **want you to reopen it when/if it becomes actionable again**.
|
||||
|
||||
This process may feel unfamiliar but unfortunately closing/re-opening is the only action
|
||||
all GitLab users are permitted to do. So we close it, you re-open it when whatever
|
||||
above has been addressed and then we know we need to look at it again.
|
||||
This issue may be closed more than once in a similar fashion but I only leave this
|
||||
comment once since now you understand how it works. :smile:
|
||||
|
||||
For a detailed explanation on the how and why of this process please see
|
||||
the [Closed Issues wiki page](https://gitlab.freedesktop.org/libinput/libinput/-/wikis/Closed-Issues).
|
||||
status: "close"
|
||||
- name: "Re-close bug for reopening"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::re-close"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::re-close"
|
||||
comment: |
|
||||
I'm temporarily closing this bug again. This is not a final close, see my comments above for the open/close process.
|
||||
status: "close"
|
||||
- *udev_hid_bpf
|
||||
- *libinput_record
|
||||
- *hid_recorder
|
||||
- *close_needinfo
|
||||
- *remind_needinfo
|
||||
- *help_needed
|
||||
merge_requests:
|
||||
rules:
|
||||
- name: "Remind contributor of commit rules"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::commit-rules"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::commit-rules"
|
||||
comment: |
|
||||
Hi. Looks like the pipeline failed because one or more of the commits in this MR do not meet our requirements.
|
||||
Most commonly this the format of the commit message itself. The "Test summary" above has the details.
|
||||
|
||||
Please see [our docs for commit messages](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#commit-messages)
|
||||
and [our docs for submitting code](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#submitting-code)
|
||||
that explain how to amend and force-push to this repo.
|
||||
- name: "Remind contributor that info needs to be in commit messages"
|
||||
conditions:
|
||||
labels:
|
||||
- "bugbot::info-in-commit-message"
|
||||
actions:
|
||||
remove_labels:
|
||||
- "bugbot::info-in-commit-message"
|
||||
comment: |
|
||||
Hi. Thanks for the merge request. I'm here to request that you add
|
||||
some documentation about this merge request to the
|
||||
**commit message** (or messages). You may have already written some
|
||||
in the merge request description and in many cases it's fine to
|
||||
copy/paste that into the commit message(s).
|
||||
|
||||
The reason is simple: once merged, no-one really looks at this this
|
||||
page here anymore. The git log on the other hand is what developers
|
||||
will use to understand the code so the information must be quickly
|
||||
accessible via git.
|
||||
|
||||
Please see [our docs for submitting code](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#submitting-code)
|
||||
that explain how to amend and force-push to this repo.
|
||||
- *udev_hid_bpf
|
||||
- *libinput_record
|
||||
- *hid_recorder
|
||||
- *close_needinfo
|
||||
- *remind_needinfo
|
||||
- *help_needed
|
||||
127
CODING_STYLE.md
|
|
@ -52,102 +52,51 @@ somenamethatiswaytoolong(int a,
|
|||
- if it generates a static checker warning, it needs to be fixed or
|
||||
commented
|
||||
|
||||
- declare variables when they are used first and try to keep them as local as possible.
|
||||
Exception: basic loop variables, e.g. for (int i = 0; ...) should always be
|
||||
declared inside the loop even where multiple loops exist
|
||||
- declare variables at the top, try to keep them as local as possible.
|
||||
Exception: if the same variable is re-used in multiple blocks, declare it
|
||||
at the top.
|
||||
Exception: basic loop variables, e.g. for (int i = 0; ...)
|
||||
|
||||
```c
|
||||
int a;
|
||||
int c;
|
||||
|
||||
if (foo) {
|
||||
int b = 10;
|
||||
int b;
|
||||
|
||||
a = get_value();
|
||||
usevalue(a, b);
|
||||
c = get_value();
|
||||
usevalue(c);
|
||||
}
|
||||
|
||||
if (bar) {
|
||||
a = get_value();
|
||||
useit(a);
|
||||
c = get_value();
|
||||
useit(c);
|
||||
}
|
||||
|
||||
int c = a * 100;
|
||||
useit(c);
|
||||
```
|
||||
|
||||
- avoid uninitialized variables where possible, declare them late instead.
|
||||
Note that most of libinput predates this style, try to stick with the code
|
||||
around you if in doubt.
|
||||
- do not mix function invocations and variable definitions.
|
||||
|
||||
wrong:
|
||||
|
||||
```c
|
||||
int *a;
|
||||
{
|
||||
int a = foo();
|
||||
int b = 7;
|
||||
|
||||
... some code ...
|
||||
|
||||
a = zalloc(32);
|
||||
}
|
||||
```
|
||||
|
||||
right:
|
||||
|
||||
```c
|
||||
{
|
||||
int a;
|
||||
int b = 7;
|
||||
... some code ...
|
||||
|
||||
int *a = zalloc(32);
|
||||
```
|
||||
|
||||
- avoid calling non-obvious functions inside declaration blocks for multiple
|
||||
variables.
|
||||
|
||||
bad:
|
||||
|
||||
```c
|
||||
{
|
||||
int a = 7;
|
||||
int b = some_complicated_function();
|
||||
int *c = zalloc(32);
|
||||
a = foo();
|
||||
}
|
||||
```
|
||||
|
||||
better:
|
||||
```c
|
||||
{
|
||||
int a = 7;
|
||||
int *c = zalloc(32);
|
||||
|
||||
int b = some_complicated_function();
|
||||
}
|
||||
```
|
||||
|
||||
There is a bit of gut-feeling involved with this, but the goal is to make
|
||||
the variable values immediately recognizable.
|
||||
|
||||
- Where statements are near-identical and repeated, try to keep them
|
||||
identical:
|
||||
|
||||
bad:
|
||||
```c
|
||||
int a = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
```
|
||||
better:
|
||||
|
||||
```c
|
||||
int a;
|
||||
a = = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
a = get_some_value(x++);
|
||||
do_something(a);
|
||||
```
|
||||
There are exceptions here, e.g. `tp_libinput_context()`,
|
||||
`litest_current_device()`
|
||||
|
||||
- if/else: { on the same line, no curly braces if both blocks are a single
|
||||
statement. If either if or else block are multiple statements, both must
|
||||
|
|
@ -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
|
||||
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
|
||||
|
||||
The canonical git commit message format is:
|
||||
|
|
@ -225,6 +206,8 @@ supported.
|
|||
You can include extra data where required like:
|
||||
- benchmark one says 10s
|
||||
- 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
|
||||
|
|
@ -236,8 +219,8 @@ sure it's on point.
|
|||
"change foo to bar", not "changed foo to bar".
|
||||
- The text width of the commit should be 78 chars or less, especially the
|
||||
subject line.
|
||||
- The author must be the name you usually identify as and email address. We do
|
||||
not accept the default `@users.noreply` gitlab addresses.
|
||||
- The author and signed-off-by must be your real name and email address. We
|
||||
do not accept the default `@users.noreply` gitlab addresses.
|
||||
```
|
||||
git config --global user.name Your Name
|
||||
git config --global user.email your@email
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
Thank you for your interest in contributing to libinput.
|
||||
|
||||
Please find more information about how to contribute in
|
||||
[the documentation](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html).
|
||||
|
|
@ -45,61 +45,40 @@ __all_seats()
|
|||
'--verbose[Use verbose output]' \
|
||||
'--show-keycodes[Make all keycodes visible]' \
|
||||
'--grab[Exclusively grab all opened devices]' \
|
||||
'--compress-motion-events[Compress repeated motion events on a TTY]' \
|
||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
||||
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
|
||||
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
|
||||
'--disable-sendevents=[Disable send-events option for the devices matching the pattern]:pattern' \
|
||||
'--set-area=[Set the desired area as "x1/y1 x2/y2" (within \[0.0, 1.0\]) ]' \
|
||||
'--set-calibration=[Set the first 6 elements of the 3x3 calibration matrix ("1.0 0.0 0.0 0.0 1.0 0.0")]' \
|
||||
'--set-click-method=[Set the desired click method]:click-method:(none clickfinger buttonareas)' \
|
||||
'--set-clickfinger-map=[Set button mapping for clickfinger]:tap-map:(( \
|
||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
||||
))' \
|
||||
'--set-eraser-button-button=[Set button mapping for the eraser button]:eraser-button:(BTN_STYLUS BTN_STYLUS2 BTN_STYLUS3)' \
|
||||
'--set-eraser-button-mode=[Set the eraser button mode]:eraser-mode:(default button)' \
|
||||
'--set-pressure-range=[Set the tablet tool pressure range (within range \[0.0, 1.0\])]' \
|
||||
'--set-profile=[Set pointer acceleration profile]:accel-profile:(adaptive flat custom)' \
|
||||
'--set-rotation-angle=[Set the rotation angle in degrees]' \
|
||||
'--set-scroll-button=[Set the button to the given button code]' \
|
||||
'--set-scroll-method=[Set the desired scroll method]:scroll-method:(none twofinger edge button)' \
|
||||
'--set-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-tap-map=[Set button mapping for tapping]:tap-map:(( \
|
||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
||||
))' \
|
||||
+ '(custom pointer acceleration)' \
|
||||
'--set-custom-points=[Set n points defining a custom acceleration function]' \
|
||||
'--set-custom-step=[Set the distance along the x axis between the custom points]' \
|
||||
'--set-custom-type=[Set the type of the acceleration function]:custom-type:(fallback motion scroll)' \
|
||||
+ '(tap-to-click)' \
|
||||
'--enable-tap[Enable tap-to-click]' \
|
||||
'--disable-tap[Disable tap-to-click]' \
|
||||
+ '(drag)' \
|
||||
'--enable-drag[Enable tap-and-drag]' \
|
||||
'--disable-drag[Disable tap-and-drag]' \
|
||||
+ '(drag-lock)' \
|
||||
'--enable-drag-lock[Enable drag-lock]' \
|
||||
'--disable-drag-lock[Disable drag-lock]' \
|
||||
+ '(dwt)' \
|
||||
'--enable-dwt[Enable disable-while-typing]' \
|
||||
'--disable-dwt[Disable disable-while-typing]' \
|
||||
+ '(dwtp)' \
|
||||
'--enable-dwtp[Enable disable-while-trackpointing]' \
|
||||
'--disable-dwtp[Disable disable-while-trackpointing]' \
|
||||
+ '(natural-scrolling)' \
|
||||
'--enable-natural-scrolling[Enable natural scrolling]' \
|
||||
'--disable-natural-scrolling[Disable natural scrolling]' \
|
||||
+ '(left-handed)' \
|
||||
'--enable-left-handed[Enable left handed button configuration]' \
|
||||
'--disable-left-handed[Disable left handed button configuration]' \
|
||||
+ '(middlebutton)' \
|
||||
'--enable-middlebutton[Enable middle button emulation]' \
|
||||
'--disable-middlebutton[Disable middle button emulation]' \
|
||||
+ '(natural-scrolling)' \
|
||||
'--enable-natural-scrolling[Enable natural scrolling]' \
|
||||
'--disable-natural-scrolling[Disable natural scrolling]' \
|
||||
+ '(plugins)' \
|
||||
'--enable-plugins[Enable plugins]' \
|
||||
'--disable-plugins[Disable plugins]' \
|
||||
+ '(tap-to-click)' \
|
||||
'--enable-tap[Enable tap-to-click]' \
|
||||
'--disable-tap[Disable tap-to-click]'
|
||||
+ '(dwt)' \
|
||||
'--enable-dwt[Enable disable-while-typing]' \
|
||||
'--disable-dwt[Disable disable-while-typing]'
|
||||
}
|
||||
|
||||
(( $+functions[_libinput_debug-gui] )) || _libinput_debug-gui()
|
||||
|
|
@ -180,7 +159,7 @@ __all_seats()
|
|||
{
|
||||
_arguments \
|
||||
'--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/'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
|
|||
DOTFILE_DIRS = "@builddir@"
|
||||
EXAMPLE_PATH = "@builddir@"
|
||||
SHOW_NAMESPACES = NO
|
||||
HAVE_DOT = YES
|
||||
|
||||
HTML_HEADER = "@builddir@/header.html"
|
||||
HTML_FOOTER = "@builddir@/footer.html"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
3
doc/touchpad-gestures-state-machine.svg
Normal file → Executable file
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 181 KiB |
|
|
@ -40,6 +40,11 @@ To fix the touchpad you need to:
|
|||
|
||||
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
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
necessary to understand all of libinput to contribute a patch.
|
||||
|
||||
As of libinput 1.29 libinput has an internal plugin pipeline that modifies
|
||||
the event stream before libinput proper sees it, see
|
||||
:ref:`architecture-plugins`.
|
||||
|
||||
:ref:`architecture-contexts` is the only user-visible implementation detail,
|
||||
everything else is purely internal implementation and may change when
|
||||
required.
|
||||
|
|
@ -154,8 +150,10 @@ pointers to handle events. Four such dispatch methods are currently
|
|||
implemented: touchpad, tablet, tablet pad, and the fallback dispatch which
|
||||
handles mice, keyboards and touchscreens.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
|
|
@ -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
|
||||
events is performed within the dispatch method.
|
||||
|
||||
|
||||
.. graphviz::
|
||||
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
|
|
@ -198,107 +194,22 @@ events is performed within the dispatch method.
|
|||
|
||||
evdev [label="evdev_device_dispatch()"]
|
||||
|
||||
plugins [label="plugin pipline"]
|
||||
|
||||
fallback [label="fallback_interface_process()"];
|
||||
touchpad [label="tp_interface_process()"]
|
||||
tablet [label="tablet_process()"]
|
||||
pad [label="pad_process()"]
|
||||
|
||||
evdev -> plugins;
|
||||
plugins -> fallback;
|
||||
plugins -> touchpad;
|
||||
plugins -> tablet;
|
||||
plugins -> pad;
|
||||
evdev -> fallback;
|
||||
evdev -> touchpad;
|
||||
evdev -> tablet;
|
||||
evdev -> pad;
|
||||
}
|
||||
|
||||
|
||||
The dispatch methods then look at the ``struct evdev_frame`` and proceed to
|
||||
update the state.
|
||||
|
||||
.. _architecture-plugins:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
The Plugin Pipeline
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
As of libinput 1.29 libinput has an **internal** plugin pipeline. These plugins
|
||||
logically sit between libevdev and the :ref:`architecture-dispatch` and modify
|
||||
the device and/or event stream. The primary motivation of such plugins is that
|
||||
modifying the event stream is often simpler than analyzing the state later.
|
||||
|
||||
Plugins are loaded on libinput context startup and are executed in-order. The last
|
||||
plugin is the hardcoded `evdev-plugin.c` which takes the modified event stream and
|
||||
passes the events to the dispatch.
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
evdev [label="evdev_device_dispatch()"]
|
||||
|
||||
p1 [label="P1"]
|
||||
p2 [label="P2"]
|
||||
p3 [label="P3"]
|
||||
ep [label="evdev-plugin"]
|
||||
|
||||
fallback [label="fallback_interface_process()"];
|
||||
touchpad [label="tp_interface_process()"]
|
||||
tablet [label="tablet_process()"]
|
||||
pad [label="pad_process()"]
|
||||
|
||||
evdev -> p1;
|
||||
p1 -> p2;
|
||||
p2 -> p3;
|
||||
p3 -> ep;
|
||||
ep -> fallback;
|
||||
ep -> touchpad;
|
||||
ep -> tablet;
|
||||
ep -> pad;
|
||||
}
|
||||
|
||||
Each plugin may not only modify the current event frame (this includes adding/removing events
|
||||
from the frame), it may also append or prepend additional event frames. For
|
||||
example the tablet proximity-timer plugin adds proximity in/out events to the
|
||||
event stream.
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph context
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
n0 [label= "", shape=none,height=.0,width=.0]
|
||||
n1 [label= "", shape=none,height=.0,width=.0]
|
||||
|
||||
p1 [label="P1"]
|
||||
p2 [label="P2"]
|
||||
p3 [label="P3"]
|
||||
ep [label="evdev-plugin"]
|
||||
|
||||
n0 -> p1 [label="F1"];
|
||||
p1 -> p2 [label="F1"];
|
||||
p2 -> p3 [label="F1,F2"];
|
||||
p3 -> ep [label="F3,F1,F2"];
|
||||
ep -> n1 [label="F3,F1,F2"];
|
||||
}
|
||||
|
||||
In the diagram above, the plugin ``P2`` *appends* a new frame (``F2``), the plugin ``P3``
|
||||
*prepends* a new frame (``F3``). The original event frame ``F1`` thus becomes the event frame
|
||||
sequence ``F3``, ``F1``, ``F2`` by the time it reaches the :ref:`architecture-dispatch`.
|
||||
|
||||
Note that each plugin only sees one event frame at a time, so ``P3`` would see ``F1`` first,
|
||||
decides to prepend ``F3`` and passes ``F1`` through. It then sees ``F2`` but does nothing with
|
||||
it (optionally modified in-place).
|
||||
The dispatch methods then look at the ``struct input_event`` and proceed to
|
||||
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
|
||||
processing until the ``SYN_REPORT`` event is received.
|
||||
|
||||
.. _architecture-configuration:
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ process below. A successful build requires the
|
|||
|
||||
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
||||
$> cd libinput
|
||||
$> meson setup --prefix=/usr builddir/
|
||||
$> meson --prefix=/usr builddir/
|
||||
$> ninja -C builddir/
|
||||
$> 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
|
||||
|
|
@ -96,7 +96,7 @@ again:
|
|||
::
|
||||
|
||||
$> rm -r builddir/
|
||||
$> meson setup --prefix=....
|
||||
$> meson --prefix=....
|
||||
|
||||
|
||||
.. _verifying_install:
|
||||
|
|
@ -189,7 +189,7 @@ running meson.
|
|||
|
||||
.. hint:: The build dependencies for some distributions can be found in the
|
||||
`GitLab Continuous Integration file <https://gitlab.freedesktop.org/libinput/libinput/blob/main/.gitlab-ci.yml>`_.
|
||||
Search for **FEDORA_PACKAGES** in the **variables:** definition
|
||||
Search for **FEDORA_RPMS** in the **variables:** definition
|
||||
and check the list for an entry for your distribution.
|
||||
|
||||
In most cases, it is sufficient to install the dependencies that your
|
||||
|
|
@ -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,
|
||||
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:
|
||||
|
||||
|
|
|
|||
|
|
@ -102,12 +102,11 @@ ignores such button clicks, this behavior is intentional.
|
|||
Clickfinger behavior
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
This is the default behavior on Apple touchpads. Here, a left, right, middle
|
||||
button event is generated when one, two, or three fingers are held down on the
|
||||
touchpad when a physical click is generated, given the default mapping. The
|
||||
location of the fingers does not matter and there are no software-defined
|
||||
button areas. It is possible to swap right and middle buttons, the same way as
|
||||
with :ref:`tapping <tapping>`.
|
||||
This is the default behavior on Apple touchpads.
|
||||
Here, a left, right, middle button event is generated when one, two, or
|
||||
three fingers are held down on the touchpad when a physical click is
|
||||
generated. The location of the fingers does not matter and there are no
|
||||
software-defined button areas.
|
||||
|
||||
.. figure:: clickfinger.svg
|
||||
:align: center
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
.. _clickpads_with_right_buttons:
|
||||
|
||||
==============================================================================
|
||||
Clickpads with a fake right button
|
||||
==============================================================================
|
||||
|
||||
libinput relies on the kernel to label :ref:`Clickpads <touchpads_buttons_clickpads>`
|
||||
with the ``INPUT_PROP_BUTTONPAD`` property so it can enable the correct
|
||||
:ref:`clickpad_softbuttons`. Clickpads are not expected to have a right button
|
||||
since the whole surface can be depressed.
|
||||
|
||||
A common bug encountered with :ref:`Clickpads <touchpads_buttons_clickpads>`
|
||||
is that the device advertises a physical right button where no such button
|
||||
exists. This is usually a bug in the firmware of the device and causes the
|
||||
following warning to be emitted by libinput::
|
||||
|
||||
"<device name> clickpad advertising right button"
|
||||
|
||||
The user-visible effect of this is usually negligible since these devices
|
||||
cannot actually trigger a right click and libinput's default behaviors for
|
||||
clickpads work as expected.
|
||||
|
||||
However, we should nonetheless correct the device to get rid of this warning
|
||||
and avoid potential issues with future features. The :ref:`device-quirks`
|
||||
provide a simple way to disable the fake right button on the device. The
|
||||
following quirk disables the right button on the MyModel laptop from the
|
||||
MyVendor OEM::
|
||||
|
||||
[MyVendor MyModel Touchpad]
|
||||
MatchName=Foo Bar Touchpad
|
||||
MatchUdevtype=touchpad
|
||||
MatchDMIModAlias=dmi:*:svnMyVendor:pnMyModel:*
|
||||
AttrEventCode=-BTN_RIGHT
|
||||
|
||||
The name of the device can be obtained using :ref:`libinput record <libinput-record>`,
|
||||
the modalias match is a shell-style glob against the value of ``/sys/class/dmi/id/modalias``.
|
||||
In most cases, matching should be against ``svn`` (system vendor) and one of
|
||||
``pn`` (product name) or ``pvr`` (product version), whichever provides a
|
||||
useful description of the individual laptop model. See the
|
||||
:ref:`device-quirks` documentation for details on testing local quirks.
|
||||
|
||||
For reference, some example commits that add such a quirk are:
|
||||
|
||||
- `bf61ab9bb0694d0ac3d60a7f815779abfe4886e6 <https://gitlab.freedesktop.org/libinput/libinput/-/commit/bf61ab9bb0694d0ac3d60a7f815779abfe4886e6>`__
|
||||
- `74fac6d040ac62048882dfb6f73da567ace6a6f5 <https://gitlab.freedesktop.org/libinput/libinput/-/commit/74fac6d040ac62048882dfb6f73da567ace6a6f5>`__
|
||||
- `89cd0f990e3bee9906754d6ca8484ed5aa392249 <https://gitlab.freedesktop.org/libinput/libinput/-/commit/89cd0f990e3bee9906754d6ca8484ed5aa392249>`__
|
||||
|
|
@ -62,7 +62,7 @@ master_doc = 'index'
|
|||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# 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
|
||||
# directories to ignore when looking for source files.
|
||||
|
|
@ -169,7 +169,7 @@ from recommonmark.parser import CommonMarkParser
|
|||
|
||||
extlinks = { 'commit' :
|
||||
('https://gitlab.freedesktop.org/libinput/libinput/commit/%s',
|
||||
'git commit %s')
|
||||
'git commit ')
|
||||
}
|
||||
|
||||
# -- git version hack -------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -6,21 +6,15 @@ Configuration options
|
|||
|
||||
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
|
||||
:ref:`libinput list-devices <libinput-list-devices>` to show the
|
||||
configuration options for local devices.
|
||||
|
||||
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
|
||||
`xf86-input-libinput driver <https://gitlab.freedesktop.org/xorg/driver/xf86-input-libinput/>`_
|
||||
exposes the options through X Input device properties and `xorg.conf.d
|
||||
<https://linux.die.net/man/5/xorg.conf.d>`_ options. See the `libinput(4)
|
||||
xf86-input-libinput driver exposes the options through X Input device
|
||||
properties and xorg.conf.d options. See the `libinput(4)
|
||||
<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
|
||||
- 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 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
|
||||
click, respectively. This order can be changed to left, middle, right click,
|
||||
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,
|
||||
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
|
||||
------------------------------------------------------------------------------
|
||||
|
|
@ -161,18 +142,6 @@ info.
|
|||
Disable-while-typing can be enabled or disabled, it is enabled by default on
|
||||
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
|
||||
------------------------------------------------------------------------------
|
||||
|
|
@ -187,51 +156,8 @@ environment should provide an interface for this.
|
|||
Rotation
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
trackball may be used in a 90° rotated position for accessibility reasons -
|
||||
such a rotated position allows triggering the buttons with the thumb or
|
||||
the non-dominant hand.
|
||||
|
||||
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.
|
||||
The device rotation applies a corrective angle to relative input events.
|
||||
This is currently only available on trackpoints which may be used sideways
|
||||
or upside-down. The angle can be freely chosen but not all devices support
|
||||
rotation other than 0, 90, 180, or 270 degrees. Rotation is off (0 degrees)
|
||||
by default.
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ will be:
|
|||
|
||||
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
||||
$> cd libinput
|
||||
$> meson setup --prefix=/usr builddir/
|
||||
$> meson --prefix=/usr builddir/
|
||||
$> ninja -C builddir/
|
||||
$> 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
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you are planning to send patches, it's a good idea to set up
|
||||
`pre-commit <https://pre-commit.com/>`_ with these commands::
|
||||
|
||||
$> pre-commit install
|
||||
$> pre-commit install --hook-type pre-push
|
||||
|
||||
This will check a few things before you commit and/or push to your repos to
|
||||
reduce the turnaround time for some common mistakes.
|
||||
|
||||
libinput has a roughly three-parts architecture:
|
||||
|
||||
- the front-end code which handles the ``libinput_some_function()`` API calls in ``libinput.c``
|
||||
|
|
@ -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
|
||||
<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
|
||||
replace `learning git <https://git-scm.com/doc>`__ but they should be
|
||||
sufficient to make some of the more confusing steps obvious.
|
||||
|
||||
- `Register an account <https://gitlab.freedesktop.org/users/sign_in>`_ in
|
||||
the freedesktop.org GitLab instance and
|
||||
`apply for fork permissions <https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home>`_.
|
||||
- `Fork libinput <https://gitlab.freedesktop.org/libinput/libinput/-/forks/new>`_
|
||||
into your username's namespace. Select public visibility.
|
||||
the freedesktop.org GitLab instance.
|
||||
- `Fork libinput <https://gitlab.freedesktop.org/libinput/libinput/forks/new>`_
|
||||
into your username's namespace
|
||||
- Get libinput's main repository. git will call this repository ``origin``. ::
|
||||
|
||||
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``. ::
|
||||
|
||||
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
|
||||
|
||||
- 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 **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
|
||||
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
|
||||
|
|
@ -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
|
||||
deserve, and the patches may cause redundant review effort.
|
||||
|
||||
If your commit solves a GitLab issue, add a ``Closes:`` tag followed by the
|
||||
issue number at the end of your commit message. For example: ::
|
||||
|
||||
Closes: #974
|
||||
|
||||
If your commit fixes an issue introduced by another commit, use a ``Fixes`` tag
|
||||
followed by the first 12 characters of the SHA-1 ID and the commit one line
|
||||
summary at the end of your commit message. For example: ::
|
||||
|
||||
Fixes: 123456789012 ("The commit that caused the issue")
|
||||
|
||||
For further reading, please see
|
||||
`'on commit messages' <http://who-t.blogspot.de/2009/12/on-commit-messages.html>`_
|
||||
as a general guideline on what commit messages should contain.
|
||||
|
|
@ -359,6 +353,26 @@ step failed.
|
|||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -68,13 +68,10 @@ MOUSE_WHEEL_CLICK_ANGLE
|
|||
|
||||
|
||||
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!="remove", KERNEL=="event[0-9]*", \
|
||||
ENV{ID_VENDOR_ID}=="012a", \
|
||||
ENV{ID_MODEL_ID}=="034b", \
|
||||
ENV{ID_SEAT}="seat1"
|
||||
ACTION=="add|change", KERNEL=="event[0-9]*", 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
|
||||
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!="remove", KERNEL=="event[0-9]*", \
|
||||
ENV{ID_VENDOR_ID}=="012a", \
|
||||
ENV{ID_MODEL_ID}=="034b", \
|
||||
ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
|
||||
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||
ENV{ID_MODEL_ID}=="034b", ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
|
||||
|
||||
|
||||
|
||||
.. _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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
installed under ``/usr/share/libinput/<filename>.quirks`` and are standard
|
||||
``.ini`` files. A file may contain multiple section headers (``[some
|
||||
identifier]``) followed by one or more :ref:`MatchFoo=Bar <device-quirks-matches>`
|
||||
directives, followed by at least one of ``ModelFoo=1`` or ``AttrFoo=bar`` directive.
|
||||
See the ``quirks/README.md`` file in the libinput source repository for more
|
||||
details on their contents.
|
||||
identifier]``) followed by one or more ``MatchFoo=Bar`` directives, followed by
|
||||
at least one of ``ModelFoo=1`` or ``AttrFoo=bar`` directive. See the
|
||||
``quirks/README.md`` file in the libinput source repository for more details on
|
||||
their contents.
|
||||
|
||||
.. warning:: Model quirks are internal API and may change at any time. No
|
||||
backwards-compatibility is guaranteed.
|
||||
|
|
@ -71,7 +71,7 @@ devices. ::
|
|||
|
||||
$ libinput quirks list /dev/input/event19
|
||||
$ libinput quirks list /dev/input/event0
|
||||
AttrLidSwitchReliability=unreliable
|
||||
AttrLidSwitchReliability=reliable
|
||||
|
||||
The device `event19` does not have any quirks assigned.
|
||||
|
||||
|
|
@ -112,11 +112,11 @@ output.
|
|||
.. _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
|
||||
patches upstream. This section shows device quirks currently available in
|
||||
patches upstream. This section shows device quirks supported in
|
||||
|git_version|.
|
||||
|
||||
.. 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.
|
||||
ModelSynapticsSerialTouchpad
|
||||
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
|
||||
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
|
||||
|
|
@ -172,20 +157,15 @@ AttrTouchSizeRange=N:M, AttrPalmSizeThreshold=O
|
|||
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
|
||||
details.
|
||||
An AttrPalmSizeThreshold of zero unsets any threshold that has been
|
||||
inherited from another quirk.
|
||||
AttrPressureRange=N:M, AttrPalmPressureThreshold=O, AttrThumbPressureThreshold=P
|
||||
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
|
||||
thumb touch is triggered (P). O > P > N > M. See
|
||||
:ref:`touchpad_pressure_hwdb` for more details.
|
||||
An AttrPalmPressureThreshold of zero unsets any threshold that has been
|
||||
inherited from another quirk.
|
||||
AttrLidSwitchReliability=reliable|unreliable|write_open
|
||||
Indicates the reliability of the lid switch. This is a string enum.
|
||||
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.
|
||||
AttrLidSwitchReliability=reliable|write_open
|
||||
Indicates the reliability of the lid switch. This is a string enum. Do not
|
||||
use "reliable" for any specific device. Very few devices need this, if in
|
||||
doubt do not set. See :ref:`switches_lid` for details.
|
||||
AttrKeyboardIntegration=internal|external
|
||||
Indicates the integration of the keyboard. This is a string enum.
|
||||
Generally only needed for USB keyboards.
|
||||
|
|
@ -193,52 +173,23 @@ AttrTPKComboLayout=below
|
|||
Indicates the position of the touchpad on an external touchpad+keyboard
|
||||
combination device. This is a string enum. Don't specify it unless the
|
||||
touchpad is below.
|
||||
AttrEventCode=+EV_ABS;-BTN_STYLUS;+EV_KEY:0x123;
|
||||
Enables or disables the evdev event type/code tuples on the device. The prefix
|
||||
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
||||
AttrEventCodeDisable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
||||
Disables the evdev event type/code tuples on the device. 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.
|
||||
AttrInputProp=+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER;
|
||||
Enables or disables the evdev input property on the device. The prefix
|
||||
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
||||
AttrEventCodeEnable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
||||
Enables the evdev event type/code tuples on the device. 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.
|
||||
|
||||
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
|
||||
Indicates the integration of the pointing stick. This is a string enum.
|
||||
Only needed for external pointing sticks. These are rare.
|
||||
AttrTabletSmoothing=1|0
|
||||
Enables (1) or disables (0) input smoothing for tablet devices. Smoothing is enabled
|
||||
by default, except on AES devices.
|
||||
|
||||
.. _device-quirks-matches:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
List of currently available matches
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
``Match*`` statements are how quirks are assigned to a device. Quirks with multiple
|
||||
match statements must match all of those to apply.
|
||||
|
||||
.. warning:: Quirks are internal API and may change at any time for any reason.
|
||||
No guarantee is given that any ``Match`` statement below works on
|
||||
your version of libinput.
|
||||
|
||||
MatchName, MatchUniq
|
||||
Match on the ``NAME`` or ``UNIQ`` udev property on this device. These properties
|
||||
are typically derived from the device's kernel name or uniq but may be overridden
|
||||
by a udev rule. These matches use ``fnmatch()`` globs.
|
||||
MatchBus
|
||||
A lower-case bus name. Currently supported are ``usb``, ``bluetooth``, ``ps2``,
|
||||
``rmi``, ``i2c``, and ``spi``.
|
||||
MatchVendor, MatchProduct, MatchVersion
|
||||
The hexadecimal 4-digit vendor ID, product ID or driver version as
|
||||
exported, uppercase with a ``0x`` prefix, e.g. ``0x12AB```.
|
||||
MatchDMIModalias, MatchDeviceTree
|
||||
An ``fnmatch()`` glob for the DMI modalias or the DeviceTree ``compatible`` string.
|
||||
See ``/sys/class/dmi/id/modalias`` and ``/sys/firmware/devicetree/base/compatible``.
|
||||
MatchUdevType
|
||||
One of ``touchpad``, ``mouse``, ``pointingstick``, ``keyboard``, ``joystick``,
|
||||
``tablet``, ``tablet-pad``. Matches the corresponding ``ID_INPUT_*`` udev
|
||||
property.
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
digraph stack
|
||||
{
|
||||
compound=true;
|
||||
splines=line;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
subgraph cluster_2 {
|
||||
label="Kernel";
|
||||
event0 [label="/dev/input/event0"];
|
||||
event1 [label="/dev/input/event1"];
|
||||
}
|
||||
|
||||
subgraph cluster_0 {
|
||||
label="Compositor process";
|
||||
libinput [label="libinput context 1"];
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
label="libinput debug-events";
|
||||
libinput2 [label="libinput context 2"];
|
||||
}
|
||||
|
||||
stdout;
|
||||
|
||||
client [label="Wayland client"];
|
||||
|
||||
event0:e -> libinput:w;
|
||||
event1:e -> libinput:w;
|
||||
event0:e -> libinput2:w;
|
||||
event1:e -> libinput2:w;
|
||||
libinput -> client [ltail=cluster_0 label="Wayland protocol"];
|
||||
libinput2 -> stdout [ltail=cluster_1];
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
digraph stack
|
||||
{
|
||||
compound=true;
|
||||
rankdir="LR";
|
||||
node [
|
||||
shape="box";
|
||||
]
|
||||
|
||||
subgraph cluster_2 {
|
||||
label="Kernel";
|
||||
event0 [label="/dev/input/event0"]
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
label="libinput";
|
||||
subgraph cluster_0 {
|
||||
label="Plugin pipeline";
|
||||
p1 [label="00-foo.lua"];
|
||||
p2 [label="10-bar.lua"];
|
||||
}
|
||||
libinput [label="libinput core"];
|
||||
}
|
||||
|
||||
|
||||
compositor [label="Compositor"];
|
||||
|
||||
event0 -> p1;
|
||||
p1 -> p2;
|
||||
p2 -> libinput;
|
||||
libinput -> compositor [ltail=cluster_1 label="libinput API"];
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
.. _drag_3fg:
|
||||
|
||||
==============================================================================
|
||||
Three-finger drag
|
||||
==============================================================================
|
||||
|
||||
Three-finger drag is a feature available on touchpads that emulates logical
|
||||
button presses if three fingers are moving on the touchpad.
|
||||
|
||||
Three-finger drag is independent from :ref:`tapping` though some specific
|
||||
behaviors may change when both features are enabled. For example, with
|
||||
tapping *disabled* a three-finger gesture will virtually always be a three-finger
|
||||
drag. With tapping *enabled* a three finger gesture may be a three finger drag
|
||||
and a short delay is required to disambiguate between the two.
|
||||
|
||||
|
||||
The exact behavior of three-finger drag is implementation defined and may
|
||||
subtly change. As a general rule, the following constraints can be expected:
|
||||
|
||||
- three fingers down and movement trigger a button down and subsequent motion
|
||||
events (i.e. a drag)
|
||||
- releasing one finger while keeping two fingers down will keep the drag
|
||||
and *not* switch to :ref:`twofinger_scrolling`.
|
||||
- releasing two fingers while keeping one finger down will end the drag
|
||||
(and thus release the button) and switch to normal pointer motion
|
||||
- releasing all three fingers and putting three fingers back on the touchpad
|
||||
immediately will keep the drag (i.e. behave as if the fingers were
|
||||
never lifted)
|
||||
|
||||
- if tapping is enabled: a three finger tap immediately after a three-finger
|
||||
drag will *not* tap, the user needs to wait past the timeout to
|
||||
three-finger tap
|
||||
|
||||
- releasing all three fingers and putting one or two fingers back on
|
||||
the touchpad will end the drag (and thus release the button)
|
||||
and proceed with pointer motion or two-finger scrolling, if applicable
|
||||
|
||||
- if tapping is enabled: a one or two finger tap immediately after a
|
||||
three-finger drag will trigger a one or two finger tap. The user does
|
||||
not have to wait past the drag release timeout
|
||||
|
|
@ -335,56 +335,3 @@ are more specialized (e.g. in-vehicle infotainment or IVI) can handle input
|
|||
devices directly but the compositor you want to use
|
||||
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.
|
||||
|
||||
.. _faq_separate_contexts:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Can I write a program to make libinput do $FOO
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
A common question is whether it's possible to write a program that can change
|
||||
libinput's behavior - specifically the libinput that is used inside the
|
||||
compositor. This indicates a misunderstanding of how libinput works:
|
||||
libinput is a library that converts kernel events into libinput events, much
|
||||
like ``sed`` reads data in, modifies it, and provides it to stdout.
|
||||
|
||||
.. graphviz:: libinput-contexts.gv
|
||||
|
||||
A libinput context is private to the process and cannot be modified from the
|
||||
outside. To use the ``sed`` analogy again: if ``sed`` is used by a
|
||||
shell-script, that script has full control over how ``sed`` processes data. In
|
||||
this analogy, ``sed`` is libinput and the shell script is the compositor. It is
|
||||
not possible to write a program to modify the behavior of the ``sed`` instance
|
||||
used inside that shell script.
|
||||
|
||||
Writing a program that uses libinput is akin to writing a new script that
|
||||
invoke ``sed``. It will not have any effect on the original ``sed`` instance.
|
||||
|
||||
The only way to modify libinput's behavior is to use the configuration options
|
||||
exposed by the respective compositor. Those affect the libinput context inside
|
||||
the compositor and thus have an effect on the input device behavior.
|
||||
|
||||
.. _faq_debug_events_not_showing_configuration:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Why doesn't libinput debug-events show my configuration
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
See :ref:`faq_separate_contexts`.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Can I configure scroll speed?
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
No, or at least, not as a libinput option.
|
||||
|
||||
When using a mouse, libinput notifies callers about physical scroll wheel
|
||||
movement. When using another device, libinput notifies scroll in scroll units.
|
||||
|
||||
It is up to the caller to transform those events into a number of pixels to
|
||||
scroll and, if desired, provide a way to adjust scroll speed.
|
||||
|
||||
This transformation cannot be done in libinput because it may depend on context
|
||||
only known by the caller. For example, a caller may want to scroll faster
|
||||
depending on how many pages a document has or depending on the widget that
|
||||
receives the scroll events.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ to be useful.
|
|||
scrolling.rst
|
||||
t440-support.rst
|
||||
tapping.rst
|
||||
drag-3fg.rst
|
||||
tablet-support.rst
|
||||
switches.rst
|
||||
touchpad-pressure.rst
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
.. _ignoring_devices:
|
||||
|
||||
==============================================================================
|
||||
Ignoring specific devices
|
||||
==============================================================================
|
||||
|
||||
If a device has the **LIBINPUT_IGNORE_DEVICE** udev property set to any
|
||||
value but "0", that device is not initialized by libinput.
|
||||
For a context created with **libinput_udev_create_context()**, the device is
|
||||
silently ignored and never shows up. If the device is added with
|
||||
**libinput_path_add_device()** to a context created with
|
||||
**libinput_path_create_context()**, adding the device will fail and return NULL
|
||||
(see that function's documentation for more
|
||||
information).
|
||||
|
||||
If the property value is exactly "0", then the property is considered unset
|
||||
and libinput initializes the device normally.
|
||||
|
||||
This property should be used for devices that are correctly detected as
|
||||
input devices (see :ref:`udev_device_type`) but that should not be used by
|
||||
libinput. It is recommended that devices that should not be handled as input
|
||||
devices at all unset the **ID_INPUT** and related properties instead. The
|
||||
**LIBINPUT_IGNORE_DEVICE** property signals that only libinput should
|
||||
ignore this property but other parts of the stack (if any) should continue
|
||||
treating this device normally.
|
||||
|
||||
Below is an example udev rule to assign **LIBINPUT_IGNORE_DEVICE** to the
|
||||
device with the vendor/model ID of ``012a``/``034b``. ::
|
||||
|
||||
$ cat /etc/udev/rules.d/99-ignore-my-device.rules
|
||||
ACTION!="remove", KERNEL=="event[0-9]*", \
|
||||
ENV{ID_VENDOR_ID}=="012a", \
|
||||
ENV{ID_MODEL_ID}=="034b", \
|
||||
ENV{LIBINPUT_IGNORE_DEVICE}="1"
|
||||
|
||||
See :ref:`udev_config` for more details on libinput's udev properties.
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
.. _incorrectly_enabled_hires:
|
||||
|
||||
==============================================================================
|
||||
Incorrectly enabled high-resolution scroll
|
||||
==============================================================================
|
||||
|
||||
Some devices might announce support for high-resolution scroll wheel by enabling
|
||||
``REL_WHEEL_HI_RES`` and/or ``REL_HWHEEL_HI_RES`` but never send a
|
||||
high-resolution scroll event.
|
||||
|
||||
When the first low-resolution scroll event is received without any previous
|
||||
high-resolution event, libinput prints a bug warning with the text **"device
|
||||
supports high-resolution scroll but only low-resolution events have been
|
||||
received"** and a link to this page.
|
||||
|
||||
.. note:: This warning will be printed only once
|
||||
|
||||
In most cases this is a bug on the device firmware, the kernel driver or in a
|
||||
software used to create user-space devices through uinput.
|
||||
|
||||
Once the bug is detected, libinput will start emulating high-resolution scroll
|
||||
events.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Detecting and fixing the issue
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Events sent by a buggy device can be shown in the
|
||||
:ref:`libinput record <libinput-record>` output for the device. Notice that
|
||||
``REL_WHEEL_HI_RES`` and ``REL_HWHEEL_HI_RES`` are set but only ``REL_WHEEL``
|
||||
events are sent: ::
|
||||
|
||||
# Supported Events:
|
||||
# Event type 0 (EV_SYN)
|
||||
# Event type 1 (EV_KEY)
|
||||
# Event code 272 (BTN_LEFT)
|
||||
# Event type 2 (EV_REL)
|
||||
# Event code 0 (REL_X)
|
||||
# Event code 1 (REL_Y)
|
||||
# Event code 6 (REL_HWHEEL)
|
||||
# Event code 8 (REL_WHEEL)
|
||||
# Event code 11 (REL_WHEEL_HI_RES)
|
||||
# Event code 12 (REL_HWHEEL_HI_RES)
|
||||
[...]
|
||||
quirks:
|
||||
events:
|
||||
- evdev:
|
||||
- [ 0, 0, 2, 8, 1] # EV_REL / REL_WHEEL 1
|
||||
- [ 0, 0, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +0ms
|
||||
- evdev:
|
||||
- [ 0, 15126, 2, 8, 1] # EV_REL / REL_WHEEL 1
|
||||
- [ 0, 15126, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +15ms
|
||||
- evdev:
|
||||
- [ 0, 30250, 2, 8, 1] # EV_REL / REL_WHEEL 1
|
||||
- [ 0, 30250, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +15ms
|
||||
|
||||
The issue can be fixed by adding a quirk to unset the ``REL_WHEEL_HI_RES`` and
|
||||
``REL_HWHEEL_HI_RES`` event codes: ::
|
||||
|
||||
AttrEventCode=-REL_WHEEL_HI_RES;-REL_HWHEEL_HI_RES;
|
||||
|
||||
Please see :ref:`device-quirks` for details.
|
||||
|
|
@ -12,7 +12,6 @@
|
|||
troubleshooting
|
||||
contributing
|
||||
development
|
||||
lua-plugins
|
||||
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
|
||||
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
|
||||
provide the common set of functionality that users expect. Input event
|
||||
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
|
||||
--------------------
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,661 +0,0 @@
|
|||
.. _lua_plugins:
|
||||
|
||||
==============================================================================
|
||||
Lua Plugins
|
||||
==============================================================================
|
||||
|
||||
libinput provides a plugin system that allows users to modify the behavior
|
||||
of devices. For example, a plugin may add or remove axes and/or buttons on a
|
||||
device and/or modify the event stream seen by this device before it is passed
|
||||
to libinput.
|
||||
|
||||
Plugins are implemented in `Lua <https://www.lua.org/>`_ (version 5.4)
|
||||
and are typically loaded from the following paths:
|
||||
|
||||
- ``/etc/libinput/plugins/*.lua``, and
|
||||
- ``/usr/lib{64}/libinput/plugins/*.lua``
|
||||
|
||||
Plugins are loaded in alphabetical order and where
|
||||
multiple plugins share the same file name, the one in the highest precedence
|
||||
directory is used. Plugins in ``/etc`` take precedence over
|
||||
plugins in ``/usr``.
|
||||
|
||||
.. note:: Plugins lookup paths and their order are decided by the compositor.
|
||||
Some compositors may support more/fewer/other lookup paths than the
|
||||
above defaults.
|
||||
|
||||
Plugins are run sequentially in ascending sort-order (i.e. ``00-foo.lua`` runs
|
||||
before ``10-bar.lua``) and each plugin sees the state left by any previous
|
||||
plugins. For example if ``00-foo.lua`` changes all left button events to right
|
||||
button events, ``10-bar.lua`` only ever sees right button events.
|
||||
|
||||
See the `Lua Reference manual <https://www.lua.org/manual/5.4/manual.html>`_ for
|
||||
details on the Lua language.
|
||||
|
||||
.. note:: Plugins are **not** loaded by default, it is up to the compositor
|
||||
whether to allow plugins. An explicit call to
|
||||
``libinput_plugin_system_load_plugins()`` is required.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Limitations
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Each script runs in its own sandbox and cannot communicate or share state with
|
||||
other scripts.
|
||||
|
||||
Tables that hold API methods are not writable, i.e. it is not possible
|
||||
to overwrite the default functionality of those APIs.
|
||||
|
||||
The Lua API available to plugins is limited to the following calls::
|
||||
|
||||
assert error ipairs next pairs tonumber
|
||||
pcall select print tostring type xpcall
|
||||
table string math _VERSION
|
||||
|
||||
It is not possible to e.g. use the ``io`` module from a script.
|
||||
|
||||
To use methods on instantiated objects, the ``object:method`` method call
|
||||
syntax must be used. For example:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:register()
|
||||
libinput.register() -- this will fail
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
When to use plugins
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput plugins are a relatively niche use-case that typically need to
|
||||
address either once-off issues (e.g. those caused by worn-out hardware) or
|
||||
user preferences that libinput does not and will not cater for.
|
||||
|
||||
Plugins should not be used for issues that can be fixed generically, for
|
||||
example via :ref:`device-quirks`.
|
||||
|
||||
As a rule of thumb: a plugin should be a once-off that only works for one
|
||||
user's hardware. If a plugin can be shared with many users then the plugin
|
||||
implements functionality that should be integrated into libinput proper.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Testing plugins
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Our :ref:`tools` support plugins if passed the ``--enable-plugins`` commandline
|
||||
option. For implementing and testing plugins the easiest commands to test are
|
||||
|
||||
- ``libinput debug-events --enable-plugins`` (see :ref:`libinput-debug-events` docs)
|
||||
- ``libinput debug-gui --enable-plugins`` (see :ref:`libinput-debug-gui` docs)
|
||||
|
||||
Where libinput is built and run from git, the tools will also look for plugins
|
||||
in the meson build directory. See the ``plugins/meson.build`` file for details.
|
||||
|
||||
.. _plugins_api_lua:
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Lua Plugin API
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Lua plugins sit effectively below libinput and the API is not a
|
||||
representation of the libinput API. Plugins modify the evdev event stream
|
||||
received from the kernel.
|
||||
|
||||
.. graphviz:: plugin-stack.gv
|
||||
|
||||
The API revolves around two types: ``libinput`` and ``EvdevDevice``. The
|
||||
``libinput`` type is used to register a plugin from a script, the
|
||||
``EvdevDevice`` represents one device that is present in the system (but may
|
||||
not have yet been added by libinput).
|
||||
|
||||
Typically a script does the following steps:
|
||||
|
||||
- register with libinput via ``libinput:register({versions})``
|
||||
- connect to the ``"new-evdev-device"`` event
|
||||
- receive an ``EvdevDevice`` object in the ``"new-evdev-device"`` callback
|
||||
|
||||
- check and/or modify the evdev event codes on the device
|
||||
- connect to the device's ``"evdev-frame"`` event
|
||||
|
||||
- receive an :ref:`evdev frame <plugins_api_evdev_frame>` in the device's
|
||||
``"evdev-frame"`` callback
|
||||
|
||||
- check and/or modify the events in that frame
|
||||
|
||||
Where multiple plugins are active, the evdev frame passed to the callback is
|
||||
the combined frame as processed by all previous plugins in ascending sort order.
|
||||
For example, if one plugin discards all button events subsequent plugins will
|
||||
never see those button events in the frame.
|
||||
|
||||
.. _plugins_api_version_stability:
|
||||
|
||||
..............................................................................
|
||||
Plugin version stability
|
||||
..............................................................................
|
||||
|
||||
Plugin API version stability is provided on a best effort basis. We aim to provide
|
||||
stable plugin versions for as long as feasible but may need to retire some older
|
||||
versions over time. For this reason a plugin can select multiple versions it
|
||||
implements, libinput will pick one supported version and adjust the plugin
|
||||
behavior to match that version. See the ``libinput:register()`` call for details.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Lua Plugin API Reference
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
libinput provides the following globals and types:
|
||||
|
||||
.. _plugins_api_evdev_usage:
|
||||
|
||||
................................................................................
|
||||
Evdev Usages
|
||||
................................................................................
|
||||
|
||||
Evdev usages are a libinput-specific wrapper around the ``linux/input-event-codes.h``
|
||||
evdev types and codes. They are used by libinput internally and are a 32-bit
|
||||
combination of ``type << 16 | code``. Each usage carries the type and code and
|
||||
is thus simpler to pass around and less prone to type confusion.
|
||||
|
||||
The :ref:`evdev global <plugins_api_evdev_global>` attempts to provide all
|
||||
available usages but for the niche cases where it does not provide a named constant
|
||||
the value can be crafted manually:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
evdev_type = 0x3 -- EV_REL
|
||||
evdev_code = 0x1 -- REL_Y
|
||||
evdev_usage = (evdev_type << 16) | evdev_code
|
||||
|
||||
assert(usage == evdev.REL_Y)
|
||||
|
||||
.. _plugins_api_evdev_global:
|
||||
|
||||
................................................................................
|
||||
The ``evdev`` global
|
||||
................................................................................
|
||||
|
||||
The ``evdev`` global represents all known :ref:`plugins_api_evdev_usage`,
|
||||
effectively in the form:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
evdev = {
|
||||
ABS_X = (3 << 16) | 0,
|
||||
ABS_Y = (3 << 16) | 1,
|
||||
...
|
||||
REL_X = (2 << 16) | 0,
|
||||
REL_Y = (2 << 16) | 1,
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
This global is provided for convenience to improve readability in the code.
|
||||
Note that the name uses the event code name only (e.g. ``evdev.ABS_Y``) but the
|
||||
value is an :ref:`Evdev Usage <plugins_api_evdev_usage>` (type and code).
|
||||
|
||||
See the ``linux/input-event-codes.h`` header file provided by your kernel
|
||||
for a list of all evdev types and codes.
|
||||
|
||||
The evdev global also provides the bus type constants, e.g. ``evdev.BUS_USB``.
|
||||
See the ``linux/input.h`` header file provided by your kernel
|
||||
for a list of bus types.
|
||||
|
||||
|
||||
.. _plugins_api_evdev_frame:
|
||||
|
||||
................................................................................
|
||||
Evdev frames
|
||||
................................................................................
|
||||
|
||||
Evdev frames represent a single frame of evdev events for a device. A frame
|
||||
is a group of events that occurred at the same time. The frame usually only
|
||||
contains state that has changed compared to the previous frame.
|
||||
|
||||
In our API a frame is exposed as a nested table with the following structure:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
frame1 = {
|
||||
{ usage = evdev.ABS_X, value = 123 },
|
||||
{ usage = evdev.ABS_Y, value = 456 },
|
||||
{ usage = evdev.BTN_LEFT, value = 1 },
|
||||
}
|
||||
frame2 = {
|
||||
{ usage = evdev.ABS_Y, value = 457 },
|
||||
}
|
||||
frame3 = {
|
||||
{ usage = evdev.ABS_X, value = 124 },
|
||||
{ usage = evdev.BTN_LEFT, value = 0 },
|
||||
}
|
||||
|
||||
.. note:: This API does not use ``SYN_REPORT`` events, it is implied at the
|
||||
end of the table. Where a plugin writes a ``SYN_REPORT`` into the
|
||||
list of events, that ``SYN_REPORT`` terminates the event frame
|
||||
(similar to writing a ``\0`` into the middle of a C string).
|
||||
A frame containing only a ``SYN_REPORT`` is functionally equivalent
|
||||
to an empty frame.
|
||||
|
||||
Events or frames do not have a timestamp. Where a timestamp is required, that
|
||||
timestamp is passed as additional argument to the function or return value.
|
||||
|
||||
See :ref:`plugins_api_evdev_global` for a list of known usages.
|
||||
|
||||
.. warning:: Evdev frames have an implementation-defined size limit of how many
|
||||
events can be added to a single frame. This limit should never be
|
||||
hit by valid plugins.
|
||||
|
||||
.. _plugins_api_libinputglobal:
|
||||
|
||||
................................................................................
|
||||
The ``libinput`` global object
|
||||
................................................................................
|
||||
|
||||
The core of our plugin API is the ``libinput`` global object. A script must
|
||||
immediately ``register()`` to be active, otherwise it is unloaded immediately.
|
||||
|
||||
All libinput-specific APIs can be accessed through the ``libinput`` object.
|
||||
|
||||
.. function:: libinput:register({1, 2, ...})
|
||||
|
||||
Register this plugin with the given table of supported version numbers and
|
||||
returns the version number selected by libinput for this plugin. See
|
||||
:ref:`plugins_api_version_stability` for details.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
-- this plugin can support versions 1, 4 and 5
|
||||
version = libinput:register({1, 4, 5})
|
||||
if version == 1 then
|
||||
...
|
||||
|
||||
This function must be the first function called.
|
||||
If the plugin calls any other functions before ``register()``, those functions
|
||||
return the default zero value for the return type (``nil``, ``0``, an empty
|
||||
table, etc.).
|
||||
|
||||
If the plugin does not call ``register()`` it will be removed immediately.
|
||||
Once registered, any connected callbacks will be invoked whenever libinput
|
||||
detects new devices, removes devices, etc.
|
||||
|
||||
This function must only be called once.
|
||||
|
||||
.. function:: libinput:unregister()
|
||||
|
||||
Unregister this plugin. This removes the plugin from libinput and releases
|
||||
any resources associated with this plugin. This call must be the last call
|
||||
in your plugin, it is effectively equivalent to Lua's
|
||||
`os.exit() <https://www.lua.org/manual/5.4/manual.html#pdf-os.exit>`_.
|
||||
|
||||
.. function:: libinput:log_debug(message)
|
||||
|
||||
Log a message at the libinput debug log priority. See
|
||||
``libinput:log_error()`` for details.
|
||||
|
||||
.. function:: libinput:log_info(message)
|
||||
|
||||
Log a message at the libinput info log priority. See
|
||||
``libinput:log_error()`` for details.
|
||||
|
||||
.. function:: libinput:log_error(message)
|
||||
|
||||
Log a message at the libinput error log priority. Whether a message is
|
||||
displayed in the log depends on libinput's log priority, set by the caller.
|
||||
|
||||
A compositor may disable stdout and stderr. Log messages should be preferred
|
||||
over Lua's ``print()`` function to ensure the messages end up in the same
|
||||
location as other libinput log messages and are not discarded.
|
||||
|
||||
.. function:: libinput:now()
|
||||
|
||||
Returns the current time in microseconds in ``CLOCK_MONOTONIC``. This is
|
||||
the timestamp libinput uses internally. This timestamp cannot be mapped
|
||||
to any particular time of day, see the
|
||||
`clock_gettime() man page <https://man7.org/linux/man-pages/man3/clock_gettime.3.html>`_
|
||||
for details.
|
||||
|
||||
.. function:: libinput:version()
|
||||
|
||||
Returns the agreed-on version of the plugin, see ``libinput:register()``.
|
||||
If called before ``libinput:register()`` this function returns ``0``.
|
||||
|
||||
.. function:: libinput:connect(name, function)
|
||||
|
||||
Set the callback to the given event name. Only one callback
|
||||
may be set for an event name at any time, subsequent callbacks
|
||||
will replace any earlier callbacks for the same name.
|
||||
|
||||
Version 1 of the plugin API supports the following events and callback arguments:
|
||||
|
||||
- ``"new-evdev-device"``: A new :ref:`EvdevDevice <plugins_api_evdevdevice>`
|
||||
has been seen by libinput but not yet added.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:connect("new-evdev-device", function (device) ... end)
|
||||
|
||||
- ``"timer-expired"``: The timer for this plugin has expired. This event is
|
||||
only sent if the plugin has set a timer with ``timer_set()``.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:connect("timer-expired", function (now) ... end)
|
||||
|
||||
The ``now`` argument is the current time in microseconds in
|
||||
``CLOCK_MONOTONIC`` (see ``libinput:now()``).
|
||||
|
||||
.. function:: libinput:timer_cancel()
|
||||
|
||||
Cancel the timer for this plugin. This is a no-op if the timer
|
||||
has not been set or has already expired.
|
||||
|
||||
.. function:: libinput:timer_set_absolute(time)
|
||||
|
||||
Set a timer for this plugin, with the given time in microseconds.
|
||||
The timeout specifies an absolute time in microseconds (see
|
||||
``libinput:now()``) The timer will expire once and then call the
|
||||
``"timer-expired"`` event handler (if any).
|
||||
|
||||
See ``libinput:timer_set_relative()`` for a relative timer.
|
||||
|
||||
The following two lines of code are equivalent:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:timer_set_relative(1000000) -- 1 second from now
|
||||
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
|
||||
|
||||
Calling this function will cancel any existing (relative or absolute) timer.
|
||||
|
||||
.. function:: libinput:timer_set_relative(timeout)
|
||||
|
||||
Set a timer for this plugin, with the given timeout in microseconds from
|
||||
the current time. The timer will expire once and then call the
|
||||
``"timer-expired"`` event handler (if any).
|
||||
|
||||
See ``libinput:timer_set_absolute()`` for an absolute timer.
|
||||
|
||||
The following two lines of code are equivalent:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
libinput:timer_set_relative(1000000) -- 1 second from now
|
||||
libinput:timer_set_absolute(libinput:now() + 1000000) -- 1 second from now
|
||||
|
||||
Calling this function will cancel any existing (relative or absolute) timer.
|
||||
|
||||
.. _plugins_api_evdevdevice:
|
||||
|
||||
................................................................................
|
||||
The ``EvdevDevice`` type
|
||||
................................................................................
|
||||
|
||||
The ``EvdevDevice`` type represents a device available in the system
|
||||
but not (yet) added by libinput. This device may be used to modify
|
||||
a device's capabilities before the device is processed by libinput.
|
||||
|
||||
A plugin should always ``connect()`` to the ``"device-removed"`` callback
|
||||
to be notified when a device is removed. If the plugin keeps a reference
|
||||
to this device but the device is discarded by libinput, the device's query
|
||||
methods will return zero values (e.g. ``nil``, ``0``, an empty table) and
|
||||
methods will be noops.
|
||||
|
||||
.. function:: EvdevDevice:info()
|
||||
|
||||
A table containing static information about the device, e.g.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
{
|
||||
bustype = evdev.BUS_USB,
|
||||
vid = 0x1234,
|
||||
pid = 0x5678,
|
||||
}
|
||||
|
||||
A plugin must ignore keys it does not know about.
|
||||
|
||||
Version 1 of the plugin API supports the following keys and values:
|
||||
|
||||
- ``bustype``: The numeric bustype of the device. See the
|
||||
``BUS_*`` defines in ``linux/input.h`` for the list of possible values.
|
||||
- ``vid``: The 16-bit vendor ID of the device
|
||||
- ``pid``: The 16-bit product ID of the device
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:name()
|
||||
|
||||
The device name as set by the kernel
|
||||
|
||||
.. function:: EvdevDevice:usages()
|
||||
|
||||
Returns a table of all usages that are currently enabled for this
|
||||
device. Any type that exists on the device has a table assigned and in this
|
||||
table any code that exists on the device is a boolean true.
|
||||
For example:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
{
|
||||
evdev.REL_X = true,
|
||||
evdev.REL_Y = true,
|
||||
evdev.BTN_LEFT = true,
|
||||
}
|
||||
|
||||
All other usages are ``nil``, so that the following code is possible:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
-- do something
|
||||
end
|
||||
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:absinfos()
|
||||
|
||||
Returns a table of all ``EV_ABS`` codes that are currently enabled for this device.
|
||||
The event code is the key, each value is a table containing the following keys:
|
||||
``minimum``, ``maximum``, ``fuzz``, ``flat``, ``resolution``.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
{
|
||||
evdev.ABS_X = {
|
||||
minimum = 0,
|
||||
maximum = 1234,
|
||||
fuzz = 0,
|
||||
flat = 0,
|
||||
resolution = 45,
|
||||
},
|
||||
}
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:udev_properties()
|
||||
|
||||
Returns a table containing a filtered list of udev properties available on this device
|
||||
in the form ``{ property_name = property_value, ... }``.
|
||||
udev properties used as a boolean (e.g. ``ID_INPUT``) are only present if their
|
||||
value is a logical true.
|
||||
|
||||
Version 1 of the plugin API supports the following udev properties:
|
||||
|
||||
- ``ID_INPUT`` and all of ``ID_INPUT_*`` that denote the device type as assigned
|
||||
by udev. This information is usually used by libinput to determine a
|
||||
device type. Note that for historical reasons these properties have
|
||||
varying rules - some properties may be mutually exclusive, others are
|
||||
independent, others may only be set if another property is set. Refer to
|
||||
the udev documentation (if any) for details. ``ID_INPUT_WIDTH_MM`` and
|
||||
``ID_INPUT_HEIGHT_MM`` are excluded from this set.
|
||||
|
||||
If the device has since been discarded by libinput, this function returns an
|
||||
empty table.
|
||||
|
||||
.. function:: EvdevDevice:enable_evdev_usage(usage)
|
||||
|
||||
Enable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
|
||||
Use :ref:`plugins_api_evdev_global` for better readability,
|
||||
e.g. ``device:enable_evdev_usage(evdev.REL_X)``.
|
||||
This function must not be used for ``ABS_*`` events, use ``set_absinfo()``
|
||||
instead.
|
||||
|
||||
Once a usage is enabled, events for that usage may be added to a device's
|
||||
frame.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
.. function:: EvdevDevice:disable_evdev_usage(usage)
|
||||
|
||||
Disable the given :ref:`evdev usage <plugins_api_evdev_usage>` for this device.
|
||||
Use :ref:`plugins_api_evdev_global` for better readability,
|
||||
e.g. ``device:disable_evdev_usage(evdev.REL_X)``.
|
||||
|
||||
Once a usage is disabled, events for that usage are discarded from any
|
||||
device frame.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
.. function:: EvdevDevice:set_absinfo(usage, absinfo)
|
||||
|
||||
Set the absolute axis information for the given :ref:`evdev usage <plugins_api_evdev_usage>`
|
||||
and enable it if it does not yet exist on the device. The ``absinfo`` argument is a table
|
||||
containing zero or more of the following keys: ``minimum``, ``maximum``, ``fuzz``,
|
||||
``flat``, ``resolution``. Any missing key defaults the corresponding
|
||||
value from the device if the device already has this event usage or zero otherwise.
|
||||
For example, the following code changes the resolution but leaves everything
|
||||
else as-is:
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
local absinfo = {
|
||||
resolution = 40,
|
||||
}
|
||||
device:set_absinfo(evdev.ABS_X, absinfo)
|
||||
device:set_absinfo(evdev.ABS_Y, absinfo)
|
||||
|
||||
Use :ref:`plugins_api_evdev_global` for better readability as shown in the
|
||||
example above.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
.. note:: Overriding the absinfo values often indicates buggy firmware. This should
|
||||
typically be fixed with an entry in the
|
||||
`60-evdev.hwdb <https://github.com/systemd/systemd/blob/main/hwdb.d/60-evdev.hwdb>`_
|
||||
or :ref:`device-quirks` instead of a plugin so all users of that
|
||||
device can benefit from the fix.
|
||||
|
||||
.. function:: EvdevDevice:connect(name, function)
|
||||
|
||||
Set the callback to the given event name. Only one callback
|
||||
may be set for an event name at any time, subsequent callbacks
|
||||
will overwrite any earlier callbacks for the same name.
|
||||
|
||||
If the device has since been discarded by libinput, this function does nothing.
|
||||
|
||||
Version 1 of the plugin API supports the following events and callback arguments:
|
||||
|
||||
- ``"evdev-frame"``: A new :ref:`evdev frame <plugins_api_evdev_frame>` has
|
||||
started for this device. If the callback returns a value other than
|
||||
``nil``, that value is the frame with any modified events.
|
||||
An empty frame (``{}``) causes libinput to drop the current event frame.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
-- change any event into a movement left by 1 pixel
|
||||
move_left = {
|
||||
{ usage = evdev.REL_X, value = -1, },
|
||||
}
|
||||
return move_left
|
||||
end
|
||||
|
||||
The timestamp of an event frame is in microseconds in ``CLOCK_MONOTONIC``, see
|
||||
``libinput:now()`` for details.
|
||||
|
||||
For performance reasons plugins that do not modify the event frame should
|
||||
return ``nil`` (or nothing) instead of the event frame that was passed
|
||||
as argument.
|
||||
|
||||
- ``"device-removed"``: This device was removed by libinput. This may happen
|
||||
without the device ever becoming a libinput device as seen by libinput's
|
||||
public API (e.g. if the device does not meet the requirements to be
|
||||
added). Once this callback is invoked, the plugin should remove any
|
||||
references to this device and stop using it.
|
||||
|
||||
.. code-block:: lua
|
||||
|
||||
device:connect("device-removed", function (device) ... end)
|
||||
|
||||
Functions to query the device's capabilities (e.g. ``usages()``) will
|
||||
return an empty table.
|
||||
|
||||
.. function:: EvdevDevice:disconnect(name)
|
||||
|
||||
Disconnect the existing callback (if any) for the given event name. See
|
||||
``EvdevDevice:connect()`` for a list of supported names.
|
||||
|
||||
.. function:: EvdevDevice:prepend_frame(frame)
|
||||
|
||||
Prepend an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
|
||||
**before** the current frame (if any). The **next** plugin will see the
|
||||
prepended frame first followed by the current frame.
|
||||
|
||||
This function can only be called from within a device's ``"evdev-frame"``
|
||||
handler or from within the plugin's timer callback function.
|
||||
|
||||
For example, to change a single event into a drag, prepend a button
|
||||
down and append a button up before each event:
|
||||
|
||||
.. code:: lua
|
||||
|
||||
function frame_handler(device, frame, timestamp)
|
||||
device:prepend_frame({
|
||||
{ usage = evdev.BTN_LEFT, value = 1}
|
||||
})
|
||||
device:append_frame({
|
||||
{ usage = evdev.BTN_LEFT, value = 0}
|
||||
})
|
||||
return nil -- return the current frame unmodified
|
||||
|
||||
-- The next plugin sees the event sequence:
|
||||
-- button down, frame, button up
|
||||
end
|
||||
|
||||
If called from within the plugin's timer there is no current frame and this
|
||||
function is identical to ``append_frame()``.
|
||||
|
||||
.. function:: EvdevDevice:append_frame(frame)
|
||||
|
||||
Appends an :ref:`evdev frame <plugins_api_evdev_frame>` for this device
|
||||
**after** the current frame (if any). This function can only be called from
|
||||
within a device's ``"evdev-frame"`` handler or from within the plugin's timer
|
||||
callback function.
|
||||
|
||||
If called from within the plugin's timer there is no current frame and this
|
||||
function is identical to ``prepend_frame()``.
|
||||
|
||||
See ``prepend_frame()`` for more details.
|
||||
|
||||
.. function:: EvdevDevice:disable_feature(feature_name)
|
||||
|
||||
Disable the given libinput-internal feature for this device. This should be used
|
||||
by plugins that replace that feature with a custom implementation for this device.
|
||||
|
||||
libinput may have multiple internal implementations for any given feature, disabling
|
||||
it via this API disables any and all of those implementations, causing the feature to
|
||||
no longer work at all. It is up to the plugin implementation to re-implement that
|
||||
feature to match the user's expectation.
|
||||
|
||||
Version 1 of the plugin API supports the following features:
|
||||
|
||||
- ``"button-debouncing"``: see :ref:`button_debouncing`
|
||||
- ``"touchpad-hysteresis"``: see :ref:`touchpad_jitter`
|
||||
- ``"touchpad-jump-detection"``: see :ref:`touchpad_jumping_cursor`
|
||||
- ``"touchpad-palm-detection"``: see :ref:`palm_detection`
|
||||
- ``"wheel-debouncing"``: some high-resolution mouse wheel movements inside libinput
|
||||
are delayed and/or modified
|
||||
|
|
@ -50,7 +50,6 @@ src_404s = [
|
|||
[ 'faqs.rst', 'faq.html'],
|
||||
[ 'features.rst', 'features.html'],
|
||||
[ 'gestures.rst', 'gestures.html'],
|
||||
[ 'incorrectly-enabled-hires.rst', 'incorrectly-enabled-hires.html'],
|
||||
[ 'middle-button-emulation.rst', 'middle_button_emulation.html'],
|
||||
[ 'normalization-of-relative-motion.rst', 'motion_normalization.html'],
|
||||
[ 'palm-detection.rst', 'palm_detection.html'],
|
||||
|
|
@ -95,13 +94,11 @@ src_rst = files(
|
|||
# dot drawings
|
||||
'dot/seats-sketch.gv',
|
||||
'dot/seats-sketch-libinput.gv',
|
||||
'dot/libinput-contexts.gv',
|
||||
'dot/libinput-stack-wayland.gv',
|
||||
'dot/libinput-stack-xorg.gv',
|
||||
'dot/libinput-stack-gnome.gv',
|
||||
'dot/evemu.gv',
|
||||
'dot/libinput-record.gv',
|
||||
'dot/plugin-stack.gv',
|
||||
# svgs
|
||||
'svg/button-debouncing-wave-diagram.svg',
|
||||
'svg/button-scrolling.svg',
|
||||
|
|
@ -112,7 +109,6 @@ src_rst = files(
|
|||
'svg/palm-detection.svg',
|
||||
'svg/pinch-gestures.svg',
|
||||
'svg/pinch-gestures-softbuttons.svg',
|
||||
'svg/ptraccel-custom.svg',
|
||||
'svg/ptraccel-linear.svg',
|
||||
'svg/ptraccel-low-dpi.svg',
|
||||
'svg/ptraccel-touchpad.svg',
|
||||
|
|
@ -122,11 +118,8 @@ src_rst = files(
|
|||
'svg/software-buttons-thumbpress.svg',
|
||||
'svg/software-buttons-visualized.svg',
|
||||
'svg/swipe-gestures.svg',
|
||||
'svg/tablet-area.svg',
|
||||
'svg/tablet-axes.svg',
|
||||
'svg/tablet-cintiq24hd-modes.svg',
|
||||
'svg/tablet-eraser-invert.svg',
|
||||
'svg/tablet-eraser-button.svg',
|
||||
'svg/tablet-interfaces.svg',
|
||||
'svg/tablet-intuos-modes.svg',
|
||||
'svg/tablet-left-handed.svg',
|
||||
|
|
@ -145,19 +138,14 @@ src_rst = files(
|
|||
'building.rst',
|
||||
'button-debouncing.rst',
|
||||
'clickpad-softbuttons.rst',
|
||||
'clickpad-with-right-button.rst',
|
||||
'contributing.rst',
|
||||
'device-configuration-via-udev.rst',
|
||||
'device-quirks.rst',
|
||||
'drag-3fg.rst',
|
||||
'faqs.rst',
|
||||
'gestures.rst',
|
||||
'incorrectly-enabled-hires.rst',
|
||||
'ignoring-devices.rst',
|
||||
'middle-button-emulation.rst',
|
||||
'normalization-of-relative-motion.rst',
|
||||
'palm-detection.rst',
|
||||
'lua-plugins.rst',
|
||||
'pointer-acceleration.rst',
|
||||
'reporting-bugs.rst',
|
||||
'scrolling.rst',
|
||||
|
|
@ -204,8 +192,7 @@ if yq.found()
|
|||
foreach distro : distributions
|
||||
yq_filter = '.distributions[] | select(.name == "@0@") | .packages | join(" ")'.format(distro)
|
||||
deps = run_command(yq, '-r', yq_filter,
|
||||
dir_gitlab_ci / 'config.yml',
|
||||
check: true).stdout()
|
||||
meson.source_root() / '.gitlab-ci' / 'config.yml').stdout()
|
||||
dependencies_config.set('@0@_PACKAGES'.format(distro.to_upper()), deps)
|
||||
endforeach
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ hardware-specific capabilities.
|
|||
- :ref:`palm_exclusion_zones`
|
||||
- :ref:`trackpoint-disabling`
|
||||
- :ref:`disable-while-typing`
|
||||
- :ref:`disable-while-trackpointing`
|
||||
- :ref:`stylus-touch-arbitration`
|
||||
|
||||
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
|
||||
avoids palm detection on such touch sequences.
|
||||
|
||||
A touch starting in the exclusion zone does not trigger a tap (see
|
||||
:ref:`tapping`).
|
||||
Each side edge exclusion zone is divided into a top part and a bottom part.
|
||||
A touch starting in the top part of the exclusion zone does not trigger a
|
||||
tap (see :ref:`tapping`).
|
||||
|
||||
In the diagram below, the exclusion zones are painted red.
|
||||
Touch 'A' starts inside the exclusion zone and moves
|
||||
|
|
@ -103,8 +103,10 @@ despite moving out of the exclusion zone.
|
|||
Touch 'B' starts inside the exclusion zone but moves horizontally out of the
|
||||
zone. It is considered a valid touch and controls the cursor.
|
||||
|
||||
Touch 'C' occurs in the exclusion zone. Despite being a tapping motion, it does
|
||||
not generate an emulated button event.
|
||||
Touch 'C' occurs in the top part of the exclusion zone. Despite being a
|
||||
tapping motion, it does not generate an emulated button event. Touch 'D'
|
||||
likewise occurs within the exclusion zone but in the bottom half. libinput
|
||||
will generate a button event for this touch.
|
||||
|
||||
.. figure:: palm-detection.svg
|
||||
: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
|
||||
**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:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -19,18 +19,12 @@ Pointer acceleration profiles
|
|||
------------------------------------------------------------------------------
|
||||
|
||||
The profile decides the general method of pointer acceleration.
|
||||
libinput currently supports three profiles: **"adaptive"**, **"flat"** and
|
||||
**"custom"**.
|
||||
|
||||
- The **adaptive** profile is the default profile for all devices and takes the
|
||||
current speed of the device into account when deciding on acceleration.
|
||||
- The **flat** profile is simply a constant factor applied to all device deltas,
|
||||
regardless of the speed of motion (see :ref:`ptraccel-profile-flat`).
|
||||
- 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.
|
||||
libinput currently supports two profiles: "adaptive" and "flat". The adaptive
|
||||
profile is the default profile for all devices and takes the current speed
|
||||
of the device into account when deciding on acceleration. The flat profile
|
||||
is simply a constant factor applied to all device deltas, regardless of the
|
||||
speed of motion (see :ref:`ptraccel-profile-flat`). Most of this document
|
||||
describes the adaptive pointer acceleration.
|
||||
|
||||
.. _ptraccel-velocity:
|
||||
|
||||
|
|
@ -172,7 +166,7 @@ what is a unit again.
|
|||
|
||||
libinput attempts to normalize unit data to the best of its abilities, see
|
||||
: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
|
||||
:align: center
|
||||
|
|
@ -202,95 +196,3 @@ Pointer acceleration on tablets
|
|||
Pointer acceleration for relative motion on tablet devices is a flat
|
||||
acceleration, with the speed setting slowing down or speeding up the pointer
|
||||
motion by a constant factor. Tablets do not allow for switchable profiles.
|
||||
|
||||
.. _ptraccel-profile-custom:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
The custom acceleration profile
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
libinput supports a user-defined custom acceleration profile, which can be
|
||||
adjusted for different movement types supported by a device. Movement types
|
||||
include pointer movement, scrolling, etc. but the set of supported
|
||||
movement types depends on the device.
|
||||
|
||||
The custom pointer acceleration profile gives users full control over the
|
||||
acceleration behavior at different speeds. libinput exposes
|
||||
an acceleration function ``f(x)`` where the x axis is the device speed in
|
||||
device units per millisecond and the y axis is the pointer speed. By
|
||||
supplying the y axis values for this function, users can control the
|
||||
behavior of the device.
|
||||
|
||||
The user should take into account the native device dpi and screen dpi in
|
||||
order to achieve the desired behavior/feel.
|
||||
|
||||
The custom acceleration function is defined using ``n`` points which are spaced
|
||||
uniformly along the x axis, starting from 0 and continuing in constant steps.
|
||||
At least two points must be defined and there is an implementation-defined
|
||||
limit on how many points may be added.
|
||||
|
||||
Thus the points defining the custom function are:
|
||||
``(0 * step, f[0]), (1 * step, f[1]), ..., ((n-1) * step, f[n-1])``
|
||||
where ``f`` is a list of ``n`` values defining the output velocity for each
|
||||
input velocity.
|
||||
The acceleration factor is defined by the ratio of the output velocity to the
|
||||
input velocity.
|
||||
When a velocity value does not lie exactly on those points, a linear
|
||||
interpolation of the two closest points will be calculated.
|
||||
When a velocity value is greater than the max point defined, a linear
|
||||
extrapolation of the two biggest points will be calculated.
|
||||
|
||||
the calculation made by libinput: ::
|
||||
|
||||
input_delta = device delta units
|
||||
delta_time = time in ms since last input_delta
|
||||
input_speed = hypot(input_delta) / delta_time
|
||||
output_speed = user_custom_function(input_speed)
|
||||
acceleration_factor = output_speed / input_speed
|
||||
output_delta = input_delta * acceleration_factor
|
||||
|
||||
An example is the curve of ``0.0, 1.0`` with a step of ``1.0``. This curve
|
||||
is the equivalent of the flat acceleration profile with any input speed ``N``
|
||||
mapped to the same pointer speed ``N``. The curve ``1.0, 1.0`` neutralizes
|
||||
any input speed differences and results in a fixed pointer speed.
|
||||
|
||||
Another example is the custom acceleration function ``x**2``,
|
||||
sampling the function at ``4`` points up to
|
||||
a maximum input speed of ``9`` will give us a custom function with
|
||||
a step of ``3`` and points ``[0.0, 9.0, 36.0, 81.0]``:
|
||||
|
||||
.. figure:: ptraccel-custom.svg
|
||||
:align: center
|
||||
|
||||
More sampled points can be added to improve the accuracy of the user custom
|
||||
function.
|
||||
|
||||
Supported Movement types:
|
||||
|
||||
+---------------+---------------------------------+----------------------+
|
||||
| Movement type | Uses | supported by |
|
||||
+===============+=================================+======================+
|
||||
| Fallback | Catch-all default movement type | All devices |
|
||||
+---------------+---------------------------------+----------------------+
|
||||
| Motion | Used for pointer motion | All devices |
|
||||
+---------------+---------------------------------+----------------------+
|
||||
| Scroll | Used for scroll movement | Mouse, Touchpad |
|
||||
+---------------+---------------------------------+----------------------+
|
||||
|
||||
If a user does not provide the fallback custom acceleration function, a
|
||||
flat acceleration function is used, i.e. no acceleration.
|
||||
|
||||
The fallback acceleration may be used for different types of movements, it is
|
||||
strongly recommended that this acceleration function is a constant function.
|
||||
|
||||
For example, a touchpad has multiple movement types: pointer
|
||||
movement, scroll movement, zoom movement (pinch), etc. As there is no separate
|
||||
movement type for zoom yet, zoom movement is accelerated using the Fallback
|
||||
acceleration function. Pointer movement is accelerated using the Motion
|
||||
acceleration function, and Scroll movement is accelerated using the Scroll
|
||||
acceleration function. If no Motion/Scroll acceleration function is set, the
|
||||
Fallback acceleration function is used.
|
||||
|
||||
When using custom acceleration profile, any calls to set the speed have no
|
||||
effect on the behavior of the custom acceleration function, but any future calls to
|
||||
get the speed will reflect the requested speed setting.
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ When you file a bug, please attach the following information:
|
|||
- the output from udevadm info, see :ref:`udev_info`.
|
||||
- the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s")
|
||||
- and the content of ``/sys/class/dmi/id/modalias``.
|
||||
- run ``libinput measure touchpad-size`` tool (see :ref:`absolute_coordinate_ranges_fix`)
|
||||
and verify that the ranges and sizes it prints match the touchpad (up to 5mm
|
||||
- run the ``touchpad-edge-detector`` tool (provided by libevdev) and verify
|
||||
that the ranges and sizes it prints match the touchpad (up to 5mm
|
||||
difference is ok)
|
||||
|
||||
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!
|
||||
- the vendor model number of the device (e.g. "Logitech M325")
|
||||
- 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
|
@ -156,23 +150,3 @@ See the **libinput_event_pointer_get_axis_source()** for details on the
|
|||
behavior of each scroll source.
|
||||
|
||||
See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
|
||||
|
||||
.. _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.
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
|
@ -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)"
|
||||
id="path13492"
|
||||
d="m 38.928571,67.914286 c 0,0 3.508205,24.810617 9.642857,57.857144 6.134651,33.04652 23.277202,79.68584 89.642852,90.35714" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:3.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
|
||||
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"
|
||||
|
|
@ -148,6 +155,13 @@
|
|||
id="tspan13876"
|
||||
y="63.628628"
|
||||
x="33.214291">A</tspan></text>
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:3.30527353px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="rect3490-2"
|
||||
width="65.272476"
|
||||
height="136.21509"
|
||||
x="321.22849"
|
||||
y="6.8830237" />
|
||||
<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"
|
||||
|
|
@ -177,6 +191,16 @@
|
|||
id="tspan13876-7-9"
|
||||
y="46.009491"
|
||||
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
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path4401"
|
||||
|
|
@ -184,6 +208,13 @@
|
|||
cy="24.53549"
|
||||
r="4.0658817"
|
||||
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
|
||||
width="248.87633"
|
||||
height="6.8111157"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<svg
|
||||
<svg
|
||||
width="600" height="480"
|
||||
viewBox="0 0 600 480"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -208,3 +208,4 @@
|
|||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
|
@ -1,228 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="229.5488mm"
|
||||
height="86.66362mm"
|
||||
viewBox="0 0 813.36188 307.07582"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
sodipodi:docname="tablet-area.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4294"
|
||||
id="linearGradient4300"
|
||||
x1="465.81339"
|
||||
y1="666.13727"
|
||||
x2="454.82117"
|
||||
y2="658.65521"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4294">
|
||||
<stop
|
||||
style="stop-color:#1a1a1a;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4296" />
|
||||
<stop
|
||||
style="stop-color:#808080;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4298" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="410.53571"
|
||||
inkscape:cy="188.39286"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer3"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="3072"
|
||||
inkscape:window-height="1659"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="tablet"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline"
|
||||
transform="translate(67.109152,-133.63374)">
|
||||
<g
|
||||
id="g4309"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"
|
||||
transform="translate(0,1.0715222)">
|
||||
<rect
|
||||
y="134.15933"
|
||||
x="75.787216"
|
||||
height="306.02466"
|
||||
width="522.19733"
|
||||
id="rect4136"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:1.05118;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:4.20473, 1.05118;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.748138;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.99255, 0.748138;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4140"
|
||||
width="357.34042"
|
||||
height="226.52563"
|
||||
x="199.33878"
|
||||
y="175.42407" />
|
||||
<rect
|
||||
y="175.72914"
|
||||
x="103.10225"
|
||||
height="22.142857"
|
||||
width="65"
|
||||
id="rect4142"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4148"
|
||||
width="65"
|
||||
height="22.142857"
|
||||
x="103.10225"
|
||||
y="203.72914" />
|
||||
<rect
|
||||
y="231.72913"
|
||||
x="103.10225"
|
||||
height="22.142857"
|
||||
width="65"
|
||||
id="rect4150"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="323.72913"
|
||||
x="103.10225"
|
||||
height="22.142857"
|
||||
width="65"
|
||||
id="rect4154"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4156"
|
||||
width="65"
|
||||
height="22.142857"
|
||||
x="103.10225"
|
||||
y="351.72913" />
|
||||
<circle
|
||||
r="22.98097"
|
||||
cy="287.06125"
|
||||
cx="135.61298"
|
||||
id="path4158"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<ellipse
|
||||
ry="12.608653"
|
||||
rx="11.5985"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.520431;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:2.08172, 0.520431;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="circle4160"
|
||||
cx="135.61298"
|
||||
cy="287.06125" />
|
||||
<rect
|
||||
y="379.72913"
|
||||
x="103.10225"
|
||||
height="22.142857"
|
||||
width="65"
|
||||
id="rect4162"
|
||||
style="opacity:0.92;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.989;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:3.956, 0.989;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="area">
|
||||
<rect
|
||||
style="display:inline;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.675728"
|
||||
id="rect1"
|
||||
width="131.51813"
|
||||
height="126.57689"
|
||||
x="326.15009"
|
||||
y="97.775696" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="display:inline;font-size:11.25px;fill:#a44d4d;fill-opacity:1;stroke:none;stroke-width:0.9375"
|
||||
x="261.92404"
|
||||
y="244.01244"
|
||||
id="text1"
|
||||
transform="translate(67.109152,-133.63374)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1"
|
||||
style="fill:#000000;stroke-width:0.9375"
|
||||
x="261.92404"
|
||||
y="244.01244">0/0</tspan></text>
|
||||
<path
|
||||
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.9375;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="m 259.17629,227.63135 v 7.63349"
|
||||
id="path1"
|
||||
transform="translate(67.109152,-133.63374)" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.9375;stroke-linecap:round;stroke-dasharray:none"
|
||||
d="m 262.99304,231.44809 h -7.63349"
|
||||
id="path2"
|
||||
transform="translate(67.109152,-133.63374)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="stylus"
|
||||
style="display:inline"
|
||||
transform="translate(67.109152,-133.63374)">
|
||||
<g
|
||||
id="g4304"
|
||||
transform="matrix(0.37129971,0.09948946,-0.09618892,0.35898192,319.19555,24.123239)"
|
||||
style="display:inline">
|
||||
<path
|
||||
sodipodi:nodetypes="czcc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4286"
|
||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4283"
|
||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
||||
style="display:inline;fill:#000000" />
|
||||
<path
|
||||
sodipodi:nodetypes="scccs"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4292"
|
||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
||||
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.8 KiB |
|
|
@ -1,198 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="104.05109mm"
|
||||
height="64.88131mm"
|
||||
viewBox="0 0 368.68495 229.89441"
|
||||
id="svg4321"
|
||||
version="1.1"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||
sodipodi:docname="tablet-eraser-button.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs4323">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4294"
|
||||
id="linearGradient4300"
|
||||
x1="465.81339"
|
||||
y1="666.13727"
|
||||
x2="454.82117"
|
||||
y2="658.65521"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4294">
|
||||
<stop
|
||||
style="stop-color:#1a1a1a;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4296" />
|
||||
<stop
|
||||
style="stop-color:#808080;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4298" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4294"
|
||||
id="linearGradient3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="465.81339"
|
||||
y1="666.13727"
|
||||
x2="454.82117"
|
||||
y2="658.65521" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="330.71429"
|
||||
inkscape:cy="144.28571"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="3072"
|
||||
inkscape:window-height="1659"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata4326">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-67.741956,-463.35919)">
|
||||
<g
|
||||
transform="matrix(0.35596319,-0.1450925,0.14027908,0.34415419,-98.897559,452.82709)"
|
||||
id="g4304"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
||||
id="path4286"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czcc" />
|
||||
<path
|
||||
style="display:inline;fill:#000000"
|
||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
||||
id="path4283"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
||||
id="path4292"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scccs" />
|
||||
</g>
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-693.18524"
|
||||
x="67.81031"
|
||||
height="16.036251"
|
||||
width="168.54825"
|
||||
id="rect4136"
|
||||
style="fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-693.18524"
|
||||
x="267.8103"
|
||||
height="16.036251"
|
||||
width="168.54825"
|
||||
id="rect5709"
|
||||
style="opacity:1;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
id="text5713"
|
||||
y="559.10828"
|
||||
x="296.20877"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="559.10828"
|
||||
x="296.20877"
|
||||
id="tspan5715"
|
||||
sodipodi:role="line"
|
||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Eraser</tspan></text>
|
||||
<text
|
||||
id="text1"
|
||||
y="559.10828"
|
||||
x="109.0436"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="559.10828"
|
||||
x="109.0436"
|
||||
id="tspan1"
|
||||
sodipodi:role="line"
|
||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Pen</tspan></text>
|
||||
<g
|
||||
transform="matrix(0.35596319,-0.1450925,0.14027908,0.34415419,117.39708,452.82709)"
|
||||
id="g3"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
||||
id="path1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czcc" />
|
||||
<path
|
||||
style="display:inline;fill:#000000"
|
||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
||||
id="path2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
||||
id="path3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scccs" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.21797128,-0.07136846,0.05329769,-0.25512499,403.9107,823.07273)"
|
||||
id="g3663-9-8">
|
||||
<path
|
||||
d="m 388.57143,893.79076 -57.14285,-130 c 0,0 -30.0247,-58.84827 4.28571,-70.00001 27.07438,-8.79984 37.32196,9.59496 40,14.64286 27.54455,51.91936 84.64285,173.21429 84.64285,173.21429 h -0.71428 z"
|
||||
id="path2820-6-7"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 360.32021,827.78041 c -15.74169,-35.7991 -29.44655,-66.92657 -30.45523,-69.17214 -7.08929,-15.78239 -10.8761,-32.88254 -9.6176,-43.43026 1.39575,-11.69796 7.19746,-18.50389 18.22574,-21.38044 5.18218,-1.35169 8.54724,-1.76827 12.41155,-1.53649 4.43642,0.26609 6.95929,0.93715 11.03011,2.93391 3.93491,1.9301 8.0085,5.56248 10.68932,9.53159 3.68818,5.46055 26.56068,50.9623 49.57778,98.62829 16.60192,34.38082 37.06388,77.41994 36.89013,77.59369 -0.13286,0.13286 -69.01932,11.92114 -69.66286,11.92114 -0.27909,0 -12.00972,-26.24842 -29.08894,-65.08929 z"
|
||||
id="path2824-1-6"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffccaa;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 334.75785,756.75053 c -7.08929,-15.78239 -10.28437,-26.89033 -9.02587,-37.43805 1.39575,-11.69796 5.8085,-16.73613 16.83678,-19.61268 12.44766,-3.59459 20.03902,-1.91353 27.39013,8.75815 11.42622,25.66382 13.40166,29.05484 15.06365,35.48866 -0.13286,0.13286 -42.89663,15.49027 -44.57776,16.18518 -1.72922,0.71479 -4.94789,-2.09377 -5.68693,-3.38126 z"
|
||||
id="path2824-7-1-7"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.92;fill:#ffe6d5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
|
@ -1,179 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="104.05109mm"
|
||||
height="64.88131mm"
|
||||
viewBox="0 0 368.68495 229.89441"
|
||||
id="svg4321"
|
||||
version="1.1"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||
sodipodi:docname="tablet-eraser-invert.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs4323">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4294"
|
||||
id="linearGradient4300"
|
||||
x1="465.81339"
|
||||
y1="666.13727"
|
||||
x2="454.82117"
|
||||
y2="658.65521"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4294">
|
||||
<stop
|
||||
style="stop-color:#1a1a1a;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4296" />
|
||||
<stop
|
||||
style="stop-color:#808080;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4298" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4294"
|
||||
id="linearGradient5721"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="465.81339"
|
||||
y1="666.13727"
|
||||
x2="454.82117"
|
||||
y2="658.65521" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="330.71429"
|
||||
inkscape:cy="144.28571"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="3072"
|
||||
inkscape:window-height="1659"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata4326">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-67.741956,-463.35919)">
|
||||
<g
|
||||
transform="matrix(0.35596319,-0.1450925,0.14027908,0.34415419,-98.897559,452.82709)"
|
||||
id="g4304"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
||||
id="path4286"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czcc" />
|
||||
<path
|
||||
style="display:inline;fill:#000000"
|
||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
||||
id="path4283"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4300);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
||||
id="path4292"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scccs" />
|
||||
</g>
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-693.18524"
|
||||
x="67.81031"
|
||||
height="16.036251"
|
||||
width="168.54825"
|
||||
id="rect4136"
|
||||
style="fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<g
|
||||
transform="matrix(-0.36104723,0.13193379,-0.12755691,-0.34906957,644.73068,698.04111)"
|
||||
id="g5701"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="display:inline;fill:#cccccc;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 387.83544,799.76093 c -1.1128,3.61694 -3.2211,13.05163 -1.08543,14.07769 2.13567,1.02606 7.81039,-3.72162 10.99756,-6.69095 z"
|
||||
id="path5703"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czcc" />
|
||||
<path
|
||||
style="display:inline;fill:#000000"
|
||||
d="m 392.64431,804.79039 c -8.52094,-5.90399 -8.49394,-11.01546 0.22879,-43.30647 1.03999,-3.85 2.46829,-9.67602 3.17399,-12.9467 0.99731,-4.62219 2.39455,-7.29497 6.27321,-12 2.74456,-3.32932 5.25157,-6.2783 5.57113,-6.5533 40.78433,-60.97488 80.48307,-125.1652 118.27253,-184 9.86283,-15.675 26.59424,-42.225 37.18089,-59 10.58666,-16.775 34.01422,-53.9 52.06125,-82.5 18.04703,-28.6 35.04505,-55.31677 37.77338,-59.37059 l 4.9606,-7.3706 4.1828,0.57332 c 4.16371,0.5707 4.19706,0.54958 7.30887,-4.62941 3.75631,-6.2516 8.82067,-11.57582 12.2516,-12.88026 5.99391,-2.27888 14.03303,2.9506 14.03303,9.12854 0,3.90203 -2.51704,10.62127 -6.02878,16.09385 -1.63417,2.54664 -2.97122,4.85949 -2.97122,5.13969 0,0.28019 0.9,1.54715 2,2.81546 2.28453,2.63408 2.47267,4.21918 0.86833,7.31574 -1.28218,2.47476 -26.61383,45.18798 -55.85724,94.18426 -10.83283,18.15 -25.72943,43.1137 -33.10357,55.47489 -7.37413,12.3612 -13.69273,23.17153 -14.04131,24.02297 -0.34859,0.85144 -7.50972,12.78774 -15.91363,26.52511 -15.54138,25.40455 -32.24417,52.9052 -70.74345,116.47703 -40.26028,66.47968 -43.66308,72.46026 -49.21634,86.5 -1.74036,4.4 -3.92035,8.675 -4.8444,9.5 -0.92405,0.825 -4.36246,3.75 -7.6409,6.5 -3.27845,2.75 -9.57132,8.3067 -13.98415,12.34823 -10.62726,9.73304 -16.99729,13.87361 -22.52334,14.64034 -3.99187,0.55386 -5.03885,0.251 -9.27207,-2.6821 z"
|
||||
id="path5705"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ssssccssscsssssssssssssssssss" />
|
||||
<path
|
||||
style="fill:url(#linearGradient5721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 450.89044,688.88586 c 8.71518,5.62513 45.74035,-59.18436 43.57923,-75.43494 l -7.07107,-6.56599 c -29.93081,25.86352 -47.78438,74.72281 -47.78438,74.72281 z"
|
||||
id="path5707"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scccs" />
|
||||
</g>
|
||||
<rect
|
||||
transform="scale(1,-1)"
|
||||
y="-693.18524"
|
||||
x="267.8103"
|
||||
height="16.036251"
|
||||
width="168.54825"
|
||||
id="rect5709"
|
||||
style="opacity:1;fill:#4d4d4d;fill-opacity:1;stroke:#4d4d4d;stroke-width:0.136709;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:0.546834, 0.136709;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
id="text5713"
|
||||
y="559.10828"
|
||||
x="296.20877"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="559.10828"
|
||||
x="296.20877"
|
||||
id="tspan5715"
|
||||
sodipodi:role="line"
|
||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Eraser</tspan></text>
|
||||
<text
|
||||
id="text1"
|
||||
y="559.10828"
|
||||
x="109.0436"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="559.10828"
|
||||
x="109.0436"
|
||||
id="tspan1"
|
||||
sodipodi:role="line"
|
||||
style="font-size:15px;line-height:1.25;font-family:sans-serif">Pen</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.4 KiB |
|
|
@ -4,9 +4,9 @@
|
|||
Switches
|
||||
==============================================================================
|
||||
|
||||
libinput supports the lid, tablet-mode, and keypad slide switches. Unlike
|
||||
button events that come in press and release pairs, switches are usually
|
||||
toggled once and left at the setting for an extended period of time.
|
||||
libinput supports the lid and tablet-mode switches. Unlike button events
|
||||
that come in press and release pairs, switches are usually toggled once and
|
||||
left at the setting for an extended period of time.
|
||||
|
||||
Only some switches are handled by libinput, see **libinput_switch** for a
|
||||
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
|
||||
notifications are sent and the device appears as enabled at all times.
|
||||
|
||||
.. _switches_keypad_slide:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Keypad slide switch handling
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Where available, libinput listens to devices providing a keypad slide switch.
|
||||
This is usually available on devices that have an always-attached physical
|
||||
keyboard which can slide under the screen. An example of such a device is the
|
||||
Nokia N900.
|
||||
|
||||
The event sent by the kernel is ``EV_SW`` ``SW_KEYPAD_SLIDE`` and is provided
|
||||
as **LIBINPUT_SWITCH_KEYPAD_SLIDE**. The keypad slide switch does not cause any
|
||||
other input devices to be enabled nor disabled in response, since on some
|
||||
devices the kernel event is sent while the keyboard is partially visible and
|
||||
thus usable.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,6 @@ the ``libinput record`` tool.
|
|||
- **resolution** indicates that the device does not have a resolution set
|
||||
for the x and y axes. This can be fixed with a hwdb entry, locate and read
|
||||
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
|
||||
`systemd <https://github.com/systemd/systemd/>`__.
|
||||
|
|
|
|||
|
|
@ -180,8 +180,8 @@ specifically:
|
|||
capable of detection distances,
|
||||
- pressure offset is only detected if the distance between the tool and the
|
||||
tablet is high enough,
|
||||
- pressure offset is only used if it is 50% or less of the pressure range
|
||||
available to the tool. A pressure offset higher than 50% indicates either
|
||||
- pressure offset is only used if it is 20% or less of the pressure range
|
||||
available to the tool. A pressure offset higher than 20% indicates either
|
||||
a misdetection or a tool that should be replaced, and
|
||||
- if a pressure value less than the current pressure offset is seen, the
|
||||
offset resets to that value.
|
||||
|
|
@ -189,52 +189,6 @@ specifically:
|
|||
Pressure offsets are not detected on **LIBINPUT_TABLET_TOOL_TYPE_MOUSE**
|
||||
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:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
|
@ -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.
|
||||
The exact behavior is device-dependent.
|
||||
|
||||
.. _tablet-area:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Tablet area
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
External tablet devices such as e.g. the Wacom Intuos series can be configured
|
||||
to reduce the available logical input area. Typically the logical input area
|
||||
is equivalent to the physical input area but it can be reduced with the
|
||||
**libinput_device_config_area_set_rectangle()** call. Once reduced, input
|
||||
events outside the logical input area are ignored and the logical input area
|
||||
acts as if it represented the extents of the physical tablet.
|
||||
|
||||
.. figure:: tablet-area.svg
|
||||
:align: center
|
||||
|
||||
Tablet area configuration example
|
||||
|
||||
In the image above, the area is set to the rectangle 0.25/0.25 to 0.5/0.75.
|
||||
Even though the tool is roughly at the physical position ``0.5 * width`` and
|
||||
``0.75 * height``, the return values of
|
||||
**libinput_event_tablet_tool_get_x_transformed()** and
|
||||
**libinput_event_tablet_tool_get_y_transformed()** would be close to the
|
||||
maximum provided in this call.
|
||||
|
||||
The size of the tablet reported by **libinput_device_get_size()** always reflects
|
||||
the physical area, not the logical area.
|
||||
|
||||
.. _tablet-eraser-button:
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Tablet eraser buttons
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Tablet tools come in a variety of forms but the most common one is a
|
||||
pen-like tool. Some of these pen-like tools have a virtual eraser at the
|
||||
tip of the tool - inverting the tool brings the eraser into proximity.
|
||||
|
||||
.. figure:: tablet-eraser-invert.svg
|
||||
:align: center
|
||||
|
||||
An pen-like tool used as pen and as eraser by inverting it
|
||||
|
||||
Having an eraser as a separate tool is beneficial in many applications as the
|
||||
eraser tool can be assigned different functionality (colors, paint tools, etc.)
|
||||
that is easily available.
|
||||
|
||||
However, a large proportion of tablet pens have an "eraser button". By
|
||||
pressing the button the pen switches to be an eraser tool.
|
||||
On the data level this is not done via a button event, instead the firmware
|
||||
will pretend the pen tool going out of proximity and the eraser coming
|
||||
into proximity immediately after - as if the tool was physically inverted.
|
||||
|
||||
.. figure:: tablet-eraser-button.svg
|
||||
:align: center
|
||||
|
||||
An pen-like tool used as pen and as eraser by pressing the eraser button
|
||||
|
||||
Microsoft mandates this behavior (see
|
||||
`Windows Pen States <https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states>`_
|
||||
for details) and thus the overwhelming majority of devices will have
|
||||
an eraser button that virtually inverts the pen.
|
||||
|
||||
Enforcing an eraser button means that users have one button less on the
|
||||
stylus that they would have otherwise. For some users the eraser button
|
||||
is in an inconvenient location, others don't want an eraser button at all.
|
||||
|
||||
libinput provides an eraser button configuration that allows disabling the
|
||||
eraser button and turning it into a normal button event. If the eraser button
|
||||
is disabled, pressing that button will generate a normal tablet tool button
|
||||
event.
|
||||
|
||||
This configuration is only available on pens with an eraser button, not on
|
||||
with an invert-type eraser.
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@ Tap-to-click behaviour
|
|||
finger touch down/up sequence maps into a button click. This is most
|
||||
commonly used on touchpads, but may be available on other devices.
|
||||
|
||||
libinput implements tapping for one, two, and three fingers, where supported by
|
||||
the hardware, and maps those taps into a left, right, and middle button click,
|
||||
respectively. This mapping can be switched to left, middle and right through
|
||||
configuration. Not all devices support three fingers, libinput will support
|
||||
tapping up to whatever is supported by the hardware. libinput does not support
|
||||
four-finger taps or any tapping with more than four fingers, even though some
|
||||
hardware can distinguish between that many fingers.
|
||||
libinput implements tapping for one, two, and three fingers, where supported
|
||||
by the hardware, and maps those taps into a left, right, and middle button
|
||||
click, respectively. Not all devices support three fingers, libinput will
|
||||
support tapping up to whatever is supported by the hardware. libinput does
|
||||
not support four-finger taps or any tapping with more than four fingers,
|
||||
even though some hardware can distinguish between that many fingers.
|
||||
|
||||
.. _tapping_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
|
||||
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
|
||||
**libinput_device_config_tap_set_enabled()** for details.
|
||||
|
||||
|
|
@ -60,13 +55,11 @@ tap-and-drag enabled by default.
|
|||
single-finger drag.
|
||||
|
||||
Also optional is a feature called "drag lock". With drag lock disabled, lifting
|
||||
the finger will stop any drag process. When enabled, the drag
|
||||
process continues even after lifting a finger but can be ended
|
||||
with an additional tap. If timeout-based drag-locks are enabled
|
||||
the drag process will also automatically end once the finger has
|
||||
been lifted for an implementation-specific timeout. Drag lock can be
|
||||
enabled and disabled with **libinput_device_config_tap_set_drag_lock_enabled()**.
|
||||
Note that drag lock only applies if tap-and-drag is enabled.
|
||||
the finger will stop any drag process. When enabled, libinput will ignore a
|
||||
finger up event during a drag process, provided the finger is set down again
|
||||
within a implementation-specific timeout. Drag lock can be enabled and
|
||||
disabled with **libinput_device_config_tap_set_drag_lock_enabled()**.
|
||||
Note that drag lock only applies if tap-and-drag is be enabled.
|
||||
|
||||
.. figure:: tap-n-drag.svg
|
||||
: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,
|
||||
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
|
||||
drag while the first is held in-place.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ must pass for any merge request. These tests are invoked by calling
|
|||
``meson test -C builddir`` (or ``ninja test``). The ``libinput-test-suite`` is
|
||||
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:
|
||||
|
||||
|
|
@ -207,7 +208,7 @@ verification of distribution composes.
|
|||
To configure libinput to install the tests, use the ``-Dinstall-tests=true``
|
||||
meson option::
|
||||
|
||||
$ meson setup builddir -Dtests=true -Dinstall-tests=true <other options>
|
||||
$ meson builddir -Dtests=true -Dinstall-tests=true <other options>
|
||||
|
||||
.. _test-meson-suites:
|
||||
|
||||
|
|
|
|||
|
|
@ -42,5 +42,3 @@ Once the timeout expires at t4, libinput generates an event of
|
|||
|
||||
Thus, the caller gets events with timestamps in the order t3, t1, t2,
|
||||
despite t3 > t2 > t1.
|
||||
|
||||
libinput timestamps use **CLOCK_MONOTONIC**.
|
||||
|
|
|
|||
|
|
@ -11,10 +11,8 @@ available in the **libinput(1)** man page.
|
|||
|
||||
The most common tools used are:
|
||||
|
||||
- ``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>`
|
||||
- ``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,
|
||||
see :ref:`here <libinput-debug-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
|
||||
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
|
||||
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. ::
|
||||
|
||||
$ 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`
|
||||
for more information.
|
||||
|
|
|
|||
|
|
@ -53,38 +53,31 @@ Example output of the tool is below: ::
|
|||
with --touch-thresholds=down:up using observed pressure values.
|
||||
See --help for more options.
|
||||
|
||||
Interactive keys:
|
||||
q/a - decrease/increase down threshold
|
||||
w/s - decrease/increase up threshold
|
||||
e/d - decrease/increase palm threshold
|
||||
r/f - decrease/increase thumb threshold
|
||||
|
||||
Press Ctrl+C to exit
|
||||
|
||||
┌───────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Touch │ down │ up │ palm │ thumb │ min │ max │ p │ avg │ median │
|
||||
├───────────────────────────────────────────────────────────────────────────────┤
|
||||
│ 178 │ x │ x │ │ │ 75 │ 75 │ 0 │ 75 │ 75 │
|
||||
│ 179 │ x │ x │ │ │ 35 │ 88 │ 0 │ 77 │ 81 │
|
||||
│ 180 │ x │ x │ │ x │ 65 │ 113 │ 0 │ 98 │ 98 │
|
||||
│ 181 │ x │ x │ │ x │ 50 │ 101 │ 0 │ 86 │ 90 │
|
||||
│ 182 │ x │ x │ │ │ 40 │ 80 │ 0 │ 66 │ 70 │
|
||||
│ 183 │ x │ │ │ │ 43 │ 78 │ 78 │ │
|
||||
│ Thresh │ 70 │ 60 │ 130 │ 100 │
|
||||
+-------------------------------------------------------------------------------+
|
||||
| Thresh | 70 | 60 | 130 | 100 | |
|
||||
+-------------------------------------------------------------------------------+
|
||||
| Touch | down | up | palm | thumb | min | max | p | avg | median |
|
||||
+-------------------------------------------------------------------------------+
|
||||
| 178 | x | x | | | 75 | 75 | 0 | 75 | 75 |
|
||||
| 179 | x | x | | | 35 | 88 | 0 | 77 | 81 |
|
||||
| 180 | x | x | | x | 65 | 113 | 0 | 98 | 98 |
|
||||
| 181 | x | x | | x | 50 | 101 | 0 | 86 | 90 |
|
||||
| 182 | x | x | | | 40 | 80 | 0 | 66 | 70 |
|
||||
| 183 | x | | | | 43 | 78 | 78 | |
|
||||
...
|
||||
|
||||
|
||||
The example output shows five completed touch sequences and one ongoing one.
|
||||
For each, the respective minimum and maximum pressure values are printed as
|
||||
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),
|
||||
two of the sequences were considered thumbs. This is an interactive tool and
|
||||
its output may change frequently. Refer to the
|
||||
**libinput-measure-touchpad-pressure(1)** man page for more details.
|
||||
considered logically down at some point, two of the sequences were considered
|
||||
thumbs. This is an interactive tool and its output may change frequently. Refer
|
||||
to the **libinput-measure-touchpad-pressure(1)** man page for more details.
|
||||
|
||||
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
|
||||
the keys q/a, w/s, e/d and r/f or specify the 'logically down'
|
||||
narrow down on the best values for your device, specify the 'logically down'
|
||||
and 'logically up' pressure thresholds with the ``--touch-thresholds``
|
||||
argument: ::
|
||||
|
||||
|
|
@ -107,10 +100,8 @@ Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
|
|||
[Touchpad pressure override]
|
||||
MatchUdevType=touchpad
|
||||
MatchName=*SynPS/2 Synaptics TouchPad
|
||||
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
|
||||
AttrPressureRange=10:8
|
||||
AttrPalmPressureThreshold=150
|
||||
AttrThumbPressureThreshold=100
|
||||
|
||||
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``
|
||||
|
|
@ -124,7 +115,7 @@ and product name (pn).
|
|||
Once in place, run the following command to verify the quirk is valid and
|
||||
works for your device: ::
|
||||
|
||||
$ sudo libinput quirks list /dev/input/event10
|
||||
$ sudo libinput list-quirks /dev/input/event10
|
||||
AttrPressureRange=10:8
|
||||
|
||||
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]
|
||||
MatchUdevType=touchpad
|
||||
MatchName=*SynPS/2 Synaptics TouchPad
|
||||
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadX230:*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX230*
|
||||
AttrTouchSizeRange=10:8
|
||||
|
||||
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
|
||||
works for your device: ::
|
||||
|
||||
$ sudo libinput quirks list /dev/input/event10
|
||||
$ sudo libinput list-quirks /dev/input/event10
|
||||
AttrTouchSizeRange=10:8
|
||||
|
||||
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
|
||||
bug" to get the thresholds into the repository.
|
||||
|
||||
|
|
|
|||
|
|
@ -56,3 +56,4 @@ these axes are supposed to be mapped, few devices forward reliable
|
|||
information. libinput uses these values together with a device-specific
|
||||
:ref:`device-quirks` entry. In other words, touch size detection does not work
|
||||
unless a device quirk is present for the device.
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ other properties.
|
|||
Number of buttons
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
.. _touchpads_buttons_phys:
|
||||
.. _touchapds_buttons_phys:
|
||||
|
||||
..............................................................................
|
||||
Physically separate buttons
|
||||
|
|
@ -57,7 +57,7 @@ property.
|
|||
.. _touchpads_buttons_forcepads:
|
||||
|
||||
..............................................................................
|
||||
Forcepads/Pressurepads
|
||||
Forcepads
|
||||
..............................................................................
|
||||
|
||||
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
|
||||
click or be co-opted for other tasks.
|
||||
|
||||
Forcepads are also called pressurepads or haptic touchpads.
|
||||
|
||||
.. _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
|
||||
slots thus equals the number of simultaneous touches a device can track.
|
||||
|
||||
.. _touchpads_touch_st:
|
||||
.. _touchapds_touch_st:
|
||||
|
||||
..............................................................................
|
||||
Single-touch touchpads
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ installed.
|
|||
$ cd path/to/libinput.git
|
||||
|
||||
# Use an approximate multiplier in the quirks file
|
||||
$ cat > quirks/99-trackpoint-override.quirks <<EOF
|
||||
$ cat > quirks/99-trackpont-override.quirks <<EOF
|
||||
[Trackpoint Override]
|
||||
MatchUdevType=pointingstick
|
||||
AttrTrackpointMultiplier=1.0
|
||||
|
|
@ -131,7 +131,7 @@ variation of the following is sufficient:
|
|||
[Trackpoint Override]
|
||||
MatchUdevType=pointingstick
|
||||
MatchName=*TPPS/2 IBM TrackPoint*
|
||||
MatchDMIModalias=dmi:*:svnLENOVO:*:pvrThinkPadT440p:*
|
||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p*
|
||||
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
|
||||
`the 1.11.0 documentation <https://wayland.freedesktop.org/libinput/doc/1.11.0/trackpoints.html#trackpoint_range_measure>`_
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ decreases, the delta decrease first, then the reporting rate until the
|
|||
trackpoint is in a neutral state and no events are reported. Trackpoint data
|
||||
is hard to generalize, see
|
||||
`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.
|
||||
|
||||
.. 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
|
||||
<trackpoint_multiplier>` to normalize the trackpoint input data.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,3 @@ Troubleshooting
|
|||
touchpad-pressure-debugging.rst
|
||||
trackpoint-configuration.rst
|
||||
tablet-debugging.rst
|
||||
incorrectly-enabled-hires.rst
|
||||
clickpad-with-right-button.rst
|
||||
ignoring-devices.rst
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ Handled device types
|
|||
- Mice
|
||||
- Keyboards
|
||||
- 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
|
||||
- :ref:`Trackpoints`
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
|
||||
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
|
|
@ -279,8 +278,7 @@
|
|||
#define KEY_PAUSECD 201
|
||||
#define KEY_PROG3 202
|
||||
#define KEY_PROG4 203
|
||||
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
||||
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
||||
#define KEY_DASHBOARD 204 /* AL Dashboard */
|
||||
#define KEY_SUSPEND 205
|
||||
#define KEY_CLOSE 206 /* AC Close */
|
||||
#define KEY_PLAY 207
|
||||
|
|
@ -517,10 +515,6 @@
|
|||
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
||||
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
||||
#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_EOS 0x1c1
|
||||
|
|
@ -548,7 +542,6 @@
|
|||
#define KEY_FN_F 0x1e2
|
||||
#define KEY_FN_S 0x1e3
|
||||
#define KEY_FN_B 0x1e4
|
||||
#define KEY_FN_RIGHT_SHIFT 0x1e5
|
||||
|
||||
#define KEY_BRL_DOT1 0x1f1
|
||||
#define KEY_BRL_DOT2 0x1f2
|
||||
|
|
@ -602,14 +595,8 @@
|
|||
#define BTN_DPAD_LEFT 0x222
|
||||
#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_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_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
||||
|
|
@ -620,29 +607,10 @@
|
|||
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
||||
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
||||
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
||||
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
||||
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
||||
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
|
||||
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
|
||||
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
|
||||
|
||||
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
||||
#define KEY_BRIGHTNESS_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_NEXT 0x261
|
||||
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
||||
|
|
@ -687,27 +655,6 @@
|
|||
/* Select an area of screen to be copied */
|
||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
||||
|
||||
/* Move the focus to the next or previous user controllable element within a UI container */
|
||||
#define KEY_NEXT_ELEMENT 0x27b
|
||||
#define KEY_PREVIOUS_ELEMENT 0x27c
|
||||
|
||||
/* Toggle Autopilot engagement */
|
||||
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
|
||||
|
||||
/* Shortcut Keys */
|
||||
#define KEY_MARK_WAYPOINT 0x27e
|
||||
#define KEY_SOS 0x27f
|
||||
#define KEY_NAV_CHART 0x280
|
||||
#define KEY_FISHING_CHART 0x281
|
||||
#define KEY_SINGLE_RANGE_RADAR 0x282
|
||||
#define KEY_DUAL_RANGE_RADAR 0x283
|
||||
#define KEY_RADAR_OVERLAY 0x284
|
||||
#define KEY_TRADITIONAL_SONAR 0x285
|
||||
#define KEY_CLEARVU_SONAR 0x286
|
||||
#define KEY_SIDEVU_SONAR 0x287
|
||||
#define KEY_NAV_INFO 0x288
|
||||
#define KEY_BRIGHTNESS_MENU 0x289
|
||||
|
||||
/*
|
||||
* Some keyboards have keys which do not have a defined meaning, these keys
|
||||
* are intended to be programmed / bound to macros by the user. For most
|
||||
|
|
@ -783,9 +730,6 @@
|
|||
#define KEY_KBD_LCD_MENU4 0x2bb
|
||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
||||
|
||||
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
|
||||
#define KEY_PERFORMANCE 0x2bd
|
||||
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
|
|
@ -890,7 +834,6 @@
|
|||
#define ABS_TOOL_WIDTH 0x1c
|
||||
|
||||
#define ABS_VOLUME 0x20
|
||||
#define ABS_PROFILE 0x21
|
||||
|
||||
#define ABS_MISC 0x28
|
||||
|
||||
|
|
@ -946,8 +889,7 @@
|
|||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
|
||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
||||
#define SW_MAX 0x11
|
||||
#define SW_MAX 0x10
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */
|
||||
#define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */
|
||||
#define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */
|
||||
#define INPUT_PROP_PRESSUREPAD 0x07 /* pressure triggers clicks */
|
||||
|
||||
#define INPUT_PROP_MAX 0x1f
|
||||
#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
|
||||
|
|
@ -279,8 +278,7 @@
|
|||
#define KEY_PAUSECD 201
|
||||
#define KEY_PROG3 202
|
||||
#define KEY_PROG4 203
|
||||
#define KEY_ALL_APPLICATIONS 204 /* AC Desktop Show All Applications */
|
||||
#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
|
||||
#define KEY_DASHBOARD 204 /* AL Dashboard */
|
||||
#define KEY_SUSPEND 205
|
||||
#define KEY_CLOSE 206 /* AC Close */
|
||||
#define KEY_PLAY 207
|
||||
|
|
@ -517,10 +515,6 @@
|
|||
#define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */
|
||||
#define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */
|
||||
#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_EOS 0x1c1
|
||||
|
|
@ -548,7 +542,6 @@
|
|||
#define KEY_FN_F 0x1e2
|
||||
#define KEY_FN_S 0x1e3
|
||||
#define KEY_FN_B 0x1e4
|
||||
#define KEY_FN_RIGHT_SHIFT 0x1e5
|
||||
|
||||
#define KEY_BRL_DOT1 0x1f1
|
||||
#define KEY_BRL_DOT2 0x1f2
|
||||
|
|
@ -602,14 +595,8 @@
|
|||
#define BTN_DPAD_LEFT 0x222
|
||||
#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_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_TASKMANAGER 0x241 /* AL Task/Project Manager */
|
||||
|
|
@ -620,29 +607,10 @@
|
|||
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
|
||||
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
|
||||
#define KEY_KBD_LAYOUT_NEXT 0x248 /* AC Next Keyboard Layout Select */
|
||||
#define KEY_EMOJI_PICKER 0x249 /* Show/hide emoji picker (HUTRR101) */
|
||||
#define KEY_DICTATE 0x24a /* Start or Stop Voice Dictation Session (HUTRR99) */
|
||||
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
|
||||
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
|
||||
#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
|
||||
#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
|
||||
|
||||
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
|
||||
#define KEY_BRIGHTNESS_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_NEXT 0x261
|
||||
#define KEY_KBDINPUTASSIST_PREVGROUP 0x262
|
||||
|
|
@ -687,27 +655,6 @@
|
|||
/* Select an area of screen to be copied */
|
||||
#define KEY_SELECTIVE_SCREENSHOT 0x27a
|
||||
|
||||
/* Move the focus to the next or previous user controllable element within a UI container */
|
||||
#define KEY_NEXT_ELEMENT 0x27b
|
||||
#define KEY_PREVIOUS_ELEMENT 0x27c
|
||||
|
||||
/* Toggle Autopilot engagement */
|
||||
#define KEY_AUTOPILOT_ENGAGE_TOGGLE 0x27d
|
||||
|
||||
/* Shortcut Keys */
|
||||
#define KEY_MARK_WAYPOINT 0x27e
|
||||
#define KEY_SOS 0x27f
|
||||
#define KEY_NAV_CHART 0x280
|
||||
#define KEY_FISHING_CHART 0x281
|
||||
#define KEY_SINGLE_RANGE_RADAR 0x282
|
||||
#define KEY_DUAL_RANGE_RADAR 0x283
|
||||
#define KEY_RADAR_OVERLAY 0x284
|
||||
#define KEY_TRADITIONAL_SONAR 0x285
|
||||
#define KEY_CLEARVU_SONAR 0x286
|
||||
#define KEY_SIDEVU_SONAR 0x287
|
||||
#define KEY_NAV_INFO 0x288
|
||||
#define KEY_BRIGHTNESS_MENU 0x289
|
||||
|
||||
/*
|
||||
* Some keyboards have keys which do not have a defined meaning, these keys
|
||||
* are intended to be programmed / bound to macros by the user. For most
|
||||
|
|
@ -783,9 +730,6 @@
|
|||
#define KEY_KBD_LCD_MENU4 0x2bb
|
||||
#define KEY_KBD_LCD_MENU5 0x2bc
|
||||
|
||||
/* Performance Boost key (Alienware)/G-Mode key (Dell) */
|
||||
#define KEY_PERFORMANCE 0x2bd
|
||||
|
||||
#define BTN_TRIGGER_HAPPY 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY1 0x2c0
|
||||
#define BTN_TRIGGER_HAPPY2 0x2c1
|
||||
|
|
@ -890,7 +834,6 @@
|
|||
#define ABS_TOOL_WIDTH 0x1c
|
||||
|
||||
#define ABS_VOLUME 0x20
|
||||
#define ABS_PROFILE 0x21
|
||||
|
||||
#define ABS_MISC 0x28
|
||||
|
||||
|
|
@ -946,8 +889,7 @@
|
|||
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
|
||||
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
|
||||
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
|
||||
#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
|
||||
#define SW_MAX 0x11
|
||||
#define SW_MAX 0x10
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@
|
|||
|| (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
|
||||
*/
|
||||
#define __VALGRIND_MAJOR__ 3
|
||||
#define __VALGRIND_MINOR__ 18
|
||||
#define __VALGRIND_MINOR__ 15
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
|
@ -110,8 +110,6 @@
|
|||
*/
|
||||
#undef PLAT_x86_darwin
|
||||
#undef PLAT_amd64_darwin
|
||||
#undef PLAT_x86_freebsd
|
||||
#undef PLAT_amd64_freebsd
|
||||
#undef PLAT_x86_win32
|
||||
#undef PLAT_amd64_win64
|
||||
#undef PLAT_x86_linux
|
||||
|
|
@ -124,7 +122,6 @@
|
|||
#undef PLAT_s390x_linux
|
||||
#undef PLAT_mips32_linux
|
||||
#undef PLAT_mips64_linux
|
||||
#undef PLAT_nanomips_linux
|
||||
#undef PLAT_x86_solaris
|
||||
#undef PLAT_amd64_solaris
|
||||
|
||||
|
|
@ -133,17 +130,12 @@
|
|||
# define PLAT_x86_darwin 1
|
||||
#elif defined(__APPLE__) && defined(__x86_64__)
|
||||
# define PLAT_amd64_darwin 1
|
||||
#elif defined(__FreeBSD__) && defined(__i386__)
|
||||
# define PLAT_x86_freebsd 1
|
||||
#elif defined(__FreeBSD__) && defined(__amd64__)
|
||||
# define PLAT_amd64_freebsd 1
|
||||
#elif (defined(__MINGW32__) && defined(__i386__)) \
|
||||
#elif (defined(__MINGW32__) && !defined(__MINGW64__)) \
|
||||
|| defined(__CYGWIN32__) \
|
||||
|| (defined(_WIN32) && defined(_M_IX86))
|
||||
# define PLAT_x86_win32 1
|
||||
#elif (defined(__MINGW32__) && defined(__x86_64__)) \
|
||||
|| (defined(_WIN32) && defined(_M_X64))
|
||||
/* __MINGW32__ and _WIN32 are defined in 64 bit mode as well. */
|
||||
#elif defined(__MINGW64__) \
|
||||
|| (defined(_WIN64) && defined(_M_X64))
|
||||
# define PLAT_amd64_win64 1
|
||||
#elif defined(__linux__) && defined(__i386__)
|
||||
# define PLAT_x86_linux 1
|
||||
|
|
@ -165,10 +157,8 @@
|
|||
# define PLAT_s390x_linux 1
|
||||
#elif defined(__linux__) && defined(__mips__) && (__mips==64)
|
||||
# define PLAT_mips64_linux 1
|
||||
#elif defined(__linux__) && defined(__mips__) && (__mips==32)
|
||||
#elif defined(__linux__) && defined(__mips__) && (__mips!=64)
|
||||
# define PLAT_mips32_linux 1
|
||||
#elif defined(__linux__) && defined(__nanomips__)
|
||||
# define PLAT_nanomips_linux 1
|
||||
#elif defined(__sun) && defined(__i386__)
|
||||
# define PLAT_x86_solaris 1
|
||||
#elif defined(__sun) && defined(__x86_64__)
|
||||
|
|
@ -264,7 +254,7 @@
|
|||
|
||||
#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
|
||||
|| (defined(PLAT_x86_win32) && defined(__GNUC__)) \
|
||||
|| defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd)
|
||||
|| defined(PLAT_x86_solaris)
|
||||
|
||||
typedef
|
||||
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) \
|
||||
|| defined(PLAT_amd64_solaris) \
|
||||
|| defined(PLAT_amd64_freebsd) \
|
||||
|| (defined(PLAT_amd64_win64) && defined(__GNUC__))
|
||||
|
||||
typedef
|
||||
|
|
@ -883,8 +872,7 @@ typedef
|
|||
/* results = r3 */ \
|
||||
"lgr %0, 3\n\t" \
|
||||
: "=d" (_zzq_result) \
|
||||
: "a" (&_zzq_args[0]), \
|
||||
"0" ((unsigned long int)_zzq_default) \
|
||||
: "a" (&_zzq_args[0]), "0" (_zzq_default) \
|
||||
: "cc", "2", "3", "memory" \
|
||||
); \
|
||||
_zzq_result; \
|
||||
|
|
@ -1057,75 +1045,6 @@ typedef
|
|||
|
||||
#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... */
|
||||
|
||||
#endif /* NVALGRIND */
|
||||
|
|
@ -1226,7 +1145,7 @@ typedef
|
|||
/* ----------------- x86-{linux,darwin,solaris} ---------------- */
|
||||
|
||||
#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
|
||||
as gcc can already see that, plus causes gcc to bomb. */
|
||||
|
|
@ -1658,7 +1577,7 @@ typedef
|
|||
/* ---------------- amd64-{linux,darwin,solaris} --------------- */
|
||||
|
||||
#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) */
|
||||
|
||||
|
|
@ -4768,16 +4687,8 @@ typedef
|
|||
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
|
||||
clobbers. */
|
||||
#if defined(__VX__) || defined(__S390_VX__)
|
||||
#define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14", \
|
||||
"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
|
||||
#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
|
||||
"f0","f1","f2","f3","f4","f5","f6","f7"
|
||||
|
||||
/* Nb: Although r11 is modified in the asm snippets below (inside
|
||||
VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
|
||||
|
|
@ -4799,9 +4710,9 @@ typedef
|
|||
"aghi 15,-160\n\t" \
|
||||
"lg 1, 0(1)\n\t" /* target->r1 */ \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,160\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||
|
|
@ -4823,9 +4734,9 @@ typedef
|
|||
"lg 2, 8(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,160\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||
|
|
@ -4848,9 +4759,9 @@ typedef
|
|||
"lg 3,16(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,160\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||
|
|
@ -4875,9 +4786,9 @@ typedef
|
|||
"lg 4,24(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,160\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||
|
|
@ -4904,9 +4815,9 @@ typedef
|
|||
"lg 5,32(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,160\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
|
||||
|
|
@ -4935,9 +4846,9 @@ typedef
|
|||
"lg 6,40(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,160\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -4969,9 +4880,9 @@ typedef
|
|||
"mvc 160(8,15), 48(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,168\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5005,9 +4916,9 @@ typedef
|
|||
"mvc 168(8,15), 56(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,176\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5043,9 +4954,9 @@ typedef
|
|||
"mvc 176(8,15), 64(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,184\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5083,9 +4994,9 @@ typedef
|
|||
"mvc 184(8,15), 72(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,192\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5125,9 +5036,9 @@ typedef
|
|||
"mvc 192(8,15), 80(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,200\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5169,9 +5080,9 @@ typedef
|
|||
"mvc 200(8,15), 88(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,208\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5215,9 +5126,9 @@ typedef
|
|||
"mvc 208(8,15), 96(1)\n\t" \
|
||||
"lg 1, 0(1)\n\t" \
|
||||
VALGRIND_CALL_NOREDIR_R1 \
|
||||
"lgr %0, 2\n\t" \
|
||||
"aghi 15,216\n\t" \
|
||||
VALGRIND_CFI_EPILOGUE \
|
||||
"lgr %0, 2\n\t" \
|
||||
: /*out*/ "=d" (_res) \
|
||||
: /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
|
||||
: /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
|
||||
|
|
@ -5767,422 +5678,6 @@ typedef
|
|||
|
||||
#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 ------------------------- */
|
||||
|
||||
#if defined(PLAT_mips64_linux)
|
||||
|
|
@ -6651,10 +6146,6 @@ typedef
|
|||
command. */
|
||||
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
|
||||
tracks malloc() et al, by using vg_replace_malloc.c. */
|
||||
VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
|
||||
|
|
@ -7137,14 +6628,6 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
|
|||
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_amd64_darwin
|
||||
#undef PLAT_x86_win32
|
||||
|
|
@ -7158,7 +6641,6 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
|
|||
#undef PLAT_s390x_linux
|
||||
#undef PLAT_mips32_linux
|
||||
#undef PLAT_mips64_linux
|
||||
#undef PLAT_nanomips_linux
|
||||
#undef PLAT_x86_solaris
|
||||
#undef PLAT_amd64_solaris
|
||||
|
||||
|
|
|
|||
452
meson.build
|
|
@ -1,8 +1,8 @@
|
|||
project('libinput', 'c',
|
||||
version : '1.31.0',
|
||||
version : '1.19.0',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||
meson_version : '>= 0.64.0')
|
||||
meson_version : '>= 0.49.0')
|
||||
|
||||
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_test = meson.current_source_dir() / 'test'
|
||||
dir_src = meson.current_source_dir() / 'src'
|
||||
dir_gitlab_ci = meson.current_source_dir() / '.gitlab-ci'
|
||||
|
||||
dir_udev = get_option('udev-dir')
|
||||
if dir_udev == ''
|
||||
|
|
@ -47,7 +46,6 @@ libinput_so_version = '@0@.@1@.@2@'.format((libinput_lt_c - libinput_lt_a),
|
|||
# Compiler setup
|
||||
cc = meson.get_compiler('c')
|
||||
cflags = [
|
||||
'-Wno-error=deprecated-declarations',
|
||||
'-Wno-unused-parameter',
|
||||
'-Wmissing-prototypes',
|
||||
'-Wstrict-prototypes',
|
||||
|
|
@ -80,11 +78,10 @@ endif
|
|||
config_h.set_quoted('HTTP_DOC_LINK', doc_url)
|
||||
|
||||
config_h.set('_GNU_SOURCE', '1')
|
||||
|
||||
is_debug_build = get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
|
||||
if is_debug_build
|
||||
config_h.set('IS_DEBUG_BUILD', '1')
|
||||
if get_option('buildtype') == 'debug' or get_option('buildtype') == 'debugoptimized'
|
||||
config_h.set_quoted('MESON_BUILD_ROOT', meson.current_build_dir())
|
||||
else
|
||||
config_h.set_quoted('MESON_BUILD_ROOT', '')
|
||||
endif
|
||||
|
||||
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')
|
||||
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 cc.has_header_symbol('stdlib.h', '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')
|
||||
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 = '''
|
||||
#include <locale.h>
|
||||
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_DETACH', 'PT_DETACH')
|
||||
endif
|
||||
if get_option('install-tests')
|
||||
config_h.set('HAVE_INSTALLED_TESTS', 1)
|
||||
endif
|
||||
|
||||
# Dependencies
|
||||
pkgconfig = import('pkgconfig')
|
||||
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_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
|
||||
includes_include = include_directories('include')
|
||||
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 ############
|
||||
|
||||
have_libwacom = get_option('libwacom')
|
||||
config_h.set10('HAVE_LIBWACOM', have_libwacom)
|
||||
if have_libwacom
|
||||
config_h.set('HAVE_LIBWACOM', 1)
|
||||
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
|
||||
dep_libwacom = declare_dependency()
|
||||
endif
|
||||
|
|
@ -238,7 +170,6 @@ executable('libinput-device-group',
|
|||
dependencies : [dep_udev, dep_libwacom],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install : true,
|
||||
install_tag : 'runtime',
|
||||
install_dir : dir_udev_callouts)
|
||||
executable('libinput-fuzz-extract',
|
||||
'udev/libinput-fuzz-extract.c',
|
||||
|
|
@ -247,18 +178,16 @@ executable('libinput-fuzz-extract',
|
|||
dependencies : [dep_udev, dep_libevdev, dep_lm],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install : true,
|
||||
install_tag : 'runtime',
|
||||
install_dir : dir_udev_callouts)
|
||||
executable('libinput-fuzz-to-zero',
|
||||
'udev/libinput-fuzz-to-zero.c',
|
||||
dependencies : [dep_udev, dep_libevdev],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install : true,
|
||||
install_tag : 'runtime',
|
||||
install_dir : dir_udev_callouts)
|
||||
|
||||
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',
|
||||
output : '80-libinput-device-groups.rules',
|
||||
install_dir : dir_udev_rules,
|
||||
|
|
@ -323,38 +252,42 @@ endif
|
|||
# Basic compilation test to make sure the headers include and define all the
|
||||
# necessary bits.
|
||||
util_headers = [
|
||||
'util-backtrace.h',
|
||||
'util-bits.h',
|
||||
'util-input-event.h',
|
||||
'util-list.h',
|
||||
'util-files.h',
|
||||
'util-macros.h',
|
||||
'util-matrix.h',
|
||||
'util-prop-parsers.h',
|
||||
'util-ratelimit.h',
|
||||
'util-stringbuf.h',
|
||||
'util-strings.h',
|
||||
'util-time.h',
|
||||
]
|
||||
foreach h: util_headers
|
||||
c = configuration_data()
|
||||
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),
|
||||
configuration : c)
|
||||
executable('test-build-@0@'.format(h),
|
||||
testfile,
|
||||
testfile, dir_src / h,
|
||||
include_directories : [includes_src, includes_include],
|
||||
dependencies: [dep_libevdev],
|
||||
install : false)
|
||||
endforeach
|
||||
|
||||
src_libinput_util = [
|
||||
'src/util-files.c',
|
||||
'src/util-bits.h',
|
||||
'src/util-list.c',
|
||||
'src/util-list.h',
|
||||
'src/util-macros.h',
|
||||
'src/util-matrix.h',
|
||||
'src/util-ratelimit.c',
|
||||
'src/util-ratelimit.h',
|
||||
'src/util-strings.h',
|
||||
'src/util-strings.c',
|
||||
'src/util-time.h',
|
||||
'src/util-prop-parsers.h',
|
||||
'src/util-prop-parsers.c',
|
||||
'src/libinput-util.h',
|
||||
]
|
||||
libinput_util = static_library('libinput-util',
|
||||
src_libinput_util,
|
||||
|
|
@ -365,7 +298,6 @@ dep_libinput_util = declare_dependency(link_with : libinput_util)
|
|||
############ libfilter.a ############
|
||||
src_libfilter = [
|
||||
'src/filter.c',
|
||||
'src/filter-custom.c',
|
||||
'src/filter-flat.c',
|
||||
'src/filter-low-dpi.c',
|
||||
'src/filter-mouse.c',
|
||||
|
|
@ -374,10 +306,11 @@ src_libfilter = [
|
|||
'src/filter-touchpad-x230.c',
|
||||
'src/filter-tablet.c',
|
||||
'src/filter-trackpoint.c',
|
||||
'src/filter-trackpoint-flat.c',
|
||||
'src/filter.h',
|
||||
'src/filter-private.h'
|
||||
]
|
||||
libfilter = static_library('filter', src_libfilter,
|
||||
dependencies : [dep_udev, dep_libwacom, dep_libevdev],
|
||||
dependencies : [dep_udev, dep_libwacom],
|
||||
include_directories : includes_include)
|
||||
dep_libfilter = declare_dependency(link_with : libfilter)
|
||||
|
||||
|
|
@ -395,6 +328,8 @@ install_subdir('quirks',
|
|||
|
||||
src_libquirks = [
|
||||
'src/quirks.c',
|
||||
'src/quirks.h',
|
||||
'src/builddir.h',
|
||||
]
|
||||
|
||||
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)
|
||||
|
||||
# Create /etc/libinput
|
||||
install_emptydir(dir_etc / 'libinput')
|
||||
install_subdir('libinput', install_dir : dir_etc)
|
||||
|
||||
############ 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')
|
||||
src_libinput = src_libfilter + [
|
||||
'src/libinput.c',
|
||||
'src/libinput-plugin.c',
|
||||
'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.h',
|
||||
'src/libinput-private-config.c',
|
||||
'src/libinput-private-config.h',
|
||||
'src/libinput-private.h',
|
||||
'src/evdev.c',
|
||||
'src/evdev.h',
|
||||
'src/evdev-debounce.c',
|
||||
'src/evdev-fallback.c',
|
||||
'src/evdev-plugin.c',
|
||||
'src/evdev-fallback.h',
|
||||
'src/evdev-totem.c',
|
||||
'src/evdev-middle-button.c',
|
||||
'src/evdev-mt-touchpad.c',
|
||||
'src/evdev-mt-touchpad.h',
|
||||
'src/evdev-mt-touchpad-tap.c',
|
||||
'src/evdev-mt-touchpad-thumb.c',
|
||||
'src/evdev-mt-touchpad-buttons.c',
|
||||
'src/evdev-mt-touchpad-edge-scroll.c',
|
||||
'src/evdev-mt-touchpad-gestures.c',
|
||||
'src/evdev-tablet.c',
|
||||
'src/evdev-tablet.h',
|
||||
'src/evdev-tablet-pad.c',
|
||||
'src/evdev-tablet-pad.h',
|
||||
'src/evdev-tablet-pad-leds.c',
|
||||
'src/path-seat.c',
|
||||
'src/udev-seat.c',
|
||||
'src/udev-seat.h',
|
||||
'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 = [
|
||||
dep_mtdev,
|
||||
dep_udev,
|
||||
|
|
@ -465,8 +385,7 @@ deps_libinput = [
|
|||
dep_rt,
|
||||
dep_libwacom,
|
||||
dep_libinput_util,
|
||||
dep_libquirks,
|
||||
dep_lua,
|
||||
dep_libquirks
|
||||
]
|
||||
|
||||
libinput_version_h_config = configuration_data()
|
||||
|
|
@ -497,18 +416,12 @@ dep_libinput = declare_dependency(
|
|||
link_with : lib_libinput,
|
||||
dependencies : deps_libinput)
|
||||
|
||||
meson.override_dependency('libinput', dep_libinput)
|
||||
|
||||
pkgconfig.generate(
|
||||
filebase : 'libinput',
|
||||
name : 'Libinput',
|
||||
description : 'Input device library',
|
||||
version : meson.project_version(),
|
||||
libraries : lib_libinput,
|
||||
requires_private : dep_udev,
|
||||
variables : [
|
||||
'plugindir=${libdir}/libinput/plugins'
|
||||
]
|
||||
libraries : lib_libinput
|
||||
)
|
||||
|
||||
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',
|
||||
output :'libinput-git-version.h')
|
||||
|
||||
subdir('plugins')
|
||||
|
||||
############ documentation ############
|
||||
|
||||
if get_option('documentation')
|
||||
|
|
@ -529,23 +440,13 @@ endif
|
|||
|
||||
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 ############
|
||||
libinput_tool_path = dir_libexec
|
||||
config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path)
|
||||
tools_shared_sources = [ 'tools/shared.c' ]
|
||||
deps_tools_shared = [ dep_libinput, dep_libevdev, dep_libinput_util_libinput ]
|
||||
tools_shared_sources = [ 'tools/shared.c',
|
||||
'tools/shared.h',
|
||||
'src/builddir.h' ]
|
||||
deps_tools_shared = [ dep_libinput, dep_libevdev ]
|
||||
lib_tools_shared = static_library('tools_shared',
|
||||
tools_shared_sources,
|
||||
include_directories : [includes_src, includes_include],
|
||||
|
|
@ -563,7 +464,6 @@ executable('libinput-debug-events',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
|
||||
|
|
@ -573,17 +473,8 @@ executable('libinput-debug-tablet',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
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 = executable('libinput-quirks',
|
||||
|
|
@ -591,7 +482,6 @@ libinput_quirks = executable('libinput-quirks',
|
|||
dependencies : [dep_libquirks, dep_tools_shared, dep_libinput],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
test('validate-quirks',
|
||||
|
|
@ -600,20 +490,12 @@ test('validate-quirks',
|
|||
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 = executable('libinput-list-devices',
|
||||
libinput_list_devices_sources,
|
||||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
test('list-devices',
|
||||
|
|
@ -626,7 +508,6 @@ executable('libinput-measure',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
|
||||
|
|
@ -636,22 +517,19 @@ executable('libinput-analyze',
|
|||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
|
||||
src_python_tools = files(
|
||||
'tools/libinput-analyze-buttons.py',
|
||||
'tools/libinput-analyze-per-slot-delta.py',
|
||||
'tools/libinput-analyze-recording.py',
|
||||
'tools/libinput-analyze-touch-down-state.py',
|
||||
'tools/libinput-list-kernel-devices.py',
|
||||
'tools/libinput-measure-fuzz.py',
|
||||
'tools/libinput-measure-touchpad-size.py',
|
||||
'tools/libinput-measure-touchpad-tap.py',
|
||||
'tools/libinput-measure-touchpad-pressure.py',
|
||||
'tools/libinput-measure-touch-size.py',
|
||||
'tools/libinput-replay.py'
|
||||
'tools/libinput-analyze-per-slot-delta.py',
|
||||
'tools/libinput-analyze-recording.py',
|
||||
'tools/libinput-analyze-touch-down-state.py',
|
||||
'tools/libinput-measure-fuzz.py',
|
||||
'tools/libinput-measure-touchpad-size.py',
|
||||
'tools/libinput-measure-touchpad-tap.py',
|
||||
'tools/libinput-measure-touchpad-pressure.py',
|
||||
'tools/libinput-measure-touch-size.py',
|
||||
'tools/libinput-replay.py'
|
||||
)
|
||||
|
||||
foreach t : src_python_tools
|
||||
|
|
@ -668,42 +546,28 @@ executable('libinput-record',
|
|||
dependencies : deps_tools + [dep_udev],
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true,
|
||||
)
|
||||
|
||||
if get_option('debug-gui')
|
||||
config_h.set('HAVE_DEBUG_GUI', 1)
|
||||
dep_gtk = dependency('gtk4', version : '>= 4.0', required : false)
|
||||
if dep_gtk.found()
|
||||
config_h.set('HAVE_GTK4', 1)
|
||||
else
|
||||
config_h.set10('HAVE_GTK4', dep_gtk.found())
|
||||
if not dep_gtk.found()
|
||||
dep_gtk = dependency('gtk+-3.0', version : '>= 3.20')
|
||||
if dep_gtk.found()
|
||||
config_h.set('HAVE_GTK3', 1)
|
||||
endif
|
||||
config_h.set10('HAVE_GTK3', dep_gtk.found())
|
||||
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_glib = dependency('glib-2.0')
|
||||
dep_x11 = dependency('x11', required : false)
|
||||
dep_wayland_client = dependency('wayland-client', required : false)
|
||||
dep_wayland_protocols = dependency('wayland-protocols', required : false)
|
||||
|
||||
if have_gtk_x11 and dep_x11.found()
|
||||
config_h.set('HAVE_GTK_X11', 1)
|
||||
endif
|
||||
dep_x11 = dependency('x11', required : false)
|
||||
|
||||
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')
|
||||
wlproto_dir = dep_wayland_protocols.get_variable('pkgdatadir')
|
||||
wlproto_dir = dep_wayland_protocols.get_pkgconfig_variable('pkgdatadir')
|
||||
|
||||
proto_name = 'pointer-constraints-unstable-v1'
|
||||
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 ]
|
||||
config_h.set('HAVE_GTK_WAYLAND', 1)
|
||||
endif
|
||||
|
||||
deps_debug_gui = [
|
||||
|
|
@ -737,7 +600,6 @@ if get_option('debug-gui')
|
|||
dependencies : deps_debug_gui,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_dir : libinput_tool_path,
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
src_man += files('tools/libinput-debug-gui.man')
|
||||
|
|
@ -749,7 +611,6 @@ libinput_tool = executable('libinput',
|
|||
libinput_sources,
|
||||
dependencies : deps_tools,
|
||||
include_directories : [includes_src, includes_include],
|
||||
install_tag : 'bin',
|
||||
install : true
|
||||
)
|
||||
|
||||
|
|
@ -763,10 +624,10 @@ executable('ptraccel-debug',
|
|||
|
||||
# Don't run the test during a release build because we rely on the magic
|
||||
# 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.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('TOOL_PATH', libinput_tool.full_path())
|
||||
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)
|
||||
test('tool-option-parsing',
|
||||
tool_option_test,
|
||||
args : [tool_option_test],
|
||||
args : [tool_option_test, '-n', 'auto'],
|
||||
suite : ['all', 'root'],
|
||||
timeout : 240)
|
||||
endif
|
||||
|
|
@ -800,13 +661,6 @@ test('tools-builddir-lookup-installed',
|
|||
|
||||
############ tests ############
|
||||
|
||||
summary({
|
||||
'Tests enabled' : get_option('tests'),
|
||||
'Install tests' : get_option('install-tests'),
|
||||
},
|
||||
section : 'Tests',
|
||||
bool_yn : true)
|
||||
|
||||
test('symbols-leak-test',
|
||||
find_program('test/symbols-leak-test'),
|
||||
args : [ dir_src / 'libinput.sym', dir_src],
|
||||
|
|
@ -833,7 +687,7 @@ executable('test-build-linker',
|
|||
dependencies : [ dep_libinput, dep_libinput_util ],
|
||||
install : false)
|
||||
# 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',
|
||||
'test/build-cxx.cc',
|
||||
dependencies : [dep_udev],
|
||||
|
|
@ -841,34 +695,23 @@ if add_languages('cpp', native: false, required: false)
|
|||
install : false)
|
||||
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
|
||||
# dependencies
|
||||
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)
|
||||
if gstack.found()
|
||||
config_h.set('HAVE_GSTACK', 1)
|
||||
endif
|
||||
config_h.set10('HAVE_GSTACK', gstack.found())
|
||||
|
||||
# for inhibit support during test run
|
||||
dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false)
|
||||
if dep_libsystemd.found()
|
||||
config_h.set('HAVE_LIBSYSTEMD', 1)
|
||||
endif
|
||||
config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found())
|
||||
|
||||
litest_sources = [
|
||||
'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-acer-hawaii-keyboard.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-elantech-touchpad.c',
|
||||
'test/litest-device-elan-tablet.c',
|
||||
'test/litest-device-format-string.c',
|
||||
'test/litest-device-generic-pressurepad.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-huion-pentablet.c',
|
||||
'test/litest-device-huion-q620m-dial.c',
|
||||
'test/litest-device-hp-wmi-hotkeys.c',
|
||||
'test/litest-device-ignored-mouse.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-blade-stealth.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-surface3.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-mouse.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-low-dpi.c',
|
||||
'test/litest-device-mouse-virtual.c',
|
||||
'test/litest-device-mouse-wheel-click-angle.c',
|
||||
'test/litest-device-mouse-wheel-click-count.c',
|
||||
'test/litest-device-ms-nano-transceiver-mouse.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-sony-vaio-keys.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-t440.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-rel-dial.c',
|
||||
'test/litest-device-thinkpad-extrabuttons.c',
|
||||
'test/litest-device-trackpoint.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-fuzz.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-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-13hdt-finger.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-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-finger.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-vmware-virtual-usb-mouse.c',
|
||||
'test/litest-device-yubikey.c',
|
||||
'test/litest-runner.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')
|
||||
deps_litest = [
|
||||
dep_libinput,
|
||||
dep_check,
|
||||
dep_udev,
|
||||
dep_libevdev,
|
||||
dep_dl,
|
||||
dep_lm,
|
||||
dep_libsystemd,
|
||||
dep_libquirks,
|
||||
dep_libinput_util_libinput,
|
||||
]
|
||||
|
||||
litest_config_h = configuration_data()
|
||||
|
|
@ -1008,28 +829,27 @@ if get_option('tests')
|
|||
meson.current_build_dir() /
|
||||
'90-libinput-fuzz-override-litest.rules')
|
||||
|
||||
if dep_check.found()
|
||||
def_disable_backtrace = '-DLITEST_DISABLE_BACKTRACE_LOGGING'
|
||||
defs_litest_selftest = [
|
||||
def_disable_backtrace,
|
||||
'-Wno-unused',
|
||||
]
|
||||
test_litest_selftest_sources = [
|
||||
'test/litest-selftest.c',
|
||||
'test/litest-runner.c',
|
||||
'test/litest.c',
|
||||
]
|
||||
test_litest_selftest = executable('test-litest-selftest',
|
||||
test_litest_selftest_sources,
|
||||
include_directories : [includes_src, includes_include],
|
||||
dependencies : [deps_litest, dep_check],
|
||||
c_args : defs_litest_selftest,
|
||||
install : false)
|
||||
test('test-litest-selftest',
|
||||
test_litest_selftest,
|
||||
suite : ['all'],
|
||||
timeout : 100)
|
||||
endif
|
||||
def_no_main = '-DLITEST_NO_MAIN'
|
||||
def_disable_backtrace = '-DLITEST_DISABLE_BACKTRACE_LOGGING'
|
||||
defs_litest_selftest = [
|
||||
def_no_main,
|
||||
def_disable_backtrace
|
||||
]
|
||||
test_litest_selftest_sources = [
|
||||
'test/litest-selftest.c',
|
||||
'test/litest.c',
|
||||
'test/litest.h'
|
||||
]
|
||||
test_litest_selftest = executable('test-litest-selftest',
|
||||
test_litest_selftest_sources,
|
||||
include_directories : [includes_src, includes_include],
|
||||
dependencies : deps_litest,
|
||||
c_args : defs_litest_selftest,
|
||||
install : false)
|
||||
test('test-litest-selftest',
|
||||
test_litest_selftest,
|
||||
suite : ['all'],
|
||||
timeout : 100)
|
||||
|
||||
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',
|
||||
|
|
@ -1041,20 +861,19 @@ if get_option('tests')
|
|||
suite : ['all'])
|
||||
|
||||
test_utils_sources = [
|
||||
'src/libinput-util.h',
|
||||
'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,
|
||||
include_directories : [includes_src, includes_include],
|
||||
dependencies : deps_litest,
|
||||
install_dir : libinput_tool_path,
|
||||
install : get_option('install-tests'))
|
||||
install: false)
|
||||
test('test-utils',
|
||||
test_utils,
|
||||
suite : ['all'])
|
||||
|
||||
# When adding new files to this list, update the CI
|
||||
tests_sources = [
|
||||
'test/test-udev.c',
|
||||
'test/test-path.c',
|
||||
|
|
@ -1076,11 +895,9 @@ if get_option('tests')
|
|||
'test/test-switch.c',
|
||||
'test/test-quirks.c',
|
||||
]
|
||||
if have_plugins and have_lua
|
||||
tests_sources += ['test/test-plugins-lua.c']
|
||||
endif
|
||||
|
||||
libinput_test_runner_sources = litest_sources + tests_sources
|
||||
libinput_test_runner_sources = litest_sources + tests_sources + [
|
||||
'src/libinput-util.h',
|
||||
]
|
||||
libinput_test_runner = executable('libinput-test-suite',
|
||||
libinput_test_runner_sources,
|
||||
include_directories : [includes_src, includes_include],
|
||||
|
|
@ -1090,54 +907,23 @@ if get_option('tests')
|
|||
|
||||
src_man += 'test/libinput-test-suite.man'
|
||||
|
||||
# When adding new TEST_COLLECTION() macros, add to this list and the CI
|
||||
# $ git grep TEST_COLLECTION test/test-* | sed -e "s|.*TEST_COLLECTION(\(.*\))|\t\t'\1',|" | sort
|
||||
collections = [
|
||||
'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
|
||||
foreach testfile : tests_sources
|
||||
tfile = testfile.split('test/test-')[1]
|
||||
group = tfile.split('.c')[0]
|
||||
test('libinput-test-suite-@0@'.format(group),
|
||||
libinput_test_runner,
|
||||
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,
|
||||
timeout : 1100)
|
||||
timeout : 1200)
|
||||
endforeach
|
||||
|
||||
test('libinput-test-deviceless',
|
||||
libinput_test_runner,
|
||||
suite : ['all', 'valgrind'],
|
||||
args: ['--filter-deviceless'])
|
||||
args: ['--filter-deviceless',
|
||||
'--xml-output=junit-deviceless-XXXXXX.xml'])
|
||||
|
||||
valgrind = find_program('valgrind', required : false)
|
||||
if valgrind.found()
|
||||
|
|
@ -1145,13 +931,12 @@ if get_option('tests')
|
|||
valgrind_suppressions_file = dir_src_test / 'valgrind.suppressions'
|
||||
add_test_setup('valgrind',
|
||||
exe_wrapper : [ valgrind,
|
||||
'--log-file=valgrind.%p.log',
|
||||
'--leak-check=full',
|
||||
'--gen-suppressions=all',
|
||||
'--error-exitcode=3',
|
||||
'--suppressions=' + valgrind_suppressions_file ],
|
||||
env : valgrind_env,
|
||||
timeout_multiplier : 3)
|
||||
timeout_multiplier : 100)
|
||||
else
|
||||
message('valgrind not found, disabling valgrind test suite')
|
||||
endif
|
||||
|
|
@ -1164,29 +949,15 @@ endif
|
|||
man_config = configuration_data()
|
||||
man_config.set('LIBINPUT_VERSION', meson.project_version())
|
||||
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(
|
||||
'tools/libinput.man',
|
||||
'tools/libinput-analyze.man',
|
||||
'tools/libinput-analyze-buttons.man',
|
||||
'tools/libinput-analyze-per-slot-delta.man',
|
||||
'tools/libinput-analyze-recording.man',
|
||||
'tools/libinput-analyze-touch-down-state.man',
|
||||
'tools/libinput-debug-events.man',
|
||||
'tools/libinput-debug-tablet.man',
|
||||
'tools/libinput-debug-tablet-pad.man',
|
||||
'tools/libinput-list-devices.man',
|
||||
'tools/libinput-list-kernel-devices.man',
|
||||
'tools/libinput-measure.man',
|
||||
'tools/libinput-measure-fuzz.man',
|
||||
'tools/libinput-measure-touchpad-size.man',
|
||||
|
|
@ -1196,7 +967,6 @@ src_man += files(
|
|||
'tools/libinput-quirks.man',
|
||||
'tools/libinput-record.man',
|
||||
'tools/libinput-replay.man',
|
||||
'tools/libinput-test.man',
|
||||
)
|
||||
|
||||
foreach m : src_man
|
||||
|
|
|
|||
|
|
@ -10,10 +10,6 @@ option('libwacom',
|
|||
type: 'boolean',
|
||||
value: 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',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
|
|
@ -38,15 +34,3 @@ option('zshcompletiondir',
|
|||
type: 'string',
|
||||
value: '',
|
||||
description: 'Directory for zsh completion scripts ["no" disables]')
|
||||
option('internal-event-debugging',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Enable additional internal event debug tracing. This will print key values to the logs and thus must never be enabled in a release build')
|
||||
option('autoload-plugins',
|
||||
type: 'boolean',
|
||||
value: false,
|
||||
description: 'Always load plugins from default plugin paths (only if the caller does not do so)')
|
||||
option('lua-plugins',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Enable support for Lua plugins')
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin detects the Copilot key on the keyboard with
|
||||
-- the given VID/PID and replaces it with a different key (sequence).
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- Replace this with your keyboard's VID/PID
|
||||
KEYBOARD_VID = 0x046d
|
||||
KEYBOARD_PID = 0x4088
|
||||
|
||||
meta_is_down = false
|
||||
shift_is_down = false
|
||||
|
||||
-- shift-A, because you can never have enough screaming
|
||||
replacement_sequence = { evdev.KEY_LEFTSHIFT, evdev.KEY_A }
|
||||
|
||||
function frame(device, frame, _)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.value ~= 2 then -- ignore key repeats
|
||||
if v.usage == evdev.KEY_LEFTMETA then
|
||||
meta_is_down = v.value == 1
|
||||
elseif v.usage == evdev.KEY_LEFTSHIFT then
|
||||
shift_is_down = v.value == 1
|
||||
elseif v.usage == evdev.KEY_F23 and meta_is_down and shift_is_down then
|
||||
-- We know from the MS requirements that F23 for copilot is
|
||||
-- either last key (on press) or the first key (on release)
|
||||
-- of the three-key sequence, and no other keys are
|
||||
-- within this frame.
|
||||
if v.value == 1 then
|
||||
-- Release our modifiers first
|
||||
device:prepend_frame({
|
||||
{ usage = evdev.KEY_LEFTSHIFT, value = 0 },
|
||||
{ usage = evdev.KEY_LEFTMETA, value = 0 },
|
||||
})
|
||||
-- Insert our replacement press sequence
|
||||
local replacement_frame = {}
|
||||
for _, rv in ipairs(replacement_sequence) do
|
||||
table.insert(replacement_frame, { usage = rv, value = 1 })
|
||||
end
|
||||
device:append_frame(replacement_frame)
|
||||
else
|
||||
-- Insert our replacement release sequence
|
||||
local replacement_frame = {}
|
||||
for idx = #replacement_sequence, 1, -1 do
|
||||
table.insert(replacement_frame, { usage = replacement_sequence[idx], value = 0 })
|
||||
end
|
||||
device:append_frame(replacement_frame)
|
||||
|
||||
-- we don't care about re-pressing shift/meta because the
|
||||
-- rest of the stack will filter the release for an
|
||||
-- unpressed key anyway.
|
||||
end
|
||||
|
||||
return {} -- discard this frame
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function device_new(device)
|
||||
local info = device:info()
|
||||
if info.vid == KEYBOARD_VID and info.pid == KEYBOARD_PID then
|
||||
device:connect("evdev-frame", frame)
|
||||
end
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin delays any event with relative motion by the given DELAY
|
||||
-- by storing it in a table and replaying it via a timer callback later.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
DELAY = 1500 * 1000 -- 1.5s
|
||||
next_timer_expiry = 0
|
||||
devices = {}
|
||||
|
||||
function timer_expired(time_in_microseconds)
|
||||
next_timer_expiry = 0
|
||||
for device, frames in pairs(devices) do
|
||||
while #frames > 0 and frames[1].time <= time_in_microseconds do
|
||||
--- we don't have a current frame so it doesn't matter
|
||||
--- whether we prepend or append
|
||||
device:prepend_frame(frames[1].frame)
|
||||
table.remove(frames, 1)
|
||||
end
|
||||
local next_frame = frames[1]
|
||||
if next_frame and (next_timer_expiry == 0 or next_frame.time < next_timer_expiry) then
|
||||
next_timer_expiry = next_frame.time
|
||||
end
|
||||
end
|
||||
if next_timer_expiry ~= 0 then
|
||||
libinput:timer_set_absolute(next_timer_expiry)
|
||||
end
|
||||
end
|
||||
|
||||
function frame(device, frame, timestamp)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
|
||||
local next_time = timestamp + DELAY
|
||||
table.insert(devices[device], {
|
||||
time = next_time,
|
||||
frame = frame
|
||||
})
|
||||
if next_timer_expiry == 0 then
|
||||
next_timer_expiry = next_time
|
||||
libinput:timer_set_absolute(next_timer_expiry)
|
||||
end
|
||||
return {} -- discard frame
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function device_new(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
devices[device] = {}
|
||||
device:connect("evdev-frame", frame)
|
||||
device:connect("device-removed", function(dev)
|
||||
devices[dev] = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
libinput:connect("timer-expired", timer_expired)
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- An example plugin to show how to disable an internal feature.
|
||||
--
|
||||
-- Typically one would expect the plugin to re-implement the feature
|
||||
-- in a more device-specific manner but that's not done here.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
libinput:connect("new-evdev-device", function(device)
|
||||
local udev_info = device:udev_properties()
|
||||
if udev_info["ID_INPUT_TOUCHPAD"] then
|
||||
libinput:log_info("Disabling palm detection on " .. device:name())
|
||||
device:disable_feature("touchpad-palm-detection")
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This plugin implements a very simple version of disable-while-typing.
|
||||
-- It monitors all keyboard devices and if any of them send an event,
|
||||
-- any touchpad device is disabled for 2 seconds.
|
||||
-- And "disabled" means any event from that touchpad is simply
|
||||
-- discarded.
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
tp_enabled = true
|
||||
|
||||
libinput:connect("timer-expired", function(now)
|
||||
libinput:log_debug("touchpad enabled")
|
||||
tp_enabled = true
|
||||
end)
|
||||
|
||||
libinput:connect("new-evdev-device", function (device)
|
||||
local props = device:udev_properties()
|
||||
if props.ID_INPUT_KEYBOARD then
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
libinput:timer_set_relative(2000000)
|
||||
if tp_enabled then
|
||||
libinput:log_debug("touchpad disabled")
|
||||
tp_enabled = false
|
||||
end
|
||||
end)
|
||||
elseif props.ID_INPUT_TOUCHPAD then
|
||||
libinput:log_debug("Touchpad detected: " .. device:name())
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
if not tp_enabled then
|
||||
-- Returning an empty table discards the event.
|
||||
return {}
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin swaps left and right buttons on any device that has both buttons.
|
||||
|
||||
-- Let's create a plugin. A single Lua script may create more than one
|
||||
-- plugin instance but that's a bit of a nice use-case. Most scripts
|
||||
-- should be a single plugin.
|
||||
|
||||
-- A plugin needs to be registered to activate. If it isn't, it is
|
||||
-- cleaned up immediately. In the register call we supply
|
||||
-- the list of plugin versions we support. Currently we only
|
||||
-- have version 1.
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- Note to the reader: it will be easier to understand this example
|
||||
-- if you read it bottom-up from here on.
|
||||
|
||||
-- The callback for our "evdev-frame" signal.
|
||||
-- These frames are sent *before* libinput gets to handle them so
|
||||
-- any modifications will affect libinput.
|
||||
function frame(device, frame, time_in_microseconds)
|
||||
-- Frame is a table in the form
|
||||
-- { { usage: 123, value: 3 }, ... }
|
||||
-- Let's use the evdev module to make it more readable, evdev.KEY_A
|
||||
-- is simply the value (0x1 << 16) | 0x1 (see linux/input-event-codes.h)
|
||||
for _, v in ipairs(frame) do
|
||||
-- If we get a right button event, change it to left, and
|
||||
-- vice versa. Because this happens before libinput (or the next
|
||||
-- plugin in the precedence order) sees the
|
||||
-- frame it doesn't know that the swap happened.
|
||||
if v.usage == evdev.BTN_RIGHT then
|
||||
v.usage = evdev.BTN_LEFT
|
||||
elseif v.usage == evdev.BTN_LEFT then
|
||||
v.usage = evdev.BTN_RIGHT
|
||||
end
|
||||
end
|
||||
-- We changed the frame, let's return it. If we return nil
|
||||
-- the original frame is being used as-is.
|
||||
return frame
|
||||
end
|
||||
|
||||
-- This is a timer callback. It is invoked after one second
|
||||
-- (see below) but only once - re-set the timer so
|
||||
-- it goes off every second.
|
||||
function timer_expired(time_in_microseconds)
|
||||
libinput:timer_set_absolute(time_in_microseconds + 1000000)
|
||||
end
|
||||
|
||||
-- Callback for the "new-evdev-device" signal, see below
|
||||
-- The argument is the EvdevDevice object, see the documentation.
|
||||
function device_new(device)
|
||||
-- A table of evdev usages available on our device.
|
||||
-- Using the evdev module makes it more readable but you can
|
||||
-- use numbers (which is what evdev.EV_KEY and
|
||||
-- friends resolve to anyway).
|
||||
local usages = device:usages()
|
||||
if usages[evdev.BTN_LEFT] and usages[evdev.BTN_RIGHT] then
|
||||
-- The "evdev-frame" callback is invoked whenever the device
|
||||
-- provided us with one evdev frame, i.e. a bunch of events up
|
||||
-- to excluding EV_SYN SYN_REPORT.
|
||||
device:connect("evdev-frame", frame)
|
||||
end
|
||||
|
||||
-- The device has udev information, let's print it out. Right
|
||||
-- now all we get are the ID_INPUT_ bits.
|
||||
-- If this is empty we know libinput will ignore this device anyway
|
||||
local udev_info = device:udev_properties()
|
||||
for k, v in pairs(udev_info) do
|
||||
libinput:log_debug(k .. "=" .. v)
|
||||
end
|
||||
end
|
||||
|
||||
-- Let's connect to the "new-evdev-device" signal. This function
|
||||
-- is invoked when libinput detects a new evdev device (but before
|
||||
-- that device is actually available to libinput as libinput device).
|
||||
-- This allows us to e.g. change properties on the device.
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
|
||||
-- Set our timer to expire 1s from now (in microseconds).
|
||||
-- Timers are absolute, so they need to be added to the
|
||||
-- current time
|
||||
libinput:connect("timer-expired", timer_expired)
|
||||
libinput:timer_set_relative(1000000)
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This plugin inverts the horizontal scroll direction of
|
||||
-- the Logitech MX Master mouse. OOTB the mouse scrolls
|
||||
-- in the opposite direction to all other mice out there.
|
||||
--
|
||||
-- This plugin is only needed when the mouse is connected
|
||||
-- to the Logitech Bolt receiver - on that receiver we cannot
|
||||
-- tell which device is connected.
|
||||
--
|
||||
-- For the Logitech Unifying receiver and Bluetooth please
|
||||
-- add the ModelInvertHorizontalScrolling=1 quirk
|
||||
-- in quirks/30-vendor-logitech.quirks.
|
||||
--
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
libinput:connect("new-evdev-device", function (device)
|
||||
local info = device:info()
|
||||
if info.vid == 0x046D and info.pid == 0xC548 then
|
||||
device:connect("evdev-frame", function (device, frame, timestamp)
|
||||
for _, event in ipairs(frame) do
|
||||
if event.usage == evdev.REL_HWHEEL or event.usage == evdev.REL_HWHEEL_HI_RES then
|
||||
event.value = -event.value
|
||||
end
|
||||
end
|
||||
return frame
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- An example plugin to make the pointer go three times as fast
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
libinput:connect("new-evdev-device", function(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
device:connect("evdev-frame", function(device, frame, timestamp)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_X or v.usage == evdev.REL_Y then
|
||||
-- Multiply the relative motion by 3
|
||||
v.value = v.value * 3
|
||||
end
|
||||
end
|
||||
return frame
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- An example plugin to make the pointer go three times as slow
|
||||
--
|
||||
-- Install this file in /etc/libinput/plugins and
|
||||
--
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
remainders = {}
|
||||
|
||||
function split(v)
|
||||
if math.abs(v) >= 1.0 then
|
||||
local i = math.floor(math.abs(v))
|
||||
local r = math.abs(v) % 1.0
|
||||
if v < 0.0 then
|
||||
i = -i
|
||||
r = -r
|
||||
end
|
||||
return i, r
|
||||
else
|
||||
return 0, v
|
||||
end
|
||||
end
|
||||
|
||||
function decelerate(device, x, y)
|
||||
local remainder = remainders[device]
|
||||
local rx, ry = 0, 0
|
||||
if x ~= 0.0 then
|
||||
rx, remainder.x = split(remainder.x + x/3.0)
|
||||
end
|
||||
if y ~= 0.0 then
|
||||
ry, remainder.y = split(remainder.y + y/3.0)
|
||||
end
|
||||
|
||||
return rx, ry
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", function(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_X] then
|
||||
remainders[device] = { x = 0.0, y = 0.0 }
|
||||
device:connect("evdev-frame", function(device, frame, timestamp)
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_X then
|
||||
v.value, _ = decelerate(device, v.value, 0.0)
|
||||
elseif v.usage == evdev.REL_Y then
|
||||
_, v.value = decelerate(device, 0.0, v.value)
|
||||
end
|
||||
end
|
||||
return frame
|
||||
end)
|
||||
device:connect("device-removed", function(dev)
|
||||
remainders[dev] = nil
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin controls a mouse/pointer from a tablet device. This
|
||||
-- effectively hides stylus interactions and sends pointer events
|
||||
-- instead. In other words: mouse emulation for tablets, implemented
|
||||
-- by (remote) controlling a mouse device. This allows using a
|
||||
-- tablet stylus as a mouse replacement without tablet limitations
|
||||
-- from compositors or clients. Note that axis usually needed for
|
||||
-- drawing (like pressure, tilt or distance) are no longer emitted
|
||||
-- when this plugin is active and a mouse is connected. When no
|
||||
-- mouse is connected, this plugin doesn't change tablet events,
|
||||
-- thus the stylus works like a normal stylus.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- globals
|
||||
pointer_device = nil
|
||||
tablet_device = nil
|
||||
maximum_x = nil
|
||||
maximum_y = nil
|
||||
|
||||
function adjust_for_aspect_ratio(y)
|
||||
-- adjust y to match monitor 21:9 aspect ratio
|
||||
local adj_maximum_y = maximum_x * 1440 / 3440
|
||||
return math.floor(math.min(y * maximum_y / adj_maximum_y, maximum_y + 1))
|
||||
end
|
||||
|
||||
function on_tablet_frame(device, frame, time_in_microseconds)
|
||||
-- emit tablet frame when there is no pointer device
|
||||
if not pointer_device then return nil end
|
||||
|
||||
-- map tablet frame to pointer frame
|
||||
local events = {}
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.ABS_MISC then
|
||||
-- save a few cycles on Wacom tablets by discarding a
|
||||
-- proximity in / out frame early, non-Wacom tablets should
|
||||
-- use BTN_TOOL_PEN/RUBBER/... instead
|
||||
return {}
|
||||
elseif v.usage == evdev.ABS_X then
|
||||
table.insert(events, { usage = evdev.ABS_X, value = v.value })
|
||||
elseif v.usage == evdev.ABS_Y then
|
||||
-- uncomment the next two lines and comment the original line
|
||||
-- for configuring aspect correction, see
|
||||
-- adjust_for_aspect_ratio() for details and configuration
|
||||
|
||||
-- local adj_value = adjust_for_aspect_ratio(v.value)
|
||||
-- table.insert(events, { usage = evdev.ABS_Y, value = adj_value })
|
||||
table.insert(events, { usage = evdev.ABS_Y, value = v.value })
|
||||
elseif v.usage == evdev.BTN_TOUCH then
|
||||
table.insert(events, { usage = evdev.BTN_LEFT, value = v.value })
|
||||
elseif v.usage == evdev.BTN_STYLUS then
|
||||
table.insert(events, { usage = evdev.BTN_RIGHT, value = v.value })
|
||||
elseif v.usage == evdev.BTN_STYLUS2 then
|
||||
table.insert(events, { usage = evdev.BTN_MIDDLE, value = v.value })
|
||||
end
|
||||
end
|
||||
|
||||
-- emit pointer frame, if any
|
||||
if #events > 0 then pointer_device:append_frame(events) end
|
||||
|
||||
-- discard tablet frame
|
||||
return {}
|
||||
end
|
||||
|
||||
function on_tablet_removed(device)
|
||||
libinput:log_info("Remove tablet device")
|
||||
tablet_device = nil
|
||||
end
|
||||
|
||||
function on_pointer_removed(device)
|
||||
libinput:log_info("Remove pointer device")
|
||||
pointer_device = nil
|
||||
end
|
||||
|
||||
function setup()
|
||||
if not pointer_device or not tablet_device then return end
|
||||
|
||||
libinput:log_info("Controlling '" .. pointer_device:name() .. "' with '" .. tablet_device:name() .. "'")
|
||||
|
||||
-- fetch absinfos from tablet
|
||||
local absinfo_x = {}
|
||||
local absinfo_y = {}
|
||||
for a, b in pairs(tablet_device:absinfos()) do
|
||||
if a == evdev.ABS_X then absinfo_x = b end
|
||||
if a == evdev.ABS_Y then absinfo_y = b end
|
||||
end
|
||||
|
||||
-- copy max values for aspect ratio correction later on
|
||||
maximum_x = absinfo_x.maximum
|
||||
maximum_y = absinfo_y.maximum
|
||||
|
||||
-- copy absinfos to pointer device
|
||||
pointer_device:set_absinfo(evdev.ABS_X, absinfo_x)
|
||||
pointer_device:set_absinfo(evdev.ABS_Y, absinfo_y)
|
||||
|
||||
-- setup listeners
|
||||
pointer_device:connect("device-removed", on_pointer_removed)
|
||||
tablet_device:connect("device-removed", on_tablet_removed)
|
||||
tablet_device:connect("evdev-frame", on_tablet_frame)
|
||||
end
|
||||
|
||||
function on_new_device(device)
|
||||
local udev = device:udev_properties()
|
||||
if udev["ID_INPUT_TABLET"] and not udev["ID_INPUT_TABLET_PAD"] then
|
||||
libinput:log_info("Found tablet device")
|
||||
tablet_device = device
|
||||
setup()
|
||||
end
|
||||
if udev["ID_INPUT_MOUSE"] then
|
||||
libinput:log_info("Found pointer device")
|
||||
pointer_device = device
|
||||
setup()
|
||||
end
|
||||
end
|
||||
|
||||
-- setup listener
|
||||
libinput:connect("new-evdev-device", on_new_device)
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
-- SPDX-License-Identifier: MIT
|
||||
--
|
||||
-- This is an example libinput plugin
|
||||
--
|
||||
-- This plugin maps a downwards mouse wheel to a button down event and
|
||||
-- an upwards wheel movement to a button up event.
|
||||
|
||||
-- UNCOMMENT THIS LINE TO ACTIVATE THE PLUGIN
|
||||
-- libinput:register({1})
|
||||
|
||||
-- The button we want to press on wheel events
|
||||
local wheel_button = evdev.BTN_EXTRA
|
||||
local button_states = {}
|
||||
|
||||
local function evdev_frame(device, frame, timestamp)
|
||||
local events = {}
|
||||
local modified = false
|
||||
|
||||
for _, v in ipairs(frame) do
|
||||
if v.usage == evdev.REL_WHEEL then
|
||||
-- REL_WHEEL is inverted, neg value -> down, pos value -> up
|
||||
if v.value < 0 then
|
||||
if not button_states[device] then
|
||||
table.insert(events, { usage = wheel_button, value = 1 })
|
||||
button_states[device] = true
|
||||
end
|
||||
else
|
||||
if button_states[device] then
|
||||
table.insert(events, { usage = wheel_button, value = 0 })
|
||||
button_states[device] = false
|
||||
end
|
||||
end
|
||||
modified = true
|
||||
-- Because REL_WHEEL is no longer a wheel, the high-res
|
||||
-- events are dropped
|
||||
elseif v.usage == evdev.REL_WHEEL_HI_RES then
|
||||
modified = true
|
||||
else
|
||||
table.insert(events, v)
|
||||
end
|
||||
end
|
||||
|
||||
if modified then
|
||||
return events
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function device_new(device)
|
||||
local usages = device:usages()
|
||||
if usages[evdev.REL_WHEEL] then
|
||||
button_states[device] = false
|
||||
if not usages[wheel_button] then
|
||||
device:enable_evdev_usage(wheel_button)
|
||||
end
|
||||
device:connect("evdev-frame", evdev_frame)
|
||||
device:connect("device-removed", function(dev)
|
||||
button_states[dev] = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
libinput:connect("new-evdev-device", device_new)
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
plugins = [
|
||||
'10-example.lua',
|
||||
'10-dwt.lua',
|
||||
'10-logitech-mx-master-horiz-scroll.lua',
|
||||
'10-pointer-go-faster.lua',
|
||||
'10-pointer-go-slower.lua',
|
||||
'10-delay-motion.lua',
|
||||
'10-disable-feature.lua',
|
||||
'10-copilot-key-override.lua',
|
||||
'10-wheel-to-button.lua',
|
||||
'10-tablet-mouse-control.lua',
|
||||
]
|
||||
|
||||
fs = import('fs')
|
||||
foreach plugin : plugins
|
||||
fs.copyfile(plugin)
|
||||
endforeach
|
||||
|
|
@ -9,23 +9,3 @@ AttrKeyboardIntegration=internal
|
|||
MatchUdevType=keyboard
|
||||
MatchBus=bluetooth
|
||||
AttrKeyboardIntegration=external
|
||||
|
||||
# Detachable devices usually have the tablet part buttons wired as ps2 keyboard,
|
||||
# don't disable them when tablet-mode switch is in effect.
|
||||
# DMI Chassis Type 20h (32 decimal) is Detachable as per SMBIOS specification.
|
||||
[Detachable Device Buttons]
|
||||
MatchBus=ps2
|
||||
MatchUdevType=keyboard
|
||||
MatchDMIModalias=dmi:*:ct32:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
||||
# Tablet devices usually have the tablet part buttons wired as ps2 keyboard,
|
||||
# despite being tablets some of them, e.g. Microsoft Surface Laptop Studio,
|
||||
# expose tablet-mode switch, so don't disable the ps2 keyboard.
|
||||
# Tablets that don't expose tablet-mode switch won't have any diference.
|
||||
# DMI Chassis Type 1Eh (30 decimal) is Tablet as per SMBIOS specification.
|
||||
[Tablet Device Buttons]
|
||||
MatchBus=ps2
|
||||
MatchUdevType=keyboard
|
||||
MatchDMIModalias=dmi:*:ct30:*
|
||||
ModelTabletModeNoSuspend=1
|
||||
|
|
|
|||
11
quirks/10-generic-lid.quirks
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Do not edit this file, it will be overwritten on update
|
||||
|
||||
[Lid Switch Ct9]
|
||||
MatchName=*Lid Switch*
|
||||
MatchDMIModalias=dmi:*:ct9:*
|
||||
AttrLidSwitchReliability=reliable
|
||||
|
||||
[Lid Switch Ct10]
|
||||
MatchName=*Lid Switch*
|
||||
MatchDMIModalias=dmi:*:ct10:*
|
||||
AttrLidSwitchReliability=reliable
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# Do not edit this file, it will be overwritten on update
|
||||
|
||||
[A4TECH USB X-710BK]
|
||||
MatchUdevType=mouse
|
||||
MatchBus=usb
|
||||
MatchVendor=0x09DA
|
||||
MatchProduct=0x9090
|
||||
ModelBouncingKeys=1
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
MatchUdevType=tablet
|
||||
MatchBus=usb
|
||||
MatchVendor=0x08CA
|
||||
AttrEventCode=-ABS_TILT_X;-ABS_TILT_Y;
|
||||
AttrEventCodeDisable=ABS_TILT_X;ABS_TILT_Y;
|
||||
|
||||
[Aiptek 8000U pressure threshold]
|
||||
MatchUdevType=tablet
|
||||
|
|
|
|||
|
|
@ -1,43 +1,23 @@
|
|||
# Do not edit this file, it will be overwritten on update
|
||||
|
||||
[Contour Design RollerMouse Free 2]
|
||||
MatchUdevType=mouse
|
||||
MatchBus=usb
|
||||
MatchVendor=0x0B33
|
||||
MatchProduct=0x0401
|
||||
MatchUdevType=mouse
|
||||
ModelBouncingKeys=1
|
||||
|
||||
[Contour Design RollerMouse Free 3]
|
||||
MatchUdevType=mouse
|
||||
MatchBus=usb
|
||||
MatchVendor=0x0B33
|
||||
MatchProduct=0x0404
|
||||
MatchUdevType=mouse
|
||||
ModelBouncingKeys=1
|
||||
|
||||
[Contour Design RollerMouse Re:d]
|
||||
MatchUdevType=mouse
|
||||
MatchBus=usb
|
||||
MatchVendor=0x0B33
|
||||
MatchProduct=0x1000
|
||||
MatchUdevType=mouse
|
||||
ModelBouncingKeys=1
|
||||
|
||||
[Contour Design RollerMouse Red v3]
|
||||
MatchUdevType=mouse
|
||||
MatchBus=usb
|
||||
MatchVendor=0x0B33
|
||||
MatchProduct=0x1004
|
||||
ModelBouncingKeys=1
|
||||
|
||||
[Contour Design RollerMouse Pro3]
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
# Do not edit this file, it will be overwritten on update
|
||||
|
||||
[Cyapa Touchpads]
|
||||
MatchBus=i2c
|
||||
MatchUdevType=touchpad
|
||||
MatchName=*Cypress APA Trackpad ?cyapa?
|
||||
AttrPressureRange=10:8
|
||||
|
||||
[Cypress Touchpads]
|
||||
MatchBus=ps2
|
||||
MatchUdevType=touchpad
|
||||
MatchName=*CyPS/2 Cypress Trackpad
|
||||
AttrPressureRange=10:8
|
||||
|
|
|
|||
|
|
@ -9,11 +9,3 @@ AttrPressureRange=10:8
|
|||
MatchName=*Elan Touchpad*
|
||||
AttrResolutionHint=31x31
|
||||
AttrPressureRange=10:8
|
||||
|
||||
# Elan Hapticpad mostly used in Lenovo laptops.
|
||||
[Elan Haptic Touchpad (04F3:3355)]
|
||||
MatchBus=i2c
|
||||
MatchVendor=0x04F3
|
||||
MatchProduct=0x3355
|
||||
MatchUdevType=touchpad
|
||||
AttrInputProp=+INPUT_PROP_PRESSUREPAD
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
# Do not edit this file, it will be overwritten on update
|
||||
|
||||
[Glorious Model O]
|
||||
MatchUdevType=mouse
|
||||
MatchBus=usb
|
||||
MatchVendor=0x258A
|
||||
MatchProduct=0x0036
|
||||
ModelBouncingKeys=1
|
||||
|
|
@ -1,55 +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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
47
quirks/30-vendor-ibm.quirks
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 Scroll Wheel]
|
||||
MatchBus=usb
|
||||
MatchVendor=0x047D
|
||||
MatchProduct=0x2048
|
||||
ModelTrackball=1
|
||||
AttrEventCode=-BTN_MIDDLE
|
||||
AttrEventCodeDisable=BTN_MIDDLE
|
||||
|
|
|
|||