mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 06:50:05 +01:00
quirks: allow overriding of AttrEventCode and AttrInputProp
This switches the quirk from AttrEventCodeEnable/Disable to just AttrEventCode with a +/- prefix for each entry. This switches the quirk from AttrInputPropEnable/Disable to just AttrInputProp with a +/- prefix for each entry. Previously, both event codes and input props would only apply the last-matching section entry for a device. Furthermore, an earlier Disable entry would take precedence over a later Enable entry. For example, a set of sections with these lines *should* enable left, right and middle: [first] AttrEventCodeEnable=BTN_LEFT;BTN_RIGHT;BTN_MIDDLE [second] AttrEventCodeDisable=BTN_RIGHT [third] AttrEventCodeEnable=BTN_LEFT;BTN_RIGHT; Alas: the first line was effectively ignored (quirks only returned the last-matching one, i.e. the one from "third"). And due to implementation details in evdev.c, the Disable attribute was processed after Enable, i.e. the device was enabled for left + right and then disabled for right. As a result, the device only had BTN_LEFT enabled. Fix this by changing the attribute to carry both enable/disable information and merging the commands together. Internally, all quirks matching a device are simply ref'd into an array in the struct quirks. The applied value is simply the last entry in the array corresponding to our quirk. For AttrEventCode and AttrInputProp instead do this: - switch them to a tuple with the code as first entry and a boolean enable/disable as second entry - if the struct quirk already has an entry for either, append the more recent one to the existing entry (instead of creating a new entry in the array). This way we have all entries that match and in-order of precedence - i.e. we can process them left-to-right to end up with the right state. Fixes: https://gitlab.freedesktop.org/libinput/libinput/-/issues/821 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
bb6ff0ec00
commit
a7e4cbc212
29 changed files with 332 additions and 211 deletions
|
|
@ -30,7 +30,7 @@ MyVendor OEM::
|
||||||
MatchName=Foo Bar Touchpad
|
MatchName=Foo Bar Touchpad
|
||||||
MatchUdevtype=touchpad
|
MatchUdevtype=touchpad
|
||||||
MatchDMIModAlias=dmi:*svnMyVendor:pnMyModel:*
|
MatchDMIModAlias=dmi:*svnMyVendor:pnMyModel:*
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
||||||
The name of the device can be obtained using :ref:`libinput record <libinput-record>`,
|
The name of the device can be obtained using :ref:`libinput record <libinput-record>`,
|
||||||
the modalias match is a shell-style glob against the value of ``/sys/class/dmi/id/modalias``.
|
the modalias match is a shell-style glob against the value of ``/sys/class/dmi/id/modalias``.
|
||||||
|
|
|
||||||
|
|
@ -174,19 +174,14 @@ AttrTPKComboLayout=below
|
||||||
Indicates the position of the touchpad on an external touchpad+keyboard
|
Indicates the position of the touchpad on an external touchpad+keyboard
|
||||||
combination device. This is a string enum. Don't specify it unless the
|
combination device. This is a string enum. Don't specify it unless the
|
||||||
touchpad is below.
|
touchpad is below.
|
||||||
AttrEventCodeDisable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
AttrEventCode=+EV_ABS;-BTN_STYLUS;+EV_KEY:0x123;
|
||||||
Disables the evdev event type/code tuples on the device. Entries may be
|
Enables or disables the evdev event type/code tuples on the device. The prefix
|
||||||
|
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
||||||
a named event type, or a named event code, or a named event type with a
|
a named event type, or a named event code, or a named event type with a
|
||||||
hexadecimal event code, separated by a single colon.
|
hexadecimal event code, separated by a single colon.
|
||||||
AttrEventCodeEnable=EV_ABS;BTN_STYLUS;EV_KEY:0x123;
|
AttrInputProp=+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER;
|
||||||
Enables the evdev event type/code tuples on the device. Entries may be
|
Enables or disables the evdev input property on the device. The prefix
|
||||||
a named event type, or a named event code, or a named event type with a
|
for each entry is either '+' (enable) or '-' (disable). Entries may be
|
||||||
hexadecimal event code, separated by a single colon.
|
|
||||||
AttrInputPropDisable=INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER;
|
|
||||||
Disables the evdev input property on the device. Entries may be
|
|
||||||
a named input property or the hexadecimal value of that property.
|
|
||||||
AttrInputPropEnable=INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER;
|
|
||||||
Enables the evdev input property on the device. Entries may be
|
|
||||||
a named input property or the hexadecimal value of that property.
|
a named input property or the hexadecimal value of that property.
|
||||||
AttrPointingStickIntegration=internal|external
|
AttrPointingStickIntegration=internal|external
|
||||||
Indicates the integration of the pointing stick. This is a string enum.
|
Indicates the integration of the pointing stick. This is a string enum.
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,6 @@ events are sent: ::
|
||||||
The issue can be fixed by adding a quirk to unset the ``REL_WHEEL_HI_RES`` and
|
The issue can be fixed by adding a quirk to unset the ``REL_WHEEL_HI_RES`` and
|
||||||
``REL_HWHEEL_HI_RES`` event codes: ::
|
``REL_HWHEEL_HI_RES`` event codes: ::
|
||||||
|
|
||||||
AttrEventCodeDisable=REL_WHEEL_HI_RES;REL_HWHEEL_HI_RES;
|
AttrEventCode=-REL_WHEEL_HI_RES;-REL_HWHEEL_HI_RES;
|
||||||
|
|
||||||
Please see :ref:`device-quirks` for details.
|
Please see :ref:`device-quirks` for details.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
MatchUdevType=tablet
|
MatchUdevType=tablet
|
||||||
MatchBus=usb
|
MatchBus=usb
|
||||||
MatchVendor=0x08CA
|
MatchVendor=0x08CA
|
||||||
AttrEventCodeDisable=ABS_TILT_X;ABS_TILT_Y;
|
AttrEventCode=-ABS_TILT_X;-ABS_TILT_Y;
|
||||||
|
|
||||||
[Aiptek 8000U pressure threshold]
|
[Aiptek 8000U pressure threshold]
|
||||||
MatchUdevType=tablet
|
MatchUdevType=tablet
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,4 @@ MatchBus=usb
|
||||||
MatchVendor=0x047D
|
MatchVendor=0x047D
|
||||||
MatchProduct=0x2048
|
MatchProduct=0x2048
|
||||||
ModelTrackball=1
|
ModelTrackball=1
|
||||||
AttrEventCodeDisable=BTN_MIDDLE
|
AttrEventCode=-BTN_MIDDLE
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ MatchUdevType=mouse
|
||||||
MatchBus=usb
|
MatchBus=usb
|
||||||
MatchVendor=0x46D
|
MatchVendor=0x46D
|
||||||
MatchProduct=0xC408
|
MatchProduct=0xC408
|
||||||
AttrEventCodeDisable=BTN_MIDDLE
|
AttrEventCode=-BTN_MIDDLE
|
||||||
|
|
||||||
[Logitech K400]
|
[Logitech K400]
|
||||||
MatchUdevType=mouse
|
MatchUdevType=mouse
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ MatchBus=usb
|
||||||
MatchVendor=0x0738
|
MatchVendor=0x0738
|
||||||
MatchProduct=0x1703
|
MatchProduct=0x1703
|
||||||
# EV_KEY 0x115, 0x116, 0x117
|
# EV_KEY 0x115, 0x116, 0x117
|
||||||
AttrEventCodeDisable=EV_KEY:0x115;EV_KEY:0x116;EV_KEY:0x117
|
AttrEventCode=-EV_KEY:0x115;-EV_KEY:0x116;-EV_KEY:0x117
|
||||||
|
|
||||||
# Like the Madcatz RAT3, but with different codes:
|
# Like the Madcatz RAT3, but with different codes:
|
||||||
# event8 POINTER_BUTTON +0.488s ??? (280) pressed, seat count: 1
|
# event8 POINTER_BUTTON +0.488s ??? (280) pressed, seat count: 1
|
||||||
|
|
@ -37,4 +37,4 @@ MatchBus=usb
|
||||||
MatchVendor=0x0738
|
MatchVendor=0x0738
|
||||||
MatchProduct=0x1708
|
MatchProduct=0x1708
|
||||||
# EV_KEY 0x118, 0x119, 0x11A
|
# EV_KEY 0x118, 0x119, 0x11A
|
||||||
AttrEventCodeDisable=EV_KEY:0x118;EV_KEY:0x119;EV_KEY:0x11A
|
AttrEventCode=-EV_KEY:0x118;-EV_KEY:0x119;-EV_KEY:0x11A
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,4 @@ ModelSynapticsSerialTouchpad=1
|
||||||
[Synaptics 0911:5288 Touchpad]
|
[Synaptics 0911:5288 Touchpad]
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchName=* 0911:5288 Touchpad
|
MatchName=* 0911:5288 Touchpad
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ MatchUdevType=tablet
|
||||||
MatchBus=usb
|
MatchBus=usb
|
||||||
MatchVendor=0x56A
|
MatchVendor=0x56A
|
||||||
MatchProduct=0x4200
|
MatchProduct=0x4200
|
||||||
AttrEventCodeDisable=ABS_TILT_X;ABS_TILT_Y;
|
AttrEventCode=-ABS_TILT_X;-ABS_TILT_Y;
|
||||||
|
|
||||||
[Wacom ISDV4 524c Pen]
|
[Wacom ISDV4 524c Pen]
|
||||||
MatchUdevType=tablet
|
MatchUdevType=tablet
|
||||||
MatchBus=usb
|
MatchBus=usb
|
||||||
MatchVendor=0x2D1F
|
MatchVendor=0x2D1F
|
||||||
MatchProduct=0x524C
|
MatchProduct=0x524C
|
||||||
AttrEventCodeDisable=ABS_TILT_X;ABS_TILT_Y;
|
AttrEventCode=-ABS_TILT_X;-ABS_TILT_Y;
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
MatchName=PIXA3854:00 093A:0274 Touchpad
|
MatchName=PIXA3854:00 093A:0274 Touchpad
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchDMIModalias=dmi:*svnFramework:pnLaptop*
|
MatchDMIModalias=dmi:*svnFramework:pnLaptop*
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ MatchUdevType=mouse
|
||||||
MatchBus=bluetooth
|
MatchBus=bluetooth
|
||||||
MatchVendor=0x05AC
|
MatchVendor=0x05AC
|
||||||
MatchProduct=0x030D
|
MatchProduct=0x030D
|
||||||
AttrEventCodeDisable=EV_ABS
|
AttrEventCode=-EV_ABS
|
||||||
|
|
||||||
# The External Apple "Magic" trackpads, both the 1st and 2nd generations, have
|
# The External Apple "Magic" trackpads, both the 1st and 2nd generations, have
|
||||||
# pretty good built-in spurious touch filtering in the device firmware. Using
|
# pretty good built-in spurious touch filtering in the device firmware. Using
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ AttrPressureRange=24:10
|
||||||
[Asus UX302LA]
|
[Asus UX302LA]
|
||||||
MatchName=*ETPS/2 Elantech Touchpad*
|
MatchName=*ETPS/2 Elantech Touchpad*
|
||||||
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnUX302LA:*
|
MatchDMIModalias=dmi:*svnASUSTeKCOMPUTERINC.:pnUX302LA:*
|
||||||
AttrEventCodeDisable=ABS_MT_PRESSURE;ABS_PRESSURE;
|
AttrEventCode=-ABS_MT_PRESSURE;-ABS_PRESSURE;
|
||||||
|
|
||||||
# Asus VivoBook Flip 14 TP412UA tablet switch seems misbehaving, always
|
# Asus VivoBook Flip 14 TP412UA tablet switch seems misbehaving, always
|
||||||
# indicating tablet position
|
# indicating tablet position
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
[Chuwi Gemibook]
|
[Chuwi Gemibook]
|
||||||
MatchName=HTIX5288:00 093A:1336 Touchpad
|
MatchName=HTIX5288:00 093A:1336 Touchpad
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
||||||
[Chuwi AeroBook Plus]
|
[Chuwi AeroBook Plus]
|
||||||
MatchName=SYNA3602:01 093A:1336 Touchpad
|
MatchName=SYNA3602:01 093A:1336 Touchpad
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,4 @@ MatchBus=usb
|
||||||
MatchVendor=0x06A3
|
MatchVendor=0x06A3
|
||||||
MatchProduct=0x0CD5
|
MatchProduct=0x0CD5
|
||||||
# EV_KEY 0x118, 0x119, 0x11a
|
# EV_KEY 0x118, 0x119, 0x11a
|
||||||
AttrEventCodeDisable=EV_KEY:0x118;EV_KEY:0x119;EV_KEY:0x11a
|
AttrEventCode=-EV_KEY:0x118;-EV_KEY:0x119;-EV_KEY:0x11a
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ AttrTrackpointMultiplier=0.3
|
||||||
MatchBus=i2c
|
MatchBus=i2c
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchDMIModalias=dmi:*svnDellInc.:pnPrecision7?50*
|
MatchDMIModalias=dmi:*svnDellInc.:pnPrecision7?50*
|
||||||
AttrInputPropDisable=INPUT_PROP_BUTTONPAD
|
AttrInputProp=-INPUT_PROP_BUTTONPAD
|
||||||
|
|
||||||
# The touch device has the same vid/pid as the totem, the MatchName
|
# The touch device has the same vid/pid as the totem, the MatchName
|
||||||
# directive is required here
|
# directive is required here
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
MatchName=HTIX5288:00 093A:0255 Touchpad
|
MatchName=HTIX5288:00 093A:0255 Touchpad
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchDMIModalias=dmi:*svnGPD:*pnG1619-*
|
MatchDMIModalias=dmi:*svnGPD:*pnG1619-*
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
[HP Compaq 6910p]
|
[HP Compaq 6910p]
|
||||||
MatchName=*SynPS/2 Synaptics TouchPad
|
MatchName=*SynPS/2 Synaptics TouchPad
|
||||||
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq6910p*
|
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq6910p*
|
||||||
AttrEventCodeDisable=BTN_TOOL_DOUBLETAP;BTN_TOOL_TRIPLETAP;
|
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
|
||||||
|
|
||||||
# Claims to have double/tripletap but doesn't actually send it
|
# Claims to have double/tripletap but doesn't actually send it
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and
|
||||||
[HP Compaq 8510w]
|
[HP Compaq 8510w]
|
||||||
MatchName=*SynPS/2 Synaptics TouchPad
|
MatchName=*SynPS/2 Synaptics TouchPad
|
||||||
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq8510w*
|
MatchDMIModalias=dmi:*svnHewlett-Packard:*pnHPCompaq8510w*
|
||||||
AttrEventCodeDisable=BTN_TOOL_DOUBLETAP;BTN_TOOL_TRIPLETAP;
|
AttrEventCode=-BTN_TOOL_DOUBLETAP;-BTN_TOOL_TRIPLETAP;
|
||||||
|
|
||||||
[HP Pavilion dmi4]
|
[HP Pavilion dmi4]
|
||||||
MatchName=*SynPS/2 Synaptics TouchPad
|
MatchName=*SynPS/2 Synaptics TouchPad
|
||||||
|
|
@ -24,7 +24,7 @@ ModelHPPavilionDM4Touchpad=1
|
||||||
[HP Stream 11]
|
[HP Stream 11]
|
||||||
MatchName=SYN1EDE:00 06CB:7442*
|
MatchName=SYN1EDE:00 06CB:7442*
|
||||||
MatchDMIModalias=dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11*
|
MatchDMIModalias=dmi:*svnHewlett-Packard:pnHPStreamNotebookPC11*
|
||||||
AttrInputPropEnable=INPUT_PROP_BUTTONPAD
|
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||||
|
|
||||||
# The HP stream x360's embedded-controller filters out events form its builtin
|
# The HP stream x360's embedded-controller filters out events form its builtin
|
||||||
# keyboard when in tablet-mode itself; and it has a capacitive home-button
|
# keyboard when in tablet-mode itself; and it has a capacitive home-button
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,4 @@
|
||||||
MatchName=ELAN2604:00 04F3:3114 Touchpad
|
MatchName=ELAN2604:00 04F3:3114 Touchpad
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchDMIModalias=dmi:*svnHUAWEI:*pvrM1010*
|
MatchDMIModalias=dmi:*svnHUAWEI:*pvrM1010*
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
|
|
|
||||||
|
|
@ -41,14 +41,14 @@ AttrTrackpointMultiplier=0.4
|
||||||
[Lenovo T480s Touchpad]
|
[Lenovo T480s Touchpad]
|
||||||
MatchName=Elan Touchpad
|
MatchName=Elan Touchpad
|
||||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT480s*
|
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT480s*
|
||||||
AttrInputPropEnable=INPUT_PROP_BUTTONPAD
|
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||||
|
|
||||||
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
|
# Touchpad is a clickpad but INPUT_PROP_BUTTONPAD is not set, see
|
||||||
# https://gitlab.freedesktop.org/libinput/libinput/issues/177
|
# https://gitlab.freedesktop.org/libinput/libinput/issues/177
|
||||||
[Lenovo T490s Touchpad]
|
[Lenovo T490s Touchpad]
|
||||||
MatchName=Elan Touchpad
|
MatchName=Elan Touchpad
|
||||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT490s*
|
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT490s*
|
||||||
AttrInputPropEnable=INPUT_PROP_BUTTONPAD
|
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||||
|
|
||||||
[Lenovo T490s Trackpoint]
|
[Lenovo T490s Trackpoint]
|
||||||
MatchName=*TPPS/2 IBM TrackPoint
|
MatchName=*TPPS/2 IBM TrackPoint
|
||||||
|
|
@ -60,7 +60,7 @@ AttrTrackpointMultiplier=0.4
|
||||||
[Lenovo L380 Touchpad]
|
[Lenovo L380 Touchpad]
|
||||||
MatchName=Elan Touchpad
|
MatchName=Elan Touchpad
|
||||||
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadL380*
|
MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadL380*
|
||||||
AttrInputPropEnable=INPUT_PROP_BUTTONPAD
|
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||||
|
|
||||||
[Lenovo X200 Trackpoint]
|
[Lenovo X200 Trackpoint]
|
||||||
MatchName=*TPPS/2 IBM TrackPoint
|
MatchName=*TPPS/2 IBM TrackPoint
|
||||||
|
|
@ -147,7 +147,7 @@ AttrTrackpointMultiplier=1.25
|
||||||
MatchBus=i2c
|
MatchBus=i2c
|
||||||
MatchVendor=0x06CB
|
MatchVendor=0x06CB
|
||||||
MatchProduct=0xCE37
|
MatchProduct=0xCE37
|
||||||
AttrEventCodeDisable=ABS_MT_PRESSURE;ABS_PRESSURE;
|
AttrEventCode=-ABS_MT_PRESSURE;-ABS_PRESSURE;
|
||||||
|
|
||||||
[Lenovo Yoga C930 Tablet]
|
[Lenovo Yoga C930 Tablet]
|
||||||
MatchBus=i2c
|
MatchBus=i2c
|
||||||
|
|
@ -160,7 +160,7 @@ AttrTabletSmoothing=1
|
||||||
[Lenovo Carbon X1 6th gen]
|
[Lenovo Carbon X1 6th gen]
|
||||||
MatchName=Synaptics TM3288-011
|
MatchName=Synaptics TM3288-011
|
||||||
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX1Carbon6th:*
|
MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX1Carbon6th:*
|
||||||
AttrEventCodeDisable=ABS_MT_TOOL_TYPE
|
AttrEventCode=-ABS_MT_TOOL_TYPE
|
||||||
ModelLenovoX1Gen6Touchpad=1
|
ModelLenovoX1Gen6Touchpad=1
|
||||||
|
|
||||||
[Lenovo X41 Tablet]
|
[Lenovo X41 Tablet]
|
||||||
|
|
@ -272,7 +272,7 @@ AttrKeyboardIntegration=internal
|
||||||
MatchBus=i2c
|
MatchBus=i2c
|
||||||
MatchVendor=0x27C6
|
MatchVendor=0x27C6
|
||||||
MatchProduct=0x01E8
|
MatchProduct=0x01E8
|
||||||
AttrEventCodeDisable=ABS_MT_PRESSURE;ABS_PRESSURE;
|
AttrEventCode=-ABS_MT_PRESSURE;-ABS_PRESSURE;
|
||||||
|
|
||||||
# Duet 7i tablet switch activated by folding keyboard cover, or removing it.
|
# Duet 7i tablet switch activated by folding keyboard cover, or removing it.
|
||||||
# We must not disable volume rocker 'keyboard'.
|
# We must not disable volume rocker 'keyboard'.
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
MatchName=*Touchpad
|
MatchName=*Touchpad
|
||||||
MatchUdevType=touchpad
|
MatchUdevType=touchpad
|
||||||
MatchDMIModalias=dmi:*svnStarLabs:*
|
MatchDMIModalias=dmi:*svnStarLabs:*
|
||||||
AttrEventCodeDisable=BTN_RIGHT
|
AttrEventCode=-BTN_RIGHT
|
||||||
AttrInputPropEnable=INPUT_PROP_BUTTONPAD
|
AttrInputProp=+INPUT_PROP_BUTTONPAD
|
||||||
|
|
|
||||||
73
src/evdev.c
73
src/evdev.c
|
|
@ -2231,8 +2231,6 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
|
||||||
struct quirks_context *quirks;
|
struct quirks_context *quirks;
|
||||||
struct quirks *q;
|
struct quirks *q;
|
||||||
const struct quirk_tuples *t;
|
const struct quirk_tuples *t;
|
||||||
const uint32_t *props = NULL;
|
|
||||||
size_t nprops = 0;
|
|
||||||
char *prop;
|
char *prop;
|
||||||
|
|
||||||
/* Touchpad claims to have 4 slots but only ever sends 2
|
/* Touchpad claims to have 4 slots but only ever sends 2
|
||||||
|
|
@ -2251,7 +2249,7 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
|
||||||
libevdev_disable_event_code(device->evdev, EV_MSC, MSC_TIMESTAMP);
|
libevdev_disable_event_code(device->evdev, EV_MSC, MSC_TIMESTAMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE_ENABLE, &t)) {
|
if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE, &t)) {
|
||||||
for (size_t i = 0; i < t->ntuples; i++) {
|
for (size_t i = 0; i < t->ntuples; i++) {
|
||||||
const struct input_absinfo absinfo = {
|
const struct input_absinfo absinfo = {
|
||||||
.minimum = 0,
|
.minimum = 0,
|
||||||
|
|
@ -2260,37 +2258,27 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
|
||||||
|
|
||||||
int type = t->tuples[i].first;
|
int type = t->tuples[i].first;
|
||||||
int code = t->tuples[i].second;
|
int code = t->tuples[i].second;
|
||||||
|
bool enable = t->tuples[i].third;
|
||||||
|
|
||||||
if (code == EVENT_CODE_UNDEFINED)
|
if (code == EVENT_CODE_UNDEFINED) {
|
||||||
|
if (enable)
|
||||||
libevdev_enable_event_type(device->evdev, type);
|
libevdev_enable_event_type(device->evdev, type);
|
||||||
else
|
else
|
||||||
|
libevdev_disable_event_type(device->evdev, type);
|
||||||
|
} else {
|
||||||
|
if (enable)
|
||||||
libevdev_enable_event_code(device->evdev,
|
libevdev_enable_event_code(device->evdev,
|
||||||
type,
|
type,
|
||||||
code,
|
code,
|
||||||
type == EV_ABS ? &absinfo : NULL);
|
type == EV_ABS ? &absinfo : NULL);
|
||||||
evdev_log_debug(device,
|
|
||||||
"quirks: enabling %s %s (%#x %#x)\n",
|
|
||||||
libevdev_event_type_get_name(type),
|
|
||||||
libevdev_event_code_get_name(type, code),
|
|
||||||
type,
|
|
||||||
code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quirks_get_tuples(q, QUIRK_ATTR_EVENT_CODE_DISABLE, &t)) {
|
|
||||||
for (size_t i = 0; i < t->ntuples; i++) {
|
|
||||||
int type = t->tuples[i].first;
|
|
||||||
int code = t->tuples[i].second;
|
|
||||||
|
|
||||||
if (code == EVENT_CODE_UNDEFINED)
|
|
||||||
libevdev_disable_event_type(device->evdev,
|
|
||||||
type);
|
|
||||||
else
|
else
|
||||||
libevdev_disable_event_code(device->evdev,
|
libevdev_disable_event_code(device->evdev,
|
||||||
type,
|
type,
|
||||||
code);
|
code);
|
||||||
|
}
|
||||||
evdev_log_debug(device,
|
evdev_log_debug(device,
|
||||||
"quirks: disabling %s %s (%#x %#x)\n",
|
"quirks: %s %s %s (%#x %#x)\n",
|
||||||
|
enable ? "enabling" : "disabling",
|
||||||
libevdev_event_type_get_name(type),
|
libevdev_event_type_get_name(type),
|
||||||
libevdev_event_code_get_name(type, code),
|
libevdev_event_code_get_name(type, code),
|
||||||
type,
|
type,
|
||||||
|
|
@ -2298,38 +2286,29 @@ evdev_pre_configure_model_quirks(struct evdev_device *device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quirks_get_uint32_array(q,
|
if (quirks_get_tuples(q, QUIRK_ATTR_INPUT_PROP, &t)) {
|
||||||
QUIRK_ATTR_INPUT_PROP_ENABLE,
|
for (size_t idx = 0; idx < t->ntuples; idx++) {
|
||||||
&props,
|
unsigned int p = t->tuples[idx].first;
|
||||||
&nprops)) {
|
bool enable = t->tuples[idx].second;
|
||||||
for (size_t idx = 0; idx < nprops; idx++) {
|
|
||||||
unsigned int p = props[idx];
|
|
||||||
libevdev_enable_property(device->evdev, p);
|
|
||||||
evdev_log_debug(device,
|
|
||||||
"quirks: enabling %s (%#x)\n",
|
|
||||||
libevdev_property_get_name(p),
|
|
||||||
p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quirks_get_uint32_array(q,
|
if (enable) {
|
||||||
QUIRK_ATTR_INPUT_PROP_DISABLE,
|
libevdev_enable_property(device->evdev, p);
|
||||||
&props,
|
|
||||||
&nprops)) {
|
|
||||||
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
|
||||||
for (size_t idx = 0; idx < nprops; idx++) {
|
|
||||||
unsigned int p = props[idx];
|
|
||||||
libevdev_disable_property(device->evdev, p);
|
|
||||||
evdev_log_debug(device,
|
|
||||||
"quirks: disabling %s (%#x)\n",
|
|
||||||
libevdev_property_get_name(p),
|
|
||||||
p);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
||||||
|
libevdev_disable_property(device->evdev, p);
|
||||||
#else
|
#else
|
||||||
evdev_log_error(device,
|
evdev_log_error(device,
|
||||||
"quirks: a quirk for this device requires newer libevdev than installed\n");
|
"quirks: a quirk for this device requires newer libevdev than installed\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
evdev_log_debug(device,
|
||||||
|
"quirks: %s %s (%#x)\n",
|
||||||
|
enable ? "enabling" : "disabling",
|
||||||
|
libevdev_property_get_name(p),
|
||||||
|
p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
quirks_unref(q);
|
quirks_unref(q);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
103
src/quirks.c
103
src/quirks.c
|
|
@ -175,6 +175,10 @@ struct quirks {
|
||||||
/* These are not ref'd, just a collection of pointers */
|
/* These are not ref'd, just a collection of pointers */
|
||||||
struct property **properties;
|
struct property **properties;
|
||||||
size_t nproperties;
|
size_t nproperties;
|
||||||
|
|
||||||
|
/* Special properties for AttrEventCode and AttrInputCode, these are
|
||||||
|
* owned by us, not the section */
|
||||||
|
struct list floating_properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -282,10 +286,8 @@ quirk_get_name(enum quirk q)
|
||||||
case QUIRK_ATTR_TABLET_SMOOTHING: return "AttrTabletSmoothing";
|
case QUIRK_ATTR_TABLET_SMOOTHING: return "AttrTabletSmoothing";
|
||||||
case QUIRK_ATTR_THUMB_SIZE_THRESHOLD: return "AttrThumbSizeThreshold";
|
case QUIRK_ATTR_THUMB_SIZE_THRESHOLD: return "AttrThumbSizeThreshold";
|
||||||
case QUIRK_ATTR_MSC_TIMESTAMP: return "AttrMscTimestamp";
|
case QUIRK_ATTR_MSC_TIMESTAMP: return "AttrMscTimestamp";
|
||||||
case QUIRK_ATTR_EVENT_CODE_DISABLE: return "AttrEventCodeDisable";
|
case QUIRK_ATTR_EVENT_CODE: return "AttrEventCode";
|
||||||
case QUIRK_ATTR_EVENT_CODE_ENABLE: return "AttrEventCodeEnable";
|
case QUIRK_ATTR_INPUT_PROP: return "AttrInputProp";
|
||||||
case QUIRK_ATTR_INPUT_PROP_DISABLE: return "AttrInputPropDisable";
|
|
||||||
case QUIRK_ATTR_INPUT_PROP_ENABLE: return "AttrInputPropEnable";
|
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
@ -817,14 +819,11 @@ parse_attr(struct quirks_context *ctx,
|
||||||
p->type = PT_STRING;
|
p->type = PT_STRING;
|
||||||
p->value.s = safe_strdup(value);
|
p->value.s = safe_strdup(value);
|
||||||
rc = true;
|
rc = true;
|
||||||
} else if (streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE_DISABLE)) ||
|
} else if (streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE))) {
|
||||||
streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE_ENABLE))) {
|
|
||||||
struct input_event events[32];
|
struct input_event events[32];
|
||||||
size_t nevents = ARRAY_LENGTH(events);
|
size_t nevents = ARRAY_LENGTH(events);
|
||||||
if (streq(key, quirk_get_name(QUIRK_ATTR_EVENT_CODE_DISABLE)))
|
|
||||||
p->id = QUIRK_ATTR_EVENT_CODE_DISABLE;
|
p->id = QUIRK_ATTR_EVENT_CODE;
|
||||||
else
|
|
||||||
p->id = QUIRK_ATTR_EVENT_CODE_ENABLE;
|
|
||||||
|
|
||||||
if (!parse_evcode_property(value, events, &nevents) ||
|
if (!parse_evcode_property(value, events, &nevents) ||
|
||||||
nevents == 0)
|
nevents == 0)
|
||||||
|
|
@ -833,27 +832,29 @@ parse_attr(struct quirks_context *ctx,
|
||||||
for (size_t i = 0; i < nevents; i++) {
|
for (size_t i = 0; i < nevents; i++) {
|
||||||
p->value.tuples.tuples[i].first = events[i].type;
|
p->value.tuples.tuples[i].first = events[i].type;
|
||||||
p->value.tuples.tuples[i].second = events[i].code;
|
p->value.tuples.tuples[i].second = events[i].code;
|
||||||
|
p->value.tuples.tuples[i].third = events[i].value;
|
||||||
}
|
}
|
||||||
p->value.tuples.ntuples = nevents;
|
p->value.tuples.ntuples = nevents;
|
||||||
p->type = PT_TUPLES;
|
p->type = PT_TUPLES;
|
||||||
|
|
||||||
rc = true;
|
rc = true;
|
||||||
} else if (streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP_DISABLE)) ||
|
} else if (streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP))) {
|
||||||
streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP_ENABLE))) {
|
struct input_prop props[INPUT_PROP_CNT];
|
||||||
unsigned int props[INPUT_PROP_CNT];
|
|
||||||
size_t nprops = ARRAY_LENGTH(props);
|
size_t nprops = ARRAY_LENGTH(props);
|
||||||
if (streq(key, quirk_get_name(QUIRK_ATTR_INPUT_PROP_DISABLE)))
|
|
||||||
p->id = QUIRK_ATTR_INPUT_PROP_DISABLE;
|
p->id = QUIRK_ATTR_INPUT_PROP;
|
||||||
else
|
|
||||||
p->id = QUIRK_ATTR_INPUT_PROP_ENABLE;
|
|
||||||
|
|
||||||
if (!parse_input_prop_property(value, props, &nprops) ||
|
if (!parse_input_prop_property(value, props, &nprops) ||
|
||||||
nprops == 0)
|
nprops == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
memcpy(p->value.array.data.u, props, nprops * sizeof(unsigned int));
|
for (size_t i = 0; i < nprops; i++) {
|
||||||
p->value.array.nelements = nprops;
|
p->value.tuples.tuples[i].first = props[i].prop;
|
||||||
p->type = PT_UINT_ARRAY;
|
p->value.tuples.tuples[i].second = props[i].enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->value.tuples.ntuples = nprops;
|
||||||
|
p->type = PT_TUPLES;
|
||||||
|
|
||||||
rc = true;
|
rc = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1201,6 +1202,7 @@ quirks_new(void)
|
||||||
q->refcount = 1;
|
q->refcount = 1;
|
||||||
q->nproperties = 0;
|
q->nproperties = 0;
|
||||||
list_init(&q->link);
|
list_init(&q->link);
|
||||||
|
list_init(&q->floating_properties);
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
@ -1219,6 +1221,13 @@ quirks_unref(struct quirks *q)
|
||||||
property_unref(q->properties[i]);
|
property_unref(q->properties[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Floating properties are owned by our quirks context, need to be
|
||||||
|
* cleaned up here */
|
||||||
|
struct property *p;
|
||||||
|
list_for_each_safe(p, &q->floating_properties, link) {
|
||||||
|
property_cleanup(p);
|
||||||
|
}
|
||||||
|
|
||||||
list_remove(&q->link);
|
list_remove(&q->link);
|
||||||
free(q->properties);
|
free(q->properties);
|
||||||
free(q);
|
free(q);
|
||||||
|
|
@ -1378,6 +1387,41 @@ match_free(struct match *m)
|
||||||
free(m);
|
free(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
quirk_merge_event_codes(struct quirks_context *ctx,
|
||||||
|
struct quirks *q,
|
||||||
|
const struct property *property)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < q->nproperties; i++) {
|
||||||
|
struct property *p = q->properties[i];
|
||||||
|
|
||||||
|
if (p->id != property->id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* We have a duplicated property, merge in with ours */
|
||||||
|
size_t offset = p->value.tuples.ntuples;
|
||||||
|
size_t max = ARRAY_LENGTH(p->value.tuples.tuples);
|
||||||
|
for (size_t j = 0; j < property->value.tuples.ntuples; j++) {
|
||||||
|
if (offset + j >= max)
|
||||||
|
break;
|
||||||
|
p->value.tuples.tuples[offset + j] = property->value.tuples.tuples[j];
|
||||||
|
p->value.tuples.ntuples++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First time we add AttrEventCode: create a new property.
|
||||||
|
* Unlike the other properties, this one isn't part of a section, it belongs
|
||||||
|
* to the quirks */
|
||||||
|
struct property *newprop = property_new();
|
||||||
|
newprop->id = property->id;
|
||||||
|
newprop->type = property->type;
|
||||||
|
newprop->value.tuples = property->value.tuples;
|
||||||
|
/* Caller responsible for pre-allocating space */
|
||||||
|
q->properties[q->nproperties++] = property_ref(newprop);
|
||||||
|
list_append(&q->floating_properties, &newprop->link);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
quirk_apply_section(struct quirks_context *ctx,
|
quirk_apply_section(struct quirks_context *ctx,
|
||||||
struct quirks *q,
|
struct quirks *q,
|
||||||
|
|
@ -1401,6 +1445,25 @@ quirk_apply_section(struct quirks_context *ctx,
|
||||||
qlog_debug(ctx, "property added: %s from %s\n",
|
qlog_debug(ctx, "property added: %s from %s\n",
|
||||||
quirk_get_name(p->id), s->name);
|
quirk_get_name(p->id), s->name);
|
||||||
|
|
||||||
|
/* All quirks but AttrEventCode and AttrInputProp
|
||||||
|
* simply overwrite each other, so we can just append the
|
||||||
|
* matching property and, later when checking the quirk, pick
|
||||||
|
* the last one in the array.
|
||||||
|
*
|
||||||
|
* The event codes/input props are special because they're lists
|
||||||
|
* that may *partially* override each other, e.g. a section may
|
||||||
|
* enable BTN_LEFT and BTN_RIGHT but a later section may disable
|
||||||
|
* only BTN_RIGHT. This should result in BTN_LEFT force-enabled
|
||||||
|
* and BTN_RIGHT force-disabled.
|
||||||
|
*
|
||||||
|
* To hack around this, those are the only ones where only ever
|
||||||
|
* have one struct property in the list (not owned by a section)
|
||||||
|
* and we simply merge any extra sections onto that.
|
||||||
|
*/
|
||||||
|
if (p->id == QUIRK_ATTR_EVENT_CODE ||
|
||||||
|
p->id == QUIRK_ATTR_INPUT_PROP)
|
||||||
|
quirk_merge_event_codes(ctx, q, p);
|
||||||
|
else
|
||||||
q->properties[q->nproperties++] = property_ref(p);
|
q->properties[q->nproperties++] = property_ref(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ struct quirk_tuples {
|
||||||
struct {
|
struct {
|
||||||
int first;
|
int first;
|
||||||
int second;
|
int second;
|
||||||
|
int third;
|
||||||
} tuples[32];
|
} tuples[32];
|
||||||
size_t ntuples;
|
size_t ntuples;
|
||||||
};
|
};
|
||||||
|
|
@ -104,10 +105,8 @@ enum quirk {
|
||||||
QUIRK_ATTR_TABLET_SMOOTHING,
|
QUIRK_ATTR_TABLET_SMOOTHING,
|
||||||
QUIRK_ATTR_THUMB_SIZE_THRESHOLD,
|
QUIRK_ATTR_THUMB_SIZE_THRESHOLD,
|
||||||
QUIRK_ATTR_MSC_TIMESTAMP,
|
QUIRK_ATTR_MSC_TIMESTAMP,
|
||||||
QUIRK_ATTR_EVENT_CODE_DISABLE,
|
QUIRK_ATTR_EVENT_CODE,
|
||||||
QUIRK_ATTR_EVENT_CODE_ENABLE,
|
QUIRK_ATTR_INPUT_PROP,
|
||||||
QUIRK_ATTR_INPUT_PROP_DISABLE,
|
|
||||||
QUIRK_ATTR_INPUT_PROP_ENABLE,
|
|
||||||
|
|
||||||
_QUIRK_LAST_ATTR_QUIRK_, /* Guard: do not modify */
|
_QUIRK_LAST_ATTR_QUIRK_, /* Guard: do not modify */
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -347,10 +347,10 @@ parse_evcode_string(const char *s, int *type_out, int *code_out)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a string of the format "EV_ABS;KEY_A;BTN_TOOL_DOUBLETAP;ABS_X;"
|
* Parses a string of the format "+EV_ABS;+KEY_A;-BTN_TOOL_DOUBLETAP;-ABS_X;"
|
||||||
* where each element must be a named event type OR a named event code OR a
|
* where each element must be + or - (enable/disable) followed by a named event
|
||||||
* tuple in the form of EV_KEY:0x123, i.e. a named event type followed by a
|
* type OR a named event code OR a tuple in the form of EV_KEY:0x123, i.e. a
|
||||||
* hex event code.
|
* named event type followed by a hex event code.
|
||||||
*
|
*
|
||||||
* events must point to an existing array of size nevents.
|
* events must point to an existing array of size nevents.
|
||||||
* nevents specifies the size of the array in events and returns the number
|
* nevents specifies the size of the array in events and returns the number
|
||||||
|
|
@ -361,7 +361,8 @@ parse_evcode_string(const char *s, int *type_out, int *code_out)
|
||||||
* other fields undefined. Where only the event type is specified, the code
|
* other fields undefined. Where only the event type is specified, the code
|
||||||
* is set to EVENT_CODE_UNDEFINED.
|
* is set to EVENT_CODE_UNDEFINED.
|
||||||
*
|
*
|
||||||
* On success, events contains nevents events.
|
* On success, events contains nevents events with each event's value set to 1
|
||||||
|
* or 0 depending on the + or - prefix.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
parse_evcode_property(const char *prop, struct input_event *events, size_t *nevents)
|
parse_evcode_property(const char *prop, struct input_event *events, size_t *nevents)
|
||||||
|
|
@ -380,6 +381,16 @@ parse_evcode_property(const char *prop, struct input_event *events, size_t *neve
|
||||||
ncodes = min(*nevents, ncodes);
|
ncodes = min(*nevents, ncodes);
|
||||||
for (size_t idx = 0; strv[idx]; idx++) {
|
for (size_t idx = 0; strv[idx]; idx++) {
|
||||||
char *s = strv[idx];
|
char *s = strv[idx];
|
||||||
|
bool enable;
|
||||||
|
|
||||||
|
switch (*s) {
|
||||||
|
case '+': enable = true; break;
|
||||||
|
case '-': enable = false; break;
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
s++;
|
||||||
|
|
||||||
int type, code;
|
int type, code;
|
||||||
|
|
||||||
|
|
@ -399,6 +410,7 @@ parse_evcode_property(const char *prop, struct input_event *events, size_t *neve
|
||||||
|
|
||||||
evs[idx].type = type;
|
evs[idx].type = type;
|
||||||
evs[idx].code = code;
|
evs[idx].code = code;
|
||||||
|
evs[idx].value = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(events, evs, ncodes * sizeof *events);
|
memcpy(events, evs, ncodes * sizeof *events);
|
||||||
|
|
@ -411,9 +423,9 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a string of the format "INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER;0x123;"
|
* Parses a string of the format "+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER;+0x123;"
|
||||||
* where each element must be a named input prop OR a hexcode in the form
|
* where each element must be a named input prop OR a hexcode in the form
|
||||||
* 0x1234
|
* 0x1234. The prefix for each element must be either '+' (enable) or '-' (disable).
|
||||||
*
|
*
|
||||||
* props must point to an existing array of size nprops.
|
* props must point to an existing array of size nprops.
|
||||||
* nprops specifies the size of the array in props and returns the number
|
* nprops specifies the size of the array in props and returns the number
|
||||||
|
|
@ -423,10 +435,10 @@ out:
|
||||||
* On success, props contains nprops elements.
|
* On success, props contains nprops elements.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
parse_input_prop_property(const char *prop, unsigned int *props_out, size_t *nprops)
|
parse_input_prop_property(const char *prop, struct input_prop *props_out, size_t *nprops)
|
||||||
{
|
{
|
||||||
bool rc = false;
|
bool rc = false;
|
||||||
unsigned int props[INPUT_PROP_CNT]; /* doubling up on quirks is a bug */
|
struct input_prop props[INPUT_PROP_CNT]; /* doubling up on quirks is a bug */
|
||||||
|
|
||||||
size_t count;
|
size_t count;
|
||||||
char **strv = strv_from_string(prop, ";", &count);
|
char **strv = strv_from_string(prop, ";", &count);
|
||||||
|
|
@ -437,6 +449,16 @@ parse_input_prop_property(const char *prop, unsigned int *props_out, size_t *npr
|
||||||
for (size_t idx = 0; strv[idx]; idx++) {
|
for (size_t idx = 0; strv[idx]; idx++) {
|
||||||
char *s = strv[idx];
|
char *s = strv[idx];
|
||||||
unsigned int prop;
|
unsigned int prop;
|
||||||
|
bool enable;
|
||||||
|
|
||||||
|
switch (*s) {
|
||||||
|
case '+': enable = true; break;
|
||||||
|
case '-': enable = false; break;
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
s++;
|
||||||
|
|
||||||
if (safe_atou_base(s, &prop, 16)) {
|
if (safe_atou_base(s, &prop, 16)) {
|
||||||
if (prop > INPUT_PROP_MAX)
|
if (prop > INPUT_PROP_MAX)
|
||||||
|
|
@ -447,7 +469,8 @@ parse_input_prop_property(const char *prop, unsigned int *props_out, size_t *npr
|
||||||
goto out;
|
goto out;
|
||||||
prop = (unsigned int)val;
|
prop = (unsigned int)val;
|
||||||
}
|
}
|
||||||
props[idx] = prop;
|
props[idx].prop = prop;
|
||||||
|
props[idx].enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(props_out, props, count * sizeof *props);
|
memcpy(props_out, props, count * sizeof *props);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct input_prop {
|
||||||
|
unsigned int prop;
|
||||||
|
bool enabled;
|
||||||
|
};
|
||||||
|
|
||||||
int parse_mouse_dpi_property(const char *prop);
|
int parse_mouse_dpi_property(const char *prop);
|
||||||
int parse_mouse_wheel_click_angle_property(const char *prop);
|
int parse_mouse_wheel_click_angle_property(const char *prop);
|
||||||
int parse_mouse_wheel_click_count_property(const char *prop);
|
int parse_mouse_wheel_click_count_property(const char *prop);
|
||||||
|
|
@ -39,7 +44,7 @@ bool parse_range_property(const char *prop, int *hi, int *lo);
|
||||||
bool parse_boolean_property(const char *prop, bool *b);
|
bool parse_boolean_property(const char *prop, bool *b);
|
||||||
#define EVENT_CODE_UNDEFINED 0xffff
|
#define EVENT_CODE_UNDEFINED 0xffff
|
||||||
bool parse_evcode_property(const char *prop, struct input_event *events, size_t *nevents);
|
bool parse_evcode_property(const char *prop, struct input_event *events, size_t *nevents);
|
||||||
bool parse_input_prop_property(const char *prop, unsigned int *props_out, size_t *nprops);
|
bool parse_input_prop_property(const char *prop, struct input_prop *props_out, size_t *nprops);
|
||||||
|
|
||||||
enum tpkbcombo_layout {
|
enum tpkbcombo_layout {
|
||||||
TPKBCOMBO_LAYOUT_UNKNOWN,
|
TPKBCOMBO_LAYOUT_UNKNOWN,
|
||||||
|
|
|
||||||
|
|
@ -199,22 +199,46 @@ static int events[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char quirk_file[] =
|
static const char quirk_file[] =
|
||||||
"[litest Quirked Keyboard enable rel]\n"
|
"[litest Quirked Keyboard enable buttons]\n"
|
||||||
"MatchName=litest Quirked Keyboard\n"
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
"AttrEventCodeEnable=BTN_RIGHT;EV_KEY:0x110\n" /* BTN_LEFT */
|
"AttrEventCode=+BTN_RIGHT;+BTN_MIDDLE;+EV_KEY:0x110\n" /* BTN_LEFT */
|
||||||
|
"\n"
|
||||||
|
"[litest Quirked Keyboard disable buttons]\n"
|
||||||
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
|
"AttrEventCode=-BTN_MIDDLE;-BTN_RIGHT\n"
|
||||||
|
"\n"
|
||||||
|
"[litest Quirked Keyboard re-enable buttons]\n"
|
||||||
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
|
"AttrEventCode=+BTN_RIGHT\n"
|
||||||
"\n"
|
"\n"
|
||||||
"[litest Quirked keyboard disable F1-F3]\n"
|
"[litest Quirked keyboard disable F1-F3]\n"
|
||||||
"MatchName=litest Quirked Keyboard\n"
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
"AttrEventCodeDisable=KEY_F1;EV_KEY:0x3c;KEY_F3\n"
|
"AttrEventCode=-KEY_F1;-EV_KEY:0x3c;-KEY_F3\n"
|
||||||
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
||||||
"\n"
|
"\n"
|
||||||
"[litest Quirked keyboard enable buttonpad]\n"
|
"[litest Quirked keyboard enable buttonpad]\n"
|
||||||
"MatchName=litest Quirked Keyboard\n"
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
"AttrInputPropEnable=INPUT_PROP_BUTTONPAD\n"
|
"AttrInputProp=+INPUT_PROP_BUTTONPAD\n"
|
||||||
"\n"
|
"\n"
|
||||||
"[litest Quirked keyboard disable pointingstick]\n"
|
"[litest Quirked keyboard disable pointingstick]\n"
|
||||||
"MatchName=litest Quirked Keyboard\n"
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
"AttrInputPropDisable=INPUT_PROP_POINTING_STICK\n"
|
"AttrInputProp=-INPUT_PROP_POINTING_STICK\n"
|
||||||
|
"\n"
|
||||||
|
"[litest Quirked keyboard enable direct]\n"
|
||||||
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
|
"AttrInputProp=+INPUT_PROP_DIRECT\n"
|
||||||
|
"\n"
|
||||||
|
"[litest Quirked keyboard disable direct]\n"
|
||||||
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
|
"AttrInputProp=-INPUT_PROP_DIRECT\n"
|
||||||
|
"\n"
|
||||||
|
"[litest Quirked keyboard disable semi-mt]\n"
|
||||||
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
|
"AttrInputProp=-INPUT_PROP_SEMI_MT\n"
|
||||||
|
"\n"
|
||||||
|
"[litest Quirked keyboard enable semi-mt]\n"
|
||||||
|
"MatchName=litest Quirked Keyboard\n"
|
||||||
|
"AttrInputProp=+INPUT_PROP_SEMI_MT\n"
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1477,7 +1477,11 @@ START_TEST(device_quirks)
|
||||||
enable_btn_left = false;
|
enable_btn_left = false;
|
||||||
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
||||||
bool disable_pointingstick = false,
|
bool disable_pointingstick = false,
|
||||||
enable_buttonpad = false;
|
enable_buttonpad = false,
|
||||||
|
enable_direct = false,
|
||||||
|
disable_direct = false,
|
||||||
|
enable_semi_mt = false,
|
||||||
|
disable_semi_mt = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
li = litest_create_context();
|
li = litest_create_context();
|
||||||
|
|
@ -1490,6 +1494,8 @@ START_TEST(device_quirks)
|
||||||
BTN_LEFT));
|
BTN_LEFT));
|
||||||
ck_assert(libinput_device_pointer_has_button(dev->libinput_device,
|
ck_assert(libinput_device_pointer_has_button(dev->libinput_device,
|
||||||
BTN_RIGHT));
|
BTN_RIGHT));
|
||||||
|
ck_assert(!libinput_device_pointer_has_button(device,
|
||||||
|
BTN_MIDDLE));
|
||||||
ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
|
ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
|
||||||
KEY_F1));
|
KEY_F1));
|
||||||
ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
|
ck_assert(!libinput_device_keyboard_has_key(dev->libinput_device,
|
||||||
|
|
@ -1510,6 +1516,22 @@ START_TEST(device_quirks)
|
||||||
enable_buttonpad = true;
|
enable_buttonpad = true;
|
||||||
if (strstr(*message, "disabling INPUT_PROP_POINTING_STICK"))
|
if (strstr(*message, "disabling INPUT_PROP_POINTING_STICK"))
|
||||||
disable_pointingstick = true;
|
disable_pointingstick = true;
|
||||||
|
if (strstr(*message, "enabling INPUT_PROP_DIRECT")) {
|
||||||
|
ck_assert(!disable_direct);
|
||||||
|
enable_direct = true;
|
||||||
|
}
|
||||||
|
if (strstr(*message, "disabling INPUT_PROP_DIRECT")) {
|
||||||
|
ck_assert(enable_direct);
|
||||||
|
disable_direct = true;
|
||||||
|
}
|
||||||
|
if (strstr(*message, "enabling INPUT_PROP_SEMI_MT")) {
|
||||||
|
ck_assert(disable_semi_mt);
|
||||||
|
enable_semi_mt = true;
|
||||||
|
}
|
||||||
|
if (strstr(*message, "disabling INPUT_PROP_SEMI_MT")) {
|
||||||
|
ck_assert(!enable_semi_mt);
|
||||||
|
disable_semi_mt = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
free(*message);
|
free(*message);
|
||||||
message++;
|
message++;
|
||||||
|
|
@ -1520,6 +1542,10 @@ START_TEST(device_quirks)
|
||||||
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
#if HAVE_LIBEVDEV_DISABLE_PROPERTY
|
||||||
ck_assert(enable_buttonpad);
|
ck_assert(enable_buttonpad);
|
||||||
ck_assert(disable_pointingstick);
|
ck_assert(disable_pointingstick);
|
||||||
|
ck_assert(enable_direct);
|
||||||
|
ck_assert(disable_direct);
|
||||||
|
ck_assert(enable_semi_mt);
|
||||||
|
ck_assert(disable_semi_mt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
litest_disable_log_handler(li);
|
litest_disable_log_handler(li);
|
||||||
|
|
|
||||||
|
|
@ -560,47 +560,50 @@ START_TEST(evcode_prop_parser)
|
||||||
struct parser_test_tuple {
|
struct parser_test_tuple {
|
||||||
const char *prop;
|
const char *prop;
|
||||||
bool success;
|
bool success;
|
||||||
size_t ntuples;
|
size_t nevents;
|
||||||
int tuples[20];
|
struct input_event events[20];
|
||||||
} tests[] = {
|
} tests[] = {
|
||||||
{ "EV_KEY", true, 1, {EV_KEY, 0xffff} },
|
{ "+EV_KEY", true, 1, {{ .type = EV_KEY, .code = 0xffff, .value = 1 }} },
|
||||||
{ "EV_ABS;", true, 1, {EV_ABS, 0xffff} },
|
{ "-EV_ABS;", true, 1, {{ .type = EV_ABS, .code = 0xffff, .value = 0 }} },
|
||||||
{ "ABS_X;", true, 1, {EV_ABS, ABS_X} },
|
{ "+ABS_X;", true, 1, {{ .type = EV_ABS, .code = ABS_X, .value = 1 }} },
|
||||||
{ "SW_TABLET_MODE;", true, 1, {EV_SW, SW_TABLET_MODE} },
|
{ "-SW_TABLET_MODE;", true, 1, {{ .type = EV_SW, .code = SW_TABLET_MODE, .value = 0 }} },
|
||||||
{ "EV_SW", true, 1, {EV_SW, 0xffff} },
|
{ "+EV_SW", true, 1, {{ .type = EV_SW, .code = 0xffff, .value = 1 }} },
|
||||||
{ "ABS_Y", true, 1, {EV_ABS, ABS_Y} },
|
{ "-ABS_Y", true, 1, {{ .type = EV_ABS, .code = ABS_Y, .value = 0 }} },
|
||||||
{ "EV_ABS:0x00", true, 1, {EV_ABS, ABS_X} },
|
{ "+EV_ABS:0x00", true, 1, {{ .type = EV_ABS, .code = ABS_X, .value = 1 }} },
|
||||||
{ "EV_ABS:01", true, 1, {EV_ABS, ABS_Y} },
|
{ "-EV_ABS:01", true, 1, {{ .type = EV_ABS, .code = ABS_Y, .value = 0 }} },
|
||||||
{ "ABS_TILT_X;ABS_TILT_Y;", true, 2,
|
{ "+ABS_TILT_X;-ABS_TILT_Y;", true, 2,
|
||||||
{ EV_ABS, ABS_TILT_X,
|
{{ .type = EV_ABS, .code = ABS_TILT_X, .value = 1 },
|
||||||
EV_ABS, ABS_TILT_Y} },
|
{ .type = EV_ABS, .code = ABS_TILT_Y, .value = 0}} },
|
||||||
{ "BTN_TOOL_DOUBLETAP;EV_KEY;KEY_A", true, 3,
|
{ "+BTN_TOOL_DOUBLETAP;+EV_KEY;-KEY_A", true, 3,
|
||||||
{ EV_KEY, BTN_TOOL_DOUBLETAP,
|
{{ .type = EV_KEY, .code = BTN_TOOL_DOUBLETAP, .value = 1 } ,
|
||||||
EV_KEY, 0xffff,
|
{ .type = EV_KEY, .code = 0xffff, .value = 1 },
|
||||||
EV_KEY, KEY_A } },
|
{ .type = EV_KEY, .code = KEY_A, .value = 0 }} },
|
||||||
{ "REL_Y;ABS_Z;BTN_STYLUS", true, 3,
|
{ "+REL_Y;-ABS_Z;+BTN_STYLUS", true, 3,
|
||||||
{ EV_REL, REL_Y,
|
{{ .type = EV_REL, .code = REL_Y, .value = 1},
|
||||||
EV_ABS, ABS_Z,
|
{ .type = EV_ABS, .code = ABS_Z, .value = 0},
|
||||||
EV_KEY, BTN_STYLUS } },
|
{ .type = EV_KEY, .code = BTN_STYLUS, .value = 1 }} },
|
||||||
{ "REL_Y;EV_KEY:0x123;BTN_STYLUS", true, 3,
|
{ "-REL_Y;+EV_KEY:0x123;-BTN_STYLUS", true, 3,
|
||||||
{ EV_REL, REL_Y,
|
{{ .type = EV_REL, .code = REL_Y, .value = 0 },
|
||||||
EV_KEY, 0x123,
|
{ .type = EV_KEY, .code = 0x123, .value = 1 },
|
||||||
EV_KEY, BTN_STYLUS } },
|
{ .type = EV_KEY, .code = BTN_STYLUS, .value = 0 }} },
|
||||||
{ .prop = "", .success = false },
|
{ .prop = "", .success = false },
|
||||||
{ .prop = "EV_FOO", .success = false },
|
{ .prop = "+", .success = false },
|
||||||
{ .prop = "EV_KEY;EV_FOO", .success = false },
|
{ .prop = "-", .success = false },
|
||||||
{ .prop = "BTN_STYLUS;EV_FOO", .success = false },
|
{ .prop = "!", .success = false },
|
||||||
{ .prop = "BTN_UNKNOWN", .success = false },
|
{ .prop = "+EV_FOO", .success = false },
|
||||||
{ .prop = "BTN_UNKNOWN;EV_KEY", .success = false },
|
{ .prop = "+EV_KEY;-EV_FOO", .success = false },
|
||||||
{ .prop = "PR_UNKNOWN", .success = false },
|
{ .prop = "+BTN_STYLUS;-EV_FOO", .success = false },
|
||||||
{ .prop = "BTN_STYLUS;PR_UNKNOWN;ABS_X", .success = false },
|
{ .prop = "-BTN_UNKNOWN", .success = false },
|
||||||
{ .prop = "EV_REL:0xffff", .success = false },
|
{ .prop = "+BTN_UNKNOWN;+EV_KEY", .success = false },
|
||||||
{ .prop = "EV_REL:0x123.", .success = false },
|
{ .prop = "-PR_UNKNOWN", .success = false },
|
||||||
{ .prop = "EV_REL:ffff", .success = false },
|
{ .prop = "-BTN_STYLUS;+PR_UNKNOWN;-ABS_X", .success = false },
|
||||||
{ .prop = "EV_REL:blah", .success = false },
|
{ .prop = "-EV_REL:0xffff", .success = false },
|
||||||
{ .prop = "KEY_A:0x11", .success = false },
|
{ .prop = "-EV_REL:0x123.", .success = false },
|
||||||
{ .prop = "EV_KEY:0x11 ", .success = false },
|
{ .prop = "-EV_REL:ffff", .success = false },
|
||||||
{ .prop = "EV_KEY:0x11not", .success = false },
|
{ .prop = "-EV_REL:blah", .success = false },
|
||||||
|
{ .prop = "+KEY_A:0x11", .success = false },
|
||||||
|
{ .prop = "+EV_KEY:0x11 ", .success = false },
|
||||||
|
{ .prop = "+EV_KEY:0x11not", .success = false },
|
||||||
{ .prop = "none", .success = false },
|
{ .prop = "none", .success = false },
|
||||||
{ .prop = NULL },
|
{ .prop = NULL },
|
||||||
};
|
};
|
||||||
|
|
@ -617,14 +620,14 @@ START_TEST(evcode_prop_parser)
|
||||||
if (!success)
|
if (!success)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ck_assert_int_eq(nevents, t->ntuples);
|
ck_assert_int_eq(nevents, t->nevents);
|
||||||
for (size_t j = 0; j < nevents; j++) {
|
for (size_t j = 0; j < nevents; j++) {
|
||||||
int type, code;
|
unsigned int type = events[j].type;
|
||||||
|
unsigned int code = events[j].code;
|
||||||
type = events[j].type;
|
int value = events[j].value;
|
||||||
code = events[j].code;
|
ck_assert_int_eq(t->events[j].type, type);
|
||||||
ck_assert_int_eq(t->tuples[j * 2], type);
|
ck_assert_int_eq(t->events[j].code, code);
|
||||||
ck_assert_int_eq(t->tuples[j * 2 + 1], code);
|
ck_assert_int_eq(t->events[j].value, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -636,16 +639,16 @@ START_TEST(input_prop_parser)
|
||||||
const char *prop;
|
const char *prop;
|
||||||
bool success;
|
bool success;
|
||||||
size_t nvals;
|
size_t nvals;
|
||||||
uint32_t values[20];
|
struct input_prop values[20];
|
||||||
} tests[] = {
|
} tests[] = {
|
||||||
{ "INPUT_PROP_BUTTONPAD", true, 1, {INPUT_PROP_BUTTONPAD}},
|
{ "+INPUT_PROP_BUTTONPAD", true, 1, {{ INPUT_PROP_BUTTONPAD, true }}},
|
||||||
{ "INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER", true, 2,
|
{ "+INPUT_PROP_BUTTONPAD;-INPUT_PROP_POINTER", true, 2,
|
||||||
{ INPUT_PROP_BUTTONPAD,
|
{ { INPUT_PROP_BUTTONPAD, true },
|
||||||
INPUT_PROP_POINTER }},
|
{ INPUT_PROP_POINTER, false }}},
|
||||||
{ "INPUT_PROP_BUTTONPAD;0x00;0x03", true, 3,
|
{ "+INPUT_PROP_BUTTONPAD;-0x00;+0x03", true, 3,
|
||||||
{ INPUT_PROP_BUTTONPAD,
|
{ { INPUT_PROP_BUTTONPAD, true },
|
||||||
INPUT_PROP_POINTER,
|
{ INPUT_PROP_POINTER, false },
|
||||||
INPUT_PROP_SEMI_MT }},
|
{ INPUT_PROP_SEMI_MT, true }}},
|
||||||
{ .prop = "", .success = false },
|
{ .prop = "", .success = false },
|
||||||
{ .prop = "0xff", .success = false },
|
{ .prop = "0xff", .success = false },
|
||||||
{ .prop = "INPUT_PROP", .success = false },
|
{ .prop = "INPUT_PROP", .success = false },
|
||||||
|
|
@ -659,7 +662,7 @@ START_TEST(input_prop_parser)
|
||||||
|
|
||||||
for (int i = 0; tests[i].prop; i++) {
|
for (int i = 0; tests[i].prop; i++) {
|
||||||
bool success;
|
bool success;
|
||||||
uint32_t props[32];
|
struct input_prop props[32];
|
||||||
size_t nprops = ARRAY_LENGTH(props);
|
size_t nprops = ARRAY_LENGTH(props);
|
||||||
|
|
||||||
t = &tests[i];
|
t = &tests[i];
|
||||||
|
|
@ -670,7 +673,8 @@ START_TEST(input_prop_parser)
|
||||||
|
|
||||||
ck_assert_int_eq(nprops, t->nvals);
|
ck_assert_int_eq(nprops, t->nvals);
|
||||||
for (size_t j = 0; j < t->nvals; j++) {
|
for (size_t j = 0; j < t->nvals; j++) {
|
||||||
ck_assert_int_eq(t->values[j], props[j]);
|
ck_assert_int_eq(t->values[j].prop, props[j].prop);
|
||||||
|
ck_assert_int_eq(t->values[j].enabled, props[j].enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -632,11 +632,13 @@ sprintf_event_codes(char *buf, size_t sz, struct quirks *quirks, enum quirk q)
|
||||||
off += printed;
|
off += printed;
|
||||||
|
|
||||||
for (size_t i = 0; off < sz && i < t->ntuples; i++) {
|
for (size_t i = 0; off < sz && i < t->ntuples; i++) {
|
||||||
const char *name = libevdev_event_code_get_name(
|
unsigned int type = t->tuples[i].first;
|
||||||
t->tuples[i].first,
|
unsigned int code = t->tuples[i].second;
|
||||||
t->tuples[i].second);
|
bool enable = t->tuples[i].third;
|
||||||
|
|
||||||
printed = snprintf(buf + off, sz - off, "%s;", name);
|
const char *name = libevdev_event_code_get_name(type, code);
|
||||||
|
|
||||||
|
printed = snprintf(buf + off, sz - off, "%c%s;", enable ? '+' : '-', name);
|
||||||
assert(printed != -1);
|
assert(printed != -1);
|
||||||
off += printed;
|
off += printed;
|
||||||
}
|
}
|
||||||
|
|
@ -645,21 +647,24 @@ sprintf_event_codes(char *buf, size_t sz, struct quirks *quirks, enum quirk q)
|
||||||
static void
|
static void
|
||||||
sprintf_input_props(char *buf, size_t sz, struct quirks *quirks, enum quirk q)
|
sprintf_input_props(char *buf, size_t sz, struct quirks *quirks, enum quirk q)
|
||||||
{
|
{
|
||||||
const uint32_t *properties;
|
const struct quirk_tuples *t;
|
||||||
size_t nprops = 0;
|
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
int printed;
|
int printed;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
quirks_get_uint32_array(quirks, q, &properties, &nprops);
|
quirks_get_tuples(quirks, q, &t);
|
||||||
name = quirk_get_name(q);
|
name = quirk_get_name(q);
|
||||||
printed = snprintf(buf, sz, "%s=", name);
|
printed = snprintf(buf, sz, "%s=", name);
|
||||||
assert(printed != -1);
|
assert(printed != -1);
|
||||||
off += printed;
|
off += printed;
|
||||||
|
|
||||||
for (size_t i = 0; off < sz && i < nprops; i++) {
|
for (size_t i = 0; off < sz && i < t->ntuples; i++) {
|
||||||
const char *name = libevdev_property_get_name(properties[i]);
|
unsigned int prop = t->tuples[i].first;
|
||||||
printed = snprintf(buf + off, sz - off, "%s;", name);
|
bool enable = t->tuples[i].second;
|
||||||
|
|
||||||
|
const char *name = libevdev_property_get_name(prop);
|
||||||
|
|
||||||
|
printed = snprintf(buf + off, sz - off, "%c%s;", enable ? '+' : '-', name);
|
||||||
assert(printed != -1);
|
assert(printed != -1);
|
||||||
off += printed;
|
off += printed;
|
||||||
}
|
}
|
||||||
|
|
@ -747,13 +752,11 @@ tools_list_device_quirks(struct quirks_context *ctx,
|
||||||
snprintf(buf, sizeof(buf), "%s=%d", name, b);
|
snprintf(buf, sizeof(buf), "%s=%d", name, b);
|
||||||
callback(userdata, buf);
|
callback(userdata, buf);
|
||||||
break;
|
break;
|
||||||
case QUIRK_ATTR_EVENT_CODE_DISABLE:
|
case QUIRK_ATTR_EVENT_CODE:
|
||||||
case QUIRK_ATTR_EVENT_CODE_ENABLE:
|
|
||||||
sprintf_event_codes(buf, sizeof(buf), quirks, q);
|
sprintf_event_codes(buf, sizeof(buf), quirks, q);
|
||||||
callback(userdata, buf);
|
callback(userdata, buf);
|
||||||
break;
|
break;
|
||||||
case QUIRK_ATTR_INPUT_PROP_DISABLE:
|
case QUIRK_ATTR_INPUT_PROP:
|
||||||
case QUIRK_ATTR_INPUT_PROP_ENABLE:
|
|
||||||
sprintf_input_props(buf, sizeof(buf), quirks, q);
|
sprintf_input_props(buf, sizeof(buf), quirks, q);
|
||||||
callback(userdata, buf);
|
callback(userdata, buf);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue