logitech_receiver: Move hidpp20 constants into new module
Related #1097
This commit is contained in:
parent
2fcab65486
commit
5f487dd3b2
|
@ -23,8 +23,8 @@ from .common import FirmwareInfo as _FirmwareInfo
|
|||
from .common import bytes2int as _bytes2int
|
||||
from .common import int2bytes as _int2bytes
|
||||
from .common import strhex as _strhex
|
||||
from .hidpp20 import BATTERY_STATUS, FIRMWARE_KIND
|
||||
from .hidpp10_constants import REGISTERS
|
||||
from .hidpp20_constants import BATTERY_STATUS, FIRMWARE_KIND
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ from .common import UnsortedNamedInts as _UnsortedNamedInts
|
|||
from .common import bytes2int as _bytes2int
|
||||
from .common import crc16 as _crc16
|
||||
from .common import int2bytes as _int2bytes
|
||||
from .hidpp20_constants import (BATTERY_STATUS, CHARGE_LEVEL, CHARGE_STATUS, CHARGE_TYPE, DEVICE_KIND, ERROR, FEATURE,
|
||||
FIRMWARE_KIND, GESTURE)
|
||||
from .i18n import _
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -52,180 +54,6 @@ _yaml.add_representer(int, hexint_presenter)
|
|||
#
|
||||
#
|
||||
|
||||
# <FeaturesSupported.xml sed '/LD_FID_/{s/.*LD_FID_/\t/;s/"[ \t]*Id="/=/;s/" \/>/,/p}' | sort -t= -k2
|
||||
# additional features names taken from https://github.com/cvuchener/hidpp and
|
||||
# https://github.com/Logitech/cpg-docs/tree/master/hidpp20
|
||||
"""Possible features available on a Logitech device.
|
||||
|
||||
A particular device might not support all these features, and may support other
|
||||
unknown features as well.
|
||||
"""
|
||||
FEATURE = _NamedInts(
|
||||
ROOT=0x0000,
|
||||
FEATURE_SET=0x0001,
|
||||
FEATURE_INFO=0x0002,
|
||||
# Common
|
||||
DEVICE_FW_VERSION=0x0003,
|
||||
DEVICE_UNIT_ID=0x0004,
|
||||
DEVICE_NAME=0x0005,
|
||||
DEVICE_GROUPS=0x0006,
|
||||
DEVICE_FRIENDLY_NAME=0x0007,
|
||||
KEEP_ALIVE=0x0008,
|
||||
CONFIG_CHANGE=0x0020,
|
||||
CRYPTO_ID=0x0021,
|
||||
TARGET_SOFTWARE=0x0030,
|
||||
WIRELESS_SIGNAL_STRENGTH=0x0080,
|
||||
DFUCONTROL_LEGACY=0x00C0,
|
||||
DFUCONTROL_UNSIGNED=0x00C1,
|
||||
DFUCONTROL_SIGNED=0x00C2,
|
||||
DFUCONTROL=0x00C3,
|
||||
DFU=0x00D0,
|
||||
BATTERY_STATUS=0x1000,
|
||||
BATTERY_VOLTAGE=0x1001,
|
||||
UNIFIED_BATTERY=0x1004,
|
||||
CHARGING_CONTROL=0x1010,
|
||||
LED_CONTROL=0x1300,
|
||||
FORCE_PAIRING=0x1500,
|
||||
GENERIC_TEST=0x1800,
|
||||
DEVICE_RESET=0x1802,
|
||||
OOBSTATE=0x1805,
|
||||
CONFIG_DEVICE_PROPS=0x1806,
|
||||
CHANGE_HOST=0x1814,
|
||||
HOSTS_INFO=0x1815,
|
||||
BACKLIGHT=0x1981,
|
||||
BACKLIGHT2=0x1982,
|
||||
BACKLIGHT3=0x1983,
|
||||
ILLUMINATION=0x1990,
|
||||
PRESENTER_CONTROL=0x1A00,
|
||||
SENSOR_3D=0x1A01,
|
||||
REPROG_CONTROLS=0x1B00,
|
||||
REPROG_CONTROLS_V2=0x1B01,
|
||||
REPROG_CONTROLS_V2_2=0x1B02, # LogiOptions 2.10.73 features.xml
|
||||
REPROG_CONTROLS_V3=0x1B03,
|
||||
REPROG_CONTROLS_V4=0x1B04,
|
||||
REPORT_HID_USAGE=0x1BC0,
|
||||
PERSISTENT_REMAPPABLE_ACTION=0x1C00,
|
||||
WIRELESS_DEVICE_STATUS=0x1D4B,
|
||||
REMAINING_PAIRING=0x1DF0,
|
||||
FIRMWARE_PROPERTIES=0x1F1F,
|
||||
ADC_MEASUREMENT=0x1F20,
|
||||
# Mouse
|
||||
LEFT_RIGHT_SWAP=0x2001,
|
||||
SWAP_BUTTON_CANCEL=0x2005,
|
||||
POINTER_AXIS_ORIENTATION=0x2006,
|
||||
VERTICAL_SCROLLING=0x2100,
|
||||
SMART_SHIFT=0x2110,
|
||||
SMART_SHIFT_ENHANCED=0x2111,
|
||||
HI_RES_SCROLLING=0x2120,
|
||||
HIRES_WHEEL=0x2121,
|
||||
LOWRES_WHEEL=0x2130,
|
||||
THUMB_WHEEL=0x2150,
|
||||
MOUSE_POINTER=0x2200,
|
||||
ADJUSTABLE_DPI=0x2201,
|
||||
EXTENDED_ADJUSTABLE_DPI=0x2202,
|
||||
POINTER_SPEED=0x2205,
|
||||
ANGLE_SNAPPING=0x2230,
|
||||
SURFACE_TUNING=0x2240,
|
||||
XY_STATS=0x2250,
|
||||
WHEEL_STATS=0x2251,
|
||||
HYBRID_TRACKING=0x2400,
|
||||
# Keyboard
|
||||
FN_INVERSION=0x40A0,
|
||||
NEW_FN_INVERSION=0x40A2,
|
||||
K375S_FN_INVERSION=0x40A3,
|
||||
ENCRYPTION=0x4100,
|
||||
LOCK_KEY_STATE=0x4220,
|
||||
SOLAR_DASHBOARD=0x4301,
|
||||
KEYBOARD_LAYOUT=0x4520,
|
||||
KEYBOARD_DISABLE_KEYS=0x4521,
|
||||
KEYBOARD_DISABLE_BY_USAGE=0x4522,
|
||||
DUALPLATFORM=0x4530,
|
||||
MULTIPLATFORM=0x4531,
|
||||
KEYBOARD_LAYOUT_2=0x4540,
|
||||
CROWN=0x4600,
|
||||
# Touchpad
|
||||
TOUCHPAD_FW_ITEMS=0x6010,
|
||||
TOUCHPAD_SW_ITEMS=0x6011,
|
||||
TOUCHPAD_WIN8_FW_ITEMS=0x6012,
|
||||
TAP_ENABLE=0x6020,
|
||||
TAP_ENABLE_EXTENDED=0x6021,
|
||||
CURSOR_BALLISTIC=0x6030,
|
||||
TOUCHPAD_RESOLUTION=0x6040,
|
||||
TOUCHPAD_RAW_XY=0x6100,
|
||||
TOUCHMOUSE_RAW_POINTS=0x6110,
|
||||
TOUCHMOUSE_6120=0x6120,
|
||||
GESTURE=0x6500,
|
||||
GESTURE_2=0x6501,
|
||||
# Gaming Devices
|
||||
GKEY=0x8010,
|
||||
MKEYS=0x8020,
|
||||
MR=0x8030,
|
||||
BRIGHTNESS_CONTROL=0x8040,
|
||||
REPORT_RATE=0x8060,
|
||||
EXTENDED_ADJUSTABLE_REPORT_RATE=0x8061,
|
||||
COLOR_LED_EFFECTS=0x8070,
|
||||
RGB_EFFECTS=0x8071,
|
||||
PER_KEY_LIGHTING=0x8080,
|
||||
PER_KEY_LIGHTING_V2=0x8081,
|
||||
MODE_STATUS=0x8090,
|
||||
ONBOARD_PROFILES=0x8100,
|
||||
MOUSE_BUTTON_SPY=0x8110,
|
||||
LATENCY_MONITORING=0x8111,
|
||||
GAMING_ATTACHMENTS=0x8120,
|
||||
FORCE_FEEDBACK=0x8123,
|
||||
# Headsets
|
||||
SIDETONE=0x8300,
|
||||
EQUALIZER=0x8310,
|
||||
HEADSET_OUT=0x8320,
|
||||
# Fake features for Solaar internal use
|
||||
MOUSE_GESTURE=0xFE00,
|
||||
)
|
||||
FEATURE._fallback = lambda x: 'unknown:%04X' % x
|
||||
|
||||
FEATURE_FLAG = _NamedInts(internal=0x20, hidden=0x40, obsolete=0x80)
|
||||
|
||||
DEVICE_KIND = _NamedInts(
|
||||
keyboard=0x00, remote_control=0x01, numpad=0x02, mouse=0x03, touchpad=0x04, trackball=0x05, presenter=0x06, receiver=0x07
|
||||
)
|
||||
|
||||
FIRMWARE_KIND = _NamedInts(Firmware=0x00, Bootloader=0x01, Hardware=0x02, Other=0x03)
|
||||
|
||||
BATTERY_OK = lambda status: status not in (BATTERY_STATUS.invalid_battery, BATTERY_STATUS.thermal_error)
|
||||
|
||||
BATTERY_STATUS = _NamedInts(
|
||||
discharging=0x00,
|
||||
recharging=0x01,
|
||||
almost_full=0x02,
|
||||
full=0x03,
|
||||
slow_recharge=0x04,
|
||||
invalid_battery=0x05,
|
||||
thermal_error=0x06
|
||||
)
|
||||
|
||||
ONBOARD_MODES = _NamedInts(MODE_NO_CHANGE=0x00, MODE_ONBOARD=0x01, MODE_HOST=0x02)
|
||||
|
||||
CHARGE_STATUS = _NamedInts(charging=0x00, full=0x01, not_charging=0x02, error=0x07)
|
||||
|
||||
CHARGE_LEVEL = _NamedInts(average=50, full=90, critical=5)
|
||||
|
||||
CHARGE_TYPE = _NamedInts(standard=0x00, fast=0x01, slow=0x02)
|
||||
|
||||
ERROR = _NamedInts(
|
||||
unknown=0x01,
|
||||
invalid_argument=0x02,
|
||||
out_of_range=0x03,
|
||||
hardware_error=0x04,
|
||||
logitech_internal=0x05,
|
||||
invalid_feature_index=0x06,
|
||||
invalid_function=0x07,
|
||||
busy=0x08,
|
||||
unsupported=0x09
|
||||
)
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
class FeaturesArray(dict):
|
||||
|
||||
|
@ -746,71 +574,6 @@ class KeysArrayPersistent(KeysArray):
|
|||
logger.warn(f"Key with index {index} was expected to exist but device doesn't report it.")
|
||||
|
||||
|
||||
# Gesture Ids for feature GESTURE_2
|
||||
GESTURE = _NamedInts(
|
||||
Tap1Finger=1, # task Left_Click
|
||||
Tap2Finger=2, # task Right_Click
|
||||
Tap3Finger=3,
|
||||
Click1Finger=4, # task Left_Click
|
||||
Click2Finger=5, # task Right_Click
|
||||
Click3Finger=6,
|
||||
DoubleTap1Finger=10,
|
||||
DoubleTap2Finger=11,
|
||||
DoubleTap3Finger=12,
|
||||
Track1Finger=20, # action MovePointer
|
||||
TrackingAcceleration=21,
|
||||
TapDrag1Finger=30, # action Drag
|
||||
TapDrag2Finger=31, # action SecondaryDrag
|
||||
Drag3Finger=32,
|
||||
TapGestures=33, # group all tap gestures under a single UI setting
|
||||
FnClickGestureSuppression=34, # suppresses Tap and Edge gestures, toggled by Fn+Click
|
||||
Scroll1Finger=40, # action ScrollOrPageXY / ScrollHorizontal
|
||||
Scroll2Finger=41, # action ScrollOrPageXY / ScrollHorizontal
|
||||
Scroll2FingerHoriz=42, # action ScrollHorizontal
|
||||
Scroll2FingerVert=43, # action WheelScrolling
|
||||
Scroll2FingerStateless=44,
|
||||
NaturalScrolling=45, # affects native HID wheel reporting by gestures, not when diverted
|
||||
Thumbwheel=46, # action WheelScrolling
|
||||
VScrollInertia=48,
|
||||
VScrollBallistics=49,
|
||||
Swipe2FingerHoriz=50, # action PageScreen
|
||||
Swipe3FingerHoriz=51, # action PageScreen
|
||||
Swipe4FingerHoriz=52, # action PageScreen
|
||||
Swipe3FingerVert=53,
|
||||
Swipe4FingerVert=54,
|
||||
LeftEdgeSwipe1Finger=60,
|
||||
RightEdgeSwipe1Finger=61,
|
||||
BottomEdgeSwipe1Finger=62,
|
||||
TopEdgeSwipe1Finger=63,
|
||||
LeftEdgeSwipe1Finger2=64, # task HorzScrollNoRepeatSet
|
||||
RightEdgeSwipe1Finger2=65, # task 122 ??
|
||||
BottomEdgeSwipe1Finger2=66, #
|
||||
TopEdgeSwipe1Finger2=67, # task 121 ??
|
||||
LeftEdgeSwipe2Finger=70,
|
||||
RightEdgeSwipe2Finger=71,
|
||||
BottomEdgeSwipe2Finger=72,
|
||||
TopEdgeSwipe2Finger=73,
|
||||
Zoom2Finger=80, # action Zoom
|
||||
Zoom2FingerPinch=81, # ZoomBtnInSet
|
||||
Zoom2FingerSpread=82, # ZoomBtnOutSet
|
||||
Zoom3Finger=83,
|
||||
Zoom2FingerStateless=84, # action Zoom
|
||||
TwoFingersPresent=85,
|
||||
Rotate2Finger=87,
|
||||
Finger1=90,
|
||||
Finger2=91,
|
||||
Finger3=92,
|
||||
Finger4=93,
|
||||
Finger5=94,
|
||||
Finger6=95,
|
||||
Finger7=96,
|
||||
Finger8=97,
|
||||
Finger9=98,
|
||||
Finger10=99,
|
||||
DeviceSpecificRawData=100,
|
||||
)
|
||||
GESTURE._fallback = lambda x: 'unknown:%04X' % x
|
||||
|
||||
# Param Ids for feature GESTURE_2
|
||||
PARAM = _NamedInts(
|
||||
ExtraCapabilities=1, # not suitable for use
|
||||
|
@ -912,9 +675,11 @@ class Gesture:
|
|||
else:
|
||||
return (None, None)
|
||||
|
||||
enable_offset_mask = lambda gesture: gesture._offset_mask(gesture.index)
|
||||
def enable_offset_mask(gesture):
|
||||
return gesture._offset_mask(gesture.index)
|
||||
|
||||
diversion_offset_mask = lambda gesture: gesture._offset_mask(gesture.diversion_index)
|
||||
def diversion_offset_mask(gesture):
|
||||
return gesture._offset_mask(gesture.diversion_index)
|
||||
|
||||
def enabled(self): # is the gesture enabled?
|
||||
if self._enabled is None and self.index is not None:
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
from .common import NamedInts
|
||||
|
||||
# <FeaturesSupported.xml sed '/LD_FID_/{s/.*LD_FID_/\t/;s/"[ \t]*Id="/=/;s/" \/>/,/p}' | sort -t= -k2
|
||||
# additional features names taken from https://github.com/cvuchener/hidpp and
|
||||
# https://github.com/Logitech/cpg-docs/tree/master/hidpp20
|
||||
"""Possible features available on a Logitech device.
|
||||
|
||||
A particular device might not support all these features, and may support other
|
||||
unknown features as well.
|
||||
"""
|
||||
FEATURE = NamedInts(
|
||||
ROOT=0x0000,
|
||||
FEATURE_SET=0x0001,
|
||||
FEATURE_INFO=0x0002,
|
||||
# Common
|
||||
DEVICE_FW_VERSION=0x0003,
|
||||
DEVICE_UNIT_ID=0x0004,
|
||||
DEVICE_NAME=0x0005,
|
||||
DEVICE_GROUPS=0x0006,
|
||||
DEVICE_FRIENDLY_NAME=0x0007,
|
||||
KEEP_ALIVE=0x0008,
|
||||
CONFIG_CHANGE=0x0020,
|
||||
CRYPTO_ID=0x0021,
|
||||
TARGET_SOFTWARE=0x0030,
|
||||
WIRELESS_SIGNAL_STRENGTH=0x0080,
|
||||
DFUCONTROL_LEGACY=0x00C0,
|
||||
DFUCONTROL_UNSIGNED=0x00C1,
|
||||
DFUCONTROL_SIGNED=0x00C2,
|
||||
DFUCONTROL=0x00C3,
|
||||
DFU=0x00D0,
|
||||
BATTERY_STATUS=0x1000,
|
||||
BATTERY_VOLTAGE=0x1001,
|
||||
UNIFIED_BATTERY=0x1004,
|
||||
CHARGING_CONTROL=0x1010,
|
||||
LED_CONTROL=0x1300,
|
||||
FORCE_PAIRING=0x1500,
|
||||
GENERIC_TEST=0x1800,
|
||||
DEVICE_RESET=0x1802,
|
||||
OOBSTATE=0x1805,
|
||||
CONFIG_DEVICE_PROPS=0x1806,
|
||||
CHANGE_HOST=0x1814,
|
||||
HOSTS_INFO=0x1815,
|
||||
BACKLIGHT=0x1981,
|
||||
BACKLIGHT2=0x1982,
|
||||
BACKLIGHT3=0x1983,
|
||||
ILLUMINATION=0x1990,
|
||||
PRESENTER_CONTROL=0x1A00,
|
||||
SENSOR_3D=0x1A01,
|
||||
REPROG_CONTROLS=0x1B00,
|
||||
REPROG_CONTROLS_V2=0x1B01,
|
||||
REPROG_CONTROLS_V2_2=0x1B02, # LogiOptions 2.10.73 features.xml
|
||||
REPROG_CONTROLS_V3=0x1B03,
|
||||
REPROG_CONTROLS_V4=0x1B04,
|
||||
REPORT_HID_USAGE=0x1BC0,
|
||||
PERSISTENT_REMAPPABLE_ACTION=0x1C00,
|
||||
WIRELESS_DEVICE_STATUS=0x1D4B,
|
||||
REMAINING_PAIRING=0x1DF0,
|
||||
FIRMWARE_PROPERTIES=0x1F1F,
|
||||
ADC_MEASUREMENT=0x1F20,
|
||||
# Mouse
|
||||
LEFT_RIGHT_SWAP=0x2001,
|
||||
SWAP_BUTTON_CANCEL=0x2005,
|
||||
POINTER_AXIS_ORIENTATION=0x2006,
|
||||
VERTICAL_SCROLLING=0x2100,
|
||||
SMART_SHIFT=0x2110,
|
||||
SMART_SHIFT_ENHANCED=0x2111,
|
||||
HI_RES_SCROLLING=0x2120,
|
||||
HIRES_WHEEL=0x2121,
|
||||
LOWRES_WHEEL=0x2130,
|
||||
THUMB_WHEEL=0x2150,
|
||||
MOUSE_POINTER=0x2200,
|
||||
ADJUSTABLE_DPI=0x2201,
|
||||
EXTENDED_ADJUSTABLE_DPI=0x2202,
|
||||
POINTER_SPEED=0x2205,
|
||||
ANGLE_SNAPPING=0x2230,
|
||||
SURFACE_TUNING=0x2240,
|
||||
XY_STATS=0x2250,
|
||||
WHEEL_STATS=0x2251,
|
||||
HYBRID_TRACKING=0x2400,
|
||||
# Keyboard
|
||||
FN_INVERSION=0x40A0,
|
||||
NEW_FN_INVERSION=0x40A2,
|
||||
K375S_FN_INVERSION=0x40A3,
|
||||
ENCRYPTION=0x4100,
|
||||
LOCK_KEY_STATE=0x4220,
|
||||
SOLAR_DASHBOARD=0x4301,
|
||||
KEYBOARD_LAYOUT=0x4520,
|
||||
KEYBOARD_DISABLE_KEYS=0x4521,
|
||||
KEYBOARD_DISABLE_BY_USAGE=0x4522,
|
||||
DUALPLATFORM=0x4530,
|
||||
MULTIPLATFORM=0x4531,
|
||||
KEYBOARD_LAYOUT_2=0x4540,
|
||||
CROWN=0x4600,
|
||||
# Touchpad
|
||||
TOUCHPAD_FW_ITEMS=0x6010,
|
||||
TOUCHPAD_SW_ITEMS=0x6011,
|
||||
TOUCHPAD_WIN8_FW_ITEMS=0x6012,
|
||||
TAP_ENABLE=0x6020,
|
||||
TAP_ENABLE_EXTENDED=0x6021,
|
||||
CURSOR_BALLISTIC=0x6030,
|
||||
TOUCHPAD_RESOLUTION=0x6040,
|
||||
TOUCHPAD_RAW_XY=0x6100,
|
||||
TOUCHMOUSE_RAW_POINTS=0x6110,
|
||||
TOUCHMOUSE_6120=0x6120,
|
||||
GESTURE=0x6500,
|
||||
GESTURE_2=0x6501,
|
||||
# Gaming Devices
|
||||
GKEY=0x8010,
|
||||
MKEYS=0x8020,
|
||||
MR=0x8030,
|
||||
BRIGHTNESS_CONTROL=0x8040,
|
||||
REPORT_RATE=0x8060,
|
||||
EXTENDED_ADJUSTABLE_REPORT_RATE=0x8061,
|
||||
COLOR_LED_EFFECTS=0x8070,
|
||||
RGB_EFFECTS=0x8071,
|
||||
PER_KEY_LIGHTING=0x8080,
|
||||
PER_KEY_LIGHTING_V2=0x8081,
|
||||
MODE_STATUS=0x8090,
|
||||
ONBOARD_PROFILES=0x8100,
|
||||
MOUSE_BUTTON_SPY=0x8110,
|
||||
LATENCY_MONITORING=0x8111,
|
||||
GAMING_ATTACHMENTS=0x8120,
|
||||
FORCE_FEEDBACK=0x8123,
|
||||
# Headsets
|
||||
SIDETONE=0x8300,
|
||||
EQUALIZER=0x8310,
|
||||
HEADSET_OUT=0x8320,
|
||||
# Fake features for Solaar internal use
|
||||
MOUSE_GESTURE=0xFE00,
|
||||
)
|
||||
FEATURE._fallback = lambda x: 'unknown:%04X' % x
|
||||
|
||||
FEATURE_FLAG = NamedInts(internal=0x20, hidden=0x40, obsolete=0x80)
|
||||
|
||||
DEVICE_KIND = NamedInts(
|
||||
keyboard=0x00, remote_control=0x01, numpad=0x02, mouse=0x03, touchpad=0x04, trackball=0x05, presenter=0x06, receiver=0x07
|
||||
)
|
||||
|
||||
FIRMWARE_KIND = NamedInts(Firmware=0x00, Bootloader=0x01, Hardware=0x02, Other=0x03)
|
||||
|
||||
|
||||
def BATTERY_OK(status):
|
||||
return status not in (BATTERY_STATUS.invalid_battery, BATTERY_STATUS.thermal_error)
|
||||
|
||||
|
||||
BATTERY_STATUS = NamedInts(
|
||||
discharging=0x00,
|
||||
recharging=0x01,
|
||||
almost_full=0x02,
|
||||
full=0x03,
|
||||
slow_recharge=0x04,
|
||||
invalid_battery=0x05,
|
||||
thermal_error=0x06
|
||||
)
|
||||
|
||||
ONBOARD_MODES = NamedInts(MODE_NO_CHANGE=0x00, MODE_ONBOARD=0x01, MODE_HOST=0x02)
|
||||
|
||||
CHARGE_STATUS = NamedInts(charging=0x00, full=0x01, not_charging=0x02, error=0x07)
|
||||
|
||||
CHARGE_LEVEL = NamedInts(average=50, full=90, critical=5)
|
||||
|
||||
CHARGE_TYPE = NamedInts(standard=0x00, fast=0x01, slow=0x02)
|
||||
|
||||
ERROR = NamedInts(
|
||||
unknown=0x01,
|
||||
invalid_argument=0x02,
|
||||
out_of_range=0x03,
|
||||
hardware_error=0x04,
|
||||
logitech_internal=0x05,
|
||||
invalid_feature_index=0x06,
|
||||
invalid_function=0x07,
|
||||
busy=0x08,
|
||||
unsupported=0x09
|
||||
)
|
||||
|
||||
# Gesture Ids for feature GESTURE_2
|
||||
GESTURE = NamedInts(
|
||||
Tap1Finger=1, # task Left_Click
|
||||
Tap2Finger=2, # task Right_Click
|
||||
Tap3Finger=3,
|
||||
Click1Finger=4, # task Left_Click
|
||||
Click2Finger=5, # task Right_Click
|
||||
Click3Finger=6,
|
||||
DoubleTap1Finger=10,
|
||||
DoubleTap2Finger=11,
|
||||
DoubleTap3Finger=12,
|
||||
Track1Finger=20, # action MovePointer
|
||||
TrackingAcceleration=21,
|
||||
TapDrag1Finger=30, # action Drag
|
||||
TapDrag2Finger=31, # action SecondaryDrag
|
||||
Drag3Finger=32,
|
||||
TapGestures=33, # group all tap gestures under a single UI setting
|
||||
FnClickGestureSuppression=34, # suppresses Tap and Edge gestures, toggled by Fn+Click
|
||||
Scroll1Finger=40, # action ScrollOrPageXY / ScrollHorizontal
|
||||
Scroll2Finger=41, # action ScrollOrPageXY / ScrollHorizontal
|
||||
Scroll2FingerHoriz=42, # action ScrollHorizontal
|
||||
Scroll2FingerVert=43, # action WheelScrolling
|
||||
Scroll2FingerStateless=44,
|
||||
NaturalScrolling=45, # affects native HID wheel reporting by gestures, not when diverted
|
||||
Thumbwheel=46, # action WheelScrolling
|
||||
VScrollInertia=48,
|
||||
VScrollBallistics=49,
|
||||
Swipe2FingerHoriz=50, # action PageScreen
|
||||
Swipe3FingerHoriz=51, # action PageScreen
|
||||
Swipe4FingerHoriz=52, # action PageScreen
|
||||
Swipe3FingerVert=53,
|
||||
Swipe4FingerVert=54,
|
||||
LeftEdgeSwipe1Finger=60,
|
||||
RightEdgeSwipe1Finger=61,
|
||||
BottomEdgeSwipe1Finger=62,
|
||||
TopEdgeSwipe1Finger=63,
|
||||
LeftEdgeSwipe1Finger2=64, # task HorzScrollNoRepeatSet
|
||||
RightEdgeSwipe1Finger2=65, # task 122 ??
|
||||
BottomEdgeSwipe1Finger2=66, #
|
||||
TopEdgeSwipe1Finger2=67, # task 121 ??
|
||||
LeftEdgeSwipe2Finger=70,
|
||||
RightEdgeSwipe2Finger=71,
|
||||
BottomEdgeSwipe2Finger=72,
|
||||
TopEdgeSwipe2Finger=73,
|
||||
Zoom2Finger=80, # action Zoom
|
||||
Zoom2FingerPinch=81, # ZoomBtnInSet
|
||||
Zoom2FingerSpread=82, # ZoomBtnOutSet
|
||||
Zoom3Finger=83,
|
||||
Zoom2FingerStateless=84, # action Zoom
|
||||
TwoFingersPresent=85,
|
||||
Rotate2Finger=87,
|
||||
Finger1=90,
|
||||
Finger2=91,
|
||||
Finger3=92,
|
||||
Finger4=93,
|
||||
Finger5=94,
|
||||
Finger6=95,
|
||||
Finger7=96,
|
||||
Finger8=97,
|
||||
Finger9=98,
|
||||
Finger10=99,
|
||||
DeviceSpecificRawData=100,
|
||||
)
|
||||
GESTURE._fallback = lambda x: 'unknown:%04X' % x
|
||||
|
||||
# Param Ids for feature GESTURE_2
|
||||
PARAM = NamedInts(
|
||||
ExtraCapabilities=1, # not suitable for use
|
||||
PixelZone=2, # 4 2-byte integers, left, bottom, width, height; pixels
|
||||
RatioZone=3, # 4 bytes, left, bottom, width, height; unit 1/240 pad size
|
||||
ScaleFactor=4, # 2-byte integer, with 256 as normal scale
|
||||
)
|
||||
PARAM._fallback = lambda x: 'unknown:%04X' % x
|
|
@ -27,6 +27,7 @@ from solaar.ui.config_panel import record_setting
|
|||
from . import diversion as _diversion
|
||||
from . import hidpp10 as _hidpp10
|
||||
from . import hidpp20 as _hidpp20
|
||||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from . import settings_templates as _st
|
||||
from .base import DJ_MESSAGE_ID as _DJ_MESSAGE_ID
|
||||
from .common import strhex as _strhex
|
||||
|
@ -37,7 +38,7 @@ from .status import KEYS as _K
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
_R = _hidpp10.REGISTERS
|
||||
_F = _hidpp20.FEATURE
|
||||
_F = _hidpp20_constants.FEATURE
|
||||
|
||||
#
|
||||
#
|
||||
|
@ -353,14 +354,14 @@ def _process_feature_notification(device, status, n, feature):
|
|||
charge, lux, adc = _unpack('!BHH', n.data[:5])
|
||||
# guesstimate the battery voltage, emphasis on 'guess'
|
||||
# status_text = '%1.2fV' % (adc * 2.67793237653 / 0x0672)
|
||||
status_text = _hidpp20.BATTERY_STATUS.discharging
|
||||
status_text = _hidpp20_constants.BATTERY_STATUS.discharging
|
||||
if n.address == 0x00:
|
||||
status[_K.LIGHT_LEVEL] = None
|
||||
status.set_battery_info(charge, None, status_text, None)
|
||||
elif n.address == 0x10:
|
||||
status[_K.LIGHT_LEVEL] = lux
|
||||
if lux > 200:
|
||||
status_text = _hidpp20.BATTERY_STATUS.recharging
|
||||
status_text = _hidpp20_constants.BATTERY_STATUS.recharging
|
||||
status.set_battery_info(charge, None, status_text, None)
|
||||
elif n.address == 0x20:
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
|
|
|
@ -22,7 +22,7 @@ import math
|
|||
from struct import unpack as _unpack
|
||||
from time import sleep as _sleep
|
||||
|
||||
from . import hidpp20 as _hidpp20
|
||||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from .common import NamedInt as _NamedInt
|
||||
from .common import NamedInts as _NamedInts
|
||||
from .common import bytes2int as _bytes2int
|
||||
|
@ -1416,7 +1416,7 @@ class ActionSettingRW:
|
|||
def write(self, device, data_bytes):
|
||||
|
||||
def handler(device, n): # Called on notification events from the device
|
||||
if n.sub_id < 0x40 and device.features.get_feature(n.sub_id) == _hidpp20.FEATURE.REPROG_CONTROLS_V4:
|
||||
if n.sub_id < 0x40 and device.features.get_feature(n.sub_id) == _hidpp20_constants.FEATURE.REPROG_CONTROLS_V4:
|
||||
if n.address == 0x00:
|
||||
cids = _unpack('!HHHH', n.data[:8])
|
||||
if not self.pressed and int(self.key.key) in cids: # trigger key pressed
|
||||
|
@ -1478,11 +1478,11 @@ class RawXYProcessing:
|
|||
self.keys = [] # the keys that can initiate processing
|
||||
self.initiating_key = None # the key that did initiate processing
|
||||
self.active = False
|
||||
self.feature_offset = device.features[_hidpp20.FEATURE.REPROG_CONTROLS_V4]
|
||||
self.feature_offset = device.features[_hidpp20_constants.FEATURE.REPROG_CONTROLS_V4]
|
||||
assert self.feature_offset is not False
|
||||
|
||||
def handler(self, device, n): # Called on notification events from the device
|
||||
if n.sub_id < 0x40 and device.features.get_feature(n.sub_id) == _hidpp20.FEATURE.REPROG_CONTROLS_V4:
|
||||
if n.sub_id < 0x40 and device.features.get_feature(n.sub_id) == _hidpp20_constants.FEATURE.REPROG_CONTROLS_V4:
|
||||
if n.address == 0x00:
|
||||
cids = _unpack('!HHHH', n.data[:8])
|
||||
## generalize to list of keys
|
||||
|
@ -1550,7 +1550,7 @@ class RawXYProcessing:
|
|||
|
||||
|
||||
def apply_all_settings(device):
|
||||
if device.features and _hidpp20.FEATURE.HIRES_WHEEL in device.features:
|
||||
if device.features and _hidpp20_constants.FEATURE.HIRES_WHEEL in device.features:
|
||||
_sleep(0.2) # delay to try to get out of race condition with Linux HID++ driver
|
||||
persister = getattr(device, 'persister', None)
|
||||
sensitives = persister.get('_sensitive', {}) if persister else {}
|
||||
|
|
|
@ -28,6 +28,7 @@ from traceback import format_exc as _format_exc
|
|||
from . import descriptors as _descriptors
|
||||
from . import hidpp10_constants as _hidpp10_constants
|
||||
from . import hidpp20 as _hidpp20
|
||||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from . import special_keys as _special_keys
|
||||
from .base import _HIDPP_Notification as _HIDPP_Notification
|
||||
from .common import NamedInt as _NamedInt
|
||||
|
@ -60,9 +61,9 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
_DK = _hidpp10_constants.DEVICE_KIND
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
_F = _hidpp20.FEATURE
|
||||
_F = _hidpp20_constants.FEATURE
|
||||
|
||||
_GG = _hidpp20.GESTURE
|
||||
_GG = _hidpp20_constants.GESTURE
|
||||
_GP = _hidpp20.PARAM
|
||||
|
||||
# Setting classes are used to control the settings that the Solaar GUI shows and manipulates.
|
||||
|
@ -556,8 +557,8 @@ class ReportRate(_Setting):
|
|||
|
||||
def write(self, device, data_bytes):
|
||||
# Host mode is required for report rate to be adjustable
|
||||
if _hidpp20.get_onboard_mode(device) != _hidpp20.ONBOARD_MODES.MODE_HOST:
|
||||
_hidpp20.set_onboard_mode(device, _hidpp20.ONBOARD_MODES.MODE_HOST)
|
||||
if _hidpp20.get_onboard_mode(device) != _hidpp20_constants.ONBOARD_MODES.MODE_HOST:
|
||||
_hidpp20.set_onboard_mode(device, _hidpp20_constants.ONBOARD_MODES.MODE_HOST)
|
||||
return super().write(device, data_bytes)
|
||||
|
||||
class validator_class(_ChoicesV):
|
||||
|
@ -602,8 +603,8 @@ class ExtendedReportRate(_Setting):
|
|||
|
||||
def write(self, device, data_bytes):
|
||||
# Host mode is required for report rate to be adjustable
|
||||
if _hidpp20.get_onboard_mode(device) != _hidpp20.ONBOARD_MODES.MODE_HOST:
|
||||
_hidpp20.set_onboard_mode(device, _hidpp20.ONBOARD_MODES.MODE_HOST)
|
||||
if _hidpp20.get_onboard_mode(device) != _hidpp20_constants.ONBOARD_MODES.MODE_HOST:
|
||||
_hidpp20.set_onboard_mode(device, _hidpp20_constants.ONBOARD_MODES.MODE_HOST)
|
||||
return super().write(device, data_bytes)
|
||||
|
||||
class validator_class(_ChoicesV):
|
||||
|
@ -849,7 +850,7 @@ class MouseGesturesXY(_RawXYProcessing):
|
|||
logger.info('mouse gesture notification %s', self.data)
|
||||
payload = _pack('!' + (len(self.data) * 'h'), *self.data)
|
||||
notification = _HIDPP_Notification(0, 0, 0, 0, payload)
|
||||
_process_notification(self.device, self.device.status, notification, _hidpp20.FEATURE.MOUSE_GESTURE)
|
||||
_process_notification(self.device, self.device.status, notification, _F.MOUSE_GESTURE)
|
||||
self.fsmState = 'idle'
|
||||
|
||||
def move_action(self, dx, dy):
|
||||
|
@ -1238,7 +1239,7 @@ class Gesture2Gestures(_BitFieldOMSetting):
|
|||
feature = _F.GESTURE_2
|
||||
rw_options = {'read_fnid': 0x10, 'write_fnid': 0x20}
|
||||
validator_options = {'om_method': _hidpp20.Gesture.enable_offset_mask}
|
||||
choices_universe = _hidpp20.GESTURE
|
||||
choices_universe = _hidpp20_constants.GESTURE
|
||||
_labels = _GESTURE2_GESTURES_LABELS
|
||||
|
||||
class validator_class(_BitFieldOMV):
|
||||
|
@ -1256,7 +1257,7 @@ class Gesture2Divert(_BitFieldOMSetting):
|
|||
feature = _F.GESTURE_2
|
||||
rw_options = {'read_fnid': 0x30, 'write_fnid': 0x40}
|
||||
validator_options = {'om_method': _hidpp20.Gesture.diversion_offset_mask}
|
||||
choices_universe = _hidpp20.GESTURE
|
||||
choices_universe = _hidpp20_constants.GESTURE
|
||||
_labels = _GESTURE2_GESTURES_LABELS
|
||||
|
||||
class validator_class(_BitFieldOMV):
|
||||
|
|
|
@ -173,8 +173,8 @@ class DeviceStatus(dict):
|
|||
old_voltage, self[KEYS.BATTERY_VOLTAGE] = self.get(KEYS.BATTERY_VOLTAGE), voltage
|
||||
|
||||
charging = status in (
|
||||
_hidpp20_constants.BATTERY_STATUS.recharging, _hidpp20_constants.BATTERY_STATUS.almost_full, _hidpp20_constants.BATTERY_STATUS.full,
|
||||
_hidpp20_constants.BATTERY_STATUS.slow_recharge
|
||||
_hidpp20_constants.BATTERY_STATUS.recharging, _hidpp20_constants.BATTERY_STATUS.almost_full,
|
||||
_hidpp20_constants.BATTERY_STATUS.full, _hidpp20_constants.BATTERY_STATUS.slow_recharge
|
||||
)
|
||||
old_charging, self[KEYS.BATTERY_CHARGING] = self.get(KEYS.BATTERY_CHARGING), charging
|
||||
|
||||
|
|
|
@ -20,13 +20,14 @@ from logitech_receiver import exceptions
|
|||
from logitech_receiver import hidpp10 as _hidpp10
|
||||
from logitech_receiver import hidpp10_constants as _hidpp10_constants
|
||||
from logitech_receiver import hidpp20 as _hidpp20
|
||||
from logitech_receiver import hidpp20_constants as _hidpp20_constants
|
||||
from logitech_receiver import receiver as _receiver
|
||||
from logitech_receiver import settings_templates as _settings_templates
|
||||
from logitech_receiver.common import NamedInt as _NamedInt
|
||||
from logitech_receiver.common import strhex as _strhex
|
||||
from solaar import NAME, __version__
|
||||
|
||||
_F = _hidpp20.FEATURE
|
||||
_F = _hidpp20_constants.FEATURE
|
||||
|
||||
|
||||
def _print_receiver(receiver):
|
||||
|
@ -142,11 +143,11 @@ def _print_device(dev, num=None):
|
|||
for feature, index in dev.features.enumerate():
|
||||
flags = dev.request(0x0000, feature.bytes(2))
|
||||
flags = 0 if flags is None else ord(flags[1:2])
|
||||
flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
|
||||
flags = _hidpp20_constants.FEATURE_FLAG.flag_names(flags)
|
||||
version = dev.features.get_feature_version(int(feature))
|
||||
version = version if version else 0
|
||||
print(' %2d: %-22s {%04X} V%s %s ' % (index, feature, feature, version, ', '.join(flags)))
|
||||
if feature == _hidpp20.FEATURE.HIRES_WHEEL:
|
||||
if feature == _hidpp20_constants.FEATURE.HIRES_WHEEL:
|
||||
wheel = _hidpp20.get_hires_wheel(dev)
|
||||
if wheel:
|
||||
multi, has_invert, has_switch, inv, res, target, ratchet = wheel
|
||||
|
@ -163,7 +164,7 @@ def _print_device(dev, num=None):
|
|||
print(' HID++ notification')
|
||||
else:
|
||||
print(' HID notification')
|
||||
elif feature == _hidpp20.FEATURE.MOUSE_POINTER:
|
||||
elif feature == _hidpp20_constants.FEATURE.MOUSE_POINTER:
|
||||
mouse_pointer = _hidpp20.get_mouse_pointer_info(dev)
|
||||
if mouse_pointer:
|
||||
print(' DPI: %s' % mouse_pointer['dpi'])
|
||||
|
@ -176,13 +177,13 @@ def _print_device(dev, num=None):
|
|||
print(' Provide vertical tuning, trackball')
|
||||
else:
|
||||
print(' No vertical tuning, standard mice')
|
||||
elif feature == _hidpp20.FEATURE.VERTICAL_SCROLLING:
|
||||
elif feature == _hidpp20_constants.FEATURE.VERTICAL_SCROLLING:
|
||||
vertical_scrolling_info = _hidpp20.get_vertical_scrolling_info(dev)
|
||||
if vertical_scrolling_info:
|
||||
print(' Roller type: %s' % vertical_scrolling_info['roller'])
|
||||
print(' Ratchet per turn: %s' % vertical_scrolling_info['ratchet'])
|
||||
print(' Scroll lines: %s' % vertical_scrolling_info['lines'])
|
||||
elif feature == _hidpp20.FEATURE.HI_RES_SCROLLING:
|
||||
elif feature == _hidpp20_constants.FEATURE.HI_RES_SCROLLING:
|
||||
scrolling_mode, scrolling_resolution = _hidpp20.get_hi_res_scrolling_info(dev)
|
||||
if scrolling_mode:
|
||||
print(' Hi-res scrolling enabled')
|
||||
|
@ -190,30 +191,30 @@ def _print_device(dev, num=None):
|
|||
print(' Hi-res scrolling disabled')
|
||||
if scrolling_resolution:
|
||||
print(' Hi-res scrolling multiplier: %s' % scrolling_resolution)
|
||||
elif feature == _hidpp20.FEATURE.POINTER_SPEED:
|
||||
elif feature == _hidpp20_constants.FEATURE.POINTER_SPEED:
|
||||
pointer_speed = _hidpp20.get_pointer_speed_info(dev)
|
||||
if pointer_speed:
|
||||
print(' Pointer Speed: %s' % pointer_speed)
|
||||
elif feature == _hidpp20.FEATURE.LOWRES_WHEEL:
|
||||
elif feature == _hidpp20_constants.FEATURE.LOWRES_WHEEL:
|
||||
wheel_status = _hidpp20.get_lowres_wheel_status(dev)
|
||||
if wheel_status:
|
||||
print(' Wheel Reports: %s' % wheel_status)
|
||||
elif feature == _hidpp20.FEATURE.NEW_FN_INVERSION:
|
||||
elif feature == _hidpp20_constants.FEATURE.NEW_FN_INVERSION:
|
||||
inversion = _hidpp20.get_new_fn_inversion(dev)
|
||||
if inversion:
|
||||
inverted, default_inverted = inversion
|
||||
print(' Fn-swap:', 'enabled' if inverted else 'disabled')
|
||||
print(' Fn-swap default:', 'enabled' if default_inverted else 'disabled')
|
||||
elif feature == _hidpp20.FEATURE.HOSTS_INFO:
|
||||
elif feature == _hidpp20_constants.FEATURE.HOSTS_INFO:
|
||||
host_names = _hidpp20.get_host_names(dev)
|
||||
for host, (paired, name) in host_names.items():
|
||||
print(' Host %s (%s): %s' % (host, 'paired' if paired else 'unpaired', name))
|
||||
elif feature == _hidpp20.FEATURE.DEVICE_NAME:
|
||||
elif feature == _hidpp20_constants.FEATURE.DEVICE_NAME:
|
||||
print(' Name: %s' % _hidpp20.get_name(dev))
|
||||
print(' Kind: %s' % _hidpp20.get_kind(dev))
|
||||
elif feature == _hidpp20.FEATURE.DEVICE_FRIENDLY_NAME:
|
||||
elif feature == _hidpp20_constants.FEATURE.DEVICE_FRIENDLY_NAME:
|
||||
print(' Friendly Name: %s' % _hidpp20.get_friendly_name(dev))
|
||||
elif feature == _hidpp20.FEATURE.DEVICE_FW_VERSION:
|
||||
elif feature == _hidpp20_constants.FEATURE.DEVICE_FW_VERSION:
|
||||
for fw in _hidpp20.get_firmware(dev):
|
||||
extras = _strhex(fw.extras) if fw.extras else ''
|
||||
print(' Firmware: %s %s %s %s' % (fw.kind, fw.name, fw.version, extras))
|
||||
|
@ -221,12 +222,12 @@ def _print_device(dev, num=None):
|
|||
if ids:
|
||||
unitId, modelId, tid_map = ids
|
||||
print(' Unit ID: %s Model ID: %s Transport IDs: %s' % (unitId, modelId, tid_map))
|
||||
elif feature == _hidpp20.FEATURE.REPORT_RATE or feature == _hidpp20.FEATURE.EXTENDED_ADJUSTABLE_REPORT_RATE:
|
||||
elif feature == _hidpp20_constants.FEATURE.REPORT_RATE or feature == _hidpp20_constants.FEATURE.EXTENDED_ADJUSTABLE_REPORT_RATE:
|
||||
print(' Report Rate: %s' % _hidpp20.get_polling_rate(dev))
|
||||
elif feature == _hidpp20.FEATURE.REMAINING_PAIRING:
|
||||
elif feature == _hidpp20_constants.FEATURE.REMAINING_PAIRING:
|
||||
print(' Remaining Pairings: %d' % _hidpp20.get_remaining_pairing(dev))
|
||||
elif feature == _hidpp20.FEATURE.ONBOARD_PROFILES:
|
||||
if _hidpp20.get_onboard_mode(dev) == _hidpp20.ONBOARD_MODES.MODE_HOST:
|
||||
elif feature == _hidpp20_constants.FEATURE.ONBOARD_PROFILES:
|
||||
if _hidpp20.get_onboard_mode(dev) == _hidpp20_constants.ONBOARD_MODES.MODE_HOST:
|
||||
mode = 'Host'
|
||||
else:
|
||||
mode = 'On-Board'
|
||||
|
@ -252,9 +253,9 @@ def _print_device(dev, num=None):
|
|||
print(' Has %d reprogrammable keys:' % len(dev.keys))
|
||||
for k in dev.keys:
|
||||
# TODO: add here additional variants for other REPROG_CONTROLS
|
||||
if dev.keys.keyversion == _hidpp20.FEATURE.REPROG_CONTROLS_V2:
|
||||
if dev.keys.keyversion == _hidpp20_constants.FEATURE.REPROG_CONTROLS_V2:
|
||||
print(' %2d: %-26s => %-27s %s' % (k.index, k.key, k.default_task, ', '.join(k.flags)))
|
||||
if dev.keys.keyversion == _hidpp20.FEATURE.REPROG_CONTROLS_V4:
|
||||
if dev.keys.keyversion == _hidpp20_constants.FEATURE.REPROG_CONTROLS_V4:
|
||||
print(' %2d: %-26s, default: %-27s => %-26s' % (k.index, k.key, k.default_task, k.mapped_to))
|
||||
gmask_fmt = ','.join(k.group_mask)
|
||||
gmask_fmt = gmask_fmt if gmask_fmt else 'empty'
|
||||
|
|
Loading…
Reference in New Issue