195 lines
12 KiB
Markdown
195 lines
12 KiB
Markdown
---
|
|
title: List of HID++ 2.0 features
|
|
layout: page
|
|
---
|
|
|
|
# Feature status
|
|
See functions in hidpp20.py and settings_templates.py
|
|
|
|
Feature | ID | Status | Notes
|
|
---------------------------------------|----------|:------------------:|------
|
|
`ROOT` | `0x0000` | :heavy_check_mark: | System
|
|
`FEATURE_SET` | `0x0001` | :heavy_check_mark: | System
|
|
`FEATURE_INFO` | `0x0002` | :heavy_check_mark: | System
|
|
`DEVICE_FW_VERSION` | `0x0003` | :heavy_check_mark: | `get_firmware`, read only
|
|
`DEVICE_UNIT_ID` | `0x0004` | :x: |
|
|
`DEVICE_NAME` | `0x0005` | :heavy_check_mark: | `get_kind`, `get_name`, read only
|
|
`DEVICE_GROUPS` | `0x0006` | :x: |
|
|
`DEVICE_FRIENDLY_NAME` | `0x0007` | :x: |
|
|
`KEEP_ALIVE` | `0x0008` | :x: |
|
|
`RESET` | `0x0020` | :x: | aka "Config Change"
|
|
`CRYPTO_ID` | `0x0021` | :x: |
|
|
`TARGET_SOFTWARE` | `0x0030` | :x: |
|
|
`WIRELESS_SIGNAL_STRENGTH` | `0x0080` | :x: |
|
|
`DFUCONTROL_LEGACY` | `0x00C0` | :x: |
|
|
`DFUCONTROL_UNSIGNED` | `0x00C1` | :x: |
|
|
`DFUCONTROL_SIGNED` | `0x00C2` | :x: |
|
|
`DFU` | `0x00D0` | :x: |
|
|
`BATTERY_STATUS` | `0x1000` | :heavy_check_mark: | `get_battery`, read only
|
|
`BATTERY_VOLTAGE` | `0x1001` | :heavy_check_mark: | `get_voltage`, read only
|
|
`CHARGING_CONTROL` | `0x1010` | :x: |
|
|
`LED_CONTROL` | `0x1300` | :x: |
|
|
`GENERIC_TEST` | `0x1800` | :x: |
|
|
`DEVICE_RESET` | `0x1802` | :x: |
|
|
`OOBSTATE` | `0x1805` | :x: |
|
|
`CONFIG_DEVICE_PROPS` | `0x1806` | :x: |
|
|
`CHANGE_HOST` | `0x1814` | :x: | :wrench:
|
|
`HOSTS_INFO` | `0x1815` | :heavy_plus_sign: | `get_host_names`, partial listing only
|
|
`BACKLIGHT` | `0x1981` | :x: |
|
|
`BACKLIGHT2` | `0x1982` | :heavy_check_mark: | `_feature_backlight2`
|
|
`BACKLIGHT3` | `0x1983` | :x: |
|
|
`PRESENTER_CONTROL` | `0x1A00` | :x: |
|
|
`SENSOR_3D` | `0x1A01` | :x: |
|
|
`REPROG_CONTROLS` | `0x1B00` | :heavy_plus_sign: | `get_keys`, only listing
|
|
`REPROG_CONTROLS_V2` | `0x1B01` | :x: |
|
|
`REPROG_CONTROLS_V2_2` | `0x1B02` | :x: |
|
|
`REPROG_CONTROLS_V3` | `0x1B03` | :x: |
|
|
`REPROG_CONTROLS_V4` | `0x1B04` | :heavy_plus_sign: | `get_keys`, _feature_reprogrammable_keys
|
|
`REPORT_HID_USAGE` | `0x1BC0` | :x: |
|
|
`PERSISTENT_REMAPPABLE_ACTION` | `0x1C00` | :x: | :wrench:
|
|
`WIRELESS_DEVICE_STATUS` | `0x1D4B` | :x: | status reporting from device
|
|
`REMAINING_PAIRING` | `0x1DF0` | :x: |
|
|
`FIRMWARE_PROPERTIES` | `0x1F1F` | :x: |
|
|
`ADC_MEASUREMENT` | `0x1F20` | :x: |
|
|
`LEFT_RIGHT_SWAP` | `0x2001` | :x: |
|
|
`SWAP_BUTTON_CANCEL` | `0x2005` | :x: |
|
|
`POINTER_AXIS_ORIENTATION` | `0x2006` | :x: |
|
|
`VERTICAL_SCROLLING` | `0x2100` | :heavy_check_mark: | `get_vertical_scrolling_info`, read only
|
|
`SMART_SHIFT` | `0x2110` | :heavy_check_mark: | `_feature_smart_shift`
|
|
`HI_RES_SCROLLING` | `0x2120` | :heavy_check_mark: | `get_hi_res_scrolling_info`, `_feature_hi_res_scroll`
|
|
`HIRES_WHEEL` | `0x2121` | :heavy_check_mark: | `get_hires_wheel`, `_feature_hires_smooth_invert`, `_feature_hires_smooth_resolution`
|
|
`LOWRES_WHEEL` | `0x2130` | :heavy_check_mark: | `get_lowres_wheel_status`, `_feature_lowres_smooth_scroll`
|
|
`THUMB_WHEEL` | `0x2150` | :x: |
|
|
`MOUSE_POINTER` | `0x2200` | :heavy_check_mark: | `get_mouse_pointer_info`, read only
|
|
`ADJUSTABLE_DPI` | `0x2201` | :heavy_check_mark: | `_feature_adjustable_dpi`
|
|
`POINTER_SPEED` | `0x2205` | :heavy_check_mark: | `get_pointer_speed_info`, `_feature_pointer_speed`
|
|
`ANGLE_SNAPPING` | `0x2230` | :x: |
|
|
`SURFACE_TUNING` | `0x2240` | :x: |
|
|
`HYBRID_TRACKING` | `0x2400` | :x: |
|
|
`FN_INVERSION` | `0x40A0` | :heavy_check_mark: | `_feature_fn_swap`
|
|
`NEW_FN_INVERSION` | `0x40A2` | :heavy_check_mark: | `get_new_fn_inversion`, `_feature_new_fn_swap`
|
|
`K375S_FN_INVERSION` | `0x40A3` | :heavy_check_mark: | `_feature_k375s_fn_swap`
|
|
`ENCRYPTION` | `0x4100` | :x: |
|
|
`LOCK_KEY_STATE` | `0x4220` | :x: |
|
|
`SOLAR_DASHBOARD` | `0x4301` | :x: |
|
|
`KEYBOARD_LAYOUT` | `0x4520` | :x: | read only
|
|
`KEYBOARD_DISABLE_KEYS` | `0x4521` | :heavy_check_mark: | `_feature_disable_keyboard_keys`
|
|
`KEYBOARD_DISABLE_BY_USAGE` | `0x4522` | :x: |
|
|
`DUALPLATFORM` | `0x4530` | :x: | :wrench:
|
|
`MULTIPLATFORM` | `0x4531` | :x: | :wrench:
|
|
`KEYBOARD_LAYOUT_2` | `0x4540` | :x: | read only
|
|
`CROWN` | `0x4600` | :x: |
|
|
`TOUCHPAD_FW_ITEMS` | `0x6010` | :x: |
|
|
`TOUCHPAD_SW_ITEMS` | `0x6011` | :x: |
|
|
`TOUCHPAD_WIN8_FW_ITEMS` | `0x6012` | :x: |
|
|
`TAP_ENABLE` | `0x6020` | :x: |
|
|
`TAP_ENABLE_EXTENDED` | `0x6021` | :x: |
|
|
`CURSOR_BALLISTIC` | `0x6030` | :x: |
|
|
`TOUCHPAD_RESOLUTION` | `0x6040` | :x: |
|
|
`TOUCHPAD_RAW_XY` | `0x6100` | :x: |
|
|
`TOUCHMOUSE_RAW_POINTS` | `0x6110` | :x: |
|
|
`TOUCHMOUSE_6120` | `0x6120` | :x: |
|
|
`GESTURE` | `0x6500` | :x: |
|
|
`GESTURE_2` | `0x6501` | :x: |
|
|
`GKEY` | `0x8010` | :x: |
|
|
`MKEYS` | `0x8020` | :x: |
|
|
`MR` | `0x8030` | :x: |
|
|
`BRIGHTNESS_CONTROL` | `0x8040` | :x: |
|
|
`REPORT_RATE` | `0x8060` | :x: | in progress
|
|
`COLOR_LED_EFFECTS` | `0x8070` | :x: |
|
|
`RGB_EFFECTS` | `0X8071` | :x: |
|
|
`PER_KEY_LIGHTING` | `0x8080` | :x: |
|
|
`PER_KEY_LIGHTING_V2` | `0x8081` | :x: |
|
|
`MODE_STATUS` | `0x8090` | :x: |
|
|
`ONBOARD_PROFILES` | `0x8100` | :x: |
|
|
`MOUSE_BUTTON_SPY` | `0x8110` | :x: |
|
|
`LATENCY_MONITORING` | `0x8111` | :x: |
|
|
`GAMING_ATTACHMENTS` | `0x8120` | :x: |
|
|
`FORCE_FEEDBACK` | `0x8123` | :x: |
|
|
`SIDETONE` | `0x8300` | :x: |
|
|
`EQUALIZER` | `0x8310` | :x: |
|
|
`HEADSET_OUT` | `0x8320` | :x: |
|
|
|
|
"read only" in the notes column means that the feature is a read-only feature and cannot be changed.
|
|
|
|
# Implementing a feature
|
|
|
|
Features are implemented as settable features in
|
|
lib/logitech_receiver/settings_templates.py
|
|
Some features also have direct implementation in
|
|
lib/logitech_receiver/hidpp20.py
|
|
|
|
In most cases it should suffice to only implement the settable feature
|
|
interface for each setting in the feature. That will add one or more
|
|
widgets in the Solaar main window to show and change the setting,
|
|
will permit storing and restoring changed settings, and
|
|
will output the feature settings in `solaar show`.
|
|
|
|
Adding a setting implementation involves several steps, described here and
|
|
illustrated by the pointer speed setting implementation.
|
|
|
|
First add a name, a label, and a description for the setting in the common strings section.
|
|
The name is used in the persistent settings structure to store and restore changed settings and
|
|
should be a valid Python identifier. (Some older settings have dashes.)
|
|
The label is displayed in the Solaar main window and the description is used as a tooltip there.
|
|
The label and description should be specified as translatable strings.
|
|
|
|
```
|
|
_POINTER_SPEED = ('pointer_speed', _("Sensitivity (Pointer Speed)"), _("How fast the pointer moves"))
|
|
```
|
|
|
|
Implement a register interface for the setting (if you are very brave and
|
|
some devices have a register interface for the setting).
|
|
Register interfaces cannot be auto-discovered and need to be stated in descriptors.py
|
|
for each device with the register interface.
|
|
|
|
Implement a feature interface for the setting. There are several possible kinds of
|
|
feature interfaces, ranging from simple toggles, to ranges, to fixed lists, to
|
|
dynamic choices, to maps of dynamic choices, each created by a macro function.
|
|
Pointer speed is a setting
|
|
whose values are integers in a range so `feature_range` is used.
|
|
The arguments to this macro are
|
|
the name of the setting (use the name from the common strings tuple),
|
|
the HID++ 2.0 feature ID for the setting (from the FEATURE structure in hidpp20.py),
|
|
the minimum and maximum values for the setting,
|
|
the HID++ 2.0 function IDs to read and write the setting (left-shifted four bits),
|
|
the byte size of the setting value,
|
|
a label and description for the setting (from the common strings tuple),
|
|
and which kinds of devices can have this setting.
|
|
(This last is no longer used because keyboards with integrated pointers only
|
|
report that they are keyboards.)
|
|
The values to be used need to be determined from documentation of the
|
|
feature or from reverse-engineering behaviour of Logitech software under
|
|
Windows or MacOS.
|
|
|
|
```
|
|
def _feature_pointer_speed():
|
|
"""Pointer Speed feature"""
|
|
return feature_range(_POINTER_SPEED[0], _F.POINTER_SPEED, 0x002e, 0x01ff,
|
|
read_function_id=0x0,
|
|
write_function_id=0x10,
|
|
bytes_count=2,
|
|
label=_POINTER_SPEED[1], description=_POINTER_SPEED[2],
|
|
device_kind=(_DK.mouse, _DK.trackball))
|
|
```
|
|
|
|
Settings that are toggles or choices work very similarly.
|
|
Settings where the choices are determined from the device
|
|
need an auxiliary function to receive and decipher the permissable choices.
|
|
See `_feature_adjustable_dpi_choices` for an example.
|
|
|
|
Add an element to _SETTINGS_TABLE with
|
|
the setting name (from the common strings),
|
|
the feature ID (if any),
|
|
the feature implementation (if any),
|
|
the register implementation (if any).
|
|
and
|
|
the identifier for the setting implementation if different from the setting name.
|
|
The identifier is used in descriptors.py to say that a device has the register or feature implementation.
|
|
The identifier can be the same as the setting name if there is only one implementation for the setting.
|
|
This table is used to generate the data structures for describing devices in descriptors.py
|
|
and is also used to auto-discover feature implementations.
|
|
```
|
|
_S( _POINTER_SPEED[0], _F.POINTER_SPEED, _feature_pointer_speed ),
|
|
```
|