mirror of
https://github.com/X11Libre/xf86-input-libinput.git
synced 2026-03-25 18:08:39 +00:00
Compare commits
332 Commits
xf86-input
...
xlibre-xf8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcfbe775cd | ||
|
|
f86600edd0 | ||
|
|
771cada821 | ||
|
|
d07bc60926 | ||
|
|
4f163b3f73 | ||
|
|
112263280f | ||
|
|
5d27c689bf | ||
|
|
8c2a8fa56c | ||
|
|
ada1d2ed6c | ||
|
|
0f6cc09321 | ||
|
|
733692c9ce | ||
|
|
e0c4e1afc4 | ||
|
|
577d0600c4 | ||
|
|
1d7b5c8196 | ||
|
|
a95e7b25e6 | ||
|
|
f03931201b | ||
|
|
13559018bd | ||
|
|
2e1f7a9b3a | ||
|
|
9e3544b258 | ||
|
|
cda5a982af | ||
|
|
83adc38e59 | ||
|
|
1330f1ded1 | ||
|
|
8366e3a41e | ||
|
|
9c64c0236c | ||
|
|
c674db53d9 | ||
|
|
8a63e97e0c | ||
|
|
c712930ef4 | ||
|
|
db7cfbe5c2 | ||
|
|
cb80d7f82d | ||
|
|
7c5635cd6f | ||
|
|
b396ba3697 | ||
|
|
0bcb60e744 | ||
|
|
3a33984cce | ||
|
|
bb41cc730c | ||
|
|
72c8eb25f8 | ||
|
|
74335c6fd6 | ||
|
|
b791b30b1f | ||
|
|
a7d2994256 | ||
|
|
c6b4d2732f | ||
|
|
6ed6814489 | ||
|
|
a24f467576 | ||
|
|
b254d491e2 | ||
|
|
0dc42f0e4e | ||
|
|
46af622e9d | ||
|
|
5e20d16dd4 | ||
|
|
310db4206f | ||
|
|
94a52a8488 | ||
|
|
a4dfadee2f | ||
|
|
141aa867a6 | ||
|
|
57b049d376 | ||
|
|
8cf533df3a | ||
|
|
484b6a7f3f | ||
|
|
e87c7bfcc2 | ||
|
|
f94a8edb0e | ||
|
|
ca02afd8d2 | ||
|
|
252bc4ba0d | ||
|
|
925903018f | ||
|
|
dfc5e20426 | ||
|
|
2ee183a6cd | ||
|
|
efa999e377 | ||
|
|
7b4a870b23 | ||
|
|
30500626fe | ||
|
|
62f267a952 | ||
|
|
c1f07edafa | ||
|
|
a3d38b0f40 | ||
|
|
e3a75f34f8 | ||
|
|
830f7c3b1b | ||
|
|
4ab7873366 | ||
|
|
b3e65904db | ||
|
|
75cc87518b | ||
|
|
3951ce739d | ||
|
|
cbdd9efaab | ||
|
|
4c54f4d0d2 | ||
|
|
8331214771 | ||
|
|
8588a19f63 | ||
|
|
beb94333e1 | ||
|
|
ca9042c7f0 | ||
|
|
bf8dc2e2ed | ||
|
|
ecd845c307 | ||
|
|
0d9184cb76 | ||
|
|
9bb9e635df | ||
|
|
cc10918bdc | ||
|
|
69888cef81 | ||
|
|
6c1c53d296 | ||
|
|
34f14fdf12 | ||
|
|
92047e5d99 | ||
|
|
b8d3c29f59 | ||
|
|
2bbc4727a1 | ||
|
|
39be944991 | ||
|
|
bd2aaa246d | ||
|
|
99773d7bda | ||
|
|
3afb6244e3 | ||
|
|
f279108ffd | ||
|
|
583ed5acdc | ||
|
|
e8e5d1a6b5 | ||
|
|
639b21d78a | ||
|
|
e52daf203b | ||
|
|
400bf493d1 | ||
|
|
27a88897be | ||
|
|
d5867e5db6 | ||
|
|
1ef2ed874e | ||
|
|
3c9052d886 | ||
|
|
39b0bb4585 | ||
|
|
8923d18d25 | ||
|
|
055481187d | ||
|
|
5a925eaa84 | ||
|
|
e7eafa199e | ||
|
|
d13ab268bd | ||
|
|
347c78387e | ||
|
|
b63f7994dc | ||
|
|
04f42d6e0f | ||
|
|
5d341d1d6c | ||
|
|
4985de5ef3 | ||
|
|
e26fc3c66c | ||
|
|
a759610292 | ||
|
|
21ff2ca7d1 | ||
|
|
c67f191d5b | ||
|
|
1978a2555b | ||
|
|
0909a1a765 | ||
|
|
20bb8d6b9f | ||
|
|
1e88664d95 | ||
|
|
d84e0035d1 | ||
|
|
6c75acfcdf | ||
|
|
eaf847be16 | ||
|
|
d319092d55 | ||
|
|
18cc042e68 | ||
|
|
0db82219bb | ||
|
|
f93bc148d4 | ||
|
|
0d4b50fd6e | ||
|
|
9d9f59fd4c | ||
|
|
7353481490 | ||
|
|
6d3bd4544a | ||
|
|
2be6487de4 | ||
|
|
6ce3d0249d | ||
|
|
87f9fe3a6f | ||
|
|
0c657e0dcf | ||
|
|
ac3574958f | ||
|
|
8772a593b4 | ||
|
|
a80773a488 | ||
|
|
8bc694595d | ||
|
|
153a7fc62f | ||
|
|
72fb6d304e | ||
|
|
aae2c8ad9a | ||
|
|
dafc296f2d | ||
|
|
7c90f06d56 | ||
|
|
2eb5a2f0c0 | ||
|
|
19ceef972e | ||
|
|
07f30ea049 | ||
|
|
6187ed0450 | ||
|
|
974ab6b62b | ||
|
|
5d04707381 | ||
|
|
f65a5c5022 | ||
|
|
0dad7408fa | ||
|
|
ea02578a4e | ||
|
|
2ceb2e1b18 | ||
|
|
f47f78eb0b | ||
|
|
1c3ce3ce3c | ||
|
|
4d481ea7c8 | ||
|
|
72bac84df9 | ||
|
|
0b073d90e6 | ||
|
|
669fbb0985 | ||
|
|
c4f0a9bcb8 | ||
|
|
a61e156326 | ||
|
|
552cbaf466 | ||
|
|
bc91d337d7 | ||
|
|
c8d2293873 | ||
|
|
a7014aa8c6 | ||
|
|
bf7fffde52 | ||
|
|
7282177756 | ||
|
|
1dd61abf7e | ||
|
|
c80954386d | ||
|
|
a790ff35f9 | ||
|
|
6318ac420b | ||
|
|
cd02040a5d | ||
|
|
0cfe9ec6c2 | ||
|
|
b87d2530db | ||
|
|
2f1df46ba9 | ||
|
|
fa69bb1bc2 | ||
|
|
af4fa36884 | ||
|
|
a5b3c209fc | ||
|
|
0f7c5ed02d | ||
|
|
0168716fa1 | ||
|
|
b508c54fa0 | ||
|
|
d43e514430 | ||
|
|
5f2fff3c24 | ||
|
|
116cddba69 | ||
|
|
fb4847d243 | ||
|
|
ce85b11e4c | ||
|
|
77a47a795c | ||
|
|
ae4f0a8d72 | ||
|
|
289de5be15 | ||
|
|
ceea2bb8ba | ||
|
|
d8aef83834 | ||
|
|
34b6ed980f | ||
|
|
ce85432f41 | ||
|
|
181ea654dd | ||
|
|
f9b6fa21df | ||
|
|
3f569ec493 | ||
|
|
602bb8eefa | ||
|
|
13726f404f | ||
|
|
5e7ee73fe2 | ||
|
|
4564a92d59 | ||
|
|
0c2bcd0358 | ||
|
|
b4541e4dff | ||
|
|
8136113139 | ||
|
|
202eb68dc0 | ||
|
|
e8f5394b07 | ||
|
|
20f5269a29 | ||
|
|
3dacb28b20 | ||
|
|
db8e73141c | ||
|
|
0d1851a000 | ||
|
|
ad8483b913 | ||
|
|
1f43f3921f | ||
|
|
83dfd31ec8 | ||
|
|
c943739a2b | ||
|
|
a72e96538a | ||
|
|
b1a9bea607 | ||
|
|
a6aad69a97 | ||
|
|
6fa5f30129 | ||
|
|
c53dde1a50 | ||
|
|
d7331f6e34 | ||
|
|
fb56f6d7a5 | ||
|
|
c8861d2a2f | ||
|
|
44f4b2ed70 | ||
|
|
0163482e22 | ||
|
|
80c356f58f | ||
|
|
1645a79c34 | ||
|
|
b7f8db12a3 | ||
|
|
6abd341279 | ||
|
|
19b42f242d | ||
|
|
f48b64c8cd | ||
|
|
b55239ef25 | ||
|
|
9563334dda | ||
|
|
353c52f2be | ||
|
|
f139f14249 | ||
|
|
e3a888c3ab | ||
|
|
cd61ddb040 | ||
|
|
a199880057 | ||
|
|
cc57eecd72 | ||
|
|
fe58cff48b | ||
|
|
4b2bed6912 | ||
|
|
223be9f62b | ||
|
|
d3ee745a24 | ||
|
|
b550b70a00 | ||
|
|
254b1f27a0 | ||
|
|
bfedf7dbac | ||
|
|
9c5cf97143 | ||
|
|
449b496a3a | ||
|
|
d4e0b5420f | ||
|
|
19c91044e4 | ||
|
|
3d6afca975 | ||
|
|
158e3264ce | ||
|
|
006c802630 | ||
|
|
d6ce065cea | ||
|
|
b9a2150576 | ||
|
|
9356471f3f | ||
|
|
d5fa03c343 | ||
|
|
446401bea9 | ||
|
|
8d4e03570c | ||
|
|
0c5620a29c | ||
|
|
fb50cef700 | ||
|
|
64a0f870e0 | ||
|
|
e362e4dc4c | ||
|
|
7b3b04b518 | ||
|
|
4ac531bdf6 | ||
|
|
7ec0bf7ae2 | ||
|
|
2ffd8d14be | ||
|
|
e9a0ee69cb | ||
|
|
fb6506f5ee | ||
|
|
275c712866 | ||
|
|
2455f0d03b | ||
|
|
98ae01b9ae | ||
|
|
2600a4a352 | ||
|
|
278a685c5a | ||
|
|
875f1696b7 | ||
|
|
45e9b6c64b | ||
|
|
dcdf1e24c8 | ||
|
|
64e1b14598 | ||
|
|
e729451bb1 | ||
|
|
7d73602c4b | ||
|
|
00b96de351 | ||
|
|
8ceed9c73d | ||
|
|
e4cd6cef91 | ||
|
|
7bc662d0b4 | ||
|
|
a55cb9121a | ||
|
|
efb5cacb25 | ||
|
|
2348a6812a | ||
|
|
0c4eaf5480 | ||
|
|
bc7bcca342 | ||
|
|
e5079cd98e | ||
|
|
200be95ac9 | ||
|
|
8b5dbd4c01 | ||
|
|
fb5c5b6f85 | ||
|
|
182363d674 | ||
|
|
f0b14c6ccc | ||
|
|
e92c9f0bad | ||
|
|
dda952fafe | ||
|
|
17302c3352 | ||
|
|
7e3926f2b7 | ||
|
|
9ad23dd1cb | ||
|
|
7b2dbdc224 | ||
|
|
eddc8cb1b2 | ||
|
|
95597d8070 | ||
|
|
a323e221a7 | ||
|
|
6385974e4d | ||
|
|
439a244ae7 | ||
|
|
4a049ad6f8 | ||
|
|
ef948537e1 | ||
|
|
576da9db26 | ||
|
|
2eb01498bd | ||
|
|
a4fb161c3e | ||
|
|
15291e53b7 | ||
|
|
d9c212d266 | ||
|
|
d48f437aa9 | ||
|
|
84f301f7e3 | ||
|
|
6f06b1dd1d | ||
|
|
fdbf7eaf4b | ||
|
|
2b6c485117 | ||
|
|
246200cbdc | ||
|
|
fb41458a93 | ||
|
|
d9d2e9a501 | ||
|
|
0a58edd3f6 | ||
|
|
8d6019c786 | ||
|
|
532fe35522 | ||
|
|
65a40e2cfc | ||
|
|
7522884a9e | ||
|
|
ef5f0295e7 | ||
|
|
adb4963109 | ||
|
|
e8c4bbceee | ||
|
|
e1a9c82dbc | ||
|
|
fe81ad3ae2 | ||
|
|
6a69462359 |
17
.editorconfig
Normal file
17
.editorconfig
Normal file
@@ -0,0 +1,17 @@
|
||||
# https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{c,h}]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[{meson.build,meson_options.txt}]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
65
.github/ISSUE_TEMPLATE/01-bug-report.yml
vendored
Normal file
65
.github/ISSUE_TEMPLATE/01-bug-report.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: 🐞 Bug report
|
||||
description: Create a report to help us improve
|
||||
|
||||
labels: [bug, needs-triage]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill out the sections below to help everyone identify and fix the bug. If you have a general idea or question then please use the [discussions](https://github.com/orgs/X11Libre/discussions).
|
||||
- type: dropdown
|
||||
id: affected-version
|
||||
attributes:
|
||||
label: Select the version
|
||||
options:
|
||||
- 1.5.0.1
|
||||
- Git master branch
|
||||
- other or don't know
|
||||
default: 1
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe your issue
|
||||
placeholder: When I did X then Y happened.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
placeholder: |
|
||||
1. Start ...
|
||||
2. Do this
|
||||
3. Do that
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: What did you expect?
|
||||
placeholder: I expected this to happen.
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: |
|
||||
Additional information you want to provide such as logs, system info, environment, screenshots, etc.
|
||||
placeholder: |
|
||||
Add any other context about the bug here.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Extra fields
|
||||
options:
|
||||
- label: I have checked the existing [issues](https://github.com/X11Libre/xf86-input-libinput/issues)
|
||||
required: true
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/X11Libre/xserver/blob/master/CONTRIBUTING.md)
|
||||
required: true
|
||||
- label: I'd like to work on this issue
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for reporting this issue! We will get back to you as soon as possible.
|
||||
49
.github/ISSUE_TEMPLATE/02-feature-request.yml
vendored
Normal file
49
.github/ISSUE_TEMPLATE/02-feature-request.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: ✨ Feature request
|
||||
description: Suggest a feature for this software
|
||||
labels: [enhancement, needs-triage]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill out the sections below to properly describe the new software feature you are suggesting. If you have a general idea or question then please use the [discussions](https://github.com/orgs/X11Libre/discussions).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: "Describe the feature"
|
||||
placeholder: A thing in X that allows to do Y.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: "It should be done because"
|
||||
placeholder: Doing Y is needed for Z.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: "What are the alternatives?"
|
||||
placeholder: We could do A or B instead.
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Additional information you want to provide such as references to related issues or protocols, the implications on existing use cases, etc.
|
||||
placeholder: |
|
||||
Add any other context about the feature request here.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Extra fields
|
||||
options:
|
||||
- label: I have checked the existing [issues](https://github.com/X11Libre/xf86-input-libinput/issues)
|
||||
required: true
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/X11Libre/xserver/blob/master/CONTRIBUTING.md)
|
||||
required: true
|
||||
- label: I'd like to work on this issue
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your suggestion! Let's see together if it can be done.
|
||||
49
.github/ISSUE_TEMPLATE/03-code-cleanup.yml
vendored
Normal file
49
.github/ISSUE_TEMPLATE/03-code-cleanup.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: 🔧 Code cleanup
|
||||
description: Level up the source code
|
||||
labels: [code-cleanup, needs-triage]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill out the sections below to properly describe the code cleanup you are suggesting. If you have a general idea or question then please use the [discussions](https://github.com/orgs/X11Libre/discussions).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: "Describe the cleanup"
|
||||
placeholder: C in X needs to be changed into D.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: "It should be done because"
|
||||
placeholder: Having D is needed for E.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: "What are the alternatives?"
|
||||
placeholder: We could do A or B instead.
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Additional information you want to provide such as implications on existing code, how to ensure API/ABI stability, which tests are needed or to be run, related issues, etc.
|
||||
placeholder: |
|
||||
Add any other context about the cleanup here.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Extra fields
|
||||
options:
|
||||
- label: I have checked the existing [issues](https://github.com/X11Libre/xf86-input-libinput/issues)
|
||||
required: true
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/X11Libre/xserver/blob/master/CONTRIBUTING.md)
|
||||
required: true
|
||||
- label: I'd like to work on this issue
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for looking at the source code! Let's see together how it can be improved.
|
||||
38
.github/ISSUE_TEMPLATE/04-doc-update.yml
vendored
Normal file
38
.github/ISSUE_TEMPLATE/04-doc-update.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: 🔖 Documentation update
|
||||
description: Make your mark for better documentation
|
||||
|
||||
labels: [documentation, needs-triage]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill out the sections below to help others understand our software. If you have a general idea or question then please use the [discussions](https://github.com/orgs/X11Libre/discussions).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the update
|
||||
placeholder: These things need to be better documented.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: Additional information you want to provide such as tickets related to changes in the software, affected files, screenshots, etc.
|
||||
placeholder: |
|
||||
Add any other context about the update here.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Extra fields
|
||||
options:
|
||||
- label: I have checked the existing [issues](https://github.com/X11Libre/xf86-input-libinput/issues)
|
||||
required: true
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/X11Libre/xserver/blob/master/CONTRIBUTING.md)
|
||||
required: true
|
||||
- label: I'd like to work on this issue
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for requesting this update! We will get back to you as soon as possible.
|
||||
43
.github/ISSUE_TEMPLATE/05-org-task.yml
vendored
Normal file
43
.github/ISSUE_TEMPLATE/05-org-task.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: ✅ Organizational task
|
||||
description: Create a task for project organization
|
||||
|
||||
labels: [needs-triage, organization]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please fill out the sections below to get organizational things done. If you have a general idea or question then please use the [discussions](https://github.com/orgs/X11Libre/discussions).
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the task
|
||||
placeholder: These things need to be done.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: rationale
|
||||
attributes:
|
||||
label: "It should be done because"
|
||||
placeholder: Doing Y is needed for Z.
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: Additional information you want to provide such as the context for bigger tasks, the implicatons on existing workflows, related issues, etc.
|
||||
placeholder: |
|
||||
Add any other context about the task here.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Extra fields
|
||||
options:
|
||||
- label: I have checked the existing [issues](https://github.com/X11Libre/xf86-input-libinput/issues)
|
||||
required: true
|
||||
- label: I have read the [Contributing Guidelines](https://github.com/X11Libre/xserver/blob/master/CONTRIBUTING.md)
|
||||
required: true
|
||||
- label: I'd like to work on this issue
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for adding this task! We will get back to you as soon as possible.
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: XLibre Community Support
|
||||
url: https://github.com/orgs/X11Libre/discussions
|
||||
about: Please ask and answer questions here.
|
||||
- name: Mailing List
|
||||
url: https://www.freelists.org/list/xlibre
|
||||
about: You can join the discussions on our mailing list.
|
||||
69
.github/actions/build-driver/action.yaml
vendored
Normal file
69
.github/actions/build-driver/action.yaml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: 'build driver'
|
||||
description: 'build driver against specific Xserver'
|
||||
inputs:
|
||||
xserver-version:
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: check out driver repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: prepare build environment
|
||||
shell: bash
|
||||
run: |
|
||||
MACHINE=`gcc -dumpmachine`
|
||||
echo "MACHINE=$MACHINE" >> "$GITHUB_ENV"
|
||||
echo "PKG_CONFIG_PATH=$X11_PREFIX/share/pkgconfig:$X11_PREFIX/lib/$MACHINE/pkgconfig:$X11_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH" >> "$GITHUB_ENV"
|
||||
sudo chown root /bin/tar && sudo chmod u+s /bin/tar
|
||||
|
||||
- name: apt cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /var/cache/apt
|
||||
key: apt-cache-${{ hashFiles('.github/scripts/ubuntu/install-pkg.sh') }}
|
||||
restore-keys: apt-cache-
|
||||
|
||||
- name: pkg install
|
||||
shell: bash
|
||||
run: sudo .github/scripts/ubuntu/install-pkg.sh
|
||||
|
||||
- name: X11 prereq cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
${{ env.X11_PREFIX }}
|
||||
key: ${{ runner.name }}-x11-deps-${{ hashFiles('.github/scripts/install-prereq.sh') }}
|
||||
restore-keys: ${{ runner.name }}-x11-deps-
|
||||
|
||||
- name: generic prereq
|
||||
shell: bash
|
||||
run: .github/scripts/install-prereq.sh
|
||||
|
||||
- name: check out xserver repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: X11Libre/xserver
|
||||
path: xserver-sdk
|
||||
ref: ${{ inputs.xserver-version }}
|
||||
|
||||
- name: build xserver sdk
|
||||
shell: bash
|
||||
env:
|
||||
MESON_ARGS: -Dc_args="-fno-common" -Dprefix=/usr -Dnamespace=false -Dxselinux=false -Dxephyr=false -Dwerror=false -Dxcsecurity=false -Dxorg=true -Dxvfb=false -Dxnest=false -Ddocs=false
|
||||
run: |
|
||||
cd xserver-sdk
|
||||
echo -n > .meson_environment
|
||||
echo "export MESON_BUILDDIR=$MESON_BUILDDIR" >> .meson_environment
|
||||
echo "export PKG_CONFIG_PATH=$PKG_CONFIG_PATH" >> .meson_environment
|
||||
.gitlab-ci/meson-build.sh --skip-test
|
||||
sudo meson install --no-rebuild -C "$MESON_BUILDDIR"
|
||||
sudo mkdir -p /usr/local/lib/$MACHINE/xorg/modules # /home/runner/x11/lib/xorg/modules
|
||||
sudo chown -R runner /usr/local/lib/$MACHINE/xorg/modules # /home/runner/x11/lib/xorg/modules
|
||||
|
||||
- name: compile driver
|
||||
shell: bash
|
||||
run: |
|
||||
CFLAGS="-Wall" ./autogen.sh # --prefix=$X11_PREFIX
|
||||
CFLAGS="-Wall" make -j # install
|
||||
13
.github/scripts/conf.sh
vendored
Normal file
13
.github/scripts/conf.sh
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export X11_OS=`uname -s`
|
||||
|
||||
export X11_PREFIX="${X11_PREFIX:-$HOME/x11}"
|
||||
export X11_BUILD_DIR="${X11_BUILD_DIR:-$HOME/build-deps}"
|
||||
export DRV_BUILD_DIR="${DRV_BUILD_DIR:-$HOME/build-drivers}"
|
||||
|
||||
case "$X11_OS" in
|
||||
Darwin) export FDO_CI_CONCURRENT=`sysctl -n hw.logicalcpu` ;;
|
||||
Linux) export FDO_CI_CONCURRENT=`nproc` ;;
|
||||
esac
|
||||
|
||||
export PATH="$X11_PREFIX/bin:$PATH"
|
||||
export PKG_CONFIG_PATH="$X11_PREFIX/lib/x86_64-linux-gnu/pkgconfig:$X11_PREFIX/lib/pkgconfig:$X11_PREFIX/share/pkgconfig:$PKG_CONFIG_PATH"
|
||||
17
.github/scripts/github/make-release
vendored
Executable file
17
.github/scripts/github/make-release
vendored
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
err() {
|
||||
echo "$0: $*"
|
||||
}
|
||||
|
||||
[ "$GITHUB_REPOSITORY" ] || err "missing variable GITHUB_REPOSITORY"
|
||||
|
||||
TITLE=$(git tag -l --format='%(contents)' $tag)
|
||||
|
||||
echo "tag=$tag"
|
||||
echo "title=$TITLE"
|
||||
|
||||
gh release create "$tag" \
|
||||
--repo="$GITHUB_REPOSITORY" \
|
||||
--title="$tag" \
|
||||
--generate-notes
|
||||
15
.github/scripts/install-prereq.sh
vendored
Executable file
15
.github/scripts/install-prereq.sh
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
. .github/scripts/util.sh
|
||||
|
||||
mkdir -p $X11_BUILD_DIR
|
||||
cd $X11_BUILD_DIR
|
||||
|
||||
if [ "$X11_OS" = "Linux" ]; then
|
||||
build_meson drm https://gitlab.freedesktop.org/mesa/drm libdrm-2.4.121 "" \
|
||||
-Domap=enabled
|
||||
fi
|
||||
build_meson libxcvt https://gitlab.freedesktop.org/xorg/lib/libxcvt libxcvt-0.1.0
|
||||
build_ac xorgproto https://gitlab.freedesktop.org/xorg/proto/xorgproto xorgproto-2024.1
|
||||
94
.github/scripts/ubuntu/install-pkg.sh
vendored
Executable file
94
.github/scripts/ubuntu/install-pkg.sh
vendored
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Packages which are needed by this script, but not for the xserver build
|
||||
EPHEMERAL="
|
||||
libexpat-dev
|
||||
libgles2-mesa-dev
|
||||
libxkbcommon-dev
|
||||
x11-utils
|
||||
x11-xserver-utils
|
||||
xauth
|
||||
xvfb
|
||||
"
|
||||
|
||||
apt-get update
|
||||
|
||||
apt-get install -y \
|
||||
$EPHEMERAL \
|
||||
autoconf \
|
||||
automake \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
libaudit-dev \
|
||||
libbsd-dev \
|
||||
libcairo2-dev \
|
||||
libdbus-1-dev \
|
||||
libdrm-dev \
|
||||
libegl1-mesa-dev \
|
||||
libepoxy-dev \
|
||||
libevdev2 \
|
||||
libexpat1 \
|
||||
libffi-dev \
|
||||
libgbm-dev \
|
||||
libgcrypt-dev \
|
||||
libgl1-mesa-dev \
|
||||
libgles2 \
|
||||
libglx-mesa0 \
|
||||
libinput10 \
|
||||
libinput-dev \
|
||||
libnvidia-egl-wayland-dev \
|
||||
libpciaccess-dev \
|
||||
libpixman-1-dev \
|
||||
libspice-protocol-dev \
|
||||
libsystemd-dev \
|
||||
libudev-dev \
|
||||
libunwind-dev \
|
||||
libx11-dev \
|
||||
libx11-xcb-dev \
|
||||
libxau-dev \
|
||||
libxaw7-dev \
|
||||
libxcb-glx0-dev \
|
||||
libxcb-icccm4-dev \
|
||||
libxcb-image0-dev \
|
||||
libxcb-keysyms1-dev \
|
||||
libxcb-randr0-dev \
|
||||
libxcb-render-util0-dev \
|
||||
libxcb-render0-dev \
|
||||
libxcb-shape0-dev \
|
||||
libxcb-shm0-dev \
|
||||
libxcb-util0-dev \
|
||||
libxcb-xf86dri0-dev \
|
||||
libxcb-xkb-dev \
|
||||
libxcb-xv0-dev \
|
||||
libxcb1-dev \
|
||||
libxdmcp-dev \
|
||||
libxext-dev \
|
||||
libxfixes-dev \
|
||||
libxfont-dev \
|
||||
libxi-dev \
|
||||
libxinerama-dev \
|
||||
libxkbcommon0 \
|
||||
libxkbfile-dev \
|
||||
libxmu-dev \
|
||||
libxmuu-dev \
|
||||
libxpm-dev \
|
||||
libxrender-dev \
|
||||
libxres-dev \
|
||||
libxshmfence-dev \
|
||||
libxt-dev \
|
||||
libxtst-dev \
|
||||
libxv-dev \
|
||||
mesa-common-dev \
|
||||
meson \
|
||||
nettle-dev \
|
||||
libpango1.0-dev \
|
||||
pkg-config \
|
||||
x11-xkb-utils \
|
||||
xfonts-utils \
|
||||
xkb-data \
|
||||
xtrans-dev \
|
||||
xutils-dev \
|
||||
libxaw7-dev \
|
||||
python3-mako
|
||||
85
.github/scripts/util.sh
vendored
Normal file
85
.github/scripts/util.sh
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
. .github/scripts/conf.sh
|
||||
|
||||
clone_source() {
|
||||
local pkgname="$1"
|
||||
local url="$2"
|
||||
local ref="$3"
|
||||
local commit="$4"
|
||||
|
||||
if [ ! -f $pkgname/.git/config ]; then
|
||||
echo "need to clone $pkgname"
|
||||
if [ "$commit" ]; then
|
||||
git clone $url $pkgname --branch=$ref
|
||||
else
|
||||
git clone $url $pkgname --branch=$ref --depth 1
|
||||
fi
|
||||
else
|
||||
echo "already cloned $pkgname"
|
||||
fi
|
||||
|
||||
if [ "$commit" ]; then
|
||||
( cd $pkgname && git checkout -f "$commit" )
|
||||
fi
|
||||
}
|
||||
|
||||
build_meson() {
|
||||
local pkgname="$1"
|
||||
local url="$2"
|
||||
local ref="$3"
|
||||
local commit="$4"
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
shift || true
|
||||
if [ -f $X11_PREFIX/$pkgname.DONE ]; then
|
||||
echo "package $pkgname already built"
|
||||
else
|
||||
clone_source "$pkgname" "$url" "$ref" "$commit"
|
||||
(
|
||||
cd $pkgname
|
||||
meson "$@" build -Dprefix=$X11_PREFIX
|
||||
ninja -j${FDO_CI_CONCURRENT:-4} -C build install
|
||||
)
|
||||
touch $X11_PREFIX/$pkgname.DONE
|
||||
fi
|
||||
}
|
||||
|
||||
build_ac() {
|
||||
local pkgname="$1"
|
||||
local url="$2"
|
||||
local ref="$3"
|
||||
local commit="$4"
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
shift || true
|
||||
if [ -f $X11_PREFIX/$pkgname.DONE ]; then
|
||||
echo "package $pkgname already built"
|
||||
else
|
||||
clone_source "$pkgname" "$url" "$ref" "$commit"
|
||||
(
|
||||
cd $pkgname
|
||||
./autogen.sh --prefix=$X11_PREFIX
|
||||
make -j${FDO_CI_CONCURRENT:-4} install
|
||||
)
|
||||
touch $X11_PREFIX/$pkgname.DONE
|
||||
fi
|
||||
}
|
||||
|
||||
build_drv_ac() {
|
||||
local pkgname="$1"
|
||||
local url="$2"
|
||||
local ref="$3"
|
||||
local commit="$4"
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
shift || true
|
||||
clone_source "$pkgname" "$url" "$ref" "$commit"
|
||||
(
|
||||
cd $pkgname
|
||||
./autogen.sh # --prefix=$X11_PREFIX
|
||||
make -j${FDO_CI_CONCURRENT:-4} # install
|
||||
)
|
||||
}
|
||||
43
.github/workflows/build.yml
vendored
Normal file
43
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Build driver
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
MESON_BUILDDIR: "build"
|
||||
X11_PREFIX: /home/runner/x11
|
||||
X11_BUILD_DIR: /home/runner/build-deps
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
for-xserver-stable-25_0:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-driver
|
||||
with:
|
||||
xserver-version: xlibre-xserver-25.0.0.5
|
||||
|
||||
for-xserver-master:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/build-driver
|
||||
with:
|
||||
xserver-version: master
|
||||
|
||||
release:
|
||||
name: Release pushed tag
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/xlibre-') }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Create release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.ref_name }}
|
||||
run: .github/scripts/github/make-release
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -71,8 +71,17 @@ core
|
||||
*.tar.bz2
|
||||
*.tar.gz
|
||||
#
|
||||
# Add & Override patterns for xf86-input-libinput
|
||||
# Add & Override patterns for xf86-input-libinput
|
||||
#
|
||||
# Edit the following section as needed
|
||||
# For example, !report.pc overrides *.pc. See 'man gitignore'
|
||||
#
|
||||
#
|
||||
*.log
|
||||
*.trs
|
||||
*.swp
|
||||
*.announce
|
||||
*.sig
|
||||
test-driver
|
||||
tags
|
||||
.vimdir
|
||||
test/test-bezier
|
||||
|
||||
98
.gitlab-ci.yml
Normal file
98
.gitlab-ci.yml
Normal file
@@ -0,0 +1,98 @@
|
||||
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
|
||||
#
|
||||
# This CI uses the freedesktop.org ci-templates.
|
||||
# Please see the ci-templates documentation for details:
|
||||
# https://freedesktop.pages.freedesktop.org/ci-templates/
|
||||
|
||||
.templates_sha: &template_sha 84052757dacc5fd65f5ace92b7fe63c60f6c8558 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
|
||||
|
||||
include:
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: *template_sha
|
||||
file: '/templates/fedora.yml'
|
||||
- project: 'freedesktop/ci-templates'
|
||||
ref: *template_sha
|
||||
file: '/templates/ci-fairy.yml'
|
||||
- template: Security/SAST.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
FDO_UPSTREAM_REPO: xorg/driver/xf86-input-libinput
|
||||
|
||||
|
||||
stages:
|
||||
- containers
|
||||
- build
|
||||
- test
|
||||
|
||||
.fedora:
|
||||
variables:
|
||||
FDO_DISTRIBUTION_VERSION: 39
|
||||
FDO_DISTRIBUTION_PACKAGES: 'git autoconf automake libtool make xorg-x11-server-devel libudev-devel libevdev-devel libinput-devel xorg-x11-util-macros diffutils'
|
||||
FDO_DISTRIBUTION_EXEC: 'env FDO_CI_CONCURRENT=${FDO_CI_CONCURRENT} bash .gitlab-ci/fedora-install.sh'
|
||||
FDO_DISTRIBUTION_TAG: '2025-04-01.0'
|
||||
|
||||
|
||||
fedora@container_build:
|
||||
extends:
|
||||
- .fedora
|
||||
- .fdo.container-build@fedora
|
||||
stage: containers
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
|
||||
.default_build:
|
||||
stage: build
|
||||
script:
|
||||
- mkdir _builddir _inst
|
||||
- pushd _builddir > /dev/null
|
||||
- ../autogen.sh --prefix=$(realpath ../_inst) --disable-silent-rules
|
||||
- make && make check
|
||||
- make install
|
||||
- popd > /dev/null
|
||||
artifacts:
|
||||
name: "automake-logs-$CI_JOB_NAME"
|
||||
when: always
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- _builddir/config.log
|
||||
|
||||
|
||||
fedora@default-build:
|
||||
extends:
|
||||
- .fedora
|
||||
- .fdo.distribution-image@fedora
|
||||
- .default_build
|
||||
|
||||
#
|
||||
# Verify that commit messages are as expected
|
||||
#
|
||||
check-commits:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: test
|
||||
script:
|
||||
- ci-fairy check-commits --junit-xml=results.xml
|
||||
except:
|
||||
- master@xorg/driver/xf86-input-libinput
|
||||
variables:
|
||||
GIT_DEPTH: 100
|
||||
artifacts:
|
||||
reports:
|
||||
junit: results.xml
|
||||
allow_failure: true
|
||||
|
||||
#
|
||||
# Verify that the merge request has the allow-collaboration checkbox ticked
|
||||
#
|
||||
check-merge-request:
|
||||
extends:
|
||||
- .fdo.ci-fairy
|
||||
stage: test
|
||||
script:
|
||||
- ci-fairy check-merge-request --require-allow-collaboration --junit-xml=results.xml
|
||||
artifacts:
|
||||
when: on_failure
|
||||
reports:
|
||||
junit: results.xml
|
||||
allow_failure: true
|
||||
9
.gitlab-ci/fedora-install.sh
Executable file
9
.gitlab-ci/fedora-install.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# we require at least inputproto >= 2.3.99.1 which has been released in xorgproto 2021.5
|
||||
git clone https://gitlab.freedesktop.org/xorg/proto/xorgproto.git --depth 1 --branch=xorgproto-2021.5
|
||||
pushd xorgproto
|
||||
./autogen.sh
|
||||
make -j${FDO_CI_CONCURRENT:-4} install
|
||||
popd
|
||||
rm -rf xorgproto
|
||||
36
COPYING
36
COPYING
@@ -1,20 +1,20 @@
|
||||
Copyright © 2014 Red Hat, Inc.
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software
|
||||
and its documentation for any purpose is hereby granted without
|
||||
fee, provided that the above copyright notice appear in all copies
|
||||
and that both that copyright notice and this permission notice
|
||||
appear in supporting documentation, and that the name of the authors
|
||||
not be used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission. The authors make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
11
Makefile.am
11
Makefile.am
@@ -19,15 +19,18 @@
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
# Provide an sdk location that is writable by the evdev module
|
||||
DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg'
|
||||
# During distcheck, system locations (as provided by pkg-config) may
|
||||
# not be writable; provide instead relative locations.
|
||||
DISTCHECK_CONFIGURE_FLAGS = --with-xorg-module-dir='$${libdir}/xorg/modules' \
|
||||
--with-sdkdir='$${includedir}/xorg'
|
||||
|
||||
SUBDIRS = src
|
||||
SUBDIRS = src include man test
|
||||
MAINTAINERCLEANFILES = ChangeLog INSTALL
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = xorg-libinput.pc
|
||||
|
||||
dist_xorgconf_DATA = conf/40-libinput.conf
|
||||
|
||||
.PHONY: ChangeLog INSTALL
|
||||
|
||||
@@ -38,3 +41,5 @@ ChangeLog:
|
||||
$(CHANGELOG_CMD)
|
||||
|
||||
dist-hook: ChangeLog INSTALL
|
||||
|
||||
EXTRA_DIST = README.md
|
||||
|
||||
33
README.md
Normal file
33
README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
xf86-input-libinput - a libinput-based X driver
|
||||
===============================================
|
||||
|
||||
The official repository for this driver is
|
||||
|
||||
https://github.com/X11Libre/xf86-input-evdev
|
||||
|
||||
This is an X driver based on libinput. It is a thin wrapper around libinput,
|
||||
so while it does provide all features that libinput supports it does little
|
||||
beyond.
|
||||
|
||||
***WARNING: misconfiguration of an X input driver may leave you without
|
||||
usable input devices in your X session. Use with caution.***
|
||||
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
To build this driver:
|
||||
|
||||
autoreconf -vif
|
||||
./configure --prefix=$HOME/build
|
||||
make && make install
|
||||
|
||||
Note that this assumes the same prefix as used in "Building the X Window
|
||||
System" above, adjust as required. If you want a system install, use a
|
||||
prefix of */usr*.
|
||||
|
||||
Install the default configuration file:
|
||||
|
||||
cp conf/99-libinput.conf /etc/X11/xorg.conf.d/
|
||||
|
||||
This will assign this driver to *all* devices. Use with caution.
|
||||
17
autogen.sh
Executable file
17
autogen.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#! /bin/sh
|
||||
|
||||
srcdir=`dirname "$0"`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd "$srcdir"
|
||||
|
||||
autoreconf -v --install || exit 1
|
||||
cd "$ORIGDIR" || exit $?
|
||||
|
||||
git config --local --get format.subjectPrefix >/dev/null 2>&1 ||
|
||||
git config --local format.subjectPrefix "PATCH xf86-input-libinput"
|
||||
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
exec "$srcdir"/configure "$@"
|
||||
fi
|
||||
52
conf/40-libinput.conf
Normal file
52
conf/40-libinput.conf
Normal file
@@ -0,0 +1,52 @@
|
||||
# Match on all types of devices but joysticks
|
||||
#
|
||||
# If you want to configure your devices, do not copy this file.
|
||||
# Instead, use a config snippet that contains something like this:
|
||||
#
|
||||
# Section "InputClass"
|
||||
# Identifier "something or other"
|
||||
# MatchDriver "libinput"
|
||||
#
|
||||
# MatchIsTouchpad "on"
|
||||
# ... other Match directives ...
|
||||
# Option "someoption" "value"
|
||||
# EndSection
|
||||
#
|
||||
# This applies the option any libinput device also matched by the other
|
||||
# directives. See the xorg.conf(5) man page for more info on
|
||||
# matching devices.
|
||||
|
||||
Section "InputClass"
|
||||
Identifier "libinput pointer catchall"
|
||||
MatchIsPointer "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "libinput"
|
||||
EndSection
|
||||
|
||||
Section "InputClass"
|
||||
Identifier "libinput keyboard catchall"
|
||||
MatchIsKeyboard "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "libinput"
|
||||
EndSection
|
||||
|
||||
Section "InputClass"
|
||||
Identifier "libinput touchpad catchall"
|
||||
MatchIsTouchpad "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "libinput"
|
||||
EndSection
|
||||
|
||||
Section "InputClass"
|
||||
Identifier "libinput touchscreen catchall"
|
||||
MatchIsTouchscreen "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "libinput"
|
||||
EndSection
|
||||
|
||||
Section "InputClass"
|
||||
Identifier "libinput tablet catchall"
|
||||
MatchIsTablet "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "libinput"
|
||||
EndSection
|
||||
122
configure.ac
122
configure.ac
@@ -22,42 +22,129 @@
|
||||
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ([2.60])
|
||||
AC_INIT([xf86-input-libinput],
|
||||
[0.1.1],
|
||||
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
|
||||
[xf86-input-libinput])
|
||||
AC_INIT([xlibre-xf86-input-libinput],
|
||||
[1.5.2],
|
||||
[https://github.com/X11Libre/xf86-input-libinput/issues],
|
||||
[xlibre-xf86-input-libinput])
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_AUX_DIR(.)
|
||||
|
||||
# Initialize Automake
|
||||
AM_INIT_AUTOMAKE([foreign dist-bzip2])
|
||||
AM_INIT_AUTOMAKE([foreign dist-xz])
|
||||
|
||||
# Initialize libtool
|
||||
AC_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
LT_INIT
|
||||
|
||||
# Initialize X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
|
||||
m4_ifndef([XORG_MACROS_VERSION],
|
||||
m4_ifndef([XORG_MACROS_VERSION],
|
||||
[m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
|
||||
XORG_MACROS_VERSION(1.8)
|
||||
XORG_DEFAULT_OPTIONS
|
||||
|
||||
CFLAGS="$CFLAGS -Wno-declaration-after-statement"
|
||||
|
||||
# Obtain compiler/linker options from server and required extensions
|
||||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto [inputproto >= 2.2])
|
||||
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 0.4.0])
|
||||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.19] xproto [inputproto >= 2.2])
|
||||
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 1.11.0])
|
||||
|
||||
PKG_CHECK_MODULES(INPUTPROTO24, [inputproto >= 2.3.99.1],
|
||||
[AC_DEFINE(HAVE_INPUTPROTO24, [1], [inputproto 2.4 is available])],
|
||||
[:])
|
||||
|
||||
OLD_LIBS=$LIBS
|
||||
OLD_CFLAGS=$CFLAGS
|
||||
LIBS="$LIBS $LIBINPUT_LIBS"
|
||||
CFLAGS="$CFLAGS $LIBINPUT_CFLAGS"
|
||||
|
||||
AC_MSG_CHECKING([if libinput_device_config_scroll_get_button_lock is available])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <libinput.h>]],
|
||||
[[libinput_device_config_scroll_get_button_lock(NULL)]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBINPUT_SCROLL_BUTTON_LOCK, [1],
|
||||
[libinput_device_config_scroll_get_button_lock() is available])
|
||||
[libinput_have_scroll_button_lock=yes]],
|
||||
[AC_MSG_RESULT([no])
|
||||
[libinput_have_scroll_button_lock=no]])
|
||||
|
||||
AC_MSG_CHECKING([if libinput_event_pointer_get_scroll_value_v120 is available])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <libinput.h>]],
|
||||
[[libinput_event_pointer_get_scroll_value_v120(NULL, 0)]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBINPUT_AXIS_VALUE_V120, [1],
|
||||
[libinput_event_pointer_get_scroll_value_v120() is available])
|
||||
[libinput_have_axis_value_v120=yes]],
|
||||
[AC_MSG_RESULT([no])
|
||||
[libinput_have_axis_value_v120=no]])
|
||||
|
||||
AC_MSG_CHECKING([if libinput_config_accel_create is available])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <libinput.h>]],
|
||||
[[libinput_config_accel_create(0)]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBINPUT_CUSTOM_ACCEL, [1],
|
||||
[libinput_config_accel_create() is available])
|
||||
[libinput_have_custom_accel=yes]],
|
||||
[AC_MSG_RESULT([no])
|
||||
[libinput_have_custom_accel=no]])
|
||||
|
||||
AC_MSG_CHECKING([if libinput_tablet_tool_config_pressure_range_set is available])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <libinput.h>]],
|
||||
[[libinput_tablet_tool_config_pressure_range_set(0)]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBINPUT_PRESURE_RANGE, [1],
|
||||
[libinput_tablet_tool_config_pressure_range_set() is available])
|
||||
[libinput_have_pressure_range=yes]],
|
||||
[AC_MSG_RESULT([no])
|
||||
[libinput_have_pressure_range=no]])
|
||||
|
||||
AC_MSG_CHECKING([if libinput_device_config_click_set_clickfinger_button_map is available])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <libinput.h>]],
|
||||
[[libinput_device_config_click_set_clickfinger_button_map(NULL, 0)]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP, [1],
|
||||
[libinput_device_config_click_set_clickfinger_button_map() is available])
|
||||
[libinput_have_clickfinger_button_map=yes]],
|
||||
[AC_MSG_RESULT([no])
|
||||
[libinput_have_clickfinger_button_map=no]])
|
||||
|
||||
AC_MSG_CHECKING([if libinput_plugin_system_load is available])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <libinput.h>]],
|
||||
[[libinput_plugin_system_load_plugins(NULL, 0)]])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LIBINPUT_PLUGINS, [1],
|
||||
[libinput_plugin_system_load_plugins() is available])
|
||||
[libinput_have_plugin_system=yes]],
|
||||
[AC_MSG_RESULT([no])
|
||||
[libinput_have_plugin_system=no]])
|
||||
|
||||
LIBS=$OLD_LIBS
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
|
||||
# Define a configure option for an alternate input module directory
|
||||
PKG_PROG_PKG_CONFIG([0.25])
|
||||
AC_ARG_WITH(xorg-module-dir,
|
||||
AC_HELP_STRING([--with-xorg-module-dir=DIR],
|
||||
[Default xorg module directory [[default=$libdir/xorg/modules]]]),
|
||||
AS_HELP_STRING([--with-xorg-module-dir=DIR],
|
||||
[Default xorg module directory]),
|
||||
[moduledir="$withval"],
|
||||
[moduledir="$libdir/xorg/modules"])
|
||||
[moduledir=`$PKG_CONFIG --variable=moduledir xorg-server`])
|
||||
inputdir=${moduledir}/input
|
||||
AC_SUBST(inputdir)
|
||||
|
||||
# X Server SDK location is required to install evdev header files
|
||||
# This location is also relayed in the xorg-evdev.pc file
|
||||
AC_ARG_WITH(xorg-conf-dir,
|
||||
AC_HELP_STRING([--with-xorg-conf-dir=DIR],
|
||||
[Default xorg.conf.d directory [[default=${prefix}/share/X11/xorg.conf.d]]]),
|
||||
[xorgconfdir="$withval"],
|
||||
[xorgconfdir='${prefix}/share/X11/xorg.conf.d'])
|
||||
AC_SUBST(xorgconfdir)
|
||||
|
||||
# X Server SDK location is required to install header files
|
||||
sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server`
|
||||
|
||||
# Workaround overriding sdkdir to be able to create a tarball when user has no
|
||||
@@ -69,6 +156,9 @@ DRIVER_NAME=libinput
|
||||
AC_SUBST([DRIVER_NAME])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
xorg-libinput.pc])
|
||||
include/Makefile
|
||||
src/Makefile
|
||||
man/Makefile
|
||||
test/Makefile
|
||||
xorg-libinput.pc])
|
||||
AC_OUTPUT
|
||||
|
||||
1
include/Makefile.am
Normal file
1
include/Makefile.am
Normal file
@@ -0,0 +1 @@
|
||||
sdk_HEADERS = libinput-properties.h
|
||||
269
include/libinput-properties.h
Normal file
269
include/libinput-properties.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBINPUT_PROPERTIES_H_
|
||||
#define _LIBINPUT_PROPERTIES_H_
|
||||
|
||||
/* Tapping enabled/disabled: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_TAP "libinput Tapping Enabled"
|
||||
|
||||
/* Tapping default enabled/disabled: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_TAP_DEFAULT "libinput Tapping Enabled Default"
|
||||
|
||||
/* Tap drag enabled/disabled: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_TAP_DRAG "libinput Tapping Drag Enabled"
|
||||
|
||||
/* Tap drag default enabled/disabled: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_TAP_DRAG_DEFAULT "libinput Tapping Drag Enabled Default"
|
||||
|
||||
/* Tap drag lock enabled/disabled: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_TAP_DRAG_LOCK "libinput Tapping Drag Lock Enabled"
|
||||
|
||||
/* Tap drag lock default enabled/disabled: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_TAP_DRAG_LOCK_DEFAULT "libinput Tapping Drag Lock Enabled Default"
|
||||
|
||||
/* Tap button order: BOOL, 2 values in order LRM, LMR, only one may be set
|
||||
at any time */
|
||||
#define LIBINPUT_PROP_TAP_BUTTONMAP "libinput Tapping Button Mapping Enabled"
|
||||
|
||||
/* Tap button default order: BOOL, 2 values in order LRM, LMR, read-only */
|
||||
#define LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT "libinput Tapping Button Mapping Default"
|
||||
|
||||
/* Clickfinger button order: BOOL, 2 values in order LRM, LMR, only one may be set
|
||||
at any time */
|
||||
#define LIBINPUT_PROP_CLICKFINGER_BUTTONMAP "libinput Clickfinger Button Mapping Enabled"
|
||||
|
||||
/* Clickfinger button default order: BOOL, 2 values in order LRM, LMR, read-only */
|
||||
#define LIBINPUT_PROP_CLICKFINGER_BUTTONMAP_DEFAULT "libinput Clickfinger Button Mapping Default"
|
||||
|
||||
/* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows */
|
||||
#define LIBINPUT_PROP_CALIBRATION "libinput Calibration Matrix"
|
||||
|
||||
/* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows, read-only*/
|
||||
#define LIBINPUT_PROP_CALIBRATION_DEFAULT "libinput Calibration Matrix Default"
|
||||
|
||||
/* Pointer accel speed: FLOAT, 1 value, 32 bit */
|
||||
#define LIBINPUT_PROP_ACCEL "libinput Accel Speed"
|
||||
|
||||
/* Pointer accel speed: FLOAT, 1 value, 32 bit, read-only*/
|
||||
#define LIBINPUT_PROP_ACCEL_DEFAULT "libinput Accel Speed Default"
|
||||
|
||||
/* Pointer accel profile: BOOL, 3 values in order adaptive, flat, custom
|
||||
* only one is enabled at a time at max, read-only */
|
||||
#define LIBINPUT_PROP_ACCEL_PROFILES_AVAILABLE "libinput Accel Profiles Available"
|
||||
|
||||
/* Pointer accel profile: BOOL, 3 values in order adaptive, flat, custom
|
||||
only one is enabled at a time at max, read-only */
|
||||
#define LIBINPUT_PROP_ACCEL_PROFILE_ENABLED_DEFAULT "libinput Accel Profile Enabled Default"
|
||||
|
||||
/* Pointer accel profile: BOOL, 3 values in order adaptive, flat, custom
|
||||
only one is enabled at a time at max */
|
||||
#define LIBINPUT_PROP_ACCEL_PROFILE_ENABLED "libinput Accel Profile Enabled"
|
||||
|
||||
/* Points for the custom accel profile: FLOAT, N values */
|
||||
#define LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_FALLBACK "libinput Accel Custom Fallback Points"
|
||||
|
||||
/* Steps for the custom accel profile: FLOAT, 1 value */
|
||||
#define LIBINPUT_PROP_ACCEL_CUSTOM_STEP_FALLBACK "libinput Accel Custom Fallback Step"
|
||||
|
||||
/* Points for the custom accel profile: FLOAT, N values */
|
||||
#define LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_MOTION "libinput Accel Custom Motion Points"
|
||||
|
||||
/* Steps for the custom accel profile: FLOAT, 1 value */
|
||||
#define LIBINPUT_PROP_ACCEL_CUSTOM_STEP_MOTION "libinput Accel Custom Motion Step"
|
||||
|
||||
/* Points for the custom accel profile: FLOAT, N values */
|
||||
#define LIBINPUT_PROP_ACCEL_CUSTOM_POINTS_SCROLL "libinput Accel Custom Scroll Points"
|
||||
|
||||
/* Steps for the custom accel profile: FLOAT, 1 value */
|
||||
#define LIBINPUT_PROP_ACCEL_CUSTOM_STEP_SCROLL "libinput Accel Custom Scroll Step"
|
||||
|
||||
/* Natural scrolling: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_NATURAL_SCROLL "libinput Natural Scrolling Enabled"
|
||||
|
||||
/* Natural scrolling: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_NATURAL_SCROLL_DEFAULT "libinput Natural Scrolling Enabled Default"
|
||||
|
||||
/* Send-events mode: BOOL read-only, 2 values in order disabled,
|
||||
disabled-on-external-mouse */
|
||||
#define LIBINPUT_PROP_SENDEVENTS_AVAILABLE "libinput Send Events Modes Available"
|
||||
|
||||
/* Send-events mode: BOOL, 2 values in order disabled,
|
||||
disabled-on-external-mouse */
|
||||
#define LIBINPUT_PROP_SENDEVENTS_ENABLED "libinput Send Events Mode Enabled"
|
||||
|
||||
/* Send-events mode: BOOL, 2 values in order disabled,
|
||||
disabled-on-external-mouse, read-only */
|
||||
#define LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT "libinput Send Events Mode Enabled Default"
|
||||
|
||||
/* Left-handed enabled/disabled: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_LEFT_HANDED "libinput Left Handed Enabled"
|
||||
|
||||
/* Left-handed enabled/disabled: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_LEFT_HANDED_DEFAULT "libinput Left Handed Enabled Default"
|
||||
|
||||
/* Scroll method: BOOL read-only, 3 values in order 2fg, edge, button.
|
||||
shows available scroll methods */
|
||||
#define LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE "libinput Scroll Methods Available"
|
||||
|
||||
/* Scroll method: BOOL, 3 values in order 2fg, edge, button
|
||||
only one is enabled at a time at max */
|
||||
#define LIBINPUT_PROP_SCROLL_METHOD_ENABLED "libinput Scroll Method Enabled"
|
||||
|
||||
/* Scroll method: BOOL, 3 values in order 2fg, edge, button
|
||||
only one is enabled at a time at max, read-only */
|
||||
#define LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT "libinput Scroll Method Enabled Default"
|
||||
|
||||
/* Scroll button for button scrolling: 32-bit int, 1 value */
|
||||
#define LIBINPUT_PROP_SCROLL_BUTTON "libinput Button Scrolling Button"
|
||||
|
||||
/* Scroll button for button scrolling: 32-bit int, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_SCROLL_BUTTON_DEFAULT "libinput Button Scrolling Button Default"
|
||||
|
||||
/* Scroll button lock: BOOL, 1 value, TRUE for enabled, FALSE otherwise */
|
||||
#define LIBINPUT_PROP_SCROLL_BUTTON_LOCK "libinput Button Scrolling Button Lock Enabled"
|
||||
|
||||
/* Scroll button lock: BOOL, 1 value, TRUE for enabled, FALSE otherwise, read-only*/
|
||||
#define LIBINPUT_PROP_SCROLL_BUTTON_LOCK_DEFAULT "libinput Button Scrolling Button Lock Enabled Default"
|
||||
|
||||
/* Scroll pixel distance: CARD32, 1 value (with implementation-defined limits) */
|
||||
#define LIBINPUT_PROP_SCROLL_PIXEL_DISTANCE "libinput Scrolling Pixel Distance"
|
||||
|
||||
/* Scroll pixel distance: CARD32, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_SCROLL_PIXEL_DISTANCE_DEFAULT "libinput Scrolling Pixel Distance Default"
|
||||
|
||||
/* Scroll factor: FLOAT, 1 value, 32 bit */
|
||||
#define LIBINPUT_PROP_SCROLL_FACTOR "libinput Scrolling Factor"
|
||||
|
||||
/* Scroll factor: FLOAT, 1 value, 32 bit, read-only */
|
||||
#define LIBINPUT_PROP_SCROLL_FACTOR_DEFAULT "libinput Scrolling Factor Default"
|
||||
|
||||
/* Click method: BOOL read-only, 2 values in order buttonareas, clickfinger
|
||||
shows available click methods */
|
||||
#define LIBINPUT_PROP_CLICK_METHODS_AVAILABLE "libinput Click Methods Available"
|
||||
|
||||
/* Click method: BOOL, 2 values in order buttonareas, clickfinger
|
||||
only one enabled at a time at max */
|
||||
#define LIBINPUT_PROP_CLICK_METHOD_ENABLED "libinput Click Method Enabled"
|
||||
|
||||
/* Click method: BOOL, 2 values in order buttonareas, clickfinger
|
||||
only one enabled at a time at max, read-only */
|
||||
#define LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT "libinput Click Method Enabled Default"
|
||||
|
||||
/* Middle button emulation: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_MIDDLE_EMULATION_ENABLED "libinput Middle Emulation Enabled"
|
||||
|
||||
/* Middle button emulation: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_MIDDLE_EMULATION_ENABLED_DEFAULT "libinput Middle Emulation Enabled Default"
|
||||
|
||||
/* Disable while typing: BOOL, 1 value */
|
||||
#define LIBINPUT_PROP_DISABLE_WHILE_TYPING "libinput Disable While Typing Enabled"
|
||||
|
||||
/* Disable while typing: BOOL, 1 value, read-only */
|
||||
#define LIBINPUT_PROP_DISABLE_WHILE_TYPING_DEFAULT "libinput Disable While Typing Enabled Default"
|
||||
|
||||
/* Drag lock buttons, either:
|
||||
CARD8, one value, the meta lock button, or
|
||||
CARD8, n * 2 values, the drag lock pairs with n being the button and n+1
|
||||
the target button number */
|
||||
#define LIBINPUT_PROP_DRAG_LOCK_BUTTONS "libinput Drag Lock Buttons"
|
||||
|
||||
/* Horizontal scroll events enabled: BOOL, 1 value (0 or 1).
|
||||
* If disabled, horizontal scroll events are discarded */
|
||||
#define LIBINPUT_PROP_HORIZ_SCROLL_ENABLED "libinput Horizontal Scroll Enabled"
|
||||
|
||||
/* Number of modes each pad mode group has available: CARD8, one for each
|
||||
* pad mode group, read-only.
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_PAD_MODE_GROUPS_AVAILABLE "libinput Pad Mode Groups Modes Available"
|
||||
|
||||
/* Mode each pad mode group is currently in: CARD8, one for each pad mode
|
||||
* group, read-only.
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_PAD_MODE_GROUPS "libinput Pad Mode Groups Modes"
|
||||
|
||||
/* The association of each logical button with the pad mode group: INT8,
|
||||
* one for each logical button. If set to -1 the button cannot be associated
|
||||
* with a mode group. read-only
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_PAD_MODE_GROUP_BUTTONS "libinput Pad Mode Group Buttons"
|
||||
|
||||
/* The association of each logical strip with the pad mode group: INT8,
|
||||
* one for each logical strip. If set to -1 the strip cannot be associated
|
||||
* with a mode group. read-only
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_PAD_MODE_GROUP_STRIPS "libinput Pad Mode Group Strips"
|
||||
|
||||
/* The association of each logical ring with the pad mode group: INT8,
|
||||
* one for each logical ring. If set to -1 the ring cannot be associated
|
||||
* with a mode group. read-only
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_PAD_MODE_GROUP_RINGS "libinput Pad Mode Group Rings"
|
||||
|
||||
/* Device rotation: FLOAT, 1 value, 32 bit */
|
||||
#define LIBINPUT_PROP_ROTATION_ANGLE "libinput Rotation Angle"
|
||||
|
||||
/* Device rotation: FLOAT, 1 value, 32 bit, read-only */
|
||||
#define LIBINPUT_PROP_ROTATION_ANGLE_DEFAULT "libinput Rotation Angle Default"
|
||||
|
||||
/* Tablet tool pressure curve: float, 8 values, 32 bit
|
||||
* Value range is [0.0, 1.0], the values specify the x/y of the four
|
||||
* control points for a cubic bezier curve.
|
||||
* Default value: 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_TOOL_PRESSURECURVE "libinput Tablet Tool Pressurecurve"
|
||||
|
||||
/* Tablet tool pressure range: float, 2 values, 32 bit
|
||||
* Value range is [0.0, 1.0] for min and max physical pressure to map to the logical range
|
||||
* Default value: 0.0 1.0
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_TOOL_PRESSURE_RANGE "libinput Tablet Tool Pressure Range"
|
||||
|
||||
/* Tablet tool pressure range: float, 2 values, 32 bit, read-only */
|
||||
#define LIBINPUT_PROP_TABLET_TOOL_PRESSURE_RANGE_DEFAULT "libinput Tablet Tool Pressure Range Default"
|
||||
|
||||
/* Tablet tool area ratio: CARD32, 2 values, w and h */
|
||||
#define LIBINPUT_PROP_TABLET_TOOL_AREA_RATIO "libinput Tablet Tool Area Ratio"
|
||||
|
||||
/* High-resolution wheel scroll events enabled: BOOL, 1 value (0 or 1).
|
||||
* If disabled, high-resolution wheel scroll events are discarded */
|
||||
#define LIBINPUT_PROP_HIRES_WHEEL_SCROLL_ENABLED "libinput High Resolution Wheel Scroll Enabled"
|
||||
|
||||
/* The tablet tool unique serial number: CARD32, 1 value, constant for the
|
||||
* lifetime of the device.
|
||||
*
|
||||
* If this property exists and is zero, the tool does not have a unique serial
|
||||
* number.
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_TOOL_SERIAL "libinput Tablet Tool Serial"
|
||||
|
||||
/* The tablet tool hardware ID: CARD32, 1 value, constant for the lifetime of the device.
|
||||
*
|
||||
* This property only exists if the device has a known tool ID.
|
||||
* See libinput_tablet_tool_get_tool_id() in the libinput documentation for details.
|
||||
*/
|
||||
#define LIBINPUT_PROP_TABLET_TOOL_ID "libinput Tablet Tool ID"
|
||||
|
||||
#endif /* _LIBINPUT_PROPERTIES_H_ */
|
||||
40
man/Makefile.am
Normal file
40
man/Makefile.am
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
drivermandir = $(DRIVER_MAN_DIR)
|
||||
|
||||
driverman_PRE = $(DRIVER_NAME).man
|
||||
|
||||
driverman_DATA = $(driverman_PRE:man=$(DRIVER_MAN_SUFFIX))
|
||||
|
||||
EXTRA_DIST = $(DRIVER_NAME).man
|
||||
|
||||
CLEANFILES = $(driverman_DATA)
|
||||
|
||||
SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man
|
||||
|
||||
MAN_SUBSTS += \
|
||||
-e 's|\@VERSION\@|$(PACKAGE_NAME) $(PACKAGE_VERSION)|g'
|
||||
|
||||
# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
|
||||
.man.$(DRIVER_MAN_SUFFIX):
|
||||
$(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
|
||||
612
man/libinput.man
Normal file
612
man/libinput.man
Normal file
@@ -0,0 +1,612 @@
|
||||
'\" t
|
||||
.\" shorthand for double quote that works everywhere.
|
||||
.ds q \N'34'
|
||||
.TH LIBINPUT 4 2025-06-01 "@VERSION@"
|
||||
.SH NAME
|
||||
libinput \- libinput-based X.Org input driver
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.B "Section \*qInputDevice\*q"
|
||||
.BI " Identifier \*q" devname \*q
|
||||
.B " Driver \*qlibinput\*q"
|
||||
.BI " Option \*qDevice\*q \*q" devpath \*q
|
||||
\ \ ...
|
||||
.B EndSection
|
||||
.fi
|
||||
|
||||
.SH NOTE
|
||||
This is the man page for the X input driver.
|
||||
If you are looking for the library documentation, go to
|
||||
.B http://wayland.freedesktop.org/libinput/doc/
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B libinput
|
||||
is an XLibre input driver based on libinput.
|
||||
It therefore supports all input devices that libinput can handle, including
|
||||
most mice, keyboards, tablets and touchscreens.
|
||||
.PP
|
||||
It is recommended that
|
||||
.B libinput
|
||||
devices are configured through the
|
||||
.B InputClass
|
||||
directive (refer to
|
||||
.BR xorg.conf (5))
|
||||
instead of manual per-device configuration.
|
||||
Devices configured using the
|
||||
.B InputDevice
|
||||
directive in the
|
||||
.BR xorg.conf (5)
|
||||
file are not hot-plug capable.
|
||||
|
||||
.SH CONFIGURATION DETAILS
|
||||
Please refer to
|
||||
.BR xorg.conf (5)
|
||||
for general configuration details
|
||||
and for options that can be used with all input drivers.
|
||||
This section only covers configuration details specific to this driver.
|
||||
.PP
|
||||
The following driver
|
||||
.B Options
|
||||
are supported:
|
||||
.TP 7
|
||||
.BI "Option \*qAccelProfile\*q \*q" string \*q
|
||||
Sets the pointer acceleration profile to the given profile.
|
||||
Permitted values are
|
||||
.BR adaptive ,
|
||||
.BR flat ,
|
||||
.BR custom .
|
||||
Not all devices support this option or all profiles.
|
||||
If a profile is unsupported, the default profile for this device is used.
|
||||
For a description on the profiles and their behavior,
|
||||
see the libinput documentation.
|
||||
.TP 7
|
||||
.BI "Option \*qAccelSpeed\*q \*q" float \*q
|
||||
Sets the pointer acceleration speed within the range [-1, 1].
|
||||
This only applies to the flat or adaptive profile.
|
||||
.TP 7
|
||||
.BI "Option \*qAccelPointsFallback\*q \*q" string \*q
|
||||
.TQ
|
||||
.BI "Option \*qAccelPointsMotion\*q \*q" string \*q
|
||||
.TQ
|
||||
.BI "Option \*qAccelPointsScroll\*q \*q" string \*q
|
||||
Sets the points of the Fallback/Motion/Scroll acceleration functions.
|
||||
The string must be a space-separated list of
|
||||
floating point non-negative numbers, e.g.,
|
||||
"0.0 1.0 2.4 2.5".
|
||||
This only applies to the custom profile.
|
||||
See section
|
||||
.B CUSTOM ACCELERATION PROFILE
|
||||
.TP 7
|
||||
.BI "Option \*qAccelStepFallback\*q \*q" float \*q
|
||||
.TQ
|
||||
.BI "Option \*qAccelStepMotion\*q \*q" float \*q
|
||||
.TQ
|
||||
.BI "Option \*qAccelStepScroll\*q \*q" float \*q
|
||||
Sets the step between the points of the Fallback/Motion/Scroll
|
||||
acceleration functions.
|
||||
When a step of 0.0 is provided,
|
||||
libinput's Fallback acceleration function is used.
|
||||
This only applies to the custom profile.
|
||||
See section
|
||||
.B CUSTOM ACCELERATION PROFILE
|
||||
.TP 7
|
||||
.BI "Option \*qButtonMapping\*q \*q" string \*q
|
||||
Sets the logical button mapping for this device, see
|
||||
.BR XSetPointerMapping (3).
|
||||
The string must be a space-separated list of button mappings in the order of the
|
||||
logical buttons on the device, starting with button 1.
|
||||
The default mapping is "1 2 3 ... 32".
|
||||
A mapping of 0 deactivates the button.
|
||||
Multiple buttons can have the same mapping.
|
||||
Invalid mapping strings are discarded and the default mapping
|
||||
is used for all buttons.
|
||||
Buttons not specified in the user's mapping use the default mapping.
|
||||
See section
|
||||
.B BUTTON MAPPING
|
||||
for more details.
|
||||
.TP 7
|
||||
.BI "Option \*qCalibrationMatrix\*q \*q" string \*q
|
||||
A string of 9 space-separated floating point numbers, in the order
|
||||
\*qa b c d e f g h i\*q.
|
||||
Sets the calibration matrix to the 3x3 matrix where the first row is (abc),
|
||||
the second row is (def) and the third row is (ghi).
|
||||
.TP 7
|
||||
.BI "Option \*qClickMethod\*q \*q" string \*q
|
||||
Enables a click method.
|
||||
Permitted values are
|
||||
.BR none ,
|
||||
.BR buttonareas ,
|
||||
.BR clickfinger .
|
||||
Not all devices support all methods.
|
||||
If an option is unsupported, the default click method for this device is used.
|
||||
.TP 7
|
||||
.BI "Option \*qDisableWhileTyping\*q \*q" bool \*q
|
||||
Indicates if the touchpad should be disabled while typing on the keyboard
|
||||
(this does not apply to modifier keys such as Ctrl or Alt).
|
||||
.TP 7
|
||||
.BI "Option \*qDevice\*q \*q" string \*q
|
||||
Specifies the device through which the device can be accessed.
|
||||
This will generally be of the form \*q/dev/input/eventX\*q,
|
||||
where X is some integer.
|
||||
When using
|
||||
.B InputClass
|
||||
directives, this option is set by the server.
|
||||
The mapping from device node to hardware is system-dependent.
|
||||
Property: "Device Node" (read-only).
|
||||
.TP 7
|
||||
.BI "Option \*qDragLockButtons\*q \*q" "L1 B1 L2 B2 ..." \*q
|
||||
Sets "drag lock buttons" that simulate a button logically down even when it has
|
||||
been physically released.
|
||||
To logically release a locked button,
|
||||
a second click of the same button is required.
|
||||
.IP
|
||||
If the option is a single button number, that button acts as the
|
||||
"meta" locking button for the next button number.
|
||||
See section
|
||||
.B BUTTON DRAG LOCK
|
||||
for details.
|
||||
.IP
|
||||
If the option is a list of button number pairs, the first number of each
|
||||
number pair is the lock button, the second number the logical button number
|
||||
to be locked.
|
||||
See section
|
||||
.B BUTTON DRAG LOCK
|
||||
for details.
|
||||
.IP
|
||||
For both meta and button pair configuration,
|
||||
the button numbers are device button numbers, i.e. the
|
||||
.B ButtonMapping
|
||||
applies after drag lock.
|
||||
.TP 7
|
||||
.BI "Option \*qHighResolutionWheelScrolling\*q \*q" bool \*q
|
||||
Disables high-resolution wheel scroll events, enabled by default. When enabled,
|
||||
the driver forwards only high-resolution wheel scroll events from libinput.
|
||||
When disabled, the driver forwards legacy wheel scroll events instead.
|
||||
.TP 7
|
||||
.BI "Option \*qHorizontalScrolling\*q \*q" bool \*q
|
||||
Enables or disables horizontal scrolling.
|
||||
When disabled,
|
||||
this driver will discard any horizontal scroll events from libinput.
|
||||
This does not disable horizontal scroll events from libinput;
|
||||
it merely discards the horizontal axis from any scroll events.
|
||||
Default is enabled.
|
||||
.TP 7
|
||||
.BI "Option \*qLeftHanded\*q \*q" bool \*q
|
||||
Enables left-handed button orientation, i.e. swapping left and right buttons.
|
||||
.TP 7
|
||||
.BI "Option \*qMiddleEmulation\*q \*q" bool \*q
|
||||
Enables middle button emulation.
|
||||
When enabled, pressing the left and right
|
||||
buttons simultaneously produces a middle mouse button click.
|
||||
A synonym
|
||||
.IP
|
||||
.BI "Option \*qEmulate3Buttons\*q \*q" bool \*q
|
||||
.IP
|
||||
is preserved for compatibility with
|
||||
.B evdev
|
||||
driver, with
|
||||
.BI "\*qMiddleEmulation\*q
|
||||
having preference if both are set.
|
||||
.TP 7
|
||||
.BI "Option \*qNaturalScrolling\*q \*q" bool \*q
|
||||
Enables or disables natural scrolling behavior.
|
||||
.TP 7
|
||||
.BI "Option \*qRotationAngle\*q \*q" float \*q
|
||||
Sets the rotation angle of the device to the given angle, in degrees clockwise.
|
||||
The angle must be between 0.0 (inclusive) and 360.0 (exclusive).
|
||||
.TP 7
|
||||
.BI "Option \*qScrollButton\*q \*q" int \*q
|
||||
Designates a button as scroll button.
|
||||
If the
|
||||
.B ScrollMethod
|
||||
is
|
||||
.B button
|
||||
and the button is logically down, x/y axis movement is converted into
|
||||
scroll events.
|
||||
.TP 7
|
||||
.BI "Option \*qScrollButtonLock\*q \*q" bool \*q
|
||||
Enables or disables the scroll button lock.
|
||||
If enabled, the
|
||||
.B ScrollButton
|
||||
is considered logically down after the first click and remains down until
|
||||
the second click of that button.
|
||||
If disabled (the default), the
|
||||
.B ScrollButton
|
||||
button is considered logically down while held down and up once physically
|
||||
released.
|
||||
.TP 7
|
||||
.BI "Option \*qScrollFactor\*q \*q" float \*q
|
||||
Sets the scroll factor for scroll events. A value higher than 1.0 means faster scrolling.
|
||||
Applications that don't support xi2 input will instead receive scroll button events
|
||||
less or more frequently depending on the scroll factor value, instead of scrolling "smoother".
|
||||
.TP 7
|
||||
.BI "Option \*qScrollMethod\*q \*q" string \*q
|
||||
Enables a scroll method. Permitted values are
|
||||
.BR none ,
|
||||
.BR twofinger ,
|
||||
.BR edge ,
|
||||
.BR button .
|
||||
Not all devices support all options.
|
||||
If an option is unsupported, the default scroll option for this device is used.
|
||||
.TP 7
|
||||
.BI "Option \*qScrollPixelDistance\*q \*q" int \*q
|
||||
Sets the movement distance, in "pixels", required to trigger one logical
|
||||
wheel click.
|
||||
This option only applies to the scroll methods
|
||||
.BR twofinger ,
|
||||
.BR edge ,
|
||||
.BR button .
|
||||
See section
|
||||
.B SCROLL PIXEL DISTANCE
|
||||
for more details.
|
||||
.TP 7
|
||||
.BI "Option \*qSendEventsMode\*q \*q" (disabled|enabled|disabled-on-external-mouse) \*q
|
||||
Sets the send events mode to disabled, enabled,
|
||||
or "disable when an external mouse is connected".
|
||||
.TP 7
|
||||
.BI "Option \*qTabletToolPressureCurve\*q \*q" "x0/y0 x1/y1 x2/y2 x3/y3" \*q
|
||||
Set the pressure curve for a tablet stylus to the bezier formed by the four
|
||||
points.
|
||||
The respective x/y coordinate must be in the [0.0, 1.0] range.
|
||||
For more information see section
|
||||
.B TABLET TOOL PRESSURE CURVE.
|
||||
.TP 7
|
||||
.BI "Option \*qTabletToolPressureRange\*q \*q" "min max" \*q
|
||||
Set the pressure range for a tablet stylus to the given subset of the physical
|
||||
range.
|
||||
The min/max values must be in the [0.0, 1.0] range.
|
||||
For example, a min of 0.3 means the tablet will send 0 pressure for anything
|
||||
equal or below 30% of the physical pressure range and a max of 0.7 means
|
||||
the tablet sends its maximum pressure value for any pressure equal or higher to
|
||||
70% of the physical pressure range.
|
||||
.TP 7
|
||||
.BI "Option \*qTabletToolAreaRatio\*q \*q" "w:h" \*q
|
||||
Sets the area ratio for a tablet tool.
|
||||
The area always starts at the origin (0/0) and
|
||||
expands to the largest available area with the specified aspect ratio.
|
||||
Events outside this area are cropped to the area.
|
||||
The special value "default" is used for the default mapping
|
||||
(i.e. the device-native mapping).
|
||||
For more information see section
|
||||
.B TABLET TOOL AREA RATIO.
|
||||
.TP 7
|
||||
.BI "Option \*qTapping\*q \*q" bool \*q
|
||||
Enables or disables tap-to-click behavior.
|
||||
.TP 7
|
||||
.BI "Option \*qTappingButtonMap\*q \*q" (lrm|lmr) \*q
|
||||
Set the button mapping for 1/2/3-finger taps to left/right/middle or
|
||||
left/middle/right, respectively.
|
||||
.TP 7
|
||||
.BI "Option \*qTappingDrag\*q \*q" bool \*q
|
||||
Enables or disables drag during tapping behavior ("tap-and-drag").
|
||||
When enabled, a tap followed by a finger held down causes a single button down
|
||||
only, all motions of that finger thus translate into dragging motion.
|
||||
Tap-and-drag requires option
|
||||
.B Tapping
|
||||
to be enabled.
|
||||
.TP 7
|
||||
.BI "Option \*qTappingDragLock\*q \*q" bool \*q
|
||||
Enables or disables drag lock during tapping behavior.
|
||||
When enabled,
|
||||
a finger up during tap-and-drag will not immediately release the button.
|
||||
If the finger is set down again within the timeout,
|
||||
the dragging process continues.
|
||||
.PP
|
||||
For all options, the options are only parsed if the device supports that
|
||||
configuration option.
|
||||
For all options, the default value is the one used by libinput.
|
||||
On configuration failure, the default value is applied.
|
||||
|
||||
.SH SUPPORTED PROPERTIES
|
||||
.B libinput
|
||||
exports runtime-configurable options as properties.
|
||||
If a property listed below is not available,
|
||||
the matching configuration option is not available on the device.
|
||||
This however does not imply that the feature is not available on the device.
|
||||
The following properties are provided by the
|
||||
.B libinput
|
||||
driver.
|
||||
.TP 7
|
||||
.B "libinput Accel Profiles Available"
|
||||
3 boolean values (8 bit, 0 or 1), in order "adaptive", "flat", "custom".
|
||||
Indicates which acceleration profiles are available on this device.
|
||||
.TP 7
|
||||
.B "libinput Accel Profile Enabled"
|
||||
3 boolean values (8 bit, 0 or 1), in order "adaptive", "flat", "custom".
|
||||
Indicates which acceleration profile is currently enabled on this device.
|
||||
.TP 7
|
||||
.B "libinput Accel Speed"
|
||||
1 32-bit float value, defines the pointer speed.
|
||||
Value range -1, 1.
|
||||
This only applies to the flat or adaptive profile.
|
||||
.TP 7
|
||||
.B "libinput Accel Custom Fallback Points"
|
||||
.TQ
|
||||
.B "libinput Accel Custom Motion Points"
|
||||
.TQ
|
||||
.B "libinput Accel Custom Scroll Points"
|
||||
A space-separated list of 32-bit floating point non-negative numbers, e.g.
|
||||
"0.0 1.0 2.4 2.5".
|
||||
Sets the points of the Fallback/Motion/Scroll acceleration functions.
|
||||
This only applies to the custom profile.
|
||||
See section
|
||||
.B CUSTOM ACCELERATION PROFILE
|
||||
.TP 7
|
||||
.B "libinput Accel Custom Fallback Step"
|
||||
.TQ
|
||||
.B "libinput Accel Custom Motion Step"
|
||||
.TQ
|
||||
.B "libinput Accel Custom Scroll Step"
|
||||
1 32-bit float value, sets the step between the points of the
|
||||
Fallback/Motion/Scroll acceleration functions.
|
||||
When a step of 0.0 is provided, libinput's Fallback acceleration
|
||||
function is used.
|
||||
This only applies to the custom profile.
|
||||
See section
|
||||
.B CUSTOM ACCELERATION PROFILE
|
||||
.TP 7
|
||||
.B "libinput Button Scrolling Button"
|
||||
1 32-bit value. Sets the button number to use for button scrolling.
|
||||
This setting is independent of the scroll method, to enable button scrolling the
|
||||
method must be set to button-scrolling and a valid button must be set.
|
||||
.TP 7
|
||||
.B "libinput Button Scrolling Button Lock Enabled"
|
||||
1 boolean value. If true, the scroll button lock is enabled.
|
||||
This setting is independent of the scroll method or the scroll button, to enable
|
||||
button scrolling the method must be set to button-scrolling and a valid
|
||||
button must be set.
|
||||
.TP 7
|
||||
.B "libinput Calibration Matrix"
|
||||
9 32-bit float values, representing a 3x3 calibration matrix, order is row
|
||||
1, row 2, row 3
|
||||
.TP 7
|
||||
.B "libinput Click Methods Available"
|
||||
2 boolean values (8 bit, 0 or 1), in order "buttonareas", "clickfinger".
|
||||
Indicates which click methods are available on this device.
|
||||
.TP 7
|
||||
.B "libinput Click Methods Enabled"
|
||||
2 boolean values (8 bit, 0 or 1), in order "buttonareas", "clickfinger".
|
||||
Indicates which click methods are enabled on this device.
|
||||
.TP 7
|
||||
.B "libinput Drag Lock Buttons"
|
||||
Either one 8-bit value specifying the meta drag lock button, or a list of
|
||||
button pairs.
|
||||
See section
|
||||
.B BUTTON DRAG LOCK
|
||||
for details.
|
||||
.TP 7
|
||||
.B "libinput High Resolution Wheel Scroll Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
Indicates whether high-resolution wheel scroll events are enabled or not.
|
||||
.TP 7
|
||||
.B "libinput Horizontal Scroll Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
Indicates whether horizontal scrolling events are enabled or not.
|
||||
.TP 7
|
||||
.B "libinput Left Handed Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
Indicates if left-handed mode is enabled or disabled.
|
||||
.TP 7
|
||||
.B "libinput Middle Emulation Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
Indicates if middle emulation is enabled or disabled.
|
||||
.TP 7
|
||||
.B "libinput Natural Scrolling Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
1 enables natural scrolling.
|
||||
.TP 7
|
||||
.B "libinput Rotation Angle"
|
||||
1 32-bit float value [0.0 to 360.0).
|
||||
Sets the rotation angle of the device,
|
||||
clockwise of its natural neutral position.
|
||||
.TP 7
|
||||
.B "libinput Scrolling Factor"
|
||||
1 32-bit float value.
|
||||
Sets the scroll factor for scroll events. A value higher than 1.0 means faster scrolling.
|
||||
Applications that don't support xi2 input will instead receive scroll button events
|
||||
less or more frequently depending on the scroll factor value, instead of scrolling "smoother".
|
||||
.TP 7
|
||||
.B "libinput Scroll Methods Available"
|
||||
3 boolean values (8 bit, 0 or 1), in order "two-finger", "edge", "button".
|
||||
Indicates which scroll methods are available on this device.
|
||||
.TP 7
|
||||
.B "libinput Scroll Method Enabled"
|
||||
3 boolean values (8 bit, 0 or 1), in order "two-finger", "edge", "button".
|
||||
Indicates which scroll method is currently enabled on this device.
|
||||
.TP 7
|
||||
.B "libinput Scrolling Pixel Distance"
|
||||
1 32-bit value (nonzero, with additional implementation-defined range checks).
|
||||
Changes the movement distance required to trigger one logical wheel click.
|
||||
.TP 7
|
||||
.B "libinput Send Events Modes Available"
|
||||
2 boolean values (8 bit, 0 or 1), in order "disabled" and
|
||||
"disabled-on-external-mouse".
|
||||
Indicates which send-event modes are available on this device.
|
||||
.TP 7
|
||||
.B "libinput Send Events Mode Enabled"
|
||||
2 boolean values (8 bit, 0 or 1), in order "disabled" and
|
||||
"disabled-on-external-mouse".
|
||||
Indicates which send-event mode is currently enabled on this device.
|
||||
.TP 7
|
||||
.B "libinput Tablet Tool Pressurecurve"
|
||||
4 32-bit float values [0.0 to 1.0].
|
||||
See section
|
||||
.B TABLET TOOL PRESSURE CURVE
|
||||
.TP 7
|
||||
.B "libinput Tablet Tool Area Ratio"
|
||||
2 32-bit values, corresponding to width and height.
|
||||
Special value 0, 0 resets to the default ratio.
|
||||
See section
|
||||
.B TABLET TOOL AREA RATIO
|
||||
for more information.
|
||||
.TP 7
|
||||
.B "libinput Tapping Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
1 enables tapping.
|
||||
.TP 7.
|
||||
.B "libinput Tapping Button Mapping Enabled"
|
||||
2 boolean value (8 bit, 0 or 1), in order "lrm" and "lmr".
|
||||
Indicates which button mapping is currently enabled on this device.
|
||||
.TP 7
|
||||
.B "libinput Tapping Drag Lock Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
1 enables drag lock during tapping.
|
||||
.TP 7
|
||||
.B "libinput Disable While Typing Enabled"
|
||||
1 boolean value (8 bit, 0 or 1).
|
||||
Indicates if disable while typing is enabled or disabled.
|
||||
.PP
|
||||
Most properties have a
|
||||
.B "libinput <property name> Default"
|
||||
equivalent that indicates the default value for this setting on this device.
|
||||
|
||||
.SH BUTTON MAPPING
|
||||
X clients receive events with logical button numbers,
|
||||
where 1, 2, 3 are usually interpreted as left, middle, right;
|
||||
and logical buttons 4, 5, 6, 7 are usually interpreted
|
||||
as scroll up, down, left, right.
|
||||
The fourth and fifth physical buttons on a device
|
||||
will thus send logical buttons 8 and 9.
|
||||
The
|
||||
.B ButtonMapping
|
||||
option adjusts the logical button mapping, it does not affect how a physical
|
||||
button is mapped to a logical button.
|
||||
.PP
|
||||
Traditionally, a device was set to left-handed button mode by applying a
|
||||
button mapping of
|
||||
.B "\*q3 2 1 ...\*q"
|
||||
On systems using the
|
||||
.B libinput
|
||||
XLibre input driver it is recommended to use the
|
||||
.B LeftHanded
|
||||
option instead.
|
||||
.PP
|
||||
The
|
||||
.B libinput
|
||||
XLibre input driver does not use the button mapping after setup.
|
||||
Use
|
||||
.BR XSetPointerMapping (3)
|
||||
to modify the button mapping at runtime.
|
||||
|
||||
.SH BUTTON DRAG LOCK
|
||||
Button drag lock holds a button logically down even when the button itself
|
||||
has been physically released since.
|
||||
Button drag lock comes in two modes.
|
||||
.PP
|
||||
If in "meta" mode, a meta button click activates drag lock for the next
|
||||
button press of any other button.
|
||||
A button click in the future will keep that button held logically down
|
||||
until a subsequent click of that same button.
|
||||
The meta button events themselves are discarded.
|
||||
A separate meta button click is required each time a drag lock should be
|
||||
activated for a button in the future.
|
||||
.PP
|
||||
If in "pairs" mode, each button can be assigned a target locking button.
|
||||
On button click, the target lock button is held logically down until the
|
||||
next click of the same button.
|
||||
The button events themselves are discarded
|
||||
and only the target button events are sent.
|
||||
.PP
|
||||
This feature is provided by this driver, not by libinput.
|
||||
|
||||
.SH TABLET TOOL PRESSURE CURVE
|
||||
The pressure curve affects how stylus pressure is reported.
|
||||
By default, the hardware pressure is reported as-is.
|
||||
By setting a pressure curve, the feel of the stylus can be adjusted
|
||||
to be more like e.g. a pencil or a brush.
|
||||
.PP
|
||||
The pressure curve is a cubic Bezier curve, drawn within a normalized range
|
||||
of 0.0 to 1.0 between the four points provided.
|
||||
This normalized range is applied to the tablet's pressure input
|
||||
so that the highest pressure maps to 1.0.
|
||||
The points must have increasing x coordinates, if x0 is larger than 0.0
|
||||
all pressure values lower than x0 are equivalent to y0.
|
||||
If x3 is less than 1.0,
|
||||
all pressure values higher than x3 are equivalent to y3.
|
||||
.PP
|
||||
The input for a linear curve (default) is "0.0/0.0 0.0/0.0 1.0/1.0 1.0/1.0";
|
||||
a slightly depressed curve (firmer) might be
|
||||
"0.0/0.0 0.05/0.0 1.0/0.95 1.0/1.0";
|
||||
a slightly raised curve (softer) might be "0.0/0.0 0.0/0.05 0.95/1.0 1.0/1.0".
|
||||
.PP
|
||||
This feature is provided by this driver, not by libinput.
|
||||
|
||||
.SH TABLET TOOL AREA RATIO
|
||||
By default, a tablet tool can access the whole sensor area and the tablet
|
||||
area is mapped to the available screen area.
|
||||
For external tablets like the Wacom Intuos series,
|
||||
the height:width ratio of the tablet may be different to that of the monitor,
|
||||
causing the skew of input data.
|
||||
.PP
|
||||
To avoid this skew of input data, an area ratio may be set to match the
|
||||
ratio of the screen device.
|
||||
For example, a ratio of 4:3 will reduce the available area of the tablet
|
||||
to the largest available area with a ratio of 4:3.
|
||||
Events within this area will scale to the tablet's announced axis range,
|
||||
the area ratio is thus transparent to the X server.
|
||||
Any events outside this area will send events equal to the maximum value of
|
||||
that axis.
|
||||
The area always starts at the device's origin in it's current rotation, i.e.,
|
||||
it takes left-handed-ness into account.
|
||||
.PP
|
||||
This feature is provided by this driver, not by libinput.
|
||||
|
||||
.SH SCROLL PIXEL DISTANCE
|
||||
The X server does not support per-pixel scrolling but it does support
|
||||
smooth scrolling.
|
||||
All scroll events however are based around a logical unit of scrolling
|
||||
(traditionally corresponding to a wheel click).
|
||||
It is thus not possible to scroll by 10 pixels, but it is possible for a
|
||||
driver to scroll by 1/10th of a logical wheel click.
|
||||
.PP
|
||||
libinput provides scroll data in pixels.
|
||||
The \fBScrollPixelDistance\fR option defines the amount of movement equivalent
|
||||
to one wheel click.
|
||||
For example, a value of 50 means the user has to move a finger by 50 pixels to
|
||||
generate one logical click event and each pixel is 1/50th of a wheel click.
|
||||
|
||||
.SH CUSTOM ACCELERATION PROFILE
|
||||
The custom pointer acceleration profile gives users full control over the
|
||||
acceleration behavior at different speeds.
|
||||
libinput exposes an acceleration function \fIf(x)\fP
|
||||
where the x-axis is the device speed in device units per millisecond
|
||||
and the y-axis is the pointer speed.
|
||||
.PP
|
||||
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.
|
||||
Thus the points defining the custom function are:
|
||||
.EX
|
||||
(0 * step, f[0]), (1 * step, f[1]), ..., ((n-1) * step, f[n-1])
|
||||
.EE
|
||||
When a velocity value does not lie exactly on those points,
|
||||
a linear interpolation/extrapolation of the two closest points
|
||||
will be calculated.
|
||||
.PP
|
||||
There are 3 custom acceleration functions,
|
||||
which are used for different movement types:
|
||||
.TS
|
||||
tab(;) allbox;
|
||||
l l l.
|
||||
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
|
||||
.TE
|
||||
.PP
|
||||
See libinput library documentation for more details:
|
||||
https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html#the-custom-acceleration-profile
|
||||
|
||||
.SH BUGS
|
||||
This driver does not work with \fBOption \*qDevice\*q\fR set to an event
|
||||
node in \fI/dev/input/by-id\fR and \fI/dev/input/by-path\fR.
|
||||
This can be usually be worked by using \fBSection \*qInputClass\*q\fR with an
|
||||
appropriate \fBMatch*\fR statement in the
|
||||
.BR xorg.conf (5).
|
||||
|
||||
.SH AUTHORS
|
||||
Peter Hutterer
|
||||
.SH "SEE ALSO"
|
||||
.BR XLibre (1),
|
||||
.BR xorg.conf (5),
|
||||
.BR Xserver (1),
|
||||
.BR X (7)
|
||||
158
meson.build
Normal file
158
meson.build
Normal file
@@ -0,0 +1,158 @@
|
||||
project('xf86-input-libinput', 'c',
|
||||
version: '1.5.0', # bump version in configure.ac
|
||||
default_options: ['warning_level=2'],
|
||||
meson_version: '>= 0.50.0')
|
||||
|
||||
driver_version = meson.project_version().split('.')
|
||||
|
||||
dir_pkgconf = get_option('prefix') / get_option('libdir') / 'pkgconfig'
|
||||
dir_man4 = get_option('prefix') / get_option('mandir') / 'man4'
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
cflags = [
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-sign-compare', # lots of work to get rid of this
|
||||
'-Wmissing-prototypes',
|
||||
'-Wstrict-prototypes',
|
||||
'-Wlogical-op',
|
||||
'-Wpointer-arith',
|
||||
'-Wuninitialized',
|
||||
'-Winit-self',
|
||||
'-Wstrict-prototypes',
|
||||
'-Wimplicit-fallthrough',
|
||||
'-Wredundant-decls',
|
||||
'-Wincompatible-pointer-types',
|
||||
'-Wformat=2',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wmissing-declarations',
|
||||
|
||||
'-fvisibility=hidden',
|
||||
]
|
||||
add_project_arguments(cc.get_supported_arguments(cflags), language: 'c')
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
dep_xserver = dependency('xorg-server', version: '>= 1.19')
|
||||
dep_xproto = dependency('xproto')
|
||||
dep_inputproto = dependency('inputproto', version: '>= 2.2')
|
||||
dep_libinput = dependency('libinput', version: '>= 1.11.0')
|
||||
|
||||
config_h = configuration_data()
|
||||
config_h.set('PACKAGE_VERSION_MAJOR', driver_version[0])
|
||||
config_h.set('PACKAGE_VERSION_MINOR', driver_version[1])
|
||||
config_h.set('PACKAGE_VERSION_PATCHLEVEL', driver_version[2])
|
||||
|
||||
if dep_inputproto.version().version_compare('>= 2.3.99.1')
|
||||
config_h.set('HAVE_INPUTPROTO24', 1)
|
||||
endif
|
||||
|
||||
if cc.has_function('libinput_device_config_scroll_get_button_lock',
|
||||
dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_SCROLL_BUTTON_LOCK', 1)
|
||||
endif
|
||||
if cc.has_function('libinput_event_pointer_get_scroll_value_v120',
|
||||
dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_AXIS_VALUE_V120', 1)
|
||||
endif
|
||||
if cc.has_function('libinput_config_accel_create',
|
||||
dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_CUSTOM_ACCEL', 1)
|
||||
endif
|
||||
if cc.has_function('libinput_tablet_tool_config_pressure_range_set',
|
||||
dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_PRESSURE_RANGE', 1)
|
||||
endif
|
||||
if cc.has_function('libinput_device_config_click_set_clickfinger_button_map',
|
||||
dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_CLICKFINGER_BUTTON_MAP', 1)
|
||||
endif
|
||||
if cc.has_header_symbol('libinput.h', 'LIBINPUT_LED_COMPOSE',
|
||||
dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_COMPOSE_AND_KANA', 1)
|
||||
endif
|
||||
if cc.has_function('libinput_plugin_system_load_plugins', dependencies: dep_libinput)
|
||||
config_h.set('HAVE_LIBINPUT_PLUGINS', 1)
|
||||
endif
|
||||
|
||||
dir_headers = get_option('sdkdir')
|
||||
if dir_headers == ''
|
||||
dir_headers = dep_xserver.get_pkgconfig_variable('sdkdir')
|
||||
endif
|
||||
|
||||
dir_xorg_module = get_option('xorg-module-dir')
|
||||
if dir_xorg_module == ''
|
||||
dir_xorg_module = dep_xserver.get_pkgconfig_variable('moduledir') / 'input'
|
||||
endif
|
||||
|
||||
dir_xorg_conf = get_option('xorg-conf-dir')
|
||||
if dir_xorg_conf == ''
|
||||
dir_xorg_conf = dep_xserver.get_pkgconfig_variable('sysconfigdir')
|
||||
endif
|
||||
|
||||
libbezier = static_library('bezier', ['src/bezier.c', 'src/bezier.h'])
|
||||
dep_libbezier = declare_dependency(link_with: libbezier)
|
||||
|
||||
libdraglock = static_library('draglock', ['src/draglock.c', 'src/draglock.h'])
|
||||
dep_libdraglock = declare_dependency(link_with: libdraglock)
|
||||
|
||||
dep_drivers = [
|
||||
dep_xserver,
|
||||
dep_xproto,
|
||||
dep_inputproto,
|
||||
dep_libinput,
|
||||
dep_libbezier,
|
||||
dep_libdraglock,
|
||||
]
|
||||
|
||||
driver_src = ['src/xf86libinput.c', 'src/util-strings.c']
|
||||
driver_lib = shared_module(
|
||||
'libinput_drv',
|
||||
driver_src,
|
||||
name_prefix: '', # we want libinput_drv.so, not liblibinput_drv.so
|
||||
include_directories: include_directories('include'),
|
||||
dependencies: dep_drivers,
|
||||
install: true,
|
||||
install_dir: dir_xorg_module,
|
||||
)
|
||||
|
||||
test_bezier = executable('test-bezier',
|
||||
['test/test-bezier.c'],
|
||||
dependencies: dep_libbezier,
|
||||
include_directories: include_directories('src'),
|
||||
install: false)
|
||||
test('test-bezier', test_bezier)
|
||||
|
||||
test_draglock = executable('test-draglock',
|
||||
['test/test-draglock.c'],
|
||||
dependencies: dep_libdraglock,
|
||||
include_directories: include_directories('src'),
|
||||
install: false)
|
||||
test('test-draglock', test_draglock)
|
||||
|
||||
|
||||
conf_pkgconf = configuration_data()
|
||||
conf_pkgconf.set('PACKAGE_VERSION', meson.project_version())
|
||||
conf_pkgconf.set('sdkdir', dir_headers)
|
||||
|
||||
configure_file(
|
||||
input: 'xorg-libinput.pc.in',
|
||||
output: 'xorg-libinput.pc',
|
||||
configuration: conf_pkgconf,
|
||||
install_dir: dir_pkgconf,
|
||||
)
|
||||
|
||||
config_man = configuration_data()
|
||||
config_man.set('VERSION', '@0@ @1@'.format(meson.project_name(), meson.project_version()))
|
||||
|
||||
configure_file(
|
||||
input: 'man/libinput.man',
|
||||
output: 'libinput.4',
|
||||
configuration: config_man,
|
||||
install_dir: dir_man4
|
||||
)
|
||||
|
||||
install_headers('include/libinput-properties.h', install_dir: dir_headers)
|
||||
|
||||
install_data('conf/40-libinput.conf', install_dir: dir_xorg_conf)
|
||||
|
||||
# Now generate config.h
|
||||
configure_file(output: 'config.h', configuration: config_h)
|
||||
15
meson_options.txt
Normal file
15
meson_options.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
option('sdkdir',
|
||||
type: 'string',
|
||||
value: '',
|
||||
description: 'Directory to install header files in [default=from xorg-server pkgconf]',
|
||||
)
|
||||
option('xorg-module-dir',
|
||||
type : 'string',
|
||||
value : '',
|
||||
description : 'Default xorg module directory [default=from xorg-server pkgconf]',
|
||||
)
|
||||
option('xorg-conf-dir',
|
||||
type : 'string',
|
||||
value : '',
|
||||
description : 'Default xorg.conf.d directory [default=from xorg-server pkgconfig]'
|
||||
)
|
||||
@@ -30,8 +30,16 @@ AM_CPPFLAGS =-I$(top_srcdir)/include $(LIBINPUT_CFLAGS)
|
||||
|
||||
@DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
|
||||
@DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
|
||||
@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS)
|
||||
@DRIVER_NAME@_drv_la_LIBADD = $(LIBINPUT_LIBS) libdraglock.la libbezier.la -lm
|
||||
@DRIVER_NAME@_drv_ladir = @inputdir@
|
||||
|
||||
@DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c
|
||||
@DRIVER_NAME@_drv_la_SOURCES = \
|
||||
xf86libinput.c \
|
||||
util-macros.h \
|
||||
util-strings.h \
|
||||
util-strings.c \
|
||||
$(NULL)
|
||||
|
||||
noinst_LTLIBRARIES = libdraglock.la libbezier.la
|
||||
libdraglock_la_SOURCES = draglock.c draglock.h
|
||||
libbezier_la_SOURCES = bezier.c bezier.h
|
||||
|
||||
179
src/bezier.c
Normal file
179
src/bezier.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2016 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bezier.h"
|
||||
|
||||
const struct bezier_control_point bezier_defaults[4] = {
|
||||
{ 0.0, 0.0 },
|
||||
{ 0.0, 0.0 },
|
||||
{ 1.0, 1.0 },
|
||||
{ 1.0, 1.0 },
|
||||
};
|
||||
|
||||
struct point {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
/**
|
||||
* de Casteljau's algorithm. See this page here
|
||||
* https://pomax.github.io/bezierinfo/#extended
|
||||
*
|
||||
* To play with bezier curve shapes, I used
|
||||
* http://cubic-bezier.com/
|
||||
*/
|
||||
static struct point
|
||||
decasteljau(const struct point *controls,
|
||||
size_t ncontrols,
|
||||
double t)
|
||||
{
|
||||
struct point new_controls[ncontrols];
|
||||
|
||||
if (ncontrols == 1)
|
||||
return controls[0];
|
||||
|
||||
for (int i = 0; i < ncontrols - 1; i++) {
|
||||
new_controls[i].x = (1.0 - t) * controls[i].x + t * controls[i + 1].x;
|
||||
new_controls[i].y = (1.0 - t) * controls[i].y + t * controls[i + 1].y;
|
||||
}
|
||||
|
||||
return decasteljau(new_controls, ncontrols - 1, t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Bézier curve defined by the control points, reduce the curve to
|
||||
* one with ncurve_points.
|
||||
*/
|
||||
static void
|
||||
flatten_curve(const struct point *controls,
|
||||
size_t ncontrols,
|
||||
struct point *curve,
|
||||
size_t ncurve_points)
|
||||
{
|
||||
ncurve_points--; /* make sure we end up with 100/100 as last point */
|
||||
|
||||
for (int i = 0; i <= ncurve_points; i++) {
|
||||
double t = 1.0 * i/ncurve_points;
|
||||
struct point p;
|
||||
|
||||
p = decasteljau(controls, ncontrols, t);
|
||||
curve[i] = p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate line through a and b, set curve[x] for each x between
|
||||
* [a.x, b.x].
|
||||
*
|
||||
* Note: pcurve must be at least b.x size.
|
||||
*/
|
||||
static void
|
||||
line_between(struct point a, struct point b,
|
||||
struct point *curve, size_t curve_sz)
|
||||
{
|
||||
double slope;
|
||||
double offset;
|
||||
|
||||
assert(b.x < curve_sz);
|
||||
|
||||
if (a.x == b.x) {
|
||||
curve[a.x].x = a.x;
|
||||
curve[a.x].y = a.y;
|
||||
return;
|
||||
}
|
||||
|
||||
slope = (double)(b.y - a.y)/(b.x - a.x);
|
||||
offset = a.y - slope * a.x;
|
||||
|
||||
for (int x = a.x; x <= b.x; x++) {
|
||||
struct point p;
|
||||
p.x = x;
|
||||
p.y = slope * x + offset;
|
||||
curve[x] = p;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
cubic_bezier(const struct bezier_control_point controls[4],
|
||||
int *bezier_out,
|
||||
size_t bezier_sz)
|
||||
{
|
||||
const int nsegments = 50;
|
||||
const int range = bezier_sz - 1;
|
||||
struct point curve[nsegments];
|
||||
struct point bezier[bezier_sz];
|
||||
struct point zero = { 0, 0 },
|
||||
max = { range, range};
|
||||
|
||||
/* Scale control points into the [0, bezier_sz) range */
|
||||
struct point ctrls[4];
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (controls[i].x < 0.0 || controls[i].x > 1.0 ||
|
||||
controls[i].y < 0.0 || controls[i].y > 1.0)
|
||||
return false;
|
||||
|
||||
ctrls[i].x = controls[i].x * range;
|
||||
ctrls[i].y = controls[i].y * range;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (ctrls[i].x > ctrls[i+1].x)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Reduce curve to nsegments, because this isn't a drawing program */
|
||||
flatten_curve(ctrls, 4, curve, nsegments);
|
||||
|
||||
/* we now have nsegments points in curve that represent the bezier
|
||||
curve (already in the [0, bezier_sz) range). Run through the
|
||||
points and draw a straight line between each point and voila, we
|
||||
have our curve.
|
||||
|
||||
If the first control points (x0/y0) is not at x == 0 or the last
|
||||
control point (x3/y3) is not at the max value, draw a line
|
||||
between from 0/0 to x0/y0 and from x3/y3 to xmax/y3.
|
||||
*/
|
||||
|
||||
line_between(zero, curve[0], bezier, bezier_sz);
|
||||
|
||||
for (int i = 0; i < nsegments - 1; i++)
|
||||
line_between(curve[i], curve[i+1], bezier, bezier_sz);
|
||||
|
||||
if (curve[nsegments - 1].x < max.x)
|
||||
line_between(curve[nsegments - 1], max, bezier, bezier_sz);
|
||||
|
||||
for (int i = 0; i < bezier_sz; i++)
|
||||
bezier_out[i] = bezier[i].y;
|
||||
|
||||
return true;
|
||||
}
|
||||
71
src/bezier.h
Normal file
71
src/bezier.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2016 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef BEZIER_H
|
||||
#define BEZIER_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct bezier_control_point {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
extern const struct bezier_control_point bezier_defaults[4];
|
||||
|
||||
/**
|
||||
* Given four control points in the range [(0.0/0.0), (1.0/1.0)]
|
||||
* construct a Bézier curve.
|
||||
*
|
||||
* ^
|
||||
*1.0 | c2 ______ c3
|
||||
* | _/
|
||||
* | /
|
||||
* |c1 /
|
||||
* | /
|
||||
* | /
|
||||
* |/_________________>
|
||||
* c0 1.0
|
||||
*
|
||||
* This function requires that c[i].x <= c[i+1].x
|
||||
*
|
||||
* The curve is mapped into a canvas size [0, bezier_sz)². For each x
|
||||
* coordinate in [0, bezier_sz), the matching y coordinate is thus
|
||||
* bezier[x].
|
||||
*
|
||||
* In other words, if you have a range [0,2048) input possible values,
|
||||
* the output is a list of 2048 points in a [0, 2048) range.
|
||||
*
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
bool
|
||||
cubic_bezier(const struct bezier_control_point controls[4],
|
||||
int *bezier,
|
||||
size_t bezier_sz);
|
||||
#endif
|
||||
284
src/draglock.c
Normal file
284
src/draglock.c
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "draglock.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
||||
static int
|
||||
draglock_parse_config(struct draglock *dl, const char *config)
|
||||
{
|
||||
int button = 0, target = 0;
|
||||
const char *str = NULL;
|
||||
char *end_str = NULL;
|
||||
int pairs[DRAGLOCK_MAX_BUTTONS] = {0};
|
||||
|
||||
if (!config)
|
||||
return 0;
|
||||
|
||||
/* empty string disables drag lock */
|
||||
if (*config == '\0') {
|
||||
dl->mode = DRAGLOCK_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for a single-number string first, config is "<int>" */
|
||||
button = strtol(config, &end_str, 10);
|
||||
if (*end_str == '\0') {
|
||||
if (button < 0 || button >= DRAGLOCK_MAX_BUTTONS)
|
||||
return 1;
|
||||
/* we allow for button 0 so stacked xorg.conf.d snippets can
|
||||
* disable the config again */
|
||||
if (button == 0) {
|
||||
dl->mode = DRAGLOCK_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return draglock_set_meta(dl, button);
|
||||
}
|
||||
|
||||
dl->mode = DRAGLOCK_DISABLED;
|
||||
|
||||
/* check for a set of button pairs, config is
|
||||
* "<int> <int> <int> <int>..." */
|
||||
str = config;
|
||||
while (*str != '\0') {
|
||||
button = strtol(str, &end_str, 10);
|
||||
if (*end_str == '\0')
|
||||
return 1;
|
||||
|
||||
str = end_str;
|
||||
target = strtol(str, &end_str, 10);
|
||||
if (end_str == str)
|
||||
return 1;
|
||||
if (button <= 0 || button >= DRAGLOCK_MAX_BUTTONS || target >= DRAGLOCK_MAX_BUTTONS)
|
||||
return 1;
|
||||
|
||||
pairs[button] = target;
|
||||
str = end_str;
|
||||
}
|
||||
|
||||
return draglock_set_pairs(dl, pairs, ARRAY_SIZE(pairs));
|
||||
}
|
||||
|
||||
int
|
||||
draglock_init_from_string(struct draglock *dl, const char *config)
|
||||
{
|
||||
dl->mode = DRAGLOCK_DISABLED;
|
||||
|
||||
dl->meta_button = 0;
|
||||
dl->meta_state = false;
|
||||
memset(dl->lock_pair, 0, sizeof(dl->lock_pair));
|
||||
memset(dl->lock_state, 0, sizeof(dl->lock_state));
|
||||
|
||||
return draglock_parse_config(dl, config);
|
||||
}
|
||||
|
||||
enum draglock_mode
|
||||
draglock_get_mode(const struct draglock *dl)
|
||||
{
|
||||
return dl->mode;
|
||||
}
|
||||
|
||||
int
|
||||
draglock_get_meta(const struct draglock *dl)
|
||||
{
|
||||
if (dl->mode == DRAGLOCK_META)
|
||||
return dl->meta_button;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
draglock_get_pairs(const struct draglock *dl, int *array, size_t nelem)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t last = 0;
|
||||
|
||||
if (dl->mode != DRAGLOCK_PAIRS)
|
||||
return 0;
|
||||
|
||||
/* size 1 array with the meta button */
|
||||
if (dl->meta_button) {
|
||||
*array = dl->meta_button;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* size N array with a[0] == 0, the rest ordered by button number */
|
||||
memset(array, 0, nelem * sizeof(array[0]));
|
||||
for (i = 0; i < nelem && i < ARRAY_SIZE(dl->lock_pair); i++) {
|
||||
array[i] = dl->lock_pair[i];
|
||||
if (array[i] != 0 && i > last)
|
||||
last = i;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
int
|
||||
draglock_set_meta(struct draglock *dl, int meta_button)
|
||||
{
|
||||
if (meta_button < 0 || meta_button >= DRAGLOCK_MAX_BUTTONS)
|
||||
return 1;
|
||||
|
||||
dl->meta_button = meta_button;
|
||||
dl->mode = meta_button ? DRAGLOCK_META : DRAGLOCK_DISABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
draglock_set_pairs(struct draglock *dl, const int *array, size_t nelem)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (nelem == 0 || array[0] != 0)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < nelem; i++) {
|
||||
if (array[i] < 0 || array[i] >= DRAGLOCK_MAX_BUTTONS)
|
||||
return 1;
|
||||
}
|
||||
|
||||
dl->mode = DRAGLOCK_DISABLED;
|
||||
for (i = 0; i < nelem; i++) {
|
||||
dl->lock_pair[i] = array[i];
|
||||
if (dl->lock_pair[i])
|
||||
dl->mode = DRAGLOCK_PAIRS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
draglock_filter_meta(struct draglock *dl, int *button, int *press)
|
||||
{
|
||||
int b = *button,
|
||||
is_press = *press;
|
||||
|
||||
if (b == dl->meta_button) {
|
||||
if (is_press)
|
||||
dl->meta_state = true;
|
||||
*button = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (dl->lock_state[b]) {
|
||||
case DRAGLOCK_BUTTON_STATE_NONE:
|
||||
if (dl->meta_state && is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_1;
|
||||
dl->meta_state = false;
|
||||
}
|
||||
break;
|
||||
case DRAGLOCK_BUTTON_STATE_DOWN_1:
|
||||
if (!is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_UP_1;
|
||||
b = 0;
|
||||
}
|
||||
break;
|
||||
case DRAGLOCK_BUTTON_STATE_UP_1:
|
||||
if (is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_2;
|
||||
b = 0;
|
||||
}
|
||||
break;
|
||||
case DRAGLOCK_BUTTON_STATE_DOWN_2:
|
||||
if (!is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*button = b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
draglock_filter_pair(struct draglock *dl, int *button, int *press)
|
||||
{
|
||||
int b = *button,
|
||||
is_press = *press;
|
||||
|
||||
if (dl->lock_pair[b] == 0)
|
||||
return 0;
|
||||
|
||||
switch (dl->lock_state[b]) {
|
||||
case DRAGLOCK_BUTTON_STATE_NONE:
|
||||
if (is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_1;
|
||||
b = dl->lock_pair[b];
|
||||
}
|
||||
break;
|
||||
case DRAGLOCK_BUTTON_STATE_DOWN_1:
|
||||
if (!is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_UP_1;
|
||||
b = 0;
|
||||
}
|
||||
break;
|
||||
case DRAGLOCK_BUTTON_STATE_UP_1:
|
||||
if (is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_DOWN_2;
|
||||
b = 0;
|
||||
}
|
||||
break;
|
||||
case DRAGLOCK_BUTTON_STATE_DOWN_2:
|
||||
if (!is_press) {
|
||||
dl->lock_state[b] = DRAGLOCK_BUTTON_STATE_NONE;
|
||||
b = dl->lock_pair[b];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*button = b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
draglock_filter_button(struct draglock *dl, int *button, int *is_press)
|
||||
{
|
||||
if (*button == 0)
|
||||
return 0;
|
||||
|
||||
switch(dl->mode) {
|
||||
case DRAGLOCK_DISABLED:
|
||||
return 0;
|
||||
case DRAGLOCK_META:
|
||||
return draglock_filter_meta(dl, button, is_press);
|
||||
case DRAGLOCK_PAIRS:
|
||||
return draglock_filter_pair(dl, button, is_press);
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
161
src/draglock.h
Normal file
161
src/draglock.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef DRAGLOCK_H
|
||||
#define DRAGLOCK_H 1
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* 32 buttons are enough for everybody™
|
||||
* Note that this is the limit of physical buttons as well as the highest
|
||||
* allowed target button.
|
||||
*/
|
||||
#define DRAGLOCK_MAX_BUTTONS 32
|
||||
|
||||
enum draglock_mode
|
||||
{
|
||||
DRAGLOCK_DISABLED,
|
||||
DRAGLOCK_META,
|
||||
DRAGLOCK_PAIRS
|
||||
};
|
||||
|
||||
enum draglock_button_state
|
||||
{
|
||||
DRAGLOCK_BUTTON_STATE_NONE,
|
||||
DRAGLOCK_BUTTON_STATE_DOWN_1,
|
||||
DRAGLOCK_BUTTON_STATE_UP_1,
|
||||
DRAGLOCK_BUTTON_STATE_DOWN_2,
|
||||
};
|
||||
|
||||
struct draglock
|
||||
{
|
||||
enum draglock_mode mode;
|
||||
int meta_button; /* meta key to lock any button */
|
||||
bool meta_state; /* meta_button state */
|
||||
unsigned int lock_pair[DRAGLOCK_MAX_BUTTONS + 1];/* specify a meta/lock pair */
|
||||
enum draglock_button_state lock_state[DRAGLOCK_MAX_BUTTONS + 1]; /* state of any locked buttons */
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the draglock struct based on the config string. The string is
|
||||
* either a single number to configure DRAGLOCK_META mode or a list of
|
||||
* number pairs, with pair[0] as button and pair[1] as target lock number to
|
||||
* configure DRAGLOCK_PAIRS mode.
|
||||
*
|
||||
* If config is NULL, the empty string, "0" or an even-numbered list of 0,
|
||||
* the drag lock mode is DRAGLOCK_DISABLED.
|
||||
*
|
||||
* @return 0 on success or nonzero on error
|
||||
*/
|
||||
int
|
||||
draglock_init_from_string(struct draglock *dl, const char *config);
|
||||
|
||||
/**
|
||||
* Get the current drag lock mode.
|
||||
*
|
||||
* If the mode is DRAGLOCK_META, a meta button click will cause the next
|
||||
* subsequent button click to be held logically down until the release of
|
||||
* the second button click of that same button. Events from the meta button
|
||||
* are always discarded.
|
||||
*
|
||||
* If the mode is DRAGLOCK_PAIRS, any button may be configured with a
|
||||
* 'target' button number. A click of that button causes the target button
|
||||
* to be held logically down until the release of the second button click.
|
||||
*/
|
||||
enum draglock_mode
|
||||
draglock_get_mode(const struct draglock *dl);
|
||||
|
||||
/**
|
||||
* @return the meta button number or 0 if the current mode is not
|
||||
* DRAGLOCK_META.
|
||||
*/
|
||||
int
|
||||
draglock_get_meta(const struct draglock *dl);
|
||||
|
||||
/**
|
||||
* Get the drag lock button mapping pairs. The array is filled with the
|
||||
* button number as index and the mapped target button number as value, i.e.
|
||||
* array[3] == 8 means button 3 will draglock button 8.
|
||||
*
|
||||
* A value of 0 indicates draglock is disabled for that button.
|
||||
*
|
||||
* @note Button numbers start at 1, array[0] is always 0.
|
||||
*
|
||||
* @param[in|out] array Caller-allocated array to hold the button mappings.
|
||||
* @param[in] nelem Maximum number of elements in array
|
||||
*
|
||||
* @return The number of valid elements in array or 0 if the current mode is
|
||||
* not DRAGLOCK_PAIRS
|
||||
*/
|
||||
size_t
|
||||
draglock_get_pairs(const struct draglock *dl, int *array, size_t nelem);
|
||||
|
||||
/**
|
||||
* Set the drag lock config to the DRAGLOCK_META mode, with the given
|
||||
* button as meta button.
|
||||
*
|
||||
* If the button is 0 the mode becomes DRAGLOCK_DISABLED.
|
||||
*
|
||||
* @return 0 on success, nonzero otherwise
|
||||
*/
|
||||
int
|
||||
draglock_set_meta(struct draglock *dl, int meta_button);
|
||||
|
||||
/**
|
||||
* Set the drag lock config to the DRAGLOCK_PAIRS mode. The array
|
||||
* must be filled with the button number as index and the mapped target
|
||||
* button number as value, i.e.
|
||||
* array[3] == 8 means button 3 will draglock button 8.
|
||||
*
|
||||
* A value of 0 indicates draglock is disabled for that button. If all
|
||||
* buttons are 0, the mode becomes DRAGLOCK_DISABLED.
|
||||
*
|
||||
* @note Button numbers start at 1, array[0] is always 0.
|
||||
*
|
||||
* @return 0 on successor nonzero otherwise
|
||||
*/
|
||||
int
|
||||
draglock_set_pairs(struct draglock *dl, const int *array, size_t nelem);
|
||||
|
||||
/**
|
||||
* Process the given button event through the drag lock state machine.
|
||||
* If the event is to be discarded by the caller, button is set to 0.
|
||||
* Otherwise, button is set to the button event to process and is_press is
|
||||
* set to the button state to process.
|
||||
*
|
||||
* @param[in|out] button The button number to process
|
||||
* @param[in|out] is_press nonzero for press, zero for release
|
||||
*
|
||||
* @return 0 on success or 1 on error
|
||||
*/
|
||||
int
|
||||
draglock_filter_button(struct draglock *dl, int *button, int *is_press);
|
||||
|
||||
#endif /* DRAGLOCK_H */
|
||||
672
src/libinput.c
672
src/libinput.c
@@ -1,672 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of Red Hat
|
||||
* not be used in advertising or publicity pertaining to distribution
|
||||
* of the software without specific, written prior permission. Red
|
||||
* Hat makes no representations about the suitability of this software
|
||||
* for any purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
||||
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <xorg-server.h>
|
||||
#include <exevents.h>
|
||||
#include <xkbsrv.h>
|
||||
#include <xf86Xinput.h>
|
||||
#include <xserver-properties.h>
|
||||
#include <libinput.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#define TOUCHPAD_MAX_BUTTONS 7 /* three buttons, 4 scroll buttons */
|
||||
#define TOUCHPAD_NUM_AXES 4 /* x, y, hscroll, vscroll */
|
||||
#define TOUCH_MAX_SLOTS 15
|
||||
#define XORG_KEYCODE_OFFSET 8
|
||||
|
||||
/*
|
||||
libinput does not provide axis information for absolute devices, instead
|
||||
it scales into the screen dimensions provided. So we set up the axes with
|
||||
a fixed range, let libinput scale into that range and then the server
|
||||
do the scaling it usually does.
|
||||
*/
|
||||
#define TOUCH_AXIS_MAX 0xffff
|
||||
|
||||
/*
|
||||
libinput scales wheel events by DEFAULT_AXIS_STEP_DISTANCE, which is
|
||||
currently 10.
|
||||
*/
|
||||
#define DEFAULT_LIBINPUT_AXIS_STEP_DISTANCE 10
|
||||
|
||||
struct xf86libinput_driver {
|
||||
struct libinput *libinput;
|
||||
int device_enabled_count;
|
||||
};
|
||||
|
||||
static struct xf86libinput_driver driver_context;
|
||||
|
||||
struct xf86libinput {
|
||||
char *path;
|
||||
struct libinput_device *device;
|
||||
|
||||
int scroll_vdist;
|
||||
int scroll_hdist;
|
||||
int scroll_vdist_remainder;
|
||||
int scroll_hdist_remainder;
|
||||
|
||||
struct {
|
||||
double x;
|
||||
double y;
|
||||
double x_remainder;
|
||||
double y_remainder;
|
||||
} scale;
|
||||
|
||||
ValuatorMask *valuators;
|
||||
};
|
||||
|
||||
static int
|
||||
xf86libinput_on(DeviceIntPtr dev)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput *libinput = driver_context.libinput;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
|
||||
device = libinput_path_add_device(libinput, driver_data->path);
|
||||
if (!device)
|
||||
return !Success;
|
||||
libinput_device_ref(device);
|
||||
libinput_device_set_user_data(device, pInfo);
|
||||
driver_data->device = device;
|
||||
|
||||
pInfo->fd = libinput_get_fd(libinput);
|
||||
|
||||
if (driver_context.device_enabled_count == 0) {
|
||||
/* Can't use xf86AddEnabledDevice on an epollfd */
|
||||
AddEnabledDevice(pInfo->fd);
|
||||
}
|
||||
|
||||
driver_context.device_enabled_count++;
|
||||
dev->public.on = TRUE;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
xf86libinput_off(DeviceIntPtr dev)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
|
||||
if (--driver_context.device_enabled_count == 0) {
|
||||
RemoveEnabledDevice(pInfo->fd);
|
||||
}
|
||||
|
||||
pInfo->fd = -1;
|
||||
dev->public.on = FALSE;
|
||||
|
||||
libinput_device_set_user_data(driver_data->device, NULL);
|
||||
libinput_path_remove_device(driver_data->device);
|
||||
libinput_device_unref(driver_data->device);
|
||||
driver_data->device = NULL;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_ptr_ctl(DeviceIntPtr dev, PtrCtrl *ctl)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_button_map(unsigned char *btnmap, size_t size)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(btnmap, 0, size);
|
||||
for (i = 0; i <= TOUCHPAD_MAX_BUTTONS; i++)
|
||||
btnmap[i] = i;
|
||||
}
|
||||
|
||||
static void
|
||||
init_button_labels(Atom *labels, size_t size)
|
||||
{
|
||||
memset(labels, 0, size * sizeof(Atom));
|
||||
labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
|
||||
labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
|
||||
labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
|
||||
labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
|
||||
labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
|
||||
labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
|
||||
labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
|
||||
}
|
||||
|
||||
static void
|
||||
init_axis_labels(Atom *labels, size_t size)
|
||||
{
|
||||
memset(labels, 0, size * sizeof(Atom));
|
||||
labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
|
||||
labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
|
||||
labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL);
|
||||
labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL);
|
||||
}
|
||||
|
||||
static int
|
||||
xf86libinput_init_pointer(InputInfoPtr pInfo)
|
||||
{
|
||||
DeviceIntPtr dev= pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
int min, max, res;
|
||||
|
||||
unsigned char btnmap[TOUCHPAD_MAX_BUTTONS + 1];
|
||||
Atom btnlabels[TOUCHPAD_MAX_BUTTONS];
|
||||
Atom axislabels[TOUCHPAD_NUM_AXES];
|
||||
|
||||
init_button_map(btnmap, ARRAY_SIZE(btnmap));
|
||||
init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
|
||||
init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
|
||||
|
||||
InitPointerDeviceStruct((DevicePtr)dev, btnmap,
|
||||
TOUCHPAD_MAX_BUTTONS,
|
||||
btnlabels,
|
||||
xf86libinput_ptr_ctl,
|
||||
GetMotionHistorySize(),
|
||||
TOUCHPAD_NUM_AXES,
|
||||
axislabels);
|
||||
min = -1;
|
||||
max = -1;
|
||||
res = 0;
|
||||
|
||||
xf86InitValuatorAxisStruct(dev, 0,
|
||||
XIGetKnownProperty(AXIS_LABEL_PROP_REL_X),
|
||||
min, max, res * 1000, 0, res * 1000, Relative);
|
||||
xf86InitValuatorAxisStruct(dev, 1,
|
||||
XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y),
|
||||
min, max, res * 1000, 0, res * 1000, Relative);
|
||||
|
||||
SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, driver_data->scroll_hdist, 0);
|
||||
SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, driver_data->scroll_vdist, 0);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_kbd_ctrl(DeviceIntPtr device, KeybdCtrl *ctrl)
|
||||
{
|
||||
#define CAPSFLAG 1
|
||||
#define NUMFLAG 2
|
||||
#define SCROLLFLAG 4
|
||||
|
||||
static struct { int xbit, code; } bits[] = {
|
||||
{ CAPSFLAG, LIBINPUT_LED_CAPS_LOCK },
|
||||
{ NUMFLAG, LIBINPUT_LED_NUM_LOCK },
|
||||
{ SCROLLFLAG, LIBINPUT_LED_SCROLL_LOCK },
|
||||
{ 0, 0 },
|
||||
};
|
||||
int i = 0;
|
||||
enum libinput_led leds = 0;
|
||||
InputInfoPtr pInfo = device->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *ldevice = driver_data->device;
|
||||
|
||||
while (bits[i].xbit) {
|
||||
if (ctrl->leds & bits[i].xbit)
|
||||
leds |= bits[i].code;
|
||||
i++;
|
||||
}
|
||||
|
||||
libinput_device_led_update(ldevice, leds);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_init_keyboard(InputInfoPtr pInfo)
|
||||
{
|
||||
DeviceIntPtr dev= pInfo->dev;
|
||||
XkbRMLVOSet rmlvo = {0};
|
||||
|
||||
rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", "evdev");
|
||||
rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", "pc104");
|
||||
rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", "us");
|
||||
rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", NULL);
|
||||
rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", NULL);
|
||||
|
||||
InitKeyboardDeviceStruct(dev, &rmlvo, NULL,
|
||||
xf86libinput_kbd_ctrl);
|
||||
XkbFreeRMLVOSet(&rmlvo, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_init_touch(InputInfoPtr pInfo)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
int min, max, res;
|
||||
unsigned char btnmap[TOUCHPAD_MAX_BUTTONS + 1];
|
||||
Atom btnlabels[TOUCHPAD_MAX_BUTTONS];
|
||||
Atom axislabels[TOUCHPAD_NUM_AXES];
|
||||
|
||||
init_button_map(btnmap, ARRAY_SIZE(btnmap));
|
||||
init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
|
||||
init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
|
||||
|
||||
InitPointerDeviceStruct((DevicePtr)dev, btnmap,
|
||||
TOUCHPAD_MAX_BUTTONS,
|
||||
btnlabels,
|
||||
xf86libinput_ptr_ctl,
|
||||
GetMotionHistorySize(),
|
||||
TOUCHPAD_NUM_AXES,
|
||||
axislabels);
|
||||
min = 0;
|
||||
max = TOUCH_AXIS_MAX;
|
||||
res = 0;
|
||||
|
||||
xf86InitValuatorAxisStruct(dev, 0,
|
||||
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X),
|
||||
min, max, res * 1000, 0, res * 1000, Absolute);
|
||||
xf86InitValuatorAxisStruct(dev, 1,
|
||||
XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y),
|
||||
min, max, res * 1000, 0, res * 1000, Absolute);
|
||||
InitTouchClassDeviceStruct(dev, TOUCH_MAX_SLOTS, XIDirectTouch, 2);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
xf86libinput_init(DeviceIntPtr dev)
|
||||
{
|
||||
InputInfoPtr pInfo = dev->public.devicePrivate;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
struct libinput_device *device = driver_data->device;
|
||||
|
||||
dev->public.on = FALSE;
|
||||
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD))
|
||||
xf86libinput_init_keyboard(pInfo);
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
|
||||
xf86libinput_init_pointer(pInfo);
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH))
|
||||
xf86libinput_init_touch(pInfo);
|
||||
|
||||
/* unref the device now, because we'll get a new ref during
|
||||
DEVICE_ON */
|
||||
libinput_device_unref(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_destroy(DeviceIntPtr dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
xf86libinput_device_control(DeviceIntPtr dev, int mode)
|
||||
{
|
||||
int rc = BadValue;
|
||||
|
||||
switch(mode) {
|
||||
case DEVICE_INIT:
|
||||
rc = xf86libinput_init(dev);
|
||||
break;
|
||||
case DEVICE_ON:
|
||||
rc = xf86libinput_on(dev);
|
||||
break;
|
||||
case DEVICE_OFF:
|
||||
rc = xf86libinput_off(dev);
|
||||
break;
|
||||
case DEVICE_CLOSE:
|
||||
xf86libinput_destroy(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_motion(InputInfoPtr pInfo, struct libinput_event_pointer *event)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
ValuatorMask *mask = driver_data->valuators;
|
||||
double x, y;
|
||||
|
||||
x = libinput_event_pointer_get_dx(event);
|
||||
y = libinput_event_pointer_get_dy(event);
|
||||
|
||||
valuator_mask_zero(mask);
|
||||
valuator_mask_set_double(mask, 0, x);
|
||||
valuator_mask_set_double(mask, 1, y);
|
||||
|
||||
xf86PostMotionEventM(dev, Relative, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_button(InputInfoPtr pInfo, struct libinput_event_pointer *event)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
int button;
|
||||
int is_press;
|
||||
|
||||
switch(libinput_event_pointer_get_button(event)) {
|
||||
case BTN_LEFT: button = 1; break;
|
||||
case BTN_MIDDLE: button = 2; break;
|
||||
case BTN_RIGHT: button = 3; break;
|
||||
default: /* no touchpad actually has those buttons */
|
||||
return;
|
||||
}
|
||||
is_press = (libinput_event_pointer_get_button_state(event) == LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
xf86PostButtonEvent(dev, Relative, button, is_press, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_key(InputInfoPtr pInfo, struct libinput_event_keyboard *event)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
int is_press;
|
||||
int key = libinput_event_keyboard_get_key(event);
|
||||
|
||||
key += XORG_KEYCODE_OFFSET;
|
||||
|
||||
is_press = (libinput_event_keyboard_get_key_state(event) == LIBINPUT_KEY_STATE_PRESSED);
|
||||
xf86PostKeyboardEvent(dev, key, is_press);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *event)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
ValuatorMask *mask = driver_data->valuators;
|
||||
int axis;
|
||||
double value;
|
||||
|
||||
if (libinput_event_pointer_get_axis(event) ==
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)
|
||||
axis = 3;
|
||||
else
|
||||
axis = 2;
|
||||
|
||||
value = libinput_event_pointer_get_axis_value(event) / DEFAULT_LIBINPUT_AXIS_STEP_DISTANCE;
|
||||
|
||||
valuator_mask_zero(mask);
|
||||
valuator_mask_set_double(mask, axis, value);
|
||||
|
||||
xf86PostMotionEventM(dev, Relative, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_touch(InputInfoPtr pInfo,
|
||||
struct libinput_event_touch *event,
|
||||
enum libinput_event_type event_type)
|
||||
{
|
||||
DeviceIntPtr dev = pInfo->dev;
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
int type;
|
||||
int slot;
|
||||
ValuatorMask *m = driver_data->valuators;
|
||||
double val;
|
||||
|
||||
/* libinput doesn't give us hw touch ids which X expects, so
|
||||
emulate them here */
|
||||
static int next_touchid;
|
||||
static int touchids[TOUCH_MAX_SLOTS] = {0};
|
||||
|
||||
slot = libinput_event_touch_get_slot(event);
|
||||
|
||||
switch (event_type) {
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||
type = XI_TouchBegin;
|
||||
touchids[slot] = next_touchid++;
|
||||
break;
|
||||
case LIBINPUT_EVENT_TOUCH_UP:
|
||||
type = XI_TouchEnd;
|
||||
break;
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||||
type = XI_TouchUpdate;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
};
|
||||
|
||||
valuator_mask_zero(m);
|
||||
|
||||
if (event_type != LIBINPUT_EVENT_TOUCH_UP) {
|
||||
val = libinput_event_touch_get_x_transformed(event, TOUCH_AXIS_MAX);
|
||||
valuator_mask_set_double(m, 0, val);
|
||||
|
||||
val = libinput_event_touch_get_y_transformed(event, TOUCH_AXIS_MAX);
|
||||
valuator_mask_set_double(m, 1, val);
|
||||
}
|
||||
|
||||
xf86PostTouchEvent(dev, touchids[slot], type, 0, m);
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_handle_event(struct libinput_event *event)
|
||||
{
|
||||
struct libinput_device *device;
|
||||
InputInfoPtr pInfo;
|
||||
|
||||
device = libinput_event_get_device(event);
|
||||
pInfo = libinput_device_get_user_data(device);
|
||||
|
||||
if (pInfo && !pInfo->dev->public.on)
|
||||
return;
|
||||
|
||||
switch (libinput_event_get_type(event)) {
|
||||
case LIBINPUT_EVENT_NONE:
|
||||
case LIBINPUT_EVENT_DEVICE_ADDED:
|
||||
case LIBINPUT_EVENT_DEVICE_REMOVED:
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
||||
/* FIXME */
|
||||
break;
|
||||
|
||||
case LIBINPUT_EVENT_POINTER_MOTION:
|
||||
xf86libinput_handle_motion(pInfo,
|
||||
libinput_event_get_pointer_event(event));
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_BUTTON:
|
||||
xf86libinput_handle_button(pInfo,
|
||||
libinput_event_get_pointer_event(event));
|
||||
break;
|
||||
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
||||
xf86libinput_handle_key(pInfo,
|
||||
libinput_event_get_keyboard_event(event));
|
||||
break;
|
||||
case LIBINPUT_EVENT_POINTER_AXIS:
|
||||
xf86libinput_handle_axis(pInfo,
|
||||
libinput_event_get_pointer_event(event));
|
||||
break;
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||
break;
|
||||
case LIBINPUT_EVENT_TOUCH_UP:
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
xf86libinput_handle_touch(pInfo,
|
||||
libinput_event_get_touch_event(event),
|
||||
libinput_event_get_type(event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xf86libinput_read_input(InputInfoPtr pInfo)
|
||||
{
|
||||
struct libinput *libinput = driver_context.libinput;
|
||||
int rc;
|
||||
struct libinput_event *event;
|
||||
|
||||
rc = libinput_dispatch(libinput);
|
||||
if (rc == -EAGAIN)
|
||||
return;
|
||||
|
||||
if (rc < 0) {
|
||||
ErrorFSigSafe("Error reading events: %d\n", -rc);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((event = libinput_get_event(libinput))) {
|
||||
xf86libinput_handle_event(event);
|
||||
libinput_event_destroy(event);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
open_restricted(const char *path, int flags, void *data)
|
||||
{
|
||||
int fd = open(path, flags);
|
||||
return fd < 0 ? -errno : fd;
|
||||
}
|
||||
|
||||
static void
|
||||
close_restricted(int fd, void *data)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
const struct libinput_interface interface = {
|
||||
.open_restricted = open_restricted,
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
static int xf86libinput_pre_init(InputDriverPtr drv,
|
||||
InputInfoPtr pInfo,
|
||||
int flags)
|
||||
{
|
||||
struct xf86libinput *driver_data = NULL;
|
||||
struct libinput *libinput = NULL;
|
||||
struct libinput_device *device;
|
||||
char *path;
|
||||
|
||||
pInfo->fd = -1;
|
||||
pInfo->type_name = XI_TOUCHPAD;
|
||||
pInfo->device_control = xf86libinput_device_control;
|
||||
pInfo->read_input = xf86libinput_read_input;
|
||||
pInfo->control_proc = NULL;
|
||||
pInfo->switch_mode = NULL;
|
||||
|
||||
driver_data = calloc(1, sizeof(*driver_data));
|
||||
if (!driver_data)
|
||||
goto fail;
|
||||
|
||||
driver_data->valuators = valuator_mask_new(2);
|
||||
if (!driver_data->valuators)
|
||||
goto fail;
|
||||
|
||||
driver_data->scroll_vdist = 1;
|
||||
driver_data->scroll_hdist = 1;
|
||||
|
||||
path = xf86SetStrOption(pInfo->options, "Device", NULL);
|
||||
if (!path)
|
||||
goto fail;
|
||||
|
||||
if (!driver_context.libinput)
|
||||
driver_context.libinput = libinput_path_create_context(&interface, &driver_context);
|
||||
else
|
||||
libinput_ref(driver_context.libinput);
|
||||
|
||||
libinput = driver_context.libinput;
|
||||
|
||||
if (libinput == NULL) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Creating a device for %s failed\n", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
device = libinput_path_add_device(libinput, path);
|
||||
if (!device) {
|
||||
xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a device for %s\n", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* We ref the device but remove it afterwards. The hope is that
|
||||
between now and DEVICE_INIT/DEVICE_ON, the device doesn't change.
|
||||
*/
|
||||
libinput_device_ref(device);
|
||||
libinput_path_remove_device(device);
|
||||
|
||||
pInfo->fd = -1;
|
||||
pInfo->private = driver_data;
|
||||
driver_data->path = path;
|
||||
driver_data->device = device;
|
||||
|
||||
return Success;
|
||||
|
||||
fail:
|
||||
if (driver_data->valuators)
|
||||
valuator_mask_free(&driver_data->valuators);
|
||||
free(path);
|
||||
free(driver_data);
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86libinput_uninit(InputDriverPtr drv,
|
||||
InputInfoPtr pInfo,
|
||||
int flags)
|
||||
{
|
||||
struct xf86libinput *driver_data = pInfo->private;
|
||||
if (driver_data) {
|
||||
driver_context.libinput = libinput_unref(driver_context.libinput);
|
||||
valuator_mask_free(&driver_data->valuators);
|
||||
free(driver_data->path);
|
||||
free(driver_data);
|
||||
pInfo->private = NULL;
|
||||
}
|
||||
xf86DeleteInput(pInfo, flags);
|
||||
}
|
||||
|
||||
InputDriverRec xf86libinput_driver = {
|
||||
.driverVersion = 1,
|
||||
.driverName = "libinput",
|
||||
.PreInit = xf86libinput_pre_init,
|
||||
.UnInit = xf86libinput_uninit,
|
||||
};
|
||||
|
||||
static XF86ModuleVersionInfo xf86libinput_version_info = {
|
||||
"libinput",
|
||||
MODULEVENDORSTRING,
|
||||
MODINFOSTRING1,
|
||||
MODINFOSTRING2,
|
||||
XORG_VERSION_CURRENT,
|
||||
PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
|
||||
ABI_CLASS_XINPUT,
|
||||
ABI_XINPUT_VERSION,
|
||||
MOD_CLASS_XINPUT,
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static pointer
|
||||
xf86libinput_setup_proc(pointer module, pointer options, int *errmaj, int *errmin)
|
||||
{
|
||||
xf86AddInputDriver(&xf86libinput_driver, module, 0);
|
||||
return module;
|
||||
}
|
||||
|
||||
_X_EXPORT XF86ModuleData libinputModuleData = {
|
||||
.vers = &xf86libinput_version_info,
|
||||
.setup = &xf86libinput_setup_proc,
|
||||
.teardown = NULL
|
||||
};
|
||||
|
||||
|
||||
65
src/util-macros.h
Normal file
65
src/util-macros.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright © 2008-2011 Kristian Høgsberg
|
||||
* Copyright © 2011 Intel Corporation
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||
/**
|
||||
* Iterate through the array _arr, assigning the variable elem to each
|
||||
* element. elem only exists within the loop.
|
||||
*/
|
||||
#define ARRAY_FOR_EACH(_arr, _elem) \
|
||||
for (__typeof__((_arr)[0]) *_elem = _arr; \
|
||||
_elem < (_arr) + ARRAY_LENGTH(_arr); \
|
||||
_elem++)
|
||||
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define ANSI_HIGHLIGHT "\x1B[0;1;39m"
|
||||
#define ANSI_RED "\x1B[0;31m"
|
||||
#define ANSI_GREEN "\x1B[0;32m"
|
||||
#define ANSI_YELLOW "\x1B[0;33m"
|
||||
#define ANSI_BLUE "\x1B[0;34m"
|
||||
#define ANSI_MAGENTA "\x1B[0;35m"
|
||||
#define ANSI_CYAN "\x1B[0;36m"
|
||||
#define ANSI_BRIGHT_RED "\x1B[0;31;1m"
|
||||
#define ANSI_BRIGHT_GREEN "\x1B[0;32;1m"
|
||||
#define ANSI_BRIGHT_YELLOW "\x1B[0;33;1m"
|
||||
#define ANSI_BRIGHT_BLUE "\x1B[0;34;1m"
|
||||
#define ANSI_BRIGHT_MAGENTA "\x1B[0;35;1m"
|
||||
#define ANSI_BRIGHT_CYAN "\x1B[0;36;1m"
|
||||
#define ANSI_NORMAL "\x1B[0m"
|
||||
|
||||
#define ANSI_UP "\x1B[%dA"
|
||||
#define ANSI_DOWN "\x1B[%dB"
|
||||
#define ANSI_RIGHT "\x1B[%dC"
|
||||
#define ANSI_LEFT "\x1B[%dD"
|
||||
|
||||
#define CASE_RETURN_STRING(a) case a: return #a
|
||||
|
||||
#define _fallthrough_ __attribute__((fallthrough))
|
||||
246
src/util-strings.c
Normal file
246
src/util-strings.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "util-strings.h"
|
||||
|
||||
/**
|
||||
* Return the next word in a string pointed to by state before the first
|
||||
* separator character. Call repeatedly to tokenize a whole string.
|
||||
*
|
||||
* @param state Current state
|
||||
* @param len String length of the word returned
|
||||
* @param separators List of separator characters
|
||||
*
|
||||
* @return The first word in *state, NOT null-terminated
|
||||
*/
|
||||
static const char *
|
||||
next_word(const char **state, size_t *len, const char *separators)
|
||||
{
|
||||
const char *next = *state;
|
||||
size_t l;
|
||||
|
||||
if (!*next)
|
||||
return NULL;
|
||||
|
||||
next += strspn(next, separators);
|
||||
if (!*next) {
|
||||
*state = next;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l = strcspn(next, separators);
|
||||
*state = next + l;
|
||||
*len = l;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a null-terminated string array with the contents of argv
|
||||
* duplicated.
|
||||
*
|
||||
* Use strv_free() to free the array.
|
||||
*
|
||||
* @return A null-terminated string array or NULL on errors
|
||||
*/
|
||||
char**
|
||||
strv_from_argv(int argc, char **argv)
|
||||
{
|
||||
char **strv = NULL;
|
||||
|
||||
assert(argc >= 0);
|
||||
|
||||
if (argc == 0)
|
||||
return NULL;
|
||||
|
||||
strv = zalloc((argc + 1) * sizeof *strv);
|
||||
for (int i = 0; i < argc; i++) {
|
||||
char *copy = safe_strdup(argv[i]);
|
||||
if (!copy) {
|
||||
strv_free(strv);
|
||||
return NULL;
|
||||
}
|
||||
strv[i] = copy;
|
||||
}
|
||||
return strv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a null-terminated string array with the tokens in the input
|
||||
* string, e.g. "one two\tthree" with a separator list of " \t" will return
|
||||
* an array [ "one", "two", "three", NULL ] and num elements 3.
|
||||
*
|
||||
* Use strv_free() to free the array.
|
||||
*
|
||||
* Another example:
|
||||
* result = strv_from_string("+1-2++3--4++-+5-+-", "+-", &nelem)
|
||||
* result == [ "1", "2", "3", "4", "5", NULL ] and nelem == 5
|
||||
*
|
||||
* @param in Input string
|
||||
* @param separators List of separator characters
|
||||
* @param num_elements Number of elements found in the input string
|
||||
*
|
||||
* @return A null-terminated string array or NULL on errors
|
||||
*/
|
||||
char **
|
||||
strv_from_string(const char *in, const char *separators, size_t *num_elements)
|
||||
{
|
||||
assert(in != NULL);
|
||||
|
||||
const char *s = in;
|
||||
size_t l, nelems = 0;
|
||||
while (next_word(&s, &l, separators) != NULL)
|
||||
nelems++;
|
||||
|
||||
if (nelems == 0) {
|
||||
*num_elements = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t strv_len = nelems + 1; /* NULL-terminated */
|
||||
char **strv = calloc(strv_len, sizeof(*strv));
|
||||
if (!strv)
|
||||
return NULL;
|
||||
|
||||
size_t idx = 0;
|
||||
const char *word;
|
||||
s = in;
|
||||
while ((word = next_word(&s, &l, separators)) != NULL) {
|
||||
char *copy = strndup(word, l);
|
||||
if (!copy) {
|
||||
strv_free(strv);
|
||||
*num_elements = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strv[idx++] = copy;
|
||||
}
|
||||
|
||||
*num_elements = nelems;
|
||||
|
||||
return strv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a newly allocated string with all elements joined by the
|
||||
* joiner, same as Python's string.join() basically.
|
||||
* A strv of ["one", "two", "three", NULL] with a joiner of ", " results
|
||||
* in "one, two, three".
|
||||
*
|
||||
* An empty strv ([NULL]) returns NULL, same for passing NULL as either
|
||||
* argument.
|
||||
*
|
||||
* @param strv Input string array
|
||||
* @param joiner Joiner between the elements in the final string
|
||||
*
|
||||
* @return A null-terminated string joining all elements
|
||||
*/
|
||||
char *
|
||||
strv_join(char **strv, const char *joiner)
|
||||
{
|
||||
char **s;
|
||||
char *str;
|
||||
size_t slen = 0;
|
||||
size_t count = 0;
|
||||
|
||||
if (!strv || !joiner)
|
||||
return NULL;
|
||||
|
||||
if (strv[0] == NULL)
|
||||
return NULL;
|
||||
|
||||
for (s = strv, count = 0; *s; s++, count++) {
|
||||
slen += strlen(*s);
|
||||
}
|
||||
|
||||
assert(slen < 1000);
|
||||
assert(strlen(joiner) < 1000);
|
||||
assert(count > 0);
|
||||
assert(count < 100);
|
||||
|
||||
slen += (count - 1) * strlen(joiner);
|
||||
|
||||
str = zalloc(slen + 1); /* trailing \0 */
|
||||
for (s = strv; *s; s++) {
|
||||
strcat(str, *s);
|
||||
--count;
|
||||
if (count > 0)
|
||||
strcat(str, joiner);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to the basename within filename.
|
||||
* If the filename the empty string or a directory (i.e. the last char of
|
||||
* filename is '/') NULL is returned.
|
||||
*/
|
||||
const char *
|
||||
safe_basename(const char *filename)
|
||||
{
|
||||
const char *basename;
|
||||
|
||||
if (*filename == '\0')
|
||||
return NULL;
|
||||
|
||||
basename = strrchr(filename, '/');
|
||||
if (basename == NULL)
|
||||
return filename;
|
||||
|
||||
if (*(basename + 1) == '\0')
|
||||
return NULL;
|
||||
|
||||
return basename + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to basename() but returns the trunk only without the (last)
|
||||
* trailing suffix, so that:
|
||||
*
|
||||
* - foo.c returns foo
|
||||
* - foo.a.b returns foo.a
|
||||
* - foo returns foo
|
||||
* - foo/ returns ""
|
||||
*
|
||||
* @return an allocated string representing the trunk name of the file
|
||||
*/
|
||||
char *
|
||||
trunkname(const char *filename)
|
||||
{
|
||||
const char *base = safe_basename(filename);
|
||||
char *suffix;
|
||||
|
||||
if (base == NULL)
|
||||
return safe_strdup("");
|
||||
|
||||
suffix = rindex(base, '.');
|
||||
if (suffix == NULL)
|
||||
return safe_strdup(base);
|
||||
else
|
||||
return strndup(base, suffix-base);
|
||||
}
|
||||
395
src/util-strings.h
Normal file
395
src/util-strings.h
Normal file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
#include "util-macros.h"
|
||||
|
||||
static inline bool
|
||||
streq(const char *str1, const char *str2)
|
||||
{
|
||||
/* one NULL, one not NULL is always false */
|
||||
if (str1 && str2)
|
||||
return strcmp(str1, str2) == 0;
|
||||
return str1 == str2;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
strneq(const char *str1, const char *str2, int n)
|
||||
{
|
||||
/* one NULL, one not NULL is always false */
|
||||
if (str1 && str2)
|
||||
return strncmp(str1, str2, n) == 0;
|
||||
return str1 == str2;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
zalloc(size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
/* We never need to alloc anything more than 1,5 MB so we can assume
|
||||
* if we ever get above that something's going wrong */
|
||||
if (size > 1536 * 1024)
|
||||
assert(!"bug: internal malloc size limit exceeded");
|
||||
|
||||
p = calloc(1, size);
|
||||
if (!p)
|
||||
abort();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* strdup guaranteed to succeed. If the input string is NULL, the output
|
||||
* string is NULL. If the input string is a string pointer, we strdup or
|
||||
* abort on failure.
|
||||
*/
|
||||
static inline char*
|
||||
safe_strdup(const char *str)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
s = strdup(str);
|
||||
if (!s)
|
||||
abort();
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
safe_atoi_base(const char *str, int *val, int base)
|
||||
{
|
||||
char *endptr;
|
||||
long v;
|
||||
|
||||
assert(base == 10 || base == 16 || base == 8);
|
||||
|
||||
errno = 0;
|
||||
v = strtol(str, &endptr, base);
|
||||
if (errno > 0)
|
||||
return false;
|
||||
if (str == endptr)
|
||||
return false;
|
||||
if (*str != '\0' && *endptr != '\0')
|
||||
return false;
|
||||
|
||||
if (v > INT_MAX || v < INT_MIN)
|
||||
return false;
|
||||
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
safe_atoi(const char *str, int *val)
|
||||
{
|
||||
return safe_atoi_base(str, val, 10);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
safe_atou_base(const char *str, unsigned int *val, int base)
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long v;
|
||||
|
||||
assert(base == 10 || base == 16 || base == 8);
|
||||
|
||||
errno = 0;
|
||||
v = strtoul(str, &endptr, base);
|
||||
if (errno > 0)
|
||||
return false;
|
||||
if (str == endptr)
|
||||
return false;
|
||||
if (*str != '\0' && *endptr != '\0')
|
||||
return false;
|
||||
|
||||
if ((long)v < 0)
|
||||
return false;
|
||||
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
safe_atou(const char *str, unsigned int *val)
|
||||
{
|
||||
return safe_atou_base(str, val, 10);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
safe_atod(const char *str, double *val)
|
||||
{
|
||||
char *endptr;
|
||||
double v;
|
||||
#ifdef HAVE_LOCALE_H
|
||||
locale_t c_locale;
|
||||
#endif
|
||||
size_t slen = strlen(str);
|
||||
|
||||
/* We don't have a use-case where we want to accept hex for a double
|
||||
* or any of the other values strtod can parse */
|
||||
for (size_t i = 0; i < slen; i++) {
|
||||
char c = str[i];
|
||||
|
||||
if (isdigit(c))
|
||||
continue;
|
||||
switch(c) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '.':
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
/* Create a "C" locale to force strtod to use '.' as separator */
|
||||
c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
|
||||
if (c_locale == (locale_t)0)
|
||||
return false;
|
||||
|
||||
errno = 0;
|
||||
v = strtod_l(str, &endptr, c_locale);
|
||||
freelocale(c_locale);
|
||||
#else
|
||||
/* No locale support in provided libc, assume it already uses '.' */
|
||||
errno = 0;
|
||||
v = strtod(str, &endptr);
|
||||
#endif
|
||||
if (errno > 0)
|
||||
return false;
|
||||
if (str == endptr)
|
||||
return false;
|
||||
if (*str != '\0' && *endptr != '\0')
|
||||
return false;
|
||||
if (v != 0.0 && !isnormal(v))
|
||||
return false;
|
||||
|
||||
*val = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
char **strv_from_argv(int argc, char **argv);
|
||||
char **strv_from_string(const char *in, const char *separator, size_t *num_elements);
|
||||
char *strv_join(char **strv, const char *joiner);
|
||||
|
||||
static inline void
|
||||
strv_free(char **strv) {
|
||||
char **s = strv;
|
||||
|
||||
if (!strv)
|
||||
return;
|
||||
|
||||
while (*s != NULL) {
|
||||
free(*s);
|
||||
*s = (char*)0x1; /* detect use-after-free */
|
||||
s++;
|
||||
}
|
||||
|
||||
free (strv);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a string containing a list of doubles into a double array.
|
||||
*
|
||||
* @param in string to parse
|
||||
* @param separator string used to separate double in list e.g. ","
|
||||
* @param result double array
|
||||
* @param length length of double array
|
||||
* @return true when parsed successfully otherwise false
|
||||
*/
|
||||
static inline double *
|
||||
double_array_from_string(const char *in,
|
||||
const char *separator,
|
||||
size_t *length)
|
||||
{
|
||||
double *result = NULL;
|
||||
*length = 0;
|
||||
|
||||
size_t nelem;
|
||||
char **strv = strv_from_string(in, separator, &nelem);
|
||||
if(!strv)
|
||||
return result;
|
||||
|
||||
double *numv = calloc(nelem, sizeof(double));
|
||||
if (!numv)
|
||||
goto out;
|
||||
|
||||
for (size_t idx = 0; idx < nelem; idx++) {
|
||||
double val;
|
||||
if (!safe_atod(strv[idx], &val))
|
||||
goto out;
|
||||
|
||||
numv[idx] = val;
|
||||
}
|
||||
|
||||
result = numv;
|
||||
numv = NULL;
|
||||
*length = nelem;
|
||||
|
||||
out:
|
||||
strv_free(strv);
|
||||
free(numv);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct key_value_str{
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct key_value_double {
|
||||
double key;
|
||||
double value;
|
||||
};
|
||||
|
||||
static inline ssize_t
|
||||
kv_double_from_string(const char *string,
|
||||
const char *pair_separator,
|
||||
const char *kv_separator,
|
||||
struct key_value_double **result_out)
|
||||
|
||||
{
|
||||
struct key_value_double *result = NULL;
|
||||
|
||||
if (!pair_separator || pair_separator[0] == '\0' ||
|
||||
!kv_separator || kv_separator[0] == '\0')
|
||||
return -1;
|
||||
|
||||
size_t npairs;
|
||||
char **pairs = strv_from_string(string, pair_separator, &npairs);
|
||||
if (!pairs || npairs == 0)
|
||||
goto error;
|
||||
|
||||
result = zalloc(npairs * sizeof *result);
|
||||
|
||||
for (size_t idx = 0; idx < npairs; idx++) {
|
||||
char *pair = pairs[idx];
|
||||
size_t nelem;
|
||||
char **kv = strv_from_string(pair, kv_separator, &nelem);
|
||||
double k, v;
|
||||
|
||||
if (!kv || nelem != 2 ||
|
||||
!safe_atod(kv[0], &k) ||
|
||||
!safe_atod(kv[1], &v)) {
|
||||
strv_free(kv);
|
||||
goto error;
|
||||
}
|
||||
|
||||
result[idx].key = k;
|
||||
result[idx].value = v;
|
||||
|
||||
strv_free(kv);
|
||||
}
|
||||
|
||||
strv_free(pairs);
|
||||
|
||||
*result_out = result;
|
||||
|
||||
return npairs;
|
||||
|
||||
error:
|
||||
strv_free(pairs);
|
||||
free(result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip any of the characters in what from the beginning and end of the
|
||||
* input string.
|
||||
*
|
||||
* @return a newly allocated string with none of "what" at the beginning or
|
||||
* end of string
|
||||
*/
|
||||
static inline char *
|
||||
strstrip(const char *input, const char *what)
|
||||
{
|
||||
char *str, *last;
|
||||
|
||||
str = safe_strdup(&input[strspn(input, what)]);
|
||||
|
||||
last = str;
|
||||
|
||||
for (char *c = str; *c != '\0'; c++) {
|
||||
if (!strchr(what, *c))
|
||||
last = c + 1;
|
||||
}
|
||||
|
||||
*last = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if str ends in suffix, false otherwise. If the suffix is the
|
||||
* empty string, strendswith() always returns false.
|
||||
*/
|
||||
static inline bool
|
||||
strendswith(const char *str, const char *suffix)
|
||||
{
|
||||
size_t slen = strlen(str);
|
||||
size_t suffixlen = strlen(suffix);
|
||||
size_t offset;
|
||||
|
||||
if (slen == 0 || suffixlen == 0 || suffixlen > slen)
|
||||
return false;
|
||||
|
||||
offset = slen - suffixlen;
|
||||
return strneq(&str[offset], suffix, suffixlen);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
strstartswith(const char *str, const char *prefix)
|
||||
{
|
||||
size_t prefixlen = strlen(prefix);
|
||||
|
||||
return prefixlen > 0 ? strneq(str, prefix, strlen(prefix)) : false;
|
||||
}
|
||||
|
||||
const char *
|
||||
safe_basename(const char *filename);
|
||||
|
||||
char *
|
||||
trunkname(const char *filename);
|
||||
6852
src/xf86libinput.c
Normal file
6852
src/xf86libinput.c
Normal file
File diff suppressed because it is too large
Load Diff
1
test/.gitignore
vendored
Normal file
1
test/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
test-draglock
|
||||
16
test/Makefile.am
Normal file
16
test/Makefile.am
Normal file
@@ -0,0 +1,16 @@
|
||||
AM_CPPFLAGS = $(XORG_CFLAGS) \
|
||||
$(CWARNFLAGS) \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/src
|
||||
|
||||
tests = test-draglock test-bezier
|
||||
|
||||
noinst_PROGRAMS = $(tests)
|
||||
|
||||
test_draglock_SOURCES = test-draglock.c
|
||||
test_draglock_LDADD = ../src/libdraglock.la
|
||||
|
||||
test_bezier_SOURCES = test-bezier.c
|
||||
test_bezier_LDADD = ../src/libbezier.la -lm
|
||||
|
||||
TESTS = $(tests)
|
||||
208
test/test-bezier.c
Normal file
208
test/test-bezier.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2016 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "bezier.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static inline void
|
||||
print_curve(int *bezier, size_t size)
|
||||
{
|
||||
/* look at it with gnuplot, "plot 'output-file.txt'" */
|
||||
for (int i = 0; i < size; i++)
|
||||
printf("%d %d\n", i, bezier[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
test_linear(void)
|
||||
{
|
||||
const int size = 2048;
|
||||
int bezier[size];
|
||||
|
||||
struct bezier_control_point controls[] = {
|
||||
{ 0.0, 0.0 },
|
||||
{ 0.0, 0.0 },
|
||||
{ 1.0, 1.0 },
|
||||
{ 1.0, 1.0 }
|
||||
};
|
||||
|
||||
cubic_bezier(controls, bezier, size);
|
||||
|
||||
assert(bezier[0] == 0);
|
||||
assert(bezier[size - 1] == size - 1);
|
||||
|
||||
for (int x = 1; x < size; x++)
|
||||
assert(bezier[x] == x);
|
||||
}
|
||||
|
||||
/* Center point pulled down towards X axis */
|
||||
static void
|
||||
test_flattened(void)
|
||||
{
|
||||
const int size = 2048;
|
||||
int bezier[size];
|
||||
|
||||
struct bezier_control_point controls[] = {
|
||||
{ 0.0, 0.0 },
|
||||
{ 0.1, 0.0 },
|
||||
{ 1.0, 0.9 },
|
||||
{ 1.0, 1.0 }
|
||||
};
|
||||
|
||||
cubic_bezier(controls, bezier, size);
|
||||
|
||||
assert(bezier[0] == 0);
|
||||
assert(bezier[size - 1] == size - 1);
|
||||
|
||||
for (int x = 1; x < size - 1; x++) {
|
||||
assert(bezier[x] < x);
|
||||
}
|
||||
}
|
||||
|
||||
/* Center point pulled up from X axis */
|
||||
static void
|
||||
test_raised(void)
|
||||
{
|
||||
const int size = 2048;
|
||||
int bezier[size];
|
||||
|
||||
struct bezier_control_point controls[] = {
|
||||
{ 0.0, 0.0 },
|
||||
{ 0.1, 0.4 },
|
||||
{ 0.4, 1.0 },
|
||||
{ 1.0, 1.0 }
|
||||
};
|
||||
|
||||
cubic_bezier(controls, bezier, size);
|
||||
|
||||
assert(bezier[0] == 0);
|
||||
assert(bezier[size - 1] == size - 1);
|
||||
|
||||
for (int x = 1; x < size; x++)
|
||||
assert(bezier[x] >= x);
|
||||
|
||||
for (int x = 10; x < size - 10; x++)
|
||||
assert(bezier[x] > x);
|
||||
}
|
||||
|
||||
static void
|
||||
test_windy(void)
|
||||
{
|
||||
const int size = 2048;
|
||||
int bezier[size];
|
||||
|
||||
struct bezier_control_point controls[] = {
|
||||
{ 0.0, 0.0 },
|
||||
{ 0.0, 0.3 },
|
||||
{ 1.0, 0.7 },
|
||||
{ 1.0, 1.0 }
|
||||
};
|
||||
|
||||
cubic_bezier(controls, bezier, size);
|
||||
|
||||
assert(bezier[0] == 0);
|
||||
assert(bezier[size - 1] == size - 1);
|
||||
|
||||
for (int x = 1; x < size/2 - 20; x++)
|
||||
assert(bezier[x] > x);
|
||||
|
||||
for (int x = size/2 + 20; x < size - 1; x++)
|
||||
assert(bezier[x] < x);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nonzero_x_linear(void)
|
||||
{
|
||||
const int size = 2048;
|
||||
int bezier[size];
|
||||
int x;
|
||||
|
||||
struct bezier_control_point controls[] = {
|
||||
{ 0.2, 0.0 },
|
||||
{ 0.2, 0.0 },
|
||||
{ 0.8, 1.0 },
|
||||
{ 0.8, 1.0 }
|
||||
};
|
||||
|
||||
cubic_bezier(controls, bezier, size);
|
||||
|
||||
x = 0;
|
||||
do {
|
||||
assert(bezier[x] == 0);
|
||||
} while (++x < size * 0.2 - 1);
|
||||
|
||||
/* ppc64le, ppc64, aarch64 have different math results at -O2,
|
||||
resulting in one extra zero at the beginning of the array.
|
||||
some other numbers are different too but within the error
|
||||
margin (#99992) */
|
||||
if (bezier[x] == 0)
|
||||
x++;
|
||||
|
||||
do {
|
||||
assert(bezier[x] > bezier[x-1]);
|
||||
} while (++x < size * 0.8 - 1);
|
||||
|
||||
do {
|
||||
assert(bezier[x] == size - 1);
|
||||
} while (++x < size);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nonzero_y_linear(void)
|
||||
{
|
||||
const int size = 2048;
|
||||
int bezier[size];
|
||||
|
||||
struct bezier_control_point controls[] = {
|
||||
{ 0.0, 0.2 },
|
||||
{ 0.0, 0.2 },
|
||||
{ 1.0, 0.8 },
|
||||
{ 1.0, 0.8 }
|
||||
};
|
||||
|
||||
cubic_bezier(controls, bezier, size);
|
||||
|
||||
assert(bezier[0] == (int)(size * 0.2));
|
||||
|
||||
for (int x = 1; x < size; x++) {
|
||||
assert(bezier[x - 1] <= bezier[x]);
|
||||
assert(bezier[x] >= (int)(size * 0.2));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
test_linear();
|
||||
test_flattened();
|
||||
test_raised();
|
||||
test_windy();
|
||||
test_nonzero_x_linear();
|
||||
test_nonzero_y_linear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
548
test/test-draglock.c
Normal file
548
test/test-draglock.c
Normal file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright © 2013-2015 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "draglock.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
test_config_empty(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
|
||||
rc = draglock_init_from_string(&dl, NULL);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_invalid(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
|
||||
/* no trailing space */
|
||||
rc = draglock_init_from_string(&dl, "1 ");
|
||||
assert(rc != 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "256");
|
||||
assert(rc != 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "-1");
|
||||
assert(rc != 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "1 2 3");
|
||||
assert(rc != 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "0 2");
|
||||
assert(rc != 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "0 0");
|
||||
assert(rc != 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_disable(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "0");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_meta_button(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "1");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_META);
|
||||
assert(dl.meta_button == 1);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "2");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_META);
|
||||
assert(dl.meta_button == 2);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "10");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_META);
|
||||
assert(dl.meta_button == 10);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_button_pairs(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "1 1");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_PAIRS);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "1 2 3 4 5 6 7 8");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_PAIRS);
|
||||
|
||||
rc = draglock_init_from_string(&dl, "1 2 3 4 5 0 7 8");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_PAIRS);
|
||||
|
||||
/* all disabled */
|
||||
rc = draglock_init_from_string(&dl, "1 0 3 0 5 0 7 0");
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_get(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
const int sz = 32;
|
||||
int map[sz];
|
||||
|
||||
draglock_init_from_string(&dl, "");
|
||||
rc = draglock_get_meta(&dl);
|
||||
assert(rc == 0);
|
||||
rc = draglock_get_pairs(&dl, map, sz);
|
||||
assert(rc == 0);
|
||||
|
||||
draglock_init_from_string(&dl, "8");
|
||||
rc = draglock_get_meta(&dl);
|
||||
assert(rc == 8);
|
||||
rc = draglock_get_pairs(&dl, map, sz);
|
||||
assert(rc == 0);
|
||||
|
||||
draglock_init_from_string(&dl, "1 2 3 4 5 6");
|
||||
rc = draglock_get_meta(&dl);
|
||||
assert(rc == 0);
|
||||
rc = draglock_get_pairs(&dl, map, sz);
|
||||
assert(rc == 5);
|
||||
assert(map[0] == 0);
|
||||
assert(map[1] == 2);
|
||||
assert(map[2] == 0);
|
||||
assert(map[3] == 4);
|
||||
assert(map[4] == 0);
|
||||
assert(map[5] == 6);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_meta(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
|
||||
draglock_init_from_string(&dl, "");
|
||||
|
||||
rc = draglock_set_meta(&dl, 0);
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_set_meta(&dl, 1);
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_META);
|
||||
|
||||
rc = draglock_set_meta(&dl, -1);
|
||||
assert(rc == 1);
|
||||
rc = draglock_set_meta(&dl, 32);
|
||||
assert(rc == 1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_pairs(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
const int sz = 32;
|
||||
int map[sz];
|
||||
|
||||
draglock_init_from_string(&dl, "");
|
||||
memset(map, 0, sizeof(map));
|
||||
|
||||
rc = draglock_set_pairs(&dl, map, sz);
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
rc = draglock_set_pairs(&dl, map, 1);
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_DISABLED);
|
||||
|
||||
map[0] = 1;
|
||||
rc = draglock_set_pairs(&dl, map, 1);
|
||||
assert(rc == 1);
|
||||
|
||||
map[0] = 0;
|
||||
map[1] = 2;
|
||||
rc = draglock_set_pairs(&dl, map, sz);
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_PAIRS);
|
||||
|
||||
map[0] = 0;
|
||||
map[1] = 0;
|
||||
map[10] = 8;
|
||||
rc = draglock_set_pairs(&dl, map, sz);
|
||||
assert(rc == 0);
|
||||
assert(dl.mode == DRAGLOCK_PAIRS);
|
||||
}
|
||||
|
||||
static void
|
||||
test_filter_meta_passthrough(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
int button, press;
|
||||
int i;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "10");
|
||||
assert(rc == 0);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
button = i;
|
||||
press = 1;
|
||||
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
assert(press == 1);
|
||||
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
assert(press == 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_filter_meta_click_meta_only(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
int button, press;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "10");
|
||||
assert(rc == 0);
|
||||
|
||||
button = 10;
|
||||
press = 1;
|
||||
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
button = 10;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_filter_meta(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
int button, press;
|
||||
int i;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "10");
|
||||
assert(rc == 0);
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
/* meta down */
|
||||
button = 10;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* meta up */
|
||||
button = 10;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button down -> passthrough */
|
||||
button = i;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
|
||||
/* button up -> eaten */
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button down -> eaten */
|
||||
button = i;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button up -> passthrough */
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
assert(press == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_filter_meta_extra_click(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
int button, press;
|
||||
int i;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "10");
|
||||
assert(rc == 0);
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
/* meta down */
|
||||
button = 10;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* meta up */
|
||||
button = 10;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button down -> passthrough */
|
||||
button = i;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
|
||||
/* button up -> eaten */
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* meta down */
|
||||
button = 10;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* meta up */
|
||||
button = 10;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button down -> eaten */
|
||||
button = i;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button up -> passthrough */
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
assert(press == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_filter_meta_interleaved(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
int button, press;
|
||||
int i;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "10");
|
||||
assert(rc == 0);
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
/* meta down */
|
||||
button = 10;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* meta up */
|
||||
button = 10;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button down -> passthrough */
|
||||
button = i;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
|
||||
/* button up -> eaten */
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
/* button down -> eaten */
|
||||
button = i;
|
||||
press = 1;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == 0);
|
||||
|
||||
/* button up -> passthrough */
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
assert(button == i);
|
||||
assert(press == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_filter_pairs(void)
|
||||
{
|
||||
struct draglock dl;
|
||||
int rc;
|
||||
int button, press;
|
||||
int i;
|
||||
|
||||
rc = draglock_init_from_string(&dl, "1 11 2 0 3 13 4 0 5 15 6 0 7 17 8 0 9 19");
|
||||
assert(rc == 0);
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
button = i;
|
||||
press = 1;
|
||||
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
if (i % 2)
|
||||
assert(button == i + 10);
|
||||
else
|
||||
assert(button == i);
|
||||
assert(press == 1);
|
||||
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
if (i % 2) {
|
||||
assert(button == 0);
|
||||
} else {
|
||||
assert(button == i);
|
||||
assert(press == 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < 10; i++) {
|
||||
button = i;
|
||||
press = 1;
|
||||
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
if (i % 2) {
|
||||
assert(button == 0);
|
||||
} else {
|
||||
assert(button == i);
|
||||
assert(press == 1);
|
||||
}
|
||||
|
||||
button = i;
|
||||
press = 0;
|
||||
rc = draglock_filter_button(&dl, &button, &press);
|
||||
assert(rc == 0);
|
||||
if (i % 2)
|
||||
assert(button == i + 10);
|
||||
else
|
||||
assert(button == i);
|
||||
assert(press == 0);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
test_config_empty();
|
||||
test_config_invalid();
|
||||
test_config_disable();
|
||||
test_config_meta_button();
|
||||
test_config_button_pairs();
|
||||
|
||||
test_config_get();
|
||||
test_set_meta();
|
||||
test_set_pairs();
|
||||
|
||||
test_filter_meta_passthrough();
|
||||
test_filter_meta_click_meta_only();
|
||||
test_filter_meta();
|
||||
test_filter_meta_extra_click();
|
||||
test_filter_meta_interleaved();
|
||||
|
||||
test_filter_pairs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user