Solaar/docs/features.md

12 KiB
Raw Blame History

title layout
List of HID++ 2.0 features page

List of HID++ 2.0 features

Feature status

See functions in hidpp20.py and settings_templates.py

Feature ID Status Notes
ROOT 0x0000 ✔️ System
FEATURE_SET 0x0001 ✔️ System
FEATURE_INFO 0x0002 ✔️ System
DEVICE_FW_VERSION 0x0003 ✔️ get_firmware, read only
DEVICE_UNIT_ID 0x0004 ❌
DEVICE_NAME 0x0005 ✔️ get_kind, get_name, read only
DEVICE_GROUPS 0x0006 ❌
DEVICE_FRIENDLY_NAME 0x0007 ❌
KEEP_ALIVE 0x0008 ❌
RESET 0x0020 ❌ aka “Config Change”
CRYPTO_ID 0x0021 ❌
TARGET_SOFTWARE 0x0030 ❌
WIRELESS_SIGNAL_STRENGTH 0x0080 ❌
DFUCONTROL_LEGACY 0x00C0 ❌
DFUCONTROL_UNSIGNED 0x00C1 ❌
DFUCONTROL_SIGNED 0x00C2 ❌
DFU 0x00D0 ❌
BATTERY_STATUS 0x1000 ✔️ get_battery, read only
BATTERY_VOLTAGE 0x1001 ✔️ get_voltage, read only
CHARGING_CONTROL 0x1010 ❌
LED_CONTROL 0x1300 ❌
GENERIC_TEST 0x1800 ❌
DEVICE_RESET 0x1802 ❌
OOBSTATE 0x1805 ❌
CONFIG_DEVICE_PROPS 0x1806 ❌
CHANGE_HOST 0x1814 🔧
HOSTS_INFO 0x1815 ➕ get_host_names, partial listing only
BACKLIGHT 0x1981 ❌
BACKLIGHT2 0x1982 ✔️ _feature_backlight2
BACKLIGHT3 0x1983 ❌
PRESENTER_CONTROL 0x1A00 ❌
SENSOR_3D 0x1A01 ❌
REPROG_CONTROLS 0x1B00 ➕ get_keys, only listing
REPROG_CONTROLS_V2 0x1B01 ❌
REPROG_CONTROLS_V2_2 0x1B02 ❌
REPROG_CONTROLS_V3 0x1B03 ❌
REPROG_CONTROLS_V4 0x1B04 ➕ get_keys, _feature_reprogrammable_keys
REPORT_HID_USAGE 0x1BC0 ❌
PERSISTENT_REMAPPABLE_ACTION 0x1C00 🔧
WIRELESS_DEVICE_STATUS 0x1D4B ❌ status reporting from device
REMAINING_PAIRING 0x1DF0 ❌
FIRMWARE_PROPERTIES 0x1F1F ❌
ADC_MEASUREMENT 0x1F20 ❌
LEFT_RIGHT_SWAP 0x2001 ❌
SWAP_BUTTON_CANCEL 0x2005 ❌
POINTER_AXIS_ORIENTATION 0x2006 ❌
VERTICAL_SCROLLING 0x2100 ✔️ get_vertical_scrolling_info, read only
SMART_SHIFT 0x2110 ✔️ _feature_smart_shift
HI_RES_SCROLLING 0x2120 ✔️ get_hi_res_scrolling_info, _feature_hi_res_scroll
HIRES_WHEEL 0x2121 ✔️ get_hires_wheel, _feature_hires_smooth_invert, _feature_hires_smooth_resolution
LOWRES_WHEEL 0x2130 ✔️ get_lowres_wheel_status, _feature_lowres_smooth_scroll
THUMB_WHEEL 0x2150 ✔️ _feature_thumb_mode, _feature_thumb_invert
MOUSE_POINTER 0x2200 ✔️ get_mouse_pointer_info, read only
ADJUSTABLE_DPI 0x2201 ✔️ _feature_adjustable_dpi
POINTER_SPEED 0x2205 ✔️ get_pointer_speed_info, _feature_pointer_speed
ANGLE_SNAPPING 0x2230 ❌
SURFACE_TUNING 0x2240 ❌
HYBRID_TRACKING 0x2400 ❌
FN_INVERSION 0x40A0 ✔️ _feature_fn_swap
NEW_FN_INVERSION 0x40A2 ✔️ get_new_fn_inversion, _feature_new_fn_swap
K375S_FN_INVERSION 0x40A3 ✔️ _feature_k375s_fn_swap
ENCRYPTION 0x4100 ❌
LOCK_KEY_STATE 0x4220 ❌
SOLAR_DASHBOARD 0x4301 ❌
KEYBOARD_LAYOUT 0x4520 ❌ read only
KEYBOARD_DISABLE_KEYS 0x4521 ✔️ _feature_disable_keyboard_keys
KEYBOARD_DISABLE_BY_USAGE 0x4522 ❌
DUALPLATFORM 0x4530 ✔️ _feature_dualplatform, untested
MULTIPLATFORM 0x4531 ✔️ _feature_multiplatform
KEYBOARD_LAYOUT_2 0x4540 ❌ read only
CROWN 0x4600 ❌
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 ❌
GKEY 0x8010 ❌
MKEYS 0x8020 ❌
MR 0x8030 ❌
BRIGHTNESS_CONTROL 0x8040 ❌
REPORT_RATE 0x8060 ❌ in progress
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 ❌
SIDETONE 0x8300 ❌
EQUALIZER 0x8310 ❌
HEADSET_OUT 0x8320 ❌

A “read only” note means 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 behavior 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 permissible 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 ),