├── .coveragerc ├── .git-blame-ignore-revs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── checks.yml │ ├── gh-pages.yml │ └── tests.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .python-version ├── CHANGELOG.md ├── COPYRIGHT ├── LICENSE.txt ├── MANIFEST.in ├── Makefile ├── README.md ├── RELEASE.md ├── Release_Notes.md ├── bin └── solaar ├── docs ├── .gitignore ├── 20121210110342697.pdf ├── README.md ├── capabilities.md ├── debian.md ├── devices.md ├── devices │ ├── 00README.txt │ ├── Bluetooth Multi-Device Keyboard K380 B342.txt │ ├── Bolt Receiver C548.txt │ ├── Candy companion chip 405F.txt │ ├── Couch Mouse M515 4007.txt │ ├── Craft Advanced Keyboard 4066.txt │ ├── Craft Advanced Keyboard B350.txt │ ├── ERGO M575 Trackball 4096.txt │ ├── EX100 Receiver 27 Mhz C517.text │ ├── G Pro Wireless Gaming Mouse 4079.txt │ ├── G213 Prodigy Gaming Keyboard C366.txt │ ├── G304 Lightspeed Wireless Gaming Mouse 4074.txt │ ├── G305 Lightspeed Wireless Gaming Mouse 4074.text │ ├── G502 Gaming Mouse C07D.text │ ├── G502 Lightspeed Wireless Gaming Mouse 407F.txt │ ├── G502 Proteus Spectrum Optical Mouse C332.txt │ ├── G502 SE Hero Gaming Mouse C08B.txt │ ├── G502 X C099.txt │ ├── G535 Wireless Gaming Headset 0AC4.txt │ ├── G600 Gaming Mouse C24A.txt │ ├── G604 Wireless Gaming Mouse 4085.txt │ ├── G613 Wireless Mechanical Gaming Keyboard 4065.txt │ ├── G703 Wired-Wireless Gaming Mouse 4070.txt │ ├── G733 Gaming Headset 0AB5.text │ ├── G733 Gaming Headset 0AFE.text │ ├── G815 Mechanical Keyboard C33F.txt │ ├── G903 LIGHTSPEED Wireless Gaming Mouse 4087.txt │ ├── G915 TKL LIGHTSPEED Wireless RGB Mechanical Gaming Keyboard 408E.txt │ ├── G915 WIRELESS RGB MECHANICAL GAMING KEYBOARD 407C.text │ ├── G915 WIRELESS RGB MECHANICAL GAMING KEYBOARD C33E.text │ ├── G915 WIRELESS RGB Mechanical Gaming Keyboard 407E.txt │ ├── G935 Gaming Headset 0A87.txt │ ├── Illuminated Keyboard C318.txt │ ├── Illuminated Living-Room Keyboard K830 4032.txt │ ├── K850 Performance Wireless Keyboard 4062.txt │ ├── K850 Performance Wireless Keyboard B34D.txt │ ├── Keyboard K600 TV 4078.txt │ ├── LIFT For Business B033.txt │ ├── LIFT VERTICAL ERGONOMIC MOUSE B031.txt │ ├── Lightspeed Receiver C539.txt │ ├── Lightspeed Receiver C53A.txt │ ├── Lightspeed Receiver C53D.txt │ ├── Lightspeed Receiver C53F.txt │ ├── Lightspeed Receiver C541.txt │ ├── Lightspeed Receiver C545.txt │ ├── Lightspeed Receiver C547.txt │ ├── Logi Pop Keys B365.txt │ ├── Logitech PRO X Wireless Gaming Headset 0ABA.txt │ ├── M720 Triathlon Multi-Device Mouse 405E.txt │ ├── M720 Triathlon Multi-Device Mouse B015.txt │ ├── MX Anywhere 3 4090.txt │ ├── MX Anywhere 3 B025.txt │ ├── MX Anywhere 3 for Business B02D.txt │ ├── MX Ergo Multi-Device Trackball 406F.txt │ ├── MX Keys Keyboard 408A.txt │ ├── MX Keys Keyboard B35B.txt │ ├── MX Keys Mini B369.txt │ ├── MX Keys S B378.text │ ├── MX Keys for Business B363.text │ ├── MX Master 3 Wireless Mouse 4082.txt │ ├── MX Master 3 Wireless Mouse B023.txt │ ├── MX Master 3 for Business B028.text │ ├── MX Master 3S B034.txt │ ├── MX Mechanical B366.txt │ ├── MX Mechanical Mini B367.txt │ ├── MX Vertical Wireless Mouse 407B.txt │ ├── MX Vertical Wireless Mouse B020.txt │ ├── Marathon Mouse M705 101B.txt │ ├── Marathon Mouse M705 406D.txt │ ├── Multi Device Silent Mouse M585-M590 406B.txt │ ├── Nano Receiver C52F.txt │ ├── Nano Receiver C534.txt │ ├── Nano Receiver C535.txt │ ├── Number Pad N545 2006.txt │ ├── PRO X 2 40A9.text │ ├── PRO X Wireless 4093.txt │ ├── Rechargeable Trackpad T651 B00C.txt │ ├── Signature M650 L Mouse B02A.txt │ ├── Unifying Receiver C52B.txt │ ├── Wireless All-in-One Keyboard TK820 4102.txt │ ├── Wireless Illuminated Keyboard K800 2010.txt │ ├── Wireless Illuminated Keyboard K800 new 406E.txt │ ├── Wireless Keyboard 4075.txt │ ├── Wireless Keyboard Dell KB714 4015.txt │ ├── Wireless Keyboard K220 4005.txt │ ├── Wireless Keyboard K230 400D.txt │ ├── Wireless Keyboard K270(unifying) 4003.txt │ ├── Wireless Keyboard K360 4004.txt │ ├── Wireless Keyboard K470 4075.txt │ ├── Wireless Keyboard K520 2011.txt │ ├── Wireless Keyboard MK270 4023.txt │ ├── Wireless Mobile Mouse MX Anywhere 2 4072.txt │ ├── Wireless Mobile Mouse MX Anywhere 2S 406A.txt │ ├── Wireless Mobile Mouse MX Anywhere 2S B01A.txt │ ├── Wireless Mouse 4022.txt │ ├── Wireless Mouse Dell WM514 4029.txt │ ├── Wireless Mouse M185 new 4054.txt │ ├── Wireless Mouse M185,M235,M310 4055.txt │ ├── Wireless Mouse M215 2nd Gen 401B.txt │ ├── Wireless Mouse M310 M310t 4031.txt │ ├── Wireless Mouse M325 400A.txt │ ├── Wireless Mouse M345 4017.txt │ ├── Wireless Mouse M510 1025.txt │ ├── Wireless Mouse M510 4051.txt │ ├── Wireless Mouse M525 4013.txt │ ├── Wireless Mouse M560 402D.txt │ ├── Wireless Mouse MX Anywhere 2 404A.txt │ ├── Wireless Mouse MX Master 2S 4069.txt │ ├── Wireless Mouse MX Master 2S B019.txt │ ├── Wireless Mouse MX Master 4041.txt │ ├── Wireless Mouse MX Master 4071.txt │ ├── Wireless Mouse MX Master B012.txt │ ├── Wireless Mouse Pebble M350 4080.txt │ ├── Wireless Multi-Device Keyboard K780 405B.txt │ ├── Wireless Rechargeable Touchpad T650 4101.txt │ ├── Wireless Solar Keyboard K750 4002.txt │ ├── Wireless Touch Keyboard K400 4024.txt │ ├── Wireless Touch Keyboard K400 Plus 404D.txt │ ├── Wireless Trackball M570 1028.txt │ ├── Zone Touch Mouse T400 4026.txt │ ├── anywhere-mx.txt │ ├── mk700.txt │ └── performance-mx.txt ├── features.md ├── hidpp-documentation.txt ├── i18n.md ├── img │ ├── favicon.ico │ ├── favicon.png │ └── solaar.svg ├── implementation.md ├── index.md ├── installation.md ├── rules.md ├── screenshots │ ├── Solaar-main-window-back-divert.png │ ├── Solaar-main-window-button-actions.png │ ├── Solaar-main-window-keyboard.png │ ├── Solaar-main-window-mouse.png │ ├── Solaar-main-window-multiple.png │ ├── Solaar-main-window-offline.png │ ├── Solaar-main-window-receiver-old.png │ ├── Solaar-main-window-receiver.png │ ├── Solaar-menu.png │ └── Solaar-rule-editor.png ├── unistallation.md ├── usage.md └── usb.ids.txt ├── lib ├── hid_parser │ ├── __init__.py │ └── data.py ├── hidapi │ ├── __init__.py │ ├── common.py │ ├── hidapi_impl.py │ ├── hidconsole.py │ └── udev_impl.py ├── keysyms │ ├── __init__.py │ ├── generate.py │ └── keysymdef.py ├── logitech_receiver │ ├── __init__.py │ ├── base.py │ ├── base_usb.py │ ├── common.py │ ├── descriptors.py │ ├── desktop_notifications.py │ ├── device.py │ ├── diversion.py │ ├── exceptions.py │ ├── hidpp10.py │ ├── hidpp10_constants.py │ ├── hidpp20.py │ ├── hidpp20_constants.py │ ├── i18n.py │ ├── listener.py │ ├── notifications.py │ ├── receiver.py │ ├── settings.py │ ├── settings_templates.py │ ├── settings_validator.py │ └── special_keys.py └── solaar │ ├── __init__.py │ ├── cli │ ├── __init__.py │ ├── config.py │ ├── pair.py │ ├── probe.py │ ├── profiles.py │ ├── show.py │ └── unpair.py │ ├── configuration.py │ ├── custom_logger.py │ ├── dbus.py │ ├── gtk.py │ ├── i18n.py │ ├── listener.py │ ├── tasks.py │ ├── ui │ ├── __init__.py │ ├── about │ │ ├── __init__.py │ │ ├── about.py │ │ ├── model.py │ │ ├── presenter.py │ │ └── view.py │ ├── action.py │ ├── common.py │ ├── config_panel.py │ ├── desktop_notifications.py │ ├── diversion_rules.py │ ├── icons.py │ ├── pair_window.py │ ├── rule_actions.py │ ├── rule_base.py │ ├── rule_conditions.py │ ├── tray.py │ └── window.py │ └── version ├── mkdocs.yml ├── po ├── README ├── ca.po ├── cs.po ├── da.po ├── de.po ├── el.po ├── es.po ├── fi.po ├── fr.po ├── hr.po ├── id.po ├── it.po ├── ja.po ├── nb.po ├── nl.po ├── nn.po ├── pl.po ├── pt.po ├── pt_BR.po ├── ro.po ├── ru.po ├── sk.po ├── solaar.pot ├── sr.po ├── sv.po ├── tr.po ├── zh_CN.po └── zh_TW.po ├── pyproject.toml ├── release.sh ├── rules.d-uinput └── 42-logitech-unify-permissions.rules ├── rules.d └── 42-logitech-unify-permissions.rules ├── setup.py ├── share ├── README ├── applications │ └── solaar.desktop ├── autostart │ └── solaar.desktop ├── solaar-master.svg └── solaar │ ├── icons │ ├── solaar-attention.svg │ ├── solaar-init.svg │ ├── solaar-light_000.png │ ├── solaar-light_020.png │ ├── solaar-light_040.png │ ├── solaar-light_060.png │ ├── solaar-light_080.png │ ├── solaar-light_100.png │ ├── solaar-light_unknown.png │ ├── solaar-symbolic.svg │ └── solaar.svg │ └── io.github.pwr_solaar.solaar.metainfo.xml ├── tests ├── __init__.py ├── hid_parser │ ├── __init__.py │ └── test_data.py ├── hidapi │ ├── __init__.py │ └── test_hidapi.py ├── logitech_receiver │ ├── __init__.py │ ├── fake_hidpp.py │ ├── test_base.py │ ├── test_base_usb.py │ ├── test_common.py │ ├── test_desktop_notifications.py │ ├── test_device.py │ ├── test_diversion.py │ ├── test_hidpp10.py │ ├── test_hidpp20_complex.py │ ├── test_hidpp20_simple.py │ ├── test_notifications.py │ ├── test_receiver.py │ ├── test_setting_templates.py │ └── test_settings_validator.py ├── solaar │ ├── test_gtk.py │ └── ui │ │ ├── test_about_dialog.py │ │ ├── test_common.py │ │ ├── test_desktop_notifications.py │ │ ├── test_i18n.py │ │ ├── test_pair_window.py │ │ └── test_probe.py └── test_keysyms │ ├── __init__.py │ └── test_keysymdef.py └── tools ├── clean.sh ├── hidconsole ├── po-compile.sh ├── po-update.sh └── scan-registers.sh /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | 4 | source = 5 | hid_parser 6 | hidapi 7 | keysyms 8 | logitech_receiver 9 | solaar 10 | 11 | omit = 12 | */tests/* 13 | */setup.py 14 | */__main__.py 15 | 16 | [report] 17 | exclude_lines = 18 | pragma: no cover 19 | if __name__ == '__main__': 20 | if typing.TYPE_CHECKING 21 | 22 | fail_under = 40 23 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # yapf bulk change 2 | 72a8d311bce64b1536c08e754d22bb91efb66460 3 | # isort bulk change 4 | e6369e0c3c240715a0a2daede6c3b225ed63cf60 5 | # pre-commit bulk change 6 | 33521558ed7007c24b24127f1448c2c23ecbfb35 7 | # flake8 bulk change 8 | 627185079f65c9cc471194b7927c833682e4a7a3 9 | # yapf style update 10 | 27c90fa736d8a7a1ef6acda4345d3599862e185c 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Information** 11 | 12 | 13 | 14 | - Solaar version (`solaar --version` or `git describe --tags` if cloned from this repository): 15 | - Distribution: 16 | - Kernel version (ex. `uname -srmo`): `KERNEL VERSION HERE` 17 | - Output of `solaar show`: 18 | 19 |
20 | 21 | ``` 22 | SOLAAR SHOW OUTPUT HERE 23 | ``` 24 |
25 | 26 | - Contents of `~/.config/solaar/config.yaml` (or `~/.config/solaar/config.json` if `~/.config/solaar/config.yaml` not present): 27 | 28 |
29 | 30 | ``` 31 | CONTENTS HERE 32 | ``` 33 |
34 | 35 | 36 | - Errors or warrnings from Solaar: 37 | 42 | 43 | 44 | **Describe the bug** 45 | A clear and concise description of what the bug is. 46 | 47 | **To Reproduce** 48 | Steps to reproduce the behavior: 49 | 1. Go to '...' 50 | 2. Click on '....' 51 | 3. Scroll down to '....' 52 | 4. See error 53 | 54 | **Screenshots** 55 | If applicable, add screenshots to help explain your problem. 56 | 57 | **Additional context** 58 | Add any other context about the problem here. 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Information** 11 | 12 | - Solaar version (`solaar --version` and `git describe --tags`): 13 | - Distribution: 14 | - Kernel version (ex. `uname -srmo`): 15 | - Output of `solaar show` for the target device (if applicable): 16 | 17 |
18 | 19 | ``` 20 | OUTPUT HERE 21 | ``` 22 |
23 | 24 | 25 | **Is your feature request related to a problem? Please describe.** 26 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 27 | 28 | **Describe the solution you'd like** 29 | A clear and concise description of what you want to happen. 30 | 31 | **Describe alternatives you've considered** 32 | A clear and concise description of any alternative solutions or features you've considered. 33 | 34 | **Additional context** 35 | Add any other context or screenshots about the feature request here. 36 | -------------------------------------------------------------------------------- /.github/workflows/checks.yml: -------------------------------------------------------------------------------- 1 | name: checks 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | pre-commit: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v4 11 | 12 | - name: Set up Python 13 | uses: actions/setup-python@v5 14 | 15 | - name: Run pre-commit 16 | uses: pre-commit/action@v3.0.0 17 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | permissions: 8 | contents: read 9 | pages: write 10 | id-token: write 11 | 12 | concurrency: 13 | group: 'pages' 14 | cancel-in-progress: false 15 | 16 | jobs: 17 | build: 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | 24 | - name: Set up Python 25 | uses: actions/setup-python@v5 26 | with: 27 | python-version: '3.x' 28 | 29 | - name: Install dependencies 30 | run: | 31 | pip install mkdocs mkdocs-rtd-dropdown mkdocs-mermaid2-plugin mkdocstrings[python] 32 | 33 | - name: Build and deploy 34 | run: | 35 | mkdocs build 36 | 37 | - name: Upload artifact 38 | uses: actions/upload-pages-artifact@v3 39 | with: 40 | path: 'site' 41 | 42 | deploy: 43 | environment: 44 | name: github-pages 45 | url: ${{ steps.deployment.outputs.page_url }} 46 | runs-on: ubuntu-latest 47 | needs: build 48 | 49 | steps: 50 | - name: Deploy to GitHub Pages 51 | id: deployment 52 | uses: actions/deploy-pages@v4 53 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ubuntu-tests: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | python-version: [3.8, 3.13] 12 | fail-fast: false 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Python ${{ matrix.python-version }} 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: ${{ matrix.python-version }} 22 | 23 | - name: Install Ubuntu dependencies for python 3.8 24 | if: matrix.python-version == '3.8' 25 | run: | 26 | make install_apt 27 | 28 | - name: Install Ubuntu dependencies for python 3.13 29 | if: matrix.python-version == '3.13' 30 | run: | 31 | make install_apt_python3.13 32 | 33 | - name: Install Python dependencies 34 | run: | 35 | make install_pip PIP_ARGS='.["test"]' 36 | 37 | - name: Run tests on Ubuntu 38 | run: | 39 | make test 40 | 41 | - name: Upload coverage to Codecov 42 | if: github.ref == 'refs/heads/master' 43 | uses: codecov/codecov-action@v4.5.0 44 | with: 45 | directory: ./coverage/reports/ 46 | env_vars: OS, PYTHON 47 | files: ./coverage.xml 48 | flags: unittests 49 | name: codecov-umbrella 50 | token: ${{ secrets.CODECOV_TOKEN }} 51 | 52 | macos-tests: 53 | runs-on: macos-latest 54 | 55 | strategy: 56 | matrix: 57 | python-version: [3.8, 3.13] 58 | fail-fast: false 59 | 60 | steps: 61 | - name: Checkout 62 | uses: actions/checkout@v4 63 | 64 | - name: Set up Python ${{ matrix.python-version }} 65 | uses: actions/setup-python@v5 66 | with: 67 | python-version: ${{ matrix.python-version }} 68 | 69 | - name: Set up macOS dependencies 70 | run: | 71 | make install_brew 72 | - name: Install Python dependencies 73 | run: | 74 | make install_pip PIP_ARGS='.["test"]' 75 | - name: Run tests on macOS 76 | run: | 77 | export DYLD_LIBRARY_PATH=$(brew --prefix hidapi)/lib:$DYLD_LIBRARY_PATH && pytest --cov --cov-report=xml 78 | - name: Upload coverage to Codecov 79 | if: github.ref == 'refs/heads/master' 80 | uses: codecov/codecov-action@v4.5.0 81 | with: 82 | directory: ./coverage/reports/ 83 | env_vars: OS, PYTHON 84 | files: ./coverage.xml 85 | flags: unittests 86 | name: codecov-umbrella 87 | token: ${{ secrets.CODECOV_TOKEN }} 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.pyo 3 | __pycache__/ 4 | *.log 5 | *.mo 6 | 7 | /lib/Solaar.egg-info/ 8 | /lib/solaar.egg-info/ 9 | /lib/solaar/commit 10 | /build/ 11 | /sdist/ 12 | /dist/ 13 | /deb_dist/ 14 | /MANIFEST 15 | 16 | .coverage 17 | /htmlcov/ 18 | 19 | /docs/captures/ 20 | /share/logitech_icons/ 21 | /share/locale/ 22 | 23 | /po/*.po~ 24 | 25 | /.idea/ 26 | 27 | .DS_Store 28 | ._* 29 | 30 | Pipfile 31 | Pipfile.lock 32 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.3.0 4 | hooks: 5 | - id: check-ast 6 | - id: check-builtin-literals 7 | - id: check-merge-conflict 8 | - id: check-yaml 9 | - id: check-toml 10 | - id: debug-statements 11 | - id: end-of-file-fixer 12 | - id: trailing-whitespace 13 | - repo: https://github.com/astral-sh/ruff-pre-commit 14 | rev: v0.2.2 15 | hooks: 16 | - id: ruff 17 | name: ruff lint 18 | args: [--fix, --exit-non-zero-on-fix] 19 | - id: ruff-format 20 | name: ruff format 21 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.11 2 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2012, 2013 2 | Daniel Pavel 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, version 2. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see . 15 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYRIGHT LICENSE.txt README.md CHANGELOG.md lib/solaar/version lib/solaar/commit 2 | recursive-include rules.d * 3 | recursive-include share/locale * 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | UDEV_RULE_FILE = 42-logitech-unify-permissions.rules 2 | UDEV_RULES_SOURCE := rules.d/$(UDEV_RULE_FILE) 3 | UDEV_RULES_SOURCE_UINPUT := rules.d-uinput/$(UDEV_RULE_FILE) 4 | UDEV_RULES_DEST := /etc/udev/rules.d/ 5 | 6 | PIP_ARGS ?= . 7 | 8 | .PHONY: install_ubuntu install_macos 9 | .PHONY: install_apt install_brew install_pip 10 | .PHONY: install_udev install_udev_uinput reload_udev uninstall_udev 11 | .PHONY: format lint test 12 | 13 | install_ubuntu: install_apt install_udev_uinput install_pip 14 | 15 | install_macos: install_brew install_pip 16 | 17 | install_apt: 18 | @echo "Installing Solaar dependencies via apt" 19 | sudo apt update 20 | sudo apt install libdbus-1-dev libglib2.0-dev libgtk-3-dev libgirepository-1.0-dev 21 | 22 | install_apt_python3.13: 23 | @echo "Installing Solaar dependencies via apt" 24 | sudo apt update 25 | sudo apt install libdbus-1-dev libglib2.0-dev libgtk-3-dev libgirepository-2.0-dev gobject-introspection 26 | 27 | install_dnf: 28 | @echo "Installing Solaar dependencies via dn" 29 | sudo dnf install gtk3 python3-gobject python3-dbus python3-pyudev python3-psutil python3-xlib python3-yaml 30 | 31 | install_brew: 32 | @echo "Installing Solaar dependencies via brew" 33 | brew update 34 | brew install hidapi gtk+3 pygobject3 gobject-introspection 35 | 36 | install_pip: 37 | @echo "Installing Solaar via pip" 38 | python -m pip install --upgrade pip 39 | pip install $(PIP_ARGS) 40 | 41 | install_pipx: 42 | @echo "Installing Solaar via pipx" 43 | pipx install --system-site-packages $(PIP_ARGS) 44 | 45 | install_udev: 46 | @echo "Copying Solaar udev rule to $(UDEV_RULES_DEST)" 47 | sudo cp $(UDEV_RULES_SOURCE) $(UDEV_RULES_DEST) 48 | make reload_udev 49 | 50 | install_udev_uinput: 51 | @echo "Copying Solaar udev rule (uinput) to $(UDEV_RULES_DEST)" 52 | sudo cp $(UDEV_RULES_SOURCE_UINPUT) $(UDEV_RULES_DEST) 53 | make reload_udev 54 | 55 | reload_udev: 56 | @echo "Reloading udev rules" 57 | sudo udevadm control --reload-rules 58 | 59 | uninstall_udev: 60 | @echo "Removing Solaar udev rules from $(UDEV_RULES_DEST)" 61 | sudo rm -f $(UDEV_RULES_DEST)/$(UDEV_RULE_FILE) 62 | make reload_udev 63 | 64 | format: 65 | @echo "Formatting Solaar code" 66 | ruff format . 67 | 68 | lint: 69 | @echo "Linting Solaar code" 70 | ruff check . --fix 71 | 72 | test: 73 | @echo "Running Solaar tests" 74 | pytest --cov --cov-report=xml 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solaar 2 | 3 | Solaar is a Linux manager for many Logitech keyboards, mice, and other devices 4 | that connect wirelessly to a Unifying, Bolt, Lightspeed or Nano receiver 5 | as well as many Logitech devices that connect via a USB cable or Bluetooth. 6 | Solaar is not a device driver and responds only to special messages from devices 7 | that are otherwise ignored by the Linux input system. 8 | 9 | More Information - 10 | Usage - 11 | Capabilities - 12 | Rules - 13 | Manual Installation 14 | 15 | 16 | [![codecov](https://codecov.io/gh/pwr-Solaar/Solaar/graph/badge.svg?token=D7YWFEWID6)](https://codecov.io/gh/pwr-Solaar/Solaar) 17 | [![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2+-blue.svg)](../LICENSE.txt) 18 | 19 |

20 | 21 |   22 | 23 |

24 | 25 |

26 | 27 |   28 | 29 |

30 | 31 | Solaar supports: 32 | - pairing/unpairing of devices with receivers 33 | - configuring device settings 34 | - custom button configuration 35 | - running rules in response to special messages from devices 36 | 37 | For more information see 38 | the main Solaar documentation page. - 39 | 40 | 41 | ## Installation Packages 42 | 43 | Up-to-date prebuilt packages are available for some Linux distros 44 | (e.g., Fedora) in their standard repositories. 45 | If a recent version of Solaar is not 46 | available from the standard repositories for your distribution, you can try 47 | one of these packages: 48 | 49 | - Arch solaar package in the [extra repository][arch] 50 | - Ubuntu/Kubuntu package in [Solaar stable ppa][ppa stable] 51 | - NixOS Flake package in [Svenum/Solaar-Flake][nix flake] 52 | 53 | Solaar is available from some other repositories 54 | but may be several versions behind the current version: 55 | 56 | - a [Debian package][debian], courtesy of Stephen Kitt 57 | - a Ubuntu package is available from [universe repository][ubuntu universe repository] 58 | - a [Gentoo package][gentoo], courtesy of Carlos Silva and Tim Harder 59 | - a [Mageia package][mageia], courtesy of David Geiger 60 | 61 | [ppa stable]: https://launchpad.net/~solaar-unifying/+archive/ubuntu/stable 62 | [arch]: https://www.archlinux.org/packages/extra/any/solaar/ 63 | [gentoo]: https://packages.gentoo.org/packages/app-misc/solaar 64 | [mageia]: http://mageia.madb.org/package/show/release/cauldron/application/0/name/solaar 65 | [ubuntu universe repository]: http://packages.ubuntu.com/search?keywords=solaar&searchon=names&suite=all§ion=all 66 | [nix flake]: https://github.com/Svenum/Solaar-Flake 67 | [debian]: https://packages.debian.org/search?keywords=solaar&searchon=names&suite=all§ion=all 68 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Solaar releases 2 | 3 | ## Please read before making a release 4 | 5 | We support two type of releases: normal releases (ex. `1.0.0`) and release 6 | candidates (ex. `1.0.0rc1`). Release candidates must have a `rcX` suffix. 7 | 8 | Release routine: 9 | 10 | - Update version in `lib/solaar/version` 11 | - Add release changes to `CHANGELOG.md` 12 | - Add release information to `share/solaar/io.github.pwr_solaar.solaar.metainfo.xml` 13 | - Create a commit that starts with `release VERSION` 14 | - Push commit to Solaar repository 15 | - Invoke `./release.sh` 16 | - Git tags are signed so you must have GPG set up 17 | - You are required to have a github token with `public_repo` access 18 | in `~/.github-token` 19 | -------------------------------------------------------------------------------- /bin/solaar: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- python-mode -*- 3 | # -*- coding: UTF-8 -*- 4 | 5 | ## Copyright (C) 2012-2013 Daniel Pavel 6 | ## 7 | ## This program is free software; you can redistribute it and/or modify 8 | ## it under the terms of the GNU General Public License as published by 9 | ## the Free Software Foundation; either version 2 of the License, or 10 | ## (at your option) any later version. 11 | ## 12 | ## This program is distributed in the hope that it will be useful, 13 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | ## GNU General Public License for more details. 16 | ## 17 | ## You should have received a copy of the GNU General Public License along 18 | ## with this program; if not, write to the Free Software Foundation, Inc., 19 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | 22 | def init_paths(): 23 | """Make the app work in the source tree.""" 24 | import os.path 25 | import sys 26 | 27 | root = os.path.join(os.path.realpath(sys.path[0]), "..") 28 | prefix = os.path.normpath(root) 29 | src_lib = os.path.join(prefix, "lib") 30 | share_lib = os.path.join(prefix, "share", "solaar", "lib") 31 | for location in src_lib, share_lib: 32 | init_py = os.path.join(location, "solaar", "__init__.py") 33 | if os.path.exists(init_py): 34 | sys.path[0] = location 35 | break 36 | 37 | 38 | if __name__ == "__main__": 39 | init_paths() 40 | import solaar.gtk 41 | 42 | solaar.gtk.main() 43 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # ignore documentation-specific files 2 | 3 | .jekyll-metadata 4 | Gemfile 5 | Gemfile.lock 6 | _site/ 7 | -------------------------------------------------------------------------------- /docs/20121210110342697.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/20121210110342697.pdf -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Documentation Readme 2 | 3 | This project's documentation is hosted using GitHub pages, which serves static pages using Jekyll. 4 | [Please refer to the official documentation for instructions for how to build the site locally.](https://help.github.com/articles/setting-up-your-github-pages-site-locally-with-jekyll/) 5 | -------------------------------------------------------------------------------- /docs/debian.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Debian Repository 3 | layout: page 4 | --- 5 | 6 | # Debian repository 7 | 8 | Solaar is now part of the [official Debian repository](https://packages.debian.org/solaar). To install it on your Debian machine, use the following command: `sudo apt install solaar` 9 | -------------------------------------------------------------------------------- /docs/devices/00README.txt: -------------------------------------------------------------------------------- 1 | Files in this directory are edited output from `solaar show` providing 2 | information about devices and receivers that Solaar supports. This 3 | directory does not contain information about all devices and receivers that 4 | Solaar supports. Information is generally only added when provided in a 5 | Solaar issue. 6 | 7 | Directions for constructing the files are given below. The files 8 | Unifying Receiver C52B.txt 9 | Craft Advanced Keyboard 4066.txt 10 | Craft Advanced Keyboard B350.txt 11 | MX Master 3 Wireless Mouse 4082.txt 12 | MX Master 3 Wireless Mouse B023.txt 13 | are good examples of following the directions below. 14 | 15 | 16 | File Naming 17 | 18 | Logitech device names are often reused so the names of files can't just be 19 | the device name. File names start with the name of the device or receiver 20 | as given in the first line of of output for the device. The file name 21 | continues with a space and the WPID, if the device is connected to a 22 | receiver, or the second half of the USB ID, if the device is connected via 23 | USB or Bluetooth. The WPID or USB ID are in upper case. As devices can 24 | behave differently when connected via a receiver or USB or Bluetooth there 25 | should be a file for each possible connection method. 26 | 27 | Files that do not follow this naming convention are retained for historical purposes. 28 | 29 | 30 | File Contents 31 | 32 | Each file should contain the output of `solaar show NAME` where NAME 33 | is enough of the full name of a device or receiver to identify it. 34 | The output of `solaar show` will provide information on all connnected 35 | devices and receivers including their names. 36 | The output of `solaar show NAME` can be edited 37 | to remove serial numbers and variable information such as the current values 38 | of settings. 39 | Passing the style requirements for Solaar documentation may require removing 40 | trailing white space on lines. 41 | 42 | For older devices probes of the device registers should be 43 | included but for newer devices this is not necessary. 44 | 45 | Unifying receivers can pair with any device that has the Unifying logo. 46 | Bolt receivers can pair with any device that has the Bolt logo. 47 | Nano and Lightspeed receivers can only pair with certain devices, 48 | so the end of their files should state the devices that they have 49 | been seen to be paired with or are part of. 50 | 51 | 52 | Updating Files 53 | 54 | Newer versions of Solaar add support for more settings so it is useful to 55 | provide updated versions of these files if there is information from the 56 | current version of `solaar show NAME` that is not in the existing file. 57 | -------------------------------------------------------------------------------- /docs/devices/Bolt Receiver C548.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | Bolt Receiver 4 | Device path : /dev/hidraw8 5 | USB id : 046d:C548 6 | Serial : 38423638313332394241363434313837 7 | Has 2 paired device(s) out of a maximum of 6. 8 | Notifications: wireless, software present (0x000900) 9 | Device activity counters: 1=252, 2=135 10 | -------------------------------------------------------------------------------- /docs/devices/Candy companion chip 405F.txt: -------------------------------------------------------------------------------- 1 | 7: Candy companion chip 2 | Device path : /dev/hidraw11 3 | Codename : Candy 4 | Kind : touchpad 5 | Protocol : HID++ 4.2 6 | Serial number: 5B2B9A98 7 | Model ID: 405F00000000 8 | Unit ID: 32314707 9 | Firmware: CC 07.00.B0010 10 | Bootloader: BOT 32.00.B0010 11 | Supports 11 HID++ 2.0 features: 12 | 0: ROOT {0000} 13 | 1: FEATURE SET {0001} 14 | 2: DEVICE FW VERSION {0003} 15 | Firmware: Firmware CC 07.00.B0010 405F 16 | Firmware: Bootloader BOT 32.00.B0010 405F 17 | Unit ID: 32314707 Model ID: 405F00000000 Transport IDs: {'wpid': '405F'} 18 | 3: DEVICE NAME {0005} 19 | Name: Candy companion chip 20 | Kind: touchpad 21 | 4: unknown:18A1 {18A1} internal, hidden 22 | 5: unknown:1E00 {1E00} hidden 23 | 6: unknown:1EB0 {1EB0} internal, hidden 24 | 7: DFUCONTROL SIGNED {00C2} 25 | 8: unknown:1801 {1801} internal, hidden 26 | 9: DEVICE RESET {1802} internal, hidden 27 | 10: unknown:1803 {1803} internal, hidden 28 | Battery status unavailable. 29 | 30 | Part of the G PowerPlay Wireless Mouse Pad. 31 | -------------------------------------------------------------------------------- /docs/devices/Couch Mouse M515 4007.txt: -------------------------------------------------------------------------------- 1 | 1: Couch Mouse M515 2 | Codename : M515 3 | Kind : mouse 4 | Wireless PID : 4007 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms 7 | Serial number: BED587E9 8 | Firmware: RQM 24.00.B0023 9 | Bootloader: DFU 00.02.B0010 10 | The power switch is located on the base. 11 | Supports 16 HID++ 2.0 features: 12 | 0: ROOT {0000} 13 | 1: FEATURE SET {0001} 14 | 2: DEVICE FW VERSION {0003} 15 | 3: DEVICE NAME {0005} 16 | 4: DFUCONTROL {00C0} 17 | 5: BATTERY STATUS {1000} 18 | 6: unknown:1A30 {1A30} hidden 19 | 7: REPROG CONTROLS {1B00} 20 | 8: WIRELESS DEVICE STATUS {1D4B} 21 | 9: unknown:1DF3 {1DF3} hidden 22 | 10: VERTICAL SCROLLING {2100} 23 | 11: HI RES SCROLLING {2120} 24 | 12: MOUSE POINTER {2200} 25 | 13: unknown:1F02 {1F02} hidden 26 | 14: unknown:1F03 {1F03} hidden 27 | 15: unknown:1E80 {1E80} hidden 28 | Has 5 reprogrammable keys: 29 | 0: LEFT CLICK => LeftClick mse, reprogrammable 30 | 1: RIGHT CLICK => RightClick mse, reprogrammable 31 | 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 32 | 3: BACK AS BUTTON 4 => BackEx mse, reprogrammable 33 | 4: FORWARD AS BUTTON 5 => BrowserForwardEx mse, reprogrammable 34 | Battery: 65%, discharging, 35 | -------------------------------------------------------------------------------- /docs/devices/G Pro Wireless Gaming Mouse 4079.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4rc1 2 | 3 | 1: G Pro Wireless Gaming Mouse 4 | Device path : /dev/hidraw10 5 | WPID : 4079 6 | Codename : G Pro 7 | Kind : mouse 8 | Protocol : HID++ 4.2 9 | Polling rate : 2 ms (500Hz) 10 | Serial number: 40B217C0 11 | Model ID: 4079C0880000 12 | Unit ID: 40B217C0 13 | Bootloader: BOT 74.02.B0026 14 | Firmware: MPM 15.02.B0026 15 | Other: 16 | The power switch is located on the base. 17 | Supports 28 HID++ 2.0 features: 18 | 0: ROOT {0000} 19 | 1: FEATURE SET {0001} 20 | 2: DEVICE FW VERSION {0003} 21 | Firmware: Bootloader BOT 74.02.B0026 AADF85EE714A 22 | Firmware: Firmware MPM 15.02.B0026 407985EE714A 23 | Firmware: Other 24 | Unit ID: 40B217C0 Model ID: 4079C0880000 Transport IDs: {'wpid': '4079', 'usbid': 'C088'} 25 | 3: DEVICE NAME {0005} 26 | Name: G Pro Wireless Gaming Mouse 27 | Kind: mouse 28 | 4: WIRELESS DEVICE STATUS {1D4B} 29 | 5: RESET {0020} 30 | 6: BATTERY VOLTAGE {1001} 31 | Battery: 3926mV, discharging, 70. 32 | 7: COLOR LED EFFECTS {8070} 33 | 8: LED CONTROL {1300} 34 | 9: ONBOARD PROFILES {8100} 35 | Device Mode: On-Board 36 | Onboard Profiles (saved): Enable 37 | Onboard Profiles : Enable 38 | 10: MOUSE BUTTON SPY {8110} 39 | 11: REPORT RATE {8060} 40 | Polling Rate (ms): 2 41 | Polling Rate (ms) (saved): 2 42 | Polling Rate (ms) : 2 43 | 12: ADJUSTABLE DPI {2201} 44 | Sensitivity (DPI) (saved): 1600 45 | Sensitivity (DPI) : 1600 46 | 13: DEVICE RESET {1802} internal, hidden 47 | 14: unknown:1803 {1803} internal, hidden 48 | 15: OOBSTATE {1805} internal, hidden 49 | 16: CONFIG DEVICE PROPS {1806} internal, hidden 50 | 17: unknown:1811 {1811} internal, hidden 51 | 18: unknown:1830 {1830} internal, hidden 52 | 19: unknown:1890 {1890} internal, hidden 53 | 20: unknown:1891 {1891} internal, hidden 54 | 21: unknown:18A1 {18A1} internal, hidden 55 | 22: unknown:1801 {1801} internal, hidden 56 | 23: unknown:18B1 {18B1} internal, hidden 57 | 24: unknown:1DF3 {1DF3} internal, hidden 58 | 25: unknown:1E00 {1E00} hidden 59 | 26: unknown:1EB0 {1EB0} internal, hidden 60 | 27: unknown:1863 {1863} internal, hidden 61 | Battery: 3926mV, discharging, 70. 62 | -------------------------------------------------------------------------------- /docs/devices/G213 Prodigy Gaming Keyboard C366.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.5rc1 2 | 3 | USB and Bluetooth Devices 4 | 5 | 1: G213 Prodigy Gaming Keyboard 6 | Device path : /dev/hidraw2 7 | USB id : 046d:C336 8 | Codename : G213 9 | Kind : keyboard 10 | Protocol : HID++ 4.2 11 | Polling rate : 1 ms (1000Hz) 12 | Serial number: 13 | Model ID: C33600000000 14 | Unit ID: 31314709 15 | Firmware: U1 09.00.B0006 16 | Bootloader: BOT 31.00.B0002 17 | Supports 15 HID++ 2.0 features: 18 | 0: ROOT {0000} V0 19 | 1: FEATURE SET {0001} V0 20 | 2: DEVICE FW VERSION {0003} V2 21 | Firmware: Firmware U1 09.00.B0006 C336 22 | Firmware: Bootloader BOT 31.00.B0002 AAC8 23 | Unit ID: 31314709 Model ID: C33600000000 Transport IDs: {'usbid': 'C336'} 24 | 3: KEYBOARD DISABLE BY USAGE {4522} V0 25 | 4: DEVICE NAME {0005} V0 26 | Name: Gaming Keyboard G213 27 | Kind: keyboard 28 | 5: unknown:1E00 {1E00} V0 hidden 29 | 6: KEYBOARD LAYOUT 2 {4540} V0 30 | 7: unknown:1EB0 {1EB0} V0 internal, hidden 31 | 8: REPORT RATE {8060} V0 32 | Polling Rate (ms): 1 33 | Polling Rate (ms) : 1 34 | 9: DFUCONTROL SIGNED {00C2} V0 35 | 10: unknown:1801 {1801} V0 internal, hidden 36 | 11: DEVICE RESET {1802} V0 internal, hidden 37 | 12: COLOR LED EFFECTS {8070} V5 38 | 13: unknown:1821 {1821} V0 39 | 14: REPORT HID USAGE {1BC0} V0 40 | Battery: N/A, None. 41 | -------------------------------------------------------------------------------- /docs/devices/G304 Lightspeed Wireless Gaming Mouse 4074.txt: -------------------------------------------------------------------------------- 1 | solaar version 1.1.8 2 | 3 | 4 | 1: G304 Lightspeed Wireless Gaming Mouse 5 | Device path : /dev/hidraw6 6 | WPID : 4074 7 | Codename : G304 8 | Kind : mouse 9 | Protocol : HID++ 4.2 10 | Polling rate : 8 ms (125Hz) 11 | Serial number: B2D05D23 12 | Model ID: 407400000000 13 | Unit ID: EB490C63 14 | Bootloader: BOT 69.02.B0021 15 | Firmware: RQM 68.02.B0021 16 | The power switch is located on the base. 17 | Supports 27 HID++ 2.0 features: 18 | 0: ROOT {0000} V0 19 | 1: FEATURE SET {0001} V0 20 | 2: DEVICE FW VERSION {0003} V2 21 | Firmware: Bootloader BOT 69.02.B0021 4074452F3940 22 | Firmware: Firmware RQM 68.02.B0021 4074452F3940 23 | Unit ID: EB490C63 Model ID: 407400000000 Transport IDs: {'wpid': '4074'} 24 | 3: DEVICE NAME {0005} V0 25 | Name: G304 Lightspeed Wireless Gaming Mouse 26 | Kind: mouse 27 | 4: WIRELESS DEVICE STATUS {1D4B} V0 28 | 5: BATTERY STATUS {1000} V0 29 | Battery: 90%, discharging, next level 50%. 30 | 6: COLOR LED EFFECTS {8070} V6 31 | 7: ONBOARD PROFILES {8100} V0 32 | Device Mode: Host 33 | Onboard Profiles (saved): Disable 34 | Onboard Profiles : Disable 35 | 8: MOUSE BUTTON SPY {8110} V0 36 | 9: REPORT RATE {8060} V0 37 | Polling Rate (ms): 8 38 | Polling Rate (ms) (saved): 8 39 | Polling Rate (ms) : 8 40 | 10: MODE STATUS {8090} V1 41 | 11: DFUCONTROL SIGNED {00C2} V0 42 | 12: DEVICE RESET {1802} V0 internal, hidden 43 | 13: unknown:1803 {1803} V0 internal, hidden 44 | 14: CONFIG DEVICE PROPS {1806} V4 internal, hidden 45 | 15: unknown:1811 {1811} V0 internal, hidden 46 | 16: OOBSTATE {1805} V0 internal, hidden 47 | 17: unknown:1830 {1830} V0 internal, hidden 48 | 18: unknown:1890 {1890} V0 internal, hidden 49 | 19: unknown:1DF3 {1DF3} V0 internal, hidden 50 | 20: unknown:1E00 {1E00} V0 hidden 51 | 21: unknown:1EB0 {1EB0} V0 internal, hidden 52 | 22: unknown:1861 {1861} V0 internal, hidden 53 | 23: unknown:18B1 {18B1} V0 internal, hidden 54 | 24: unknown:1E22 {1E22} V0 internal, hidden 55 | 25: unknown:1801 {1801} V0 internal, hidden 56 | 26: ADJUSTABLE DPI {2201} V1 57 | Sensitivity (DPI) (saved): 2200 58 | Sensitivity (DPI) : 2200 59 | Battery: 90%, discharging, next level 50%. 60 | -------------------------------------------------------------------------------- /docs/devices/G305 Lightspeed Wireless Gaming Mouse 4074.text: -------------------------------------------------------------------------------- 1 | solaar version 1.1.10 2 | 3 | 1: G305 Lightspeed Wireless Gaming Mouse 4 | Device path : /dev/hidraw7 5 | WPID : 4074 6 | Codename : G305 7 | Kind : mouse 8 | Protocol : HID++ 4.2 9 | Polling rate : 1 ms (1000Hz) 10 | Serial number: ED5E9515 11 | Model ID: 407400000000 12 | Unit ID: F074D567 13 | Bootloader: BOT 69.02.B0021 14 | Firmware: RQM 68.02.B0021 15 | The power switch is located on the base. 16 | Supports 27 HID++ 2.0 features: 17 | 0: ROOT {0000} V0 18 | 1: FEATURE SET {0001} V0 19 | 2: DEVICE FW VERSION {0003} V2 20 | Firmware: Bootloader BOT 69.02.B0021 4074452F3940 21 | Firmware: Firmware RQM 68.02.B0021 4074452F3940 22 | Unit ID: F074D567 Model ID: 407400000000 Transport IDs: {'wpid': '4074'} 23 | 3: DEVICE NAME {0005} V0 24 | Name: G305 Lightspeed Wireless Gaming Mouse 25 | Kind: mouse 26 | 4: WIRELESS DEVICE STATUS {1D4B} V0 27 | 5: BATTERY STATUS {1000} V0 28 | Battery: 50%, discharging, next level 30%. 29 | 6: COLOR LED EFFECTS {8070} V6 30 | 7: ONBOARD PROFILES {8100} V0 31 | Device Mode: On-Board 32 | Onboard Profiles (saved): Enable 33 | Onboard Profiles : Enable 34 | 8: MOUSE BUTTON SPY {8110} V0 35 | 9: REPORT RATE {8060} V0 36 | Polling Rate (ms): 1 37 | Polling Rate (ms) (saved): 1 38 | Polling Rate (ms) : 1 39 | 10: MODE STATUS {8090} V1 40 | 11: DFUCONTROL SIGNED {00C2} V0 41 | 12: DEVICE RESET {1802} V0 internal, hidden 42 | 13: unknown:1803 {1803} V0 internal, hidden 43 | 14: CONFIG DEVICE PROPS {1806} V4 internal, hidden 44 | 15: unknown:1811 {1811} V0 internal, hidden 45 | 16: OOBSTATE {1805} V0 internal, hidden 46 | 17: unknown:1830 {1830} V0 internal, hidden 47 | 18: unknown:1890 {1890} V0 internal, hidden 48 | 19: unknown:1DF3 {1DF3} V0 internal, hidden 49 | 20: unknown:1E00 {1E00} V0 hidden 50 | 21: unknown:1EB0 {1EB0} V0 internal, hidden 51 | 22: unknown:1861 {1861} V0 internal, hidden 52 | 23: unknown:18B1 {18B1} V0 internal, hidden 53 | 24: unknown:1E22 {1E22} V0 internal, hidden 54 | 25: unknown:1801 {1801} V0 internal, hidden 55 | 26: ADJUSTABLE DPI {2201} V1 56 | Sensitivity (DPI) (saved): 1600 57 | Sensitivity (DPI) : 1600 58 | Battery: 50%, discharging, next level 30%. 59 | -------------------------------------------------------------------------------- /docs/devices/G502 Gaming Mouse C07D.text: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.5 2 | 3 | 1: G502 Gaming Mouse 4 | Device path : /dev/hidraw1 5 | USB id : 046d:C07D 6 | Codename : G502 7 | Kind : mouse 8 | Protocol : HID++ 4.2 9 | Polling rate : 1 ms (1000Hz) 10 | Serial number: 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: U 88.02.B0017 14 | Bootloader: BOT 14.00.B0007 15 | Hardware: 72 16 | Other: 17 | Supports 19 HID++ 2.0 features: 18 | 0: ROOT {0000} V0 19 | 1: FEATURE SET {0001} V0 20 | 2: FEATURE INFO {0002} V0 21 | 3: DEVICE FW VERSION {0003} V0 22 | Firmware: Firmware U 88.02.B0017 23 | Firmware: Bootloader BOT 14.00.B0007 24 | Firmware: Hardware 72 25 | Firmware: Other 26 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 27 | 4: DEVICE NAME {0005} V0 28 | Name: Tunable FPS Gaming Mouse G502 29 | Kind: mouse 30 | 5: LED CONTROL {1300} V0 31 | 6: unknown:18A1 {18A1} V0 internal, hidden 32 | 7: unknown:1E00 {1E00} V0 hidden 33 | 8: unknown:1E20 {1E20} V0 34 | 9: unknown:1EB0 {1EB0} V0 internal, hidden 35 | 10: ADJUSTABLE DPI {2201} V0 36 | Sensitivity (DPI) : 800 37 | 11: ANGLE SNAPPING {2230} V0 38 | 12: SURFACE TUNING {2240} V0 39 | 13: REPORT RATE {8060} V0 40 | Polling Rate (ms): 1 41 | Polling Rate (ms) : 1 42 | 14: ONBOARD PROFILES {8100} V0 43 | Device Mode: Host 44 | Onboard Profiles : Disable 45 | 15: MOUSE BUTTON SPY {8110} V0 46 | 16: unknown:1850 {1850} V0 internal, hidden 47 | 17: DFUCONTROL UNSIGNED {00C1} V0 48 | 18: unknown:1801 {1801} V0 internal, hidden 49 | Battery: N/A, None. 50 | -------------------------------------------------------------------------------- /docs/devices/G502 Proteus Spectrum Optical Mouse C332.txt: -------------------------------------------------------------------------------- 1 | solaar version 1.1.9 2 | 3 | 2: G502 Proteus Spectrum Optical Mouse 4 | Device path : /dev/hidraw4 5 | USB id : 046d:C332 6 | Codename : G502 Proteus Spectrum 7 | Kind : mouse 8 | Protocol : HID++ 4.2 9 | Polling rate : 1 ms (1000Hz) 10 | Serial number: 11 | Model ID: C33200000000 12 | Unit ID: 31374706 13 | Firmware: U1 03.02.B0012 14 | Bootloader: BOT 14.00.B0007 15 | Supports 20 HID++ 2.0 features: 16 | 0: ROOT {0000} V0 17 | 1: FEATURE SET {0001} V0 18 | 2: COLOR LED EFFECTS {8070} V3 19 | 3: DEVICE FW VERSION {0003} V1 20 | Firmware: Firmware U1 03.02.B0012 C332 21 | Firmware: Bootloader BOT 14.00.B0007 AABF 22 | Unit ID: 31374706 Model ID: C33200000000 Transport IDs: {'usbid': 'C332'} 23 | 4: DEVICE NAME {0005} V0 24 | Name: Tunable RGB Gaming Mouse G502 25 | Kind: mouse 26 | 5: LED CONTROL {1300} V0 27 | 6: unknown:18A1 {18A1} V0 internal, hidden 28 | 7: unknown:1E00 {1E00} V0 hidden 29 | 8: unknown:1E20 {1E20} V0 30 | 9: unknown:1EB0 {1EB0} V0 internal, hidden 31 | 10: ADJUSTABLE DPI {2201} V1 32 | Sensitivity (DPI) (saved): 7000 33 | Sensitivity (DPI) : 7000 34 | 11: ANGLE SNAPPING {2230} V0 35 | 12: SURFACE TUNING {2240} V0 36 | 13: REPORT RATE {8060} V0 37 | Polling Rate (ms): 1 38 | Polling Rate (ms) (saved): 1 39 | Polling Rate (ms) : 1 40 | 14: ONBOARD PROFILES {8100} V0 41 | Device Mode: On-Board 42 | Onboard Profiles (saved): Enable 43 | Onboard Profiles : Enable 44 | 15: MOUSE BUTTON SPY {8110} V0 45 | 16: unknown:1850 {1850} V0 internal, hidden 46 | 17: DFUCONTROL UNSIGNED {00C1} V0 47 | 18: unknown:1801 {1801} V0 internal, hidden 48 | 19: DEVICE RESET {1802} V0 internal, hidden 49 | Battery status unavailable. 50 | -------------------------------------------------------------------------------- /docs/devices/G502 SE Hero Gaming Mouse C08B.txt: -------------------------------------------------------------------------------- 1 | 1: G502 SE Hero Gaming Mouse 2 | Device path : /dev/hidraw7 3 | USB id : 046d:C08B 4 | Codename : G502 Hero 5 | Kind : mouse 6 | Protocol : HID++ 4.2 7 | Polling rate : 1 ms (1000Hz) 8 | Serial number: 9 | Model ID: C08B00000000 10 | Unit ID: 30324703 11 | Firmware: U1 27.03.B0010 12 | Bootloader: BOT 81.00.B0002 13 | Supports 19 HID++ 2.0 features: 14 | 0: ROOT {0000} 15 | 1: FEATURE SET {0001} 16 | 2: COLOR LED EFFECTS {8070} 17 | 3: DEVICE FW VERSION {0003} 18 | Firmware: Firmware U1 27.03.B0010 C08B 19 | Firmware: Bootloader BOT 81.00.B0002 AAE6 20 | Unit ID: 30324703 Model ID: C08B00000000 Transport IDs: {'usbid': 'C08B'} 21 | 4: DEVICE NAME {0005} 22 | Name: G502 HERO Gaming Mouse 23 | Kind: mouse 24 | 5: LED CONTROL {1300} 25 | 6: unknown:18A1 {18A1} internal, hidden 26 | 7: unknown:1E00 {1E00} hidden 27 | 8: unknown:1E22 {1E22} internal, hidden 28 | 9: unknown:1EB0 {1EB0} internal, hidden 29 | 10: ADJUSTABLE DPI {2201} 30 | Sensitivity (DPI) (saved): 2400 31 | Sensitivity (DPI) : 2400 32 | 11: REPORT RATE {8060} 33 | Polling Rate (ms): 1 34 | Polling Rate (ms) (saved): 1 35 | Polling Rate (ms) : 1 36 | 12: ONBOARD PROFILES {8100} 37 | Device Mode: Host 38 | 13: MOUSE BUTTON SPY {8110} 39 | 14: DFUCONTROL SIGNED {00C2} 40 | 15: unknown:1801 {1801} internal, hidden 41 | 16: DEVICE RESET {1802} internal, hidden 42 | 17: CONFIG DEVICE PROPS {1806} internal, hidden 43 | 18: unknown:18B1 {18B1} internal, hidden 44 | Battery status unavailable. 45 | -------------------------------------------------------------------------------- /docs/devices/G502 X C099.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.7 2 | 3 | 1: G502 X 4 | Device path : /dev/hidraw2 5 | USB id : 046d:C099 6 | Codename : G502 7 | Kind : mouse 8 | Protocol : HID++ 4.2 9 | Polling rate : 1 ms (1000Hz) 10 | Serial number: 11 | Model ID: C09900000000 12 | Unit ID: 42004C00 13 | Bootloader: BL1 59.00.B0002 14 | Firmware: U1 60.00.B0009 15 | Supports 22 HID++ 2.0 features: 16 | 0: ROOT {0000} V0 17 | 1: FEATURE SET {0001} V0 18 | 2: DEVICE FW VERSION {0003} V4 19 | Firmware: Bootloader BL1 59.00.B0002 AB17 20 | Firmware: Firmware U1 60.00.B0009 C099 21 | Unit ID: 42004C00 Model ID: C09900000000 Transport IDs: {'usbid': 'C099'} 22 | 3: DEVICE NAME {0005} V0 23 | Name: G502 X 24 | Kind: mouse 25 | 4: RESET {0020} V0 26 | 5: DFUCONTROL SIGNED {00C2} V0 27 | 6: unknown:1801 {1801} V0 internal, hidden, unknown:000010 28 | 7: DEVICE RESET {1802} V0 internal, hidden, unknown:000010 29 | 8: OOBSTATE {1805} V0 internal, hidden 30 | 9: CONFIG DEVICE PROPS {1806} V8 internal, hidden, unknown:000010 31 | 10: unknown:1875 {1875} V0 internal, hidden, unknown:000010 32 | 11: unknown:18A1 {18A1} V0 internal, hidden, unknown:000010 33 | 12: unknown:18B1 {18B1} V0 internal, hidden, unknown:000010 34 | 13: unknown:18C0 {18C0} V0 internal, hidden, unknown:000010 35 | 14: unknown:1E00 {1E00} V0 hidden 36 | 15: unknown:1E22 {1E22} V0 internal, hidden, unknown:000010 37 | 16: unknown:1EB0 {1EB0} V0 internal, hidden, unknown:000010 38 | 17: HIRES WHEEL {2121} V1 39 | Multiplier: 8 40 | Has invert: Normal wheel motion 41 | Has ratchet switch: Normal wheel mode 42 | High resolution mode 43 | HID notification 44 | Scroll Wheel Direction (saved): False 45 | Scroll Wheel Direction : False 46 | Scroll Wheel Resolution (saved): True 47 | Scroll Wheel Resolution : True 48 | Scroll Wheel Diversion (saved): False 49 | Scroll Wheel Diversion : False 50 | 18: ADJUSTABLE DPI {2201} V2 51 | Sensitivity (DPI) (saved): 1600 52 | Sensitivity (DPI) : 1600 53 | 19: REPORT RATE {8060} V0 54 | Polling Rate (ms): 1 55 | Polling Rate (ms) (saved): 1 56 | Polling Rate (ms) : 1 57 | 20: ONBOARD PROFILES {8100} V0 58 | Device Mode: On-Board 59 | Onboard Profiles (saved): Enable 60 | Onboard Profiles : Enable 61 | 21: MOUSE BUTTON SPY {8110} V0 62 | Battery status unavailable. 63 | -------------------------------------------------------------------------------- /docs/devices/G535 Wireless Gaming Headset 0AC4.txt: -------------------------------------------------------------------------------- 1 | solaar version 1.1.8 2 | 3 | USB and Bluetooth Devices 4 | 5 | 1: G535 Wireless Gaming Headset 6 | Device path : /dev/hidraw2 7 | USB id : 046d:0AC4 8 | Codename : G535 9 | Kind : ? 10 | Protocol : HID++ 4.2 11 | Serial number: 12 | Model ID: 000000000AC4 13 | Unit ID: FFFFFFFF 14 | Firmware: U1 90.00.B0200 15 | Supports 6 HID++ 2.0 features: 16 | 0: ROOT {0000} V0 17 | 1: FEATURE SET {0001} V0 18 | 2: DEVICE FW VERSION {0003} V2 19 | Firmware: Firmware U1 90.00.B0200 0AC4 20 | Unit ID: FFFFFFFF Model ID: 000000000AC4 Transport IDs: {'btid': '0000', 'btleid': '0000'} 21 | 3: DEVICE NAME {0005} V0 22 | Name: G535 Wireless Gaming Headset 23 | Kind: None 24 | 4: SIDETONE {8300} V0 25 | Sidetone (saved): 0 26 | Sidetone : 0 27 | 5: ADC MEASUREMENT {1F20} V0 28 | Battery: 60% 3920mV , discharging. 29 | Battery: 60% 3920mV , discharging. 30 | -------------------------------------------------------------------------------- /docs/devices/G703 Wired-Wireless Gaming Mouse 4070.txt: -------------------------------------------------------------------------------- 1 | 1: G703 Wired/Wireless Gaming Mouse 2 | Codename : G703 3 | Kind : mouse 4 | Wireless PID : 4070 5 | Protocol : HID++ 4.2 6 | Polling rate : 1 ms (1000Hz) 7 | Serial number: AFE674F7 8 | Firmware: MPM 14.02.B0007 9 | Bootloader: BOT 64.02.B0007 10 | Other: 11 | The power switch is located on the base. 12 | Supports 29 HID++ 2.0 features: 13 | 0: ROOT {0000} 14 | 1: FEATURE SET {0001} 15 | 2: DEVICE FW VERSION {0003} 16 | 3: DEVICE NAME {0005} 17 | 4: BATTERY VOLTAGE {1001} 18 | 5: unknown:1863 {1863} internal, hidden 19 | 6: unknown:18A1 {18A1} internal, hidden 20 | 7: unknown:1E00 {1E00} hidden 21 | 8: unknown:1E20 {1E20} 22 | 9: unknown:1EB0 {1EB0} internal, hidden 23 | 10: ADJUSTABLE DPI {2201} 24 | Sensitivity (DPI): 1600 25 | 11: ANGLE SNAPPING {2230} 26 | 12: SURFACE TUNING {2240} 27 | 13: REPORT RATE {8060} 28 | 14: ONBOARD PROFILES {8100} 29 | 15: MOUSE BUTTON SPY {8110} 30 | 16: unknown:1850 {1850} internal, hidden 31 | 17: DFUCONTROL SIGNED {00C2} 32 | 18: unknown:1801 {1801} internal, hidden 33 | 19: DEVICE RESET {1802} internal, hidden 34 | 20: unknown:1803 {1803} internal, hidden 35 | 21: unknown:1890 {1890} internal, hidden 36 | 22: unknown:1811 {1811} internal, hidden 37 | 23: LATENCY MONITORING {8111} 38 | 24: COLOR LED EFFECTS {8070} 39 | 25: unknown:1809 {1809} 40 | 26: unknown:1830 {1830} internal, hidden 41 | 27: OOBSTATE {1805} internal, hidden 42 | 28: CONFIG DEVICE PROPS {1806} internal, hidden 43 | Battery: 3807mV, discharging, average 44 | -------------------------------------------------------------------------------- /docs/devices/G733 Gaming Headset 0AB5.text: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.5 2 | 3 | 2: G733 Gaming Headset 4 | Device path : /dev/hidraw2 5 | USB id : 046d:0AB5 6 | Codename : G733 Headset 7 | Kind : headset 8 | Protocol : HID++ 4.2 9 | Serial number: 10 | Model ID: 0AB500000000 11 | Unit ID: FFFFFFFF 12 | Firmware: U1 37.00.B0131 13 | Supports 9 HID++ 2.0 features: 14 | 0: ROOT {0000} V0 15 | 1: FEATURE SET {0001} V0 16 | 2: DEVICE FW VERSION {0003} V2 17 | Firmware: Firmware U1 37.00.B0131 0AB5 18 | Unit ID: FFFFFFFF Model ID: 0AB500000000 Transport IDs: {'usbid': '0AB5'} 19 | 3: DEVICE NAME {0005} V0 20 | Name: G733 Gaming Headset 21 | Kind: None 22 | 4: COLOR LED EFFECTS {8070} V0 23 | 5: GKEY {8010} V0 24 | Divert G Keys (saved): True 25 | Divert G Keys : False 26 | 6: EQUALIZER {8310} V0 27 | 7: SIDETONE {8300} V0 28 | Sidetone (saved): 65 29 | Sidetone : 65 30 | 8: ADC MEASUREMENT {1F20} V0 31 | Battery status unavailable. 32 | Battery status unavailable. 33 | -------------------------------------------------------------------------------- /docs/devices/G733 Gaming Headset 0AFE.text: -------------------------------------------------------------------------------- 1 | solaar version 1.1.11 2 | 3 | G733 Gaming Headset 4 | Device path : /dev/hidraw3 5 | USB id : 046d:0AFE 6 | Codename : G733 Headset New 7 | Kind : headset 8 | Protocol : HID++ 4.2 9 | Serial number: 10 | Model ID: 0AFE00000000 11 | Unit ID: FFFFFFFF 12 | Firmware: U2 00.06 13 | Supports 9 HID++ 2.0 features: 14 | 0: ROOT {0000} V0 15 | 1: FEATURE SET {0001} V0 16 | 2: DEVICE FW VERSION {0003} V2 17 | Firmware: Firmware U2 00.06 0AFE 18 | Unit ID: FFFFFFFF Model ID: 0AFE00000000 Transport IDs: {'usbid': '0AFE'} 19 | 3: DEVICE NAME {0005} V0 20 | Name: G733 Gaming Headset 21 | Kind: None 22 | 4: COLOR LED EFFECTS {8070} V3 23 | LED Control (saved): Device 24 | LED Control : Device 25 | LEDs Logo (saved): !LEDEffectSetting {ID: 0x0} 26 | LEDs Logo : !LEDEffectSetting {ID: 0} 27 | LEDs Primary (saved): !LEDEffectSetting {ID: 0x1, color: 0x0, ramp: 0x0} 28 | LEDs Primary : !LEDEffectSetting {ID: 1, color: 0x10000, ramp: 0x0} 29 | 5: GKEY {8010} V0 30 | Divert G and M Keys (saved): False 31 | Divert G and M Keys : False 32 | 6: EQUALIZER {8310} V1 33 | Equalizer (saved): {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0} 34 | Equalizer : {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0} 35 | 7: SIDETONE {8300} V0 36 | Sidetone (saved): 0 37 | Sidetone : 0 38 | 8: ADC MEASUREMENT {1F20} V4 39 | Battery: 60% 3867mV , discharging. 40 | Power Management (saved): 0 41 | Power Management : 0 42 | Battery: 60% 3867mV , discharging. 43 | -------------------------------------------------------------------------------- /docs/devices/G815 Mechanical Keyboard C33F.txt: -------------------------------------------------------------------------------- 1 | solaar version 1.1.9 2 | 3 | 1: G815 Mechanical Keyboard 4 | Device path : /dev/hidraw2 5 | USB id : 046d:C33F 6 | Codename : G815 7 | Kind : keyboard 8 | Protocol : HID++ 4.2 9 | Polling rate : 1 ms (1000Hz) 10 | Serial number: 11 | Model ID: C33F00000000 12 | Unit ID: 35304716 13 | Bootloader: BOT 84.00.B0003 14 | Firmware: U1 31.02.B0018 15 | Other: 16 | Other: 17 | Other: 18 | Supports 24 HID++ 2.0 features: 19 | 0: ROOT {0000} V0 20 | 1: FEATURE SET {0001} V0 21 | 2: DEVICE FW VERSION {0003} V2 22 | Firmware: Bootloader BOT 84.00.B0003 AAEA 23 | Firmware: Firmware U1 31.02.B0018 C33F 24 | Firmware: Other 25 | Firmware: Other 26 | Firmware: Other 27 | Unit ID: 35304716 Model ID: C33F00000000 Transport IDs: {'usbid': 'C33F'} 28 | 3: DEVICE NAME {0005} V0 29 | Name: G815 RGB MECHANICAL GAMING KEYBOARD 30 | Kind: keyboard 31 | 4: CONFIG CHANGE {0020} V0 32 | 5: DFUCONTROL SIGNED {00C2} V0 33 | 6: DFU {00D0} V0 34 | 7: REPORT HID USAGE {1BC0} V0 35 | 8: KEYBOARD DISABLE BY USAGE {4522} V0 36 | 9: KEYBOARD LAYOUT 2 {4540} V0 37 | 10: GKEY {8010} V0 38 | Divert G Keys (saved): True 39 | Divert G Keys : False 40 | 11: MKEYS {8020} V0 41 | M-Key LEDs (saved): {M1:False, M2:False, M3:False} 42 | M-Key LEDs : {M1:False, M2:False, M3:False} 43 | 12: MR {8030} V0 44 | MR-Key LED (saved): False 45 | MR-Key LED : False 46 | 13: BRIGHTNESS CONTROL {8040} V0 47 | 14: REPORT RATE {8060} V0 48 | Polling Rate (ms): 1 49 | Polling Rate (ms) (saved): 1 50 | Polling Rate (ms) : 1 51 | 15: RGB EFFECTS {8071} V0 52 | 16: PER KEY LIGHTING V2 {8081} V2 53 | 17: ONBOARD PROFILES {8100} V0 54 | Device Mode: Host 55 | Onboard Profiles (saved): Disable 56 | Onboard Profiles : Disable 57 | 18: unknown:1801 {1801} V0 internal, hidden 58 | 19: DEVICE RESET {1802} V0 internal, hidden 59 | 20: CONFIG DEVICE PROPS {1806} V5 internal, hidden 60 | 21: unknown:18B0 {18B0} V0 internal, hidden 61 | 22: unknown:1E00 {1E00} V0 hidden 62 | 23: unknown:1EB0 {1EB0} V0 internal, hidden 63 | Battery status unavailable. 64 | -------------------------------------------------------------------------------- /docs/devices/G935 Gaming Headset 0A87.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.7 2 | 3 | 1: G935 Gaming Headset 4 | Device path : /dev/hidraw2 5 | USB id : 046d:0A87 6 | Codename : G935 Headset 7 | Kind : headset 8 | Protocol : HID++ 4.2 9 | Serial number: 10 | Model ID: 000000000A87 11 | Unit ID: FFFFFFFF 12 | Firmware: U1 29.00.B0012 13 | Supports 9 HID++ 2.0 features: 14 | 0: ROOT {0000} V0 15 | 1: FEATURE SET {0001} V0 16 | 2: DEVICE FW VERSION {0003} V2 17 | Firmware: Firmware U1 29.00.B0012 0A87 18 | Unit ID: FFFFFFFF Model ID: 000000000A87 19 | Transport IDs: {'btid': '0000', 'btleid': '0000'} 20 | 3: DEVICE NAME {0005} V0 21 | Name: G935 Gaming Headset 22 | Kind: None 23 | 4: COLOR LED EFFECTS {8070} V0 24 | 5: GKEY {8010} V0 25 | Divert G Keys (saved): False 26 | Divert G Keys : False 27 | 6: EQUALIZER {8310} V0 28 | 7: SIDETONE {8300} V0 29 | Sidetone (saved): 0 30 | Sidetone : 0 31 | 8: ADC MEASUREMENT {1F20} V0 32 | Battery status unavailable. 33 | Battery status unavailable. 34 | -------------------------------------------------------------------------------- /docs/devices/Illuminated Keyboard C318.txt: -------------------------------------------------------------------------------- 1 | solaar version 1.1.8-29-g0ae14c7 2 | 3 | 1: Illuminated Keyboard 4 | Device path : /dev/hidraw1 5 | USB id : 046d:C318 6 | Codename : Illuminated 7 | Kind : keyboard 8 | Protocol : HID++ 1.0 9 | Serial number: 10 | Firmware: 55.01.B0025 11 | Notifications: (none). 12 | Features: (none) 13 | Battery status unavailable. 14 | -------------------------------------------------------------------------------- /docs/devices/Illuminated Living-Room Keyboard K830 4032.txt: -------------------------------------------------------------------------------- 1 | # Provided by Mikkel Munch Mortensen 2 | 3 | (solaar) 4 | 3: Illuminated Living-Room Keyboard K830 5 | Codename : K830 6 | Kind : keyboard 7 | Wireless PID : 4032 8 | Protocol : HID++ 4.1 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 9F7C6FD7 11 | Firmware: RQK 56.00.B0020 12 | The power switch is located on the edge of top right corner. 13 | Supports 27 HID++ 2.0 features: 14 | 0: ROOT {0000} 15 | 1: FEATURE SET {0001} 16 | 2: DEVICE FW VERSION {0003} 17 | 3: DEVICE NAME {0005} 18 | 4: WIRELESS DEVICE STATUS {1D4B} 19 | 5: unknown:0020 {0020} 20 | 6: BATTERY STATUS {1000} 21 | 7: BACKLIGHT {1981} 22 | 8: unknown:1B04 {1B04} 23 | 9: unknown:2005 {2005} 24 | 10: NEW FN INVERSION {40A2} 25 | 11: ENCRYPTION {4100} 26 | 12: unknown:4521 {4521} 27 | 13: TOUCHPAD RAW XY {6100} hidden 28 | 14: unknown:6501 {6501} 29 | 15: unknown:00C1 {00C1} 30 | 16: unknown:1811 {1811} internal, hidden 31 | 17: unknown:1830 {1830} internal, hidden 32 | 18: unknown:1890 {1890} internal, hidden 33 | 19: unknown:18A0 {18A0} internal, hidden 34 | 20: unknown:1DF3 {1DF3} internal, hidden 35 | 21: unknown:1E00 {1E00} hidden 36 | 22: unknown:1EB0 {1EB0} internal, hidden 37 | 23: unknown:1861 {1861} internal, hidden 38 | 24: unknown:1A20 {1A20} internal, hidden 39 | 25: unknown:18B0 {18B0} internal, hidden 40 | 26: unknown:1F07 {1F07} internal, hidden 41 | Battery: 50%, discharging. 42 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C539.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | Lightspeed Receiver 4 | Device path : /dev/hidraw8 5 | USB id : 046d:C539 6 | Serial : C1469DD4 7 | Firmware : 39.06.B0040 8 | Bootloader : 02.09 9 | Other : AA.BE 10 | Has 1 paired device(s) out of a maximum of 1. 11 | Notifications: wireless, software present (0x000900) 12 | Device activity counters: (empty) 13 | 14 | Seen paired with G502 Gaming Mouse 407F 15 | Seen paired with G Pro Wireless Gaming Mouse 4079 16 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C53A.txt: -------------------------------------------------------------------------------- 1 | Lightspeed Receiver 2 | Device path : /dev/hidraw9 3 | USB id : 046d:C53A 4 | Serial : 5B2B9A98 5 | Firmware : 40.03.B0014 6 | Bootloader : 02.09 7 | Other : AA.CA 8 | Has 2 paired device(s) out of a maximum of 1. 9 | Notifications: wireless, software present (0x000900) 10 | Device activity counters: (empty) 11 | 12 | Seen as part of a G PowerPlay Wireless Mouse Pad with a Candy companion chip paired a number 7 13 | Seen paired with a G502 Gaming Mouse 407F. 14 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C53D.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.3 2 | 3 | Lightspeed Receiver 4 | Device path : /dev/hidraw2 5 | USB id : 046d:C53D 6 | Serial : C271A999 7 | Firmware : 43.01.B0009 8 | Bootloader : 02.10 9 | Other : AA.D2 10 | Has 1 paired device(s) out of a maximum of 1. 11 | Notifications: wireless, software present (0x000900) 12 | Device activity counters: (empty) 13 | 14 | Seen paired with G613 Wireless Mechanical Gaming Keyboard 4065 15 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C53F.txt: -------------------------------------------------------------------------------- 1 | Lightspeed Receiver 2 | Device path : /dev/hidraw3 3 | USB id : 046d:C53F 4 | Serial : 5 | Firmware : 44.01.B0005 6 | Bootloader : 00.02 7 | Other : AA.DE 8 | Has 0 paired device(s) out of a maximum of 1. 9 | Notifications: wireless, software present (0x000900) 10 | Device activity counters: (empty) 11 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C541.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.1 2 | 3 | Lightspeed Receiver 4 | Device path : /dev/hidraw4 5 | USB id : 046d:C541 6 | Serial : 18E8EC31 7 | Firmware : 01.01.B0027 8 | Bootloader : 01.27 9 | Other : B9.BC 10 | Has 1 paired device(s) out of a maximum of 1. 11 | Notifications: wireless, software present (0x000900) 12 | Device activity counters: (empty) 13 | 14 | Seen paired with G915 WIRELESS RGB Mechanical Gaming Keyboard 407E 15 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C545.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | Lightspeed Receiver 4 | Device path : /dev/hidraw5 5 | USB id : 046d:C545 6 | Serial : AD1567FD 7 | Firmware : 02.01.B0006 8 | Bootloader : 00.01 9 | Other : 3D.88 10 | Has 1 paired device(s) out of a maximum of 2. 11 | Notifications: wireless, software present (0x000900) 12 | Device activity counters: 1=22 13 | 14 | Seen paired with G915 TKL LIGHTSPEED Wireless RGB Mechanical Gaming Keyboard 408E 15 | -------------------------------------------------------------------------------- /docs/devices/Lightspeed Receiver C547.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.3 2 | 3 | Lightspeed Receiver 4 | Device path : /dev/hidraw6 5 | USB id : 046d:C547 6 | Serial : 9B341CD1 7 | Firmware : 04.02.B0009 8 | Bootloader : 00.05 9 | Other : F3.24 10 | Has 1 paired device(s) out of a maximum of 2. 11 | Notifications: wireless, software present (0x000900) 12 | Device activity counters: 1=171 13 | 14 | Seen paired with the PRO X Wireless 4093 15 | -------------------------------------------------------------------------------- /docs/devices/Logitech PRO X Wireless Gaming Headset 0ABA.txt: -------------------------------------------------------------------------------- 1 | 2 | 1: Logitech PRO X Wireless Gaming Headset 3 | Device path : /dev/hidraw2 4 | USB id : 046d:0ABA 5 | Codename : PRO Headset 6 | Kind : headset 7 | Protocol : HID++ 4.2 8 | Serial number: 9 | Model ID: 000000000ABA 10 | Unit ID: FFFFFFFF 11 | Firmware: U1 12.01.B0203 12 | Supports 6 HID++ 2.0 features: 13 | 0: ROOT {0000} 14 | 1: FEATURE SET {0001} 15 | 2: DEVICE FW VERSION {0003} 16 | Firmware: Firmware U1 12.01.B0203 0ABA 17 | Unit ID: FFFFFFFF Model ID: 000000000ABA Transport IDs: {'btid': '0000', 'btleid': '0000'} 18 | 3: DEVICE NAME {0005} 19 | Name: PRO X Wireless Gaming Headset 20 | Kind: None 21 | 4: EQUALIZER {8310} 22 | 5: SIDETONE {8300} 23 | 6: ADC MEASUREMENT {1F20} 24 | Battery status unavailable. 25 | 26 | 27 | 2: Logitech PRO X Wireless Gaming Headset 28 | Device path : /dev/hidraw5 29 | USB id : 046d:0ABA 30 | Codename : PRO Headset 31 | Kind : headset 32 | Protocol : HID++ 4.2 33 | Serial number: 34 | Model ID: 000000000ABA 35 | Unit ID: FFFFFFFF 36 | Firmware: U1 12.01.B0203 37 | Supports 6 HID++ 2.0 features: 38 | 0: ROOT {0000} 39 | 1: FEATURE SET {0001} 40 | 2: DEVICE FW VERSION {0003} 41 | Firmware: Firmware U1 12.01.B0203 0ABA 42 | Unit ID: FFFFFFFF Model ID: 000000000ABA Transport IDs: {'btid': '0000', 'btleid': '0000'} 43 | 3: DEVICE NAME {0005} 44 | Name: PRO X Wireless Gaming Headset 45 | Kind: None 46 | 4: EQUALIZER {8310} 47 | 5: SIDETONE {8300} 48 | Sidetone (saved): 0 49 | Sidetone : 0 50 | Battery status unavailable. 51 | -------------------------------------------------------------------------------- /docs/devices/Marathon Mouse M705 101B.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.5 2 | 3 | 1: Marathon Mouse M705 (M-R0009) 4 | Device path : /dev/hidraw1 5 | WPID : 101B 6 | Codename : M705 (M-R0009) 7 | Kind : mouse 8 | Protocol : HID++ 1.0 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 23691D3D 11 | Firmware: 17.01.B0017 12 | Bootloader: 02.06 13 | Other: 00.04 14 | The power switch is located on the base. 15 | Notifications: battery status (0x100000). 16 | Features: special buttons, scroll accel (0x420000) 17 | Battery: 65%, discharging. 18 | 19 | registers: 20 | 21 | # writing 0x10 in this register will generate an event 22 | # 10 02 0Dxx yyzz00 23 | # where 0D happens to be the battery register number 24 | # xx is the battery charge 25 | # yy, zz ? 26 | << ( 0.001) [10 02 8100 000000] '\x10\x02\x81\x00\x00\x00\x00' 27 | >> ( 1.132) [10 02 8100 100000] '\x10\x02\x81\x00\x10\x00\x00' 28 | 29 | # smooth scroll - possible values 30 | # - 00 (off) 31 | # - 02 ?, apparently off as well, default value at power-on 32 | # - 0x40 (on) 33 | << ( 2.005) [10 02 8101 000000] '\x10\x02\x81\x01\x00\x00\x00' 34 | >> ( 2.052) [10 02 8101 020000] '\x10\x02\x81\x01\x02\x00\x00' 35 | 36 | # battery status: percentage full, ?, ? 37 | << ( 14.835) [10 02 810D 000000] '\x10\x02\x81\r\x00\x00\x00' 38 | >> ( 14.847) [10 02 810D 644734] '\x10\x02\x81\rdG4' 39 | 40 | # accepts mask 0xF1 41 | # setting 0x10 turns off the movement events (but buttons still work) 42 | << ( 221.495) [10 02 81D0 000000] '\x10\x02\x81\xd0\x00\x00\x00' 43 | >> ( 221.509) [10 02 81D0 000000] '\x10\x02\x81\xd0\x00\x00\x00' 44 | 45 | # appears to be read-only? 46 | << ( 223.527) [10 02 81D2 000000] '\x10\x02\x81\xd2\x00\x00\x00' 47 | >> ( 223.540) [10 02 81D2 000003] '\x10\x02\x81\xd2\x00\x00\x03' 48 | 49 | # appears to be read-only? 50 | << ( 225.557) [10 02 81D4 000000] '\x10\x02\x81\xd4\x00\x00\x00' 51 | >> ( 225.571) [10 02 81D4 000004] '\x10\x02\x81\xd4\x00\x00\x04' 52 | 53 | # read-only, 01-04 firmware info 54 | << ( 259.270) [10 02 81F1 000000] '\x10\x02\x81\xf1\x00\x00\x00' 55 | >> ( 259.283) [10 02 8F81 F10300] '\x10\x02\x8f\x81\xf1\x03\x00' 56 | 57 | # writing 01 here will trigger an avalanche of events, most likely 58 | # raw input from the mouse; disable by writing 00 59 | << ( 261.300) [10 02 81F3 000000] '\x10\x02\x81\xf3\x00\x00\x00' 60 | >> ( 261.315) [10 02 81F3 000000] '\x10\x02\x81\xf3\x00\x00\x00' 61 | -------------------------------------------------------------------------------- /docs/devices/Nano Receiver C52F.txt: -------------------------------------------------------------------------------- 1 | Nano Receiver 2 | Device path : /dev/hidraw3 3 | USB id : 046d:c52f 4 | Serial : 6D0342C5 5 | Firmware : 30.00.B0009 6 | Has 1 paired device(s) out of a maximum of 1. 7 | Notifications: (none) 8 | 9 | Seen with Marathon Mouse M705 10 | -------------------------------------------------------------------------------- /docs/devices/Nano Receiver C534.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4rc2 2 | 3 | Nano Receiver 4 | Device path : /dev/hidraw1 5 | USB id : 046d:C534 6 | Serial : None 7 | Firmware : 29.01.B0016 8 | Has 2 paired device(s) out of a maximum of 2. 9 | Has 18 successful pairing(s) remaining. 10 | Notifications: wireless, software present (0x000900) 11 | 12 | 13 | Seen paired with Wireless Keyboard 4075 and Wireless Mouse M185 new 4054 14 | -------------------------------------------------------------------------------- /docs/devices/Nano Receiver C535.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.5 2 | 3 | Nano Receiver 4 | Device path : /dev/hidraw5 5 | USB id : 046d:C535 6 | Serial : 1F3F94FC 7 | Firmware : 31.00.B0001 8 | Has 1 paired device(s) out of a maximum of 1. 9 | Has 39 successful pairing(s) remaining. 10 | Notifications: wireless, software present (0x000900) 11 | -------------------------------------------------------------------------------- /docs/devices/Number Pad N545 2006.txt: -------------------------------------------------------------------------------- 1 | solaar version 1.1.8 2 | 3 | 3: Number Pad N545 4 | Device path : /dev/hidraw3 5 | WPID : 2006 6 | Codename : N545 7 | Kind : numpad 8 | Protocol : HID++ 1.0 9 | Polling rate : 20 ms (50Hz) 10 | Serial number: 900A4D98 11 | Firmware: 13.00.B0037 12 | Bootloader: 02.03 13 | Other: 00.01 14 | The power switch is located on the base. 15 | Notifications: battery status (0x100000). 16 | Features: (none) 17 | Battery: full, discharging. 18 | -------------------------------------------------------------------------------- /docs/devices/PRO X 2 40A9.text: -------------------------------------------------------------------------------- 1 | solaar version 1.1.10 2 | 3 | Receiver 4 | Device path : /dev/hidraw3 5 | USB id : 046d:C54D 6 | Serial : 8FF3BF7B 7 | Firmware : 07.00.B0008 8 | Bootloader : 00.08 9 | Other : C1.53 10 | Has 1 paired device(s) out of a maximum of 2. 11 | Notifications: (none) 12 | Device activity counters: 1=51 13 | 14 | 1: PRO X 2 15 | Device path : None 16 | WPID : 40A9 17 | Codename : PRO X 2 18 | Kind : mouse 19 | Protocol : HID++ 4.2 20 | Polling rate : 8 ms (125Hz) 21 | Serial number: 22 | Model ID: 40A9C09B0000 23 | Unit ID: 24 | Bootloader: BL1 71.00.B0012 25 | Firmware: MPM 32.00.B0012 26 | Supports 32 HID++ 2.0 features: 27 | 0: ROOT {0000} V0 28 | 1: FEATURE SET {0001} V0 29 | 2: DEVICE FW VERSION {0003} V4 30 | Firmware: Bootloader BL1 71.00.B0012 AB1CDBC0A7D9 31 | Firmware: Firmware MPM 32.00.B0012 40A9DBC0A7D9 32 | Unit ID: Model ID: 40A9C09B0000 Transport IDs: {'wpid': '40A9', 'usbid': 'C09B'} 33 | 3: DEVICE NAME {0005} V2 34 | Name: PRO X 2 35 | Kind: mouse 36 | 4: WIRELESS DEVICE STATUS {1D4B} V0 37 | 5: CONFIG CHANGE {0020} V0 38 | 6: UNIFIED BATTERY {1004} V3 39 | Battery: 96%, discharging. 40 | 7: XY STATS {2250} V1 41 | 8: WHEEL STATS {2251} V0 42 | 9: unknown:2202 {2202} V0 EXTENDED_ADJUSTABLE_DPI 43 | 10: MODE STATUS {8090} V2 44 | 11: unknown:8061 {8061} V0 EXTENDED_ADJUSTABLE_REPORT_RATE 45 | 12: ONBOARD PROFILES {8100} V0 46 | Device Mode: On-Board 47 | Onboard Profiles (saved): Enable 48 | Onboard Profiles : Enable 49 | 13: MOUSE BUTTON SPY {8110} V0 50 | 14: unknown:1500 {1500} V0 FORCE_PAIRING 51 | 15: unknown:1801 {1801} V0 internal, hidden, unknown:000010 52 | 16: DEVICE RESET {1802} V0 internal, hidden, unknown:000010 53 | 17: unknown:1803 {1803} V0 internal, hidden, unknown:000010 54 | 18: CONFIG DEVICE PROPS {1806} V8 internal, hidden, unknown:000010 55 | 19: unknown:1817 {1817} V0 internal, hidden, unknown:000010 56 | 20: OOBSTATE {1805} V0 internal, hidden 57 | 21: unknown:1830 {1830} V0 internal, hidden, unknown:000010 58 | 22: unknown:1875 {1875} V0 internal, hidden, unknown:000010 59 | 23: unknown:1861 {1861} V1 internal, hidden, unknown:000010 60 | 24: unknown:1890 {1890} V9 internal, hidden, unknown:000008 61 | 25: unknown:18A1 {18A1} V0 internal, hidden, unknown:000010 62 | 26: unknown:1E00 {1E00} V0 hidden 63 | 27: unknown:1E02 {1E02} V0 internal, hidden 64 | 28: unknown:1E22 {1E22} V1 internal, hidden, unknown:000010 65 | 29: unknown:1602 {1602} V0 66 | 30: unknown:1EB0 {1EB0} V0 internal, hidden, unknown:000010 67 | 31: unknown:18B1 {18B1} V0 internal, hidden, unknown:000010 68 | Battery: 96%, discharging. 69 | -------------------------------------------------------------------------------- /docs/devices/PRO X Wireless 4093.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.3 2 | 3 | 1: PRO X Wireless 4 | Device path : None 5 | WPID : 4093 6 | Codename : PRO X 7 | Kind : mouse 8 | Protocol : HID++ 4.2 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 42F42E12 11 | Model ID: 4093C0940000 12 | Unit ID: 42F42E12 13 | Bootloader: BL1 25.00.B0013 14 | Other: 15 | Firmware: MPM 25.01.B0018 16 | Supports 28 HID++ 2.0 features: 17 | 0: ROOT {0000} 18 | 1: FEATURE SET {0001} 19 | 2: DEVICE FW VERSION {0003} 20 | Firmware: Bootloader BL1 25.00.B0013 AB00BE657A82 21 | Firmware: Other 22 | Firmware: Firmware MPM 25.01.B0018 4093FE92436C 23 | Unit ID: 42F42E12 Model ID: 4093C0940000 Transport IDs: {'wpid': '4093', 'usbid': 'C094'} 24 | 3: DEVICE NAME {0005} 25 | Name: PRO X Wireless 26 | Kind: mouse 27 | 4: WIRELESS DEVICE STATUS {1D4B} 28 | 5: RESET {0020} 29 | 6: UNIFIED BATTERY {1004} 30 | 7: COLOR LED EFFECTS {8070} internal, hidden 31 | 8: ONBOARD PROFILES {8100} 32 | Device Mode: Host 33 | Onboard Profiles (saved): Disable 34 | Onboard Profiles : Disable 35 | 9: MOUSE BUTTON SPY {8110} 36 | 10: REPORT RATE {8060} 37 | Polling Rate (ms): 1 38 | Polling Rate (ms) (saved): 1 39 | Polling Rate (ms) : 1 40 | 11: ADJUSTABLE DPI {2201} 41 | Sensitivity (DPI) (saved): 1000 42 | Sensitivity (DPI) : 1000 43 | 12: unknown:1500 {1500} 44 | 13: DEVICE RESET {1802} internal, hidden 45 | 14: unknown:1803 {1803} internal, hidden 46 | 15: CONFIG DEVICE PROPS {1806} internal, hidden 47 | 16: unknown:1811 {1811} internal, hidden 48 | 17: OOBSTATE {1805} internal, hidden 49 | 18: unknown:1830 {1830} internal, hidden 50 | 19: unknown:1890 {1890} internal, hidden 51 | 20: unknown:1891 {1891} internal, hidden 52 | 21: unknown:18A1 {18A1} internal, hidden 53 | 22: unknown:1801 {1801} internal, hidden 54 | 23: unknown:18B1 {18B1} internal, hidden 55 | 24: unknown:1E00 {1E00} hidden 56 | 25: unknown:1EB0 {1EB0} internal, hidden 57 | 26: unknown:1863 {1863} internal, hidden 58 | 27: unknown:1E22 {1E22} internal, hidden 59 | Battery: 76%, discharging. 60 | -------------------------------------------------------------------------------- /docs/devices/Rechargeable Trackpad T651 B00C.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.7 2 | 3 | 1: Rechargeable Trackpad T651 4 | Device path : /dev/hidraw9 5 | USB id : 046d:B00C 6 | Codename : Rechargeable 7 | Kind : touchpad 8 | Protocol : HID++ 2.0 9 | Serial number: 10 | Model ID: 000000000000 11 | Unit ID: 00000000 12 | Firmware: RBM 05.00.B0026 13 | Other: 14 | Supports 9 HID++ 2.0 features: 15 | 0: ROOT {0000} V0 16 | 1: FEATURE SET {0001} V0 17 | 2: FEATURE INFO {0002} V0 18 | 3: DEVICE FW VERSION {0003} V0 19 | Firmware: Firmware RBM 05.00.B0026 B00C 20 | Firmware: Other 21 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 22 | 4: DEVICE NAME {0005} V0 23 | Name: Rechargeable Trackpad T651 24 | Kind: touchpad 25 | 5: unknown:1E00 {1E00} V0 hidden 26 | 6: GENERIC TEST {1800} V0 internal, hidden 27 | 7: BATTERY STATUS {1000} V0 28 | Battery: 90%, discharging, next level 70%. 29 | 8: TOUCHPAD RAW XY {6100} V0 30 | Battery: 90%, discharging, next level 70%. 31 | -------------------------------------------------------------------------------- /docs/devices/Unifying Receiver C52B.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | Unifying Receiver 4 | Device path : /dev/hidraw0 5 | USB id : 046d:C52B 6 | Serial : E0662192 7 | Firmware : 24.11.B0036 8 | Bootloader : 02.09 9 | Other : AA.AC 10 | Has 2 paired device(s) out of a maximum of 6. 11 | Notifications: wireless, software present (0x000900) 12 | Device activity counters: 1=225, 2=132 13 | -------------------------------------------------------------------------------- /docs/devices/Wireless Illuminated Keyboard K800 2010.txt: -------------------------------------------------------------------------------- 1 | 2: Wireless Illuminated Keyboard K800 2 | Codename : K800 3 | Kind : keyboard 4 | Wireless PID : 2010 5 | Protocol : HID++ 1.0 6 | Polling rate : 20 ms (50Hz) 7 | Serial number: FFC65665 8 | Firmware: 22.01.B0019 9 | Bootloader: 02.01 10 | Other: 00.07 11 | The power switch is located on the top right corner. 12 | Notifications: battery status (0x100000). 13 | Battery: full, discharging. 14 | 15 | 16 | # 0x00 - Enabled Notifications. rw (see HID++ 1.0 spec) 17 | << ( 0.055) [10 02 8100 000000] '\x10\x02\x81\x00\x00\x00\x00' 18 | >> ( 0.084) [10 02 8100 000000] '\x10\x02\x81\x00\x00\x00\x00' 19 | 20 | # 0x01 - Keyboard hand detection. rw, last param is 00 when hand detection is 21 | # enabled, 30 when disabled. (when enabled, keyboard will light up if not 22 | # already when hovering over the front) 23 | << ( 1.085) [10 02 8101 000000] '\x10\x02\x81\x01\x00\x00\x00' 24 | >> ( 1.114) [10 02 8101 000000] '\x10\x02\x81\x01\x00\x00\x00' 25 | 26 | # 0x07 - Battery status (3 = one bar; 1 = red/critical; 5=two bars; 7=three 27 | # bars/full. Second returned param is 25 when keyboard is charging ) 28 | << ( 7.327) [10 02 8107 000000] '\x10\x02\x81\x07\x00\x00\x00' 29 | >> ( 7.368) [10 02 8107 030000] '\x10\x02\x81\x07\x03\x00\x00' 30 | 31 | # 0x09 - F key function. rw (read: status, set/get: 00 01 00 means swap 32 | # functions, 00 00 00 means do not swap functions) 33 | << ( 9.411) [10 02 8109 000000] '\x10\x02\x81\t\x00\x00\x00' 34 | >> ( 9.440) [10 02 8109 000000] '\x10\x02\x81\t\x00\x00\x00' 35 | 36 | # 0x17 - Illumination info r/w. Last param: 02 to disable backlight, 01 to 37 | # enable backlight 38 | << ( 24.965) [10 02 8117 000000] '\x10\x02\x81\x17\x00\x00\x00' 39 | >> ( 24.988) [10 02 8117 3C0001] '\x10\x02\x81\x17<\x00\x01' 40 | 41 | # 0x51 - ? 42 | << ( 99.294) [10 02 8151 000000] '\x10\x02\x81Q\x00\x00\x00' 43 | >> ( 99.543) [10 02 8151 000000] '\x10\x02\x81Q\x00\x00\x00' 44 | 45 | # 0x54 - ? 46 | << ( 103.046) [10 02 8154 000000] '\x10\x02\x81T\x00\x00\x00' 47 | >> ( 103.295) [10 02 8154 FF0000] '\x10\x02\x81T\xff\x00\x00' 48 | 49 | # 0xD0 - ? 50 | << ( 253.860) [10 02 81D0 000000] '\x10\x02\x81\xd0\x00\x00\x00' 51 | >> ( 253.883) [10 02 81D0 000000] '\x10\x02\x81\xd0\x00\x00\x00' 52 | 53 | # 0xF1 - Version info (params 0n 00 00 where n is 1..4) 54 | << ( 289.991) [10 02 81F1 000000] '\x10\x02\x81\xf1\x00\x00\x00' 55 | >> ( 290.032) [10 02 8F81 F10300] '\x10\x02\x8f\x81\xf1\x03\x00' 56 | 57 | # 0xF3 - ? 58 | << ( 292.075) [10 02 81F3 000000] '\x10\x02\x81\xf3\x00\x00\x00' 59 | >> ( 292.116) [10 02 81F3 000000] '\x10\x02\x81\xf3\x00\x00\x00' 60 | 61 | # 0x0F - This changes, the last commented line was observed in an earlier run 62 | << ( 17.728) [10 02 830F 000000] '\x10\x02\x83\x0f\x00\x00\x00' 63 | >> ( 17.976) [11 02 830F FFFB00000240025C000000000FF90080] '\x11\x02\x83\x0f\xff\xfb\x00\x00\x02@\x02\\\x00\x00\x00\x00\x0f\xf9\x00\x80' 64 | #>> ( 17.999) [11 02 830F FFFC007F0243025D000000000FF60080] '\x11\x02\x83\x0f\xff\xfc\x00\x7f\x02C\x02]\x00\x00\x00\x00\x0f\xf6\x00\x80' 65 | 66 | # See also https://git.lekensteyn.nl/ltunify/tree/registers.txt for a verbose 67 | # meaning of registers and params. 68 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard 4075.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4rc2 2 | 3 | 1: Wireless Keyboard 4 | Device path : /dev/hidraw2 5 | WPID : 4075 6 | Codename : 7 | Kind : keyboard 8 | Protocol : HID++ 4.5 9 | Polling rate : 20 ms (50Hz) 10 | Serial number: 00000000 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQK 71.00.B0002 14 | Supports 19 HID++ 2.0 features: 15 | 0: ROOT {0000} 16 | 1: FEATURE SET {0001} 17 | 2: DEVICE FW VERSION {0003} 18 | Firmware: Firmware RQK 71.00.B0002 4075 19 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 20 | 3: DEVICE NAME {0005} 21 | Name: Wireless Keyboard 22 | Kind: keyboard 23 | 4: RESET {0020} 24 | 5: BATTERY STATUS {1000} 25 | Battery: 30%, discharging, next level 5%. 26 | 6: REPROG CONTROLS V4 {1B04} 27 | Key/Button Diversion (saved): {Calculator:Regular, Mail:Regular, My Home:Regular, Search:Regular} 28 | Key/Button Diversion : {Calculator:Regular, Mail:Regular, My Home:Regular, Search:Regular} 29 | 7: WIRELESS DEVICE STATUS {1D4B} 30 | 8: NEW FN INVERSION {40A2} 31 | Fn-swap: disabled 32 | Fn-swap default: disabled 33 | Swap Fx function (saved): False 34 | Swap Fx function : False 35 | 9: ENCRYPTION {4100} 36 | 10: LOCK KEY STATE {4220} 37 | 11: KEYBOARD DISABLE KEYS {4521} 38 | Disable keys (saved): {Caps Lock:False, Num Lock:False, Scroll Lock:False, Insert:False, Win:False} 39 | Disable keys : {Caps Lock:False, Num Lock:False, Scroll Lock:False, Insert:False, Win:False} 40 | 12: unknown:1810 {1810} internal, hidden 41 | 13: unknown:1830 {1830} internal, hidden 42 | 14: unknown:1890 {1890} internal, hidden 43 | 15: unknown:18A0 {18A0} internal, hidden 44 | 16: unknown:18B0 {18B0} internal, hidden 45 | 17: unknown:1DF3 {1DF3} internal, hidden 46 | 18: unknown:1E00 {1E00} hidden 47 | Has 4 reprogrammable keys: 48 | 0: My Home , default: HomePage => HomePage 49 | is FN, FN sensitive, reprogrammable, divertable, pos:1, group:0, group mask:empty 50 | reporting: default 51 | 1: Mail , default: Email => Email 52 | is FN, FN sensitive, reprogrammable, divertable, pos:2, group:0, group mask:empty 53 | reporting: default 54 | 2: Search , default: Search Files => Search Files 55 | is FN, FN sensitive, reprogrammable, divertable, pos:3, group:0, group mask:empty 56 | reporting: default 57 | 3: Calculator , default: Calculator => Calculator 58 | is FN, FN sensitive, reprogrammable, divertable, pos:4, group:0, group mask:empty 59 | reporting: default 60 | Battery: 30%, discharging, next level 5%. 61 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard Dell KB714 4015.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.6rc4 2 | 3 | 4: Wireless Keyboard Dell KB714 4 | Device path : /dev/hidraw6 5 | WPID : 4015 6 | Codename : Dell KB714 7 | Kind : keyboard 8 | Protocol : HID++ 3.0 9 | Polling rate : 20 ms (50Hz) 10 | Serial number: C0A37A58 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQK 51.00.B0005 14 | Supports 19 HID++ 2.0 features: 15 | 0: ROOT {0000} V0 16 | 1: FEATURE SET {0001} V0 17 | 2: DEVICE FW VERSION {0003} V0 18 | Firmware: Firmware RQK 51.00.B0005 4015 19 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 20 | 3: DEVICE NAME {0005} V0 21 | Name: Wireless Keyboard Dell KB714 22 | Kind: keyboard 23 | 4: BATTERY STATUS {1000} V0 24 | Battery: 90%, discharging, next level 5%. 25 | 5: WIRELESS DEVICE STATUS {1D4B} V0 26 | 6: ENCRYPTION {4100} V0 27 | 7: KEYBOARD LAYOUT {4520} V0 28 | 8: unknown:1810 {1810} V0 internal, hidden 29 | 9: unknown:1830 {1830} V0 internal, hidden 30 | 10: unknown:1860 {1860} V0 internal, hidden 31 | 11: unknown:1890 {1890} V0 internal, hidden 32 | 12: unknown:18A0 {18A0} V0 internal, hidden 33 | 13: unknown:18B0 {18B0} V0 internal, hidden 34 | 14: REMAINING PAIRING {1DF0} V0 hidden 35 | Remaining Pairings: 54 36 | 15: unknown:1DF3 {1DF3} V0 internal, hidden 37 | 16: unknown:1E00 {1E00} V0 hidden 38 | 17: unknown:1E90 {1E90} V0 internal, hidden 39 | 18: DEVICE GROUPS {0006} V0 40 | Battery: 90%, discharging, next level 5%. 41 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard K220 4005.txt: -------------------------------------------------------------------------------- 1 | 2: Wireless Keyboard K220 2 | Codename : K220 3 | Kind : keyboard 4 | Wireless PID : 4005 5 | Protocol : HID++ 2.0 6 | Polling rate : 20 ms (50Hz) 7 | Serial number: 5BB1D72E 8 | Firmware: RQK 37.00.B0011 9 | Supports 14 HID++ 2.0 features: 10 | 0: ROOT {0000} 11 | 1: FEATURE SET {0001} 12 | 2: FEATURE INFO {0002} 13 | 3: DEVICE FW VERSION {0003} 14 | 4: DEVICE NAME {0005} 15 | 5: BATTERY STATUS {1000} 16 | 6: unknown:1820 {1820} hidden 17 | 7: REPROG CONTROLS {1B00} 18 | 8: REPROG CONTROLS V2 {1B01} 19 | 9: WIRELESS DEVICE STATUS {1D4B} 20 | 10: unknown:1DF0 {1DF0} hidden 21 | 11: unknown:1DF3 {1DF3} hidden 22 | 12: ENCRYPTION {4100} 23 | 13: KEYBOARD LAYOUT {4520} 24 | Has 12 reprogrammable keys: 25 | 0: FN F1 => Do Nothing One is FN, reprogrammable 26 | 1: FN F2 => Do Nothing One is FN, reprogrammable 27 | 2: FN F3 => Do Nothing One is FN, reprogrammable 28 | 3: FN F4 => Do Nothing One is FN, reprogrammable 29 | 4: FN F5 => Do Nothing One is FN, reprogrammable 30 | 5: FN F6 => Do Nothing One is FN, reprogrammable 31 | 6: FN F7 => Do Nothing One is FN, reprogrammable 32 | 7: FN F8 => Do Nothing One is FN, reprogrammable 33 | 8: FN F9 => Do Nothing One is FN, reprogrammable 34 | 9: Mute => Mute is FN 35 | 10: Volume Down => Volume Down is FN 36 | 11: Volume Up => Volume Up is FN 37 | Battery: 90%, discharging. 38 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard K230 400D.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Keyboard K230 2 | Device path : /dev/hidraw5 3 | WPID : 400D 4 | Codename : K230 5 | Kind : keyboard 6 | Protocol : HID++ 2.0 7 | Polling rate : 20 ms (50Hz) 8 | Serial number: 9BB42D7D 9 | Model ID: 000000000000 10 | Unit ID: 00000000 11 | Firmware: RQK 40.00.B0011 12 | The power switch is located on the bottom left corner. 13 | Supports 14 HID++ 2.0 features: 14 | 0: ROOT {0000} 15 | 1: FEATURE SET {0001} 16 | 2: FEATURE INFO {0002} 17 | 3: DEVICE FW VERSION {0003} 18 | Firmware: Firmware RQK 40.00.B0011 400D 19 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 20 | 4: DEVICE NAME {0005} 21 | Name: Wireless Keyboard K230 22 | Kind: keyboard 23 | 5: BATTERY STATUS {1000} 24 | Battery: 70%, discharging, next level 20%. 25 | 6: unknown:1820 {1820} hidden 26 | 7: REPROG CONTROLS {1B00} 27 | 8: REPROG CONTROLS V2 {1B01} 28 | 9: WIRELESS DEVICE STATUS {1D4B} 29 | 10: REMAINING PAIRING {1DF0} hidden 30 | Remaining Pairings: 54 31 | 11: unknown:1DF3 {1DF3} hidden 32 | 12: ENCRYPTION {4100} 33 | 13: KEYBOARD LAYOUT {4520} 34 | Has 12 reprogrammable keys: 35 | 0: Fn F1 => Do Nothing One is FN, reprogrammable 36 | 1: Fn F2 => Do Nothing One is FN, reprogrammable 37 | 2: Fn F3 => Do Nothing One is FN, reprogrammable 38 | 3: Fn F4 => Do Nothing One is FN, reprogrammable 39 | 4: Fn F5 => Do Nothing One is FN, reprogrammable 40 | 5: Fn F6 => Do Nothing One is FN, reprogrammable 41 | 6: Fn F7 => Do Nothing One is FN, reprogrammable 42 | 7: Fn F8 => Do Nothing One is FN, reprogrammable 43 | 8: Fn F9 => Do Nothing One is FN, reprogrammable 44 | 9: Mute => Mute is FN 45 | 10: Volume Down => Volume Down is FN 46 | 11: Volume Up => Volume Up is FN 47 | Battery: 70%, discharging, next level 20%. 48 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard K270(unifying) 4003.txt: -------------------------------------------------------------------------------- 1 | 2: Wireless Keyboard K270(unifying) 2 | Codename : K270(unifying) 3 | Kind : keyboard 4 | Wireless PID : 4003 5 | Protocol : HID++ 2.0 6 | Polling rate : 20 ms (50Hz) 7 | Serial number: FE8C8542 8 | Firmware: RQK 35.00.B0017 9 | The power switch is located on the top case. 10 | Supports 12 HID++ 2.0 features: 11 | 0: ROOT {0000} 12 | 1: FEATURE SET {0001} 13 | 2: DEVICE FW VERSION {0003} 14 | 3: DEVICE NAME {0005} 15 | 4: BATTERY STATUS {1000} 16 | 5: unknown:1820 {1820} hidden 17 | 6: REPROG CONTROLS {1B00} 18 | 7: WIRELESS DEVICE STATUS {1D4B} 19 | 8: unknown:1DF0 {1DF0} hidden 20 | 9: unknown:1DF3 {1DF3} hidden 21 | 10: ENCRYPTION {4100} 22 | 11: KEYBOARD LAYOUT {4520} 23 | Has 8 reprogrammable keys: 24 | 0: Play/Pause => Play/Pause nonstandard 25 | 1: Mute => Mute nonstandard 26 | 2: Volume Down => Volume Down nonstandard 27 | 3: Volume Up => Volume Up nonstandard 28 | 4: MY HOME => HomePage nonstandard, reprogrammable 29 | 5: Mail => Email nonstandard, reprogrammable 30 | 6: SLEEP => Sleep nonstandard, reprogrammable 31 | 7: Calculator => Calculator nonstandard, reprogrammable 32 | Battery: 90%, discharging. 33 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard K360 4004.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | 2: Wireless Keyboard K360 4 | Device path : /dev/hidraw2 5 | WPID : 4004 6 | Codename : K360 7 | Kind : keyboard 8 | Protocol : HID++ 2.0 9 | Polling rate : 20 ms (50Hz) 10 | Serial number: 334AC01A 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQK 36.00.B0007 14 | The power switch is located on the top case. 15 | Supports 12 HID++ 2.0 features: 16 | 0: ROOT {0000} 17 | 1: FEATURE SET {0001} 18 | 2: DEVICE FW VERSION {0003} 19 | Firmware: Firmware RQK 36.00.B0007 4004 20 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 21 | 3: DEVICE NAME {0005} 22 | Name: Wireless Keyboard K360 23 | Kind: keyboard 24 | 4: BATTERY STATUS {1000} 25 | Battery: 70%, discharging, next level 20%. 26 | 5: unknown:1820 {1820} hidden 27 | 6: REPROG CONTROLS {1B00} 28 | 7: WIRELESS DEVICE STATUS {1D4B} 29 | 8: REMAINING PAIRING {1DF0} hidden 30 | Remaining Pairings: 55 31 | 9: unknown:1DF3 {1DF3} hidden 32 | 10: FN INVERSION {40A0} 33 | Swap Fx function (saved): False 34 | Swap Fx function : False 35 | 11: ENCRYPTION {4100} 36 | Battery: 70%, discharging, next level 20%. 37 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard K470 4075.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.7 2 | 3 | 1: Wireless Keyboard 4 | Device path : /dev/hidraw6 5 | WPID : 4075 6 | Codename : 7 | Kind : keyboard 8 | Protocol : HID++ 4.5 9 | Polling rate : 20 ms (50Hz) 10 | Serial number: 00000000 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQK 71.00.B0002 14 | Supports 20 HID++ 2.0 features: 15 | 0: ROOT {0000} V0 16 | 1: FEATURE SET {0001} V0 17 | 2: DEVICE FW VERSION {0003} V0 18 | Firmware: Firmware RQK 71.00.B0002 4075 19 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 20 | 3: DEVICE NAME {0005} V0 21 | Name: Wireless Keyboard 22 | Kind: keyboard 23 | 4: RESET {0020} V0 24 | 5: BATTERY STATUS {1000} V0 25 | Battery: 30%, discharging, next level 5%. 26 | 6: REPROG CONTROLS V4 {1B04} V2 27 | Key/Button Diversion (saved): {Calculator:Regular, Mail:Regular, My Home:Regular, Search:Regular} 28 | Key/Button Diversion : {Calculator:Regular, Mail:Regular, My Home:Regular, Search:Regular} 29 | 7: WIRELESS DEVICE STATUS {1D4B} V0 30 | 8: NEW FN INVERSION {40A2} V0 31 | Fn-swap: disabled 32 | Fn-swap default: disabled 33 | Swap Fx function (saved): False 34 | Swap Fx function : False 35 | 9: ENCRYPTION {4100} V0 36 | 10: LOCK KEY STATE {4220} V0 37 | 11: KEYBOARD DISABLE KEYS {4521} V0 38 | Disable keys (saved): {Caps Lock:False, Num Lock:False, Scroll Lock:False, Insert:False, Win:False} 39 | Disable keys : {Caps Lock:False, Num Lock:False, Scroll Lock:False, Insert:False, Win:False} 40 | 12: unknown:1810 {1810} V0 internal, hidden 41 | 13: unknown:1830 {1830} V0 internal, hidden 42 | 14: unknown:1890 {1890} V0 internal, hidden 43 | 15: unknown:18A0 {18A0} V0 internal, hidden 44 | 16: unknown:18B0 {18B0} V0 internal, hidden 45 | 17: unknown:1DF3 {1DF3} V0 internal, hidden 46 | 18: unknown:1E00 {1E00} V0 hidden 47 | 19: unknown:1868 {1868} V0 internal, hidden 48 | Has 4 reprogrammable keys: 49 | 0: My Home , default: HomePage => HomePage 50 | is FN, FN sensitive, reprogrammable, divertable, pos:1, group:0, group mask:empty 51 | reporting: default 52 | 1: Mail , default: Email => Email 53 | is FN, FN sensitive, reprogrammable, divertable, pos:2, group:0, group mask:empty 54 | reporting: default 55 | 2: Search , default: Search Files => Search Files 56 | is FN, FN sensitive, reprogrammable, divertable, pos:3, group:0, group mask:empty 57 | reporting: default 58 | 3: Calculator , default: Calculator => Calculator 59 | is FN, FN sensitive, reprogrammable, divertable, pos:4, group:0, group mask:empty 60 | reporting: default 61 | Battery: 30%, discharging, next level 5%. 62 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard K520 2011.txt: -------------------------------------------------------------------------------- 1 | 2: Wireless Keyboard K520 2 | Device path : /dev/hidraw5 3 | WPID : 2011 4 | Codename : K520 5 | Kind : keyboard 6 | Protocol : HID++ 1.0 7 | Polling rate : 20 ms (50Hz) 8 | Serial number: C17F6771 9 | Firmware: 26.00.B0012 10 | Other: 00.07 11 | The power switch is located on the top case. 12 | Notifications: battery status (0x100000). 13 | Battery: full, discharging. 14 | 15 | Has Swap Fn register 16 | -------------------------------------------------------------------------------- /docs/devices/Wireless Keyboard MK270 4023.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.7 2 | 3 | 1: Wireless Keyboard MK270 4 | Device path : /dev/hidraw6 5 | WPID : 4023 6 | Codename : MK270 7 | Kind : keyboard 8 | Protocol : HID++ 2.0 9 | Polling rate : 20 ms (50Hz) 10 | Serial number: 90A794A3 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQK 49.00.B0029 14 | Supports 18 HID++ 2.0 features: 15 | 0: ROOT {0000} V0 16 | 1: FEATURE SET {0001} V0 17 | 2: DEVICE FW VERSION {0003} V0 18 | Firmware: Firmware RQK 49.00.B0029 4023 19 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 20 | 3: DEVICE NAME {0005} V0 21 | Name: Wireless Keyboard 22 | Kind: keyboard 23 | 4: BATTERY STATUS {1000} V0 24 | Battery: 30%, discharging, next level 5%. 25 | 5: REPROG CONTROLS {1B00} V0 26 | 6: WIRELESS DEVICE STATUS {1D4B} V0 27 | 7: FN INVERSION {40A0} V0 28 | Swap Fx function (saved): False 29 | Swap Fx function : False 30 | 8: ENCRYPTION {4100} V0 31 | 9: KEYBOARD LAYOUT {4520} V0 32 | 10: unknown:1810 {1810} V0 internal, hidden 33 | 11: unknown:1830 {1830} V0 internal, hidden 34 | 12: unknown:1890 {1890} V0 internal, hidden 35 | 13: unknown:18A0 {18A0} V0 internal, hidden 36 | 14: unknown:18B0 {18B0} V0 internal, hidden 37 | 15: unknown:1DF3 {1DF3} V0 internal, hidden 38 | 16: unknown:1E00 {1E00} V0 hidden 39 | 17: unknown:1868 {1868} V0 internal, hidden 40 | Battery: 30%, discharging, next level 5%. 41 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse 4022.txt: -------------------------------------------------------------------------------- 1 | 2: Wireless Mouse 2 | Codename : 3 | Kind : mouse 4 | Wireless PID : 4022 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 00000000 8 | Firmware: RQM 38.00.B0044 9 | Supports 18 HID++ 2.0 features: 10 | 0: ROOT {0000} 11 | 1: FEATURE SET {0001} 12 | 2: DEVICE FW VERSION {0003} 13 | 3: DEVICE NAME {0005} 14 | 4: BATTERY STATUS {1000} 15 | 5: REPROG CONTROLS {1B00} 16 | 6: WIRELESS DEVICE STATUS {1D4B} 17 | 7: VERTICAL SCROLLING {2100} 18 | 8: MOUSE POINTER {2200} 19 | 9: unknown:1810 {1810} internal, hidden 20 | 10: unknown:1830 {1830} internal, hidden 21 | 11: unknown:1850 {1850} internal, hidden 22 | 12: unknown:1890 {1890} internal, hidden 23 | 13: unknown:18B0 {18B0} internal, hidden 24 | 14: unknown:1DF3 {1DF3} internal, hidden 25 | 15: unknown:1868 {1868} internal, hidden 26 | 16: unknown:1869 {1869} internal, hidden 27 | 17: unknown:1E00 {1E00} hidden 28 | Has 3 reprogrammable keys: 29 | 0: LEFT CLICK => LeftClick mse, reprogrammable 30 | 1: RIGHT CLICK => RightClick mse, reprogrammable 31 | 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 32 | Battery: 30%, discharging. 33 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse Dell WM514 4029.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.6rc4 2 | 3 | 3: Wireless Mouse Dell WM514 4 | Device path : /dev/hidraw5 5 | WPID : 4029 6 | Codename : Dell WM514 7 | Kind : mouse 8 | Protocol : HID++ 3.0 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 17F2CD56 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQM 44.00.B0013 14 | The power switch is located on the base. 15 | Supports 23 HID++ 2.0 features: 16 | 0: ROOT {0000} V0 17 | 1: FEATURE SET {0001} V0 18 | 2: DEVICE FW VERSION {0003} V0 19 | Firmware: Firmware RQM 44.00.B0013 4029 20 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 21 | 3: DEVICE NAME {0005} V0 22 | Name: Wireless Mouse Dell WM514 23 | Kind: mouse 24 | 4: BATTERY STATUS {1000} V0 25 | Battery: 70%, discharging, next level 5%. 26 | 5: unknown:1830 {1830} V0 internal, hidden 27 | 6: unknown:1860 {1860} V0 internal, hidden 28 | 7: unknown:1890 {1890} V0 internal, hidden 29 | 8: unknown:18A0 {18A0} V0 internal, hidden 30 | 9: unknown:18B0 {18B0} V0 internal, hidden 31 | 10: unknown:18C0 {18C0} V0 internal, hidden 32 | 11: WIRELESS DEVICE STATUS {1D4B} V0 33 | 12: unknown:1DF3 {1DF3} V0 internal, hidden 34 | 13: REPROG CONTROLS {1B00} V0 35 | 14: REMAINING PAIRING {1DF0} V0 hidden 36 | Remaining Pairings: 124 37 | 15: unknown:1E00 {1E00} V0 hidden 38 | 16: unknown:1850 {1850} V0 internal, hidden 39 | 17: unknown:1E90 {1E90} V0 internal, hidden 40 | 18: unknown:1F03 {1F03} V0 internal, hidden 41 | 19: VERTICAL SCROLLING {2100} V0 42 | Roller type: standard 43 | Ratchet per turn: 24 44 | Scroll lines: 0 45 | 20: MOUSE POINTER {2200} V0 46 | DPI: 1000 47 | Acceleration: low 48 | Override OS ballistics 49 | No vertical tuning, standard mice 50 | 21: DEVICE GROUPS {0006} V0 51 | 22: unknown:1BB0 {1BB0} V0 52 | Battery: 70%, discharging, next level 5%. 53 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M185 new 4054.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4rc2 2 | 3 | 2: Wireless Mouse M185 new 4 | Device path : /dev/hidraw3 5 | WPID : 4054 6 | Codename : M185n 7 | Kind : mouse 8 | Protocol : HID++ 4.5 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 00000000 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQM 64.00.B0008 14 | The power switch is located on the base. 15 | Supports 19 HID++ 2.0 features: 16 | 0: ROOT {0000} 17 | 1: FEATURE SET {0001} 18 | 2: DEVICE FW VERSION {0003} 19 | Firmware: Firmware RQM 64.00.B0008 4054 20 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 21 | 3: DEVICE NAME {0005} 22 | Name: Wireless Mouse 23 | Kind: mouse 24 | 4: RESET {0020} 25 | 5: REPROG CONTROLS V4 {1B04} 26 | Mouse Gestures (saved): Off 27 | Mouse Gestures : Off 28 | Key/Button Actions (saved): {Left Button:Left Click, Right Button:Right Click, Middle Button:Mouse Middle Button} 29 | Key/Button Actions : {Left Button:Left Click, Right Button:Right Click, Middle Button:Mouse Middle Button} 30 | Key/Button Diversion (saved): {Middle Button:Regular} 31 | Key/Button Diversion : {Middle Button:Regular} 32 | 6: WIRELESS DEVICE STATUS {1D4B} 33 | 7: LOWRES WHEEL {2130} 34 | Wheel Reports: HID 35 | Scroll Wheel Diversion (saved): False 36 | Scroll Wheel Diversion : False 37 | 8: POINTER SPEED {2205} 38 | Pointer Speed: 1.0 39 | Sensitivity (Pointer Speed) (saved): 256 40 | Sensitivity (Pointer Speed) : 256 41 | 9: DEVICE RESET {1802} internal, hidden 42 | 10: unknown:1810 {1810} internal, hidden 43 | 11: unknown:1830 {1830} internal, hidden 44 | 12: unknown:1850 {1850} internal, hidden 45 | 13: unknown:1869 {1869} internal, hidden 46 | 14: unknown:1890 {1890} internal, hidden 47 | 15: unknown:18B1 {18B1} internal, hidden 48 | 16: unknown:1DF3 {1DF3} internal, hidden 49 | 17: unknown:1E00 {1E00} hidden 50 | 18: unknown:1F03 {1F03} internal, hidden 51 | Has 3 reprogrammable keys: 52 | 0: Left Button , default: Left Click => Left Click 53 | mse, reprogrammable, pos:0, group:1, group mask:g1 54 | reporting: default 55 | 1: Right Button , default: Right Click => Right Click 56 | mse, reprogrammable, pos:0, group:1, group mask:g1 57 | reporting: default 58 | 2: Middle Button , default: Mouse Middle Button => Mouse Middle Button 59 | mse, reprogrammable, divertable, raw XY, pos:0, group:2, group mask:g1,g2 60 | reporting: default 61 | Battery status unavailable. 62 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M185,M235,M310 4055.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | 1: Wireless Mouse M185/M235/M310 4 | Device path : /dev/hidraw2 5 | WPID : 4055 6 | Codename : M185/M235/M310 7 | Kind : mouse 8 | Protocol : HID++ 4.5 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 82C9A01F 11 | Model ID: 405500000000 12 | Unit ID: 82C9A01F 13 | Firmware: RQM 65.00.B0003 14 | The power switch is located on the base. 15 | Supports 21 HID++ 2.0 features: 16 | 0: ROOT {0000} 17 | 1: FEATURE SET {0001} 18 | 2: DEVICE FW VERSION {0003} 19 | Firmware: Firmware RQM 65.00.B0003 4055 20 | Unit ID: 82C9A01F Model ID: 405500000000 Transport IDs: {'wpid': '4055'} 21 | 3: DEVICE NAME {0005} 22 | Name: Wireless Mouse 23 | Kind: mouse 24 | 4: RESET {0020} 25 | 5: BATTERY STATUS {1000} 26 | Battery: 70%, discharging, next level 5%. 27 | 6: unknown:1810 {1810} internal, hidden 28 | 7: unknown:1830 {1830} internal, hidden 29 | 8: DEVICE RESET {1802} internal, hidden 30 | 9: unknown:1862 {1862} internal, hidden 31 | 10: unknown:1890 {1890} internal, hidden 32 | 11: unknown:18A0 {18A0} internal, hidden 33 | 12: unknown:18B1 {18B1} internal, hidden 34 | 13: REPROG CONTROLS V4 {1B04} 35 | Key/Button Actions (saved): {Left Button:Left Click, Right Button:Right Click, Middle Button:Mouse Middle Button} 36 | Key/Button Actions : {Left Button:Left Click, Right Button:Right Click, Middle Button:Mouse Middle Button} 37 | Key/Button Diversion (saved): {Left Button:Regular, Right Button:Regular, Middle Button:Regular} 38 | Key/Button Diversion : {Left Button:Regular, Right Button:Regular, Middle Button:Regular} 39 | 14: WIRELESS DEVICE STATUS {1D4B} 40 | 15: REMAINING PAIRING {1DF0} hidden 41 | Remaining Pairings: 116 42 | 16: unknown:1DF3 {1DF3} internal, hidden 43 | 17: unknown:1E00 {1E00} hidden 44 | 18: unknown:1EB0 {1EB0} internal, hidden 45 | 19: unknown:1F03 {1F03} internal, hidden 46 | 20: LOWRES WHEEL {2130} 47 | Wheel Reports: HID 48 | Scroll Wheel Diversion (saved): False 49 | Scroll Wheel Diversion : False 50 | Has 3 reprogrammable keys: 51 | 0: Left Button , default: Left Click => Left Click 52 | mse, divertable, pos:0, group:1, group mask:g1 53 | reporting: default 54 | 1: Right Button , default: Right Click => Right Click 55 | mse, divertable, pos:0, group:1, group mask:g1 56 | reporting: analytics key events reporting 57 | 2: Middle Button , default: Mouse Middle Button => Mouse Middle Button 58 | mse, reprogrammable, divertable, raw XY, pos:0, group:2, group mask:g1,g2 59 | reporting: unknown:000200 60 | Battery: 70%, discharging, next level 5%. 61 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M215 2nd Gen 401B.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.5 2 | 3 | 1: Wireless Mouse M215 2nd Gen 4 | Device path : None 5 | WPID : 401B 6 | Codename : Wireless 7 | Kind : mouse 8 | Protocol : HID++ 2.0 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: D225825E 11 | Model ID: 000000000000 12 | Unit ID: 00000000 13 | Firmware: RQM 27.12.B0029 14 | The power switch is located on the base. 15 | Supports 13 HID++ 2.0 features: 16 | 0: ROOT {0000} V0 17 | 1: FEATURE SET {0001} V0 18 | 2: DEVICE FW VERSION {0003} V0 19 | Firmware: Firmware RQM 27.12.B0029 401B 20 | Unit ID: 00000000 Model ID: 000000000000 Transport IDs: {} 21 | 3: DEVICE NAME {0005} V0 22 | Name: Wireless Mouse M215 2nd Gen 23 | Kind: mouse 24 | 4: BATTERY STATUS {1000} V0 25 | Battery: 90%, discharging, next level 5%. 26 | 5: WIRELESS DEVICE STATUS {1D4B} V0 27 | 6: unknown:1DF3 {1DF3} V0 hidden 28 | 7: REPROG CONTROLS {1B00} V0 29 | 8: REMAINING PAIRING {1DF0} V0 hidden 30 | Remaining Pairings: 126 31 | 9: unknown:1F03 {1F03} V0 hidden 32 | 10: VERTICAL SCROLLING {2100} V0 33 | Roller type: standard 34 | Ratchet per turn: 24 35 | Scroll lines: 0 36 | 11: HI RES SCROLLING {2120} V0 37 | Hi-res scrolling disabled 38 | Hi-res scrolling multiplier: 8 39 | Scroll Wheel High Resolution (saved): False 40 | Scroll Wheel High Resolution : False 41 | 12: MOUSE POINTER {2200} V0 42 | DPI: 800 43 | Acceleration: low 44 | Override OS ballistics 45 | No vertical tuning, standard mice 46 | Battery: 90%, discharging, next level 5%. 47 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M310 M310t 4031.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Mouse M310/M310t 2 | Codename : M310/M310t 3 | Kind : mouse 4 | Wireless PID : 4031 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 03E8C0B4 8 | Firmware: RQM 40.01.B0017 9 | The power switch is located on the base. 10 | Supports 21 HID++ 2.0 features: 11 | 0: ROOT {0000} 12 | 1: FEATURE SET {0001} 13 | 2: DEVICE FW VERSION {0003} 14 | 3: DEVICE NAME {0005} 15 | 4: BATTERY STATUS {1000} 16 | 5: unknown:1830 {1830} internal, hidden 17 | 6: unknown:1850 {1850} internal, hidden 18 | 7: unknown:1860 {1860} internal, hidden 19 | 8: unknown:1890 {1890} internal, hidden 20 | 9: unknown:18A0 {18A0} internal, hidden 21 | 10: unknown:18C0 {18C0} internal, hidden 22 | 11: WIRELESS DEVICE STATUS {1D4B} 23 | 12: unknown:1DF3 {1DF3} internal, hidden 24 | 13: REPROG CONTROLS {1B00} 25 | 14: unknown:1DF0 {1DF0} hidden 26 | 15: unknown:1E00 {1E00} hidden 27 | 16: unknown:1E80 {1E80} internal, hidden 28 | 17: unknown:1E90 {1E90} internal, hidden 29 | 18: unknown:1F03 {1F03} internal, hidden 30 | 19: VERTICAL SCROLLING {2100} 31 | 20: MOUSE POINTER {2200} 32 | Has 3 reprogrammable keys: 33 | 0: LEFT CLICK => LeftClick mse, reprogrammable 34 | 1: RIGHT CLICK => RightClick mse, reprogrammable 35 | 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 36 | Battery: 70%, discharging. 37 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M345 4017.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Mouse M345 2 | Codename : M345 3 | Kind : mouse 4 | Wireless PID : 4017 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms 7 | Serial number: 920DC223 8 | Firmware: RQM 27.02.B0028 9 | The power switch is located on the base. 10 | Supports 13 HID++ 2.0 features: 11 | 0: ROOT {0000} 12 | 1: FEATURE SET {0001} 13 | 2: DEVICE FW VERSION {0003} 14 | 3: DEVICE NAME {0005} 15 | 4: BATTERY STATUS {1000} 16 | 5: WIRELESS DEVICE STATUS {1D4B} 17 | 6: unknown:1DF3 {1DF3} hidden 18 | 7: REPROG CONTROLS {1B00} 19 | 8: unknown:1DF0 {1DF0} hidden 20 | 9: unknown:1F03 {1F03} hidden 21 | 10: VERTICAL SCROLLING {2100} 22 | 11: HI RES SCROLLING {2120} 23 | 12: MOUSE POINTER {2200} 24 | Battery: 90%, discharging, 25 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M510 1025.txt: -------------------------------------------------------------------------------- 1 | Solaar version 1.1.4 2 | 3 | 1: Wireless Mouse M510 4 | Device path : /dev/hidraw2 5 | WPID : 1025 6 | Codename : M510 7 | Kind : mouse 8 | Protocol : HID++ 1.0 9 | Polling rate : 8 ms (125Hz) 10 | Serial number: 93E8527F 11 | Firmware: 23.01.B0016 12 | The power switch is located on the base. 13 | Notifications: battery status (0x100000). 14 | Features: special buttons, buttons control resolution (0x820000) 15 | Battery: good, discharging. 16 | 17 | Has Side Scrolling register 18 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M510 4051.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Mouse M510 2 | Codename : M510v2 3 | Kind : mouse 4 | Wireless PID : 4051 5 | Protocol : HID++ 4.5 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 8989B04C 8 | Firmware: RQM 62.00.B0013 9 | The power switch is located on the base. 10 | Supports 22 HID++ 2.0 features: 11 | 0: ROOT {0000} 12 | 1: FEATURE SET {0001} 13 | 2: DEVICE FW VERSION {0003} 14 | 3: DEVICE NAME {0005} 15 | 4: RESET {0020} 16 | 5: BATTERY STATUS {1000} 17 | 6: unknown:1802 {1802} internal, hidden 18 | 7: unknown:1810 {1810} internal, hidden 19 | 8: unknown:1830 {1830} internal, hidden 20 | 9: unknown:1862 {1862} internal, hidden 21 | 10: unknown:1890 {1890} internal, hidden 22 | 11: unknown:18A0 {18A0} internal, hidden 23 | 12: unknown:18B1 {18B1} internal, hidden 24 | 13: REPROG CONTROLS V4 {1B04} 25 | 14: WIRELESS DEVICE STATUS {1D4B} 26 | 15: unknown:1DF0 {1DF0} hidden 27 | 16: unknown:1DF3 {1DF3} internal, hidden 28 | 17: unknown:1E00 {1E00} hidden 29 | 18: unknown:1EB0 {1EB0} internal, hidden 30 | 19: unknown:1F03 {1F03} internal, hidden 31 | 20: LOWRES WHEEL {2130} 32 | 21: POINTER SPEED {2205} 33 | Has 7 reprogrammable keys: 34 | 0: LEFT CLICK , default: LeftClick => LEFT CLICK 35 | divertable, mse, pos:0, group:1, gmask:1 36 | 1: RIGHT CLICK , default: RightClick => RIGHT CLICK 37 | divertable, mse, pos:0, group:1, gmask:1 38 | 2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON 39 | divertable, mse, reprogrammable, pos:0, group:2, gmask:3 40 | 3: LEFT SCROLL AS AC PAN , default: HorzScrollLeftSet => LEFT SCROLL AS AC PAN 41 | divertable, mse, reprogrammable, pos:0, group:2, gmask:3 42 | 4: RIGHT SCROLL AS AC PAN , default: HorzScrollRightSet => RIGHT SCROLL AS AC PAN 43 | divertable, mse, reprogrammable, pos:0, group:2, gmask:3 44 | 5: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4 45 | divertable, mse, reprogrammable, pos:0, group:2, gmask:3 46 | 6: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5 47 | divertable, mse, reprogrammable, pos:0, group:2, gmask:3 48 | Battery: 70%, discharging. 49 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M525 4013.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Mouse M525 2 | Codename : M525 3 | Kind : mouse 4 | Wireless PID : 4013 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: DAFA335E 8 | Firmware: RQM 27.02.B0028 9 | The power switch is located on the base. 10 | Supports 13 HID++ 2.0 features: 11 | 0: ROOT {0000} 12 | 1: FEATURE SET {0001} 13 | 2: DEVICE FW VERSION {0003} 14 | 3: DEVICE NAME {0005} 15 | 4: BATTERY STATUS {1000} 16 | 5: WIRELESS DEVICE STATUS {1D4B} 17 | 6: unknown:1DF3 {1DF3} hidden 18 | 7: REPROG CONTROLS {1B00} 19 | 8: unknown:1DF0 {1DF0} hidden 20 | 9: unknown:1F03 {1F03} hidden 21 | 10: VERTICAL SCROLLING {2100} 22 | 11: HI RES SCROLLING {2120} 23 | 12: MOUSE POINTER {2200} 24 | Has 5 reprogrammable keys: 25 | 0: LEFT CLICK => LeftClick mse, reprogrammable 26 | 1: RIGHT CLICK => RightClick mse, reprogrammable 27 | 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 28 | 3: BACK AS BUTTON 4 => Back mse, reprogrammable 29 | 4: FORWARD AS BUTTON 5 => BrowserForward mse, reprogrammable 30 | Battery: 90%, discharging. 31 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse M560 402D.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Mouse M560 2 | Codename : M560 3 | Kind : mouse 4 | Wireless PID : 402D 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 16E6E42A 8 | Firmware: RQM 48.00.B0015 9 | The power switch is located on the base. 10 | Supports 22 HID++ 2.0 features: 11 | 0: ROOT {0000} 12 | 1: FEATURE SET {0001} 13 | 2: DEVICE FW VERSION {0003} 14 | 3: DEVICE NAME {0005} 15 | 4: BATTERY STATUS {1000} 16 | 5: unknown:1830 {1830} internal, hidden 17 | 6: unknown:1850 {1850} internal, hidden 18 | 7: unknown:1860 {1860} internal, hidden 19 | 8: unknown:1890 {1890} internal, hidden 20 | 9: unknown:18A0 {18A0} internal, hidden 21 | 10: REPROG CONTROLS V3 {1B03} 22 | 11: WIRELESS DEVICE STATUS {1D4B} 23 | 12: unknown:1DF3 {1DF3} internal, hidden 24 | 13: REPROG CONTROLS {1B00} 25 | 14: unknown:1DF0 {1DF0} hidden 26 | 15: unknown:1E00 {1E00} hidden 27 | 16: unknown:18B0 {18B0} internal, hidden 28 | 17: unknown:1E90 {1E90} internal, hidden 29 | 18: unknown:1F03 {1F03} internal, hidden 30 | 19: VERTICAL SCROLLING {2100} 31 | 20: HI RES SCROLLING {2120} 32 | 21: MOUSE POINTER {2200} 33 | Has 7 reprogrammable keys: 34 | 0: LEFT CLICK => LeftClick mse, reprogrammable 35 | 1: RIGHT CLICK => RightClick mse, reprogrammable 36 | 2: BACK AS BUTTON 4 => Win8BackHorzLeft mse, reprogrammable 37 | 3: FORWARD AS BUTTON 5 => Win8ForwardHorzRight mse, reprogrammable 38 | 4: unknown:00B0 => Win8MetroWin7Forward mse, reprogrammable 39 | 5: SHOW DESKTOP HPP => Win8ShowDesktopWin7Back mse, reprogrammable 40 | 6: unknown:00AF => Win8Charm Appswitch GifAnimation mse, reprogrammable, unknown:000020 41 | Battery: 70%, discharging. 42 | -------------------------------------------------------------------------------- /docs/devices/Wireless Mouse MX Anywhere 2 404A.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Mouse MX Anywhere 2 2 | Codename : MX Anywhere 2 3 | Kind : mouse 4 | Wireless PID : 404A 5 | Protocol : HID++ 4.5 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: F3B81C5B 8 | Bootloader: BOT 23.00.B0007 9 | Firmware: MPM 02.00.B0007 10 | Firmware: MPM 02.00.B0007 11 | Other: 12 | The power switch is located on the base. 13 | Supports 26 HID++ 2.0 features: 14 | 0: ROOT {0000} 15 | 1: FEATURE SET {0001} 16 | 2: DEVICE FW VERSION {0003} 17 | 3: DEVICE NAME {0005} 18 | 4: WIRELESS DEVICE STATUS {1D4B} 19 | 5: RESET {0020} 20 | 6: BATTERY STATUS {1000} 21 | 7: CHANGE HOST {1814} 22 | 8: REPROG CONTROLS V4 {1B04} 23 | 9: ADJUSTABLE DPI {2201} 24 | 10: VERTICAL SCROLLING {2100} 25 | 11: HIRES WHEEL {2121} 26 | 12: DFUCONTROL 2 {00C1} 27 | 13: unknown:1813 {1813} internal, hidden 28 | 14: unknown:1830 {1830} internal, hidden 29 | 15: unknown:1890 {1890} internal, hidden 30 | 16: unknown:1891 {1891} internal, hidden 31 | 17: unknown:18A1 {18A1} internal, hidden 32 | 18: unknown:18C0 {18C0} internal, hidden 33 | 19: unknown:1DF3 {1DF3} internal, hidden 34 | 20: unknown:1E00 {1E00} hidden 35 | 21: unknown:1EB0 {1EB0} internal, hidden 36 | 22: unknown:1803 {1803} internal, hidden 37 | 23: unknown:1861 {1861} internal, hidden 38 | 24: unknown:9000 {9000} internal, hidden 39 | 25: unknown:1805 {1805} internal, hidden 40 | Battery: 0%, recharging. 41 | -------------------------------------------------------------------------------- /docs/devices/Wireless Rechargeable Touchpad T650 4101.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Rechargeable Touchpad T650 2 | Codename : T650 3 | Kind : touchpad 4 | Wireless PID : 4101 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 22205A4D 8 | Firmware: RQM 41.01.B0037 9 | Bootloader: BL 03.00 10 | Hardware: 72 11 | Other: 12 | The power switch is located on the base. 13 | Supports 23 HID++ 2.0 features: 14 | 0: ROOT {0000} 15 | 1: FEATURE SET {0001} 16 | 2: FEATURE INFO {0002} 17 | 3: DEVICE FW VERSION {0003} 18 | 4: DEVICE NAME {0005} 19 | 5: BATTERY STATUS {1000} 20 | 6: WIRELESS DEVICE STATUS {1D4B} 21 | 7: unknown:1DF3 {1DF3} internal, hidden 22 | 8: REPROG CONTROLS {1B00} 23 | 9: unknown:1F03 {1F03} internal, hidden 24 | 10: VERTICAL SCROLLING {2100} 25 | 11: HI RES SCROLLING {2120} 26 | 12: MOUSE POINTER {2200} 27 | 13: DFUCONTROL {00C0} 28 | 14: unknown:1E80 {1E80} internal, hidden 29 | 15: TOUCHPAD RAW XY {6100} 30 | 16: unknown:1860 {1860} internal, hidden 31 | 17: unknown:1E00 {1E00} hidden 32 | 18: REPROG CONTROLS V2 {1B01} 33 | 19: unknown:1890 {1890} internal, hidden 34 | 20: unknown:18E5 {18E5} internal, hidden 35 | 21: unknown:18A0 {18A0} internal, hidden 36 | 22: unknown:1830 {1830} internal, hidden 37 | Has 2 reprogrammable keys: 38 | 0: LEFT CLICK => LeftClick mse, reprogrammable 39 | 1: RIGHT CLICK => RightClick mse, reprogrammable 40 | Battery: 50%, discharging. 41 | -------------------------------------------------------------------------------- /docs/devices/Wireless Solar Keyboard K750 4002.txt: -------------------------------------------------------------------------------- 1 | 2: Wireless Solar Keyboard K750 2 | Codename : K750 3 | Kind : keyboard 4 | Wireless PID : 4002 5 | Protocol : HID++ 2.0 6 | Polling rate : 20 ms (50Hz) 7 | Serial number: 5692B2EC 8 | Firmware: RQK 33.00.B0015 9 | Bootloader: DFU 00.02.B0003 10 | The power switch is located on the edge of top right corner. 11 | Supports 11 HID++ 2.0 features: 12 | 0: ROOT {0000} 13 | 1: FEATURE SET {0001} 14 | 2: DEVICE FW VERSION {0003} 15 | 3: DEVICE NAME {0005} 16 | 4: REPROG CONTROLS {1B00} 17 | 5: WIRELESS DEVICE STATUS {1D4B} 18 | 6: unknown:1DF3 {1DF3} hidden 19 | 7: FN INVERSION {40A0} 20 | 8: ENCRYPTION {4100} 21 | 9: SOLAR DASHBOARD {4301} 22 | 10: KEYBOARD LAYOUT {4520} 23 | Has 12 reprogrammable keys: 24 | 0: MY HOME => HomePage FN sensitive, is FN, reprogrammable 25 | 1: Mail => Email FN sensitive, is FN, reprogrammable 26 | 2: SEARCH => Search FN sensitive, is FN, reprogrammable 27 | 3: Calculator => Calculator FN sensitive, is FN, reprogrammable 28 | 4: MEDIA PLAYER => Music FN sensitive, is FN, reprogrammable 29 | 5: Previous => Previous FN sensitive, is FN 30 | 6: Play/Pause => Play/Pause FN sensitive, is FN 31 | 7: Next => Next FN sensitive, is FN 32 | 8: Mute => Mute FN sensitive, is FN 33 | 9: Volume Down => Volume Down FN sensitive, is FN 34 | 10: Volume Up => Volume Up FN sensitive, is FN 35 | 11: SLEEP => Sleep FN sensitive, is FN, reprogrammable 36 | Battery status unavailable. 37 | -------------------------------------------------------------------------------- /docs/devices/Wireless Touch Keyboard K400 4024.txt: -------------------------------------------------------------------------------- 1 | 2 | 1: Wireless Touch Keyboard K400 3 | Codename : K400 4 | Kind : keyboard 5 | Wireless PID : 4024 6 | Protocol : HID++ 2.0 7 | Polling rate : 8 ms (125Hz) 8 | Serial number: AC5F5069 9 | Firmware: RQK 50.01.B0013 10 | The power switch is located on the edge of top right corner. 11 | Supports 22 HID++ 2.0 features: 12 | 0: ROOT {0000} 13 | 1: FEATURE SET {0001} 14 | 2: FEATURE INFO {0002} 15 | 3: DEVICE FW VERSION {0003} 16 | 4: DEVICE NAME {0005} 17 | 5: BATTERY STATUS {1000} 18 | 6: REPROG CONTROLS {1B00} 19 | 7: REPROG CONTROLS V3 {1B03} 20 | 8: WIRELESS DEVICE STATUS {1D4B} 21 | 9: unknown:1DF0 {1DF0} hidden 22 | 10: unknown:1DF3 {1DF3} internal, hidden 23 | 11: unknown:1E00 {1E00} hidden 24 | 12: VERTICAL SCROLLING {2100} 25 | 13: HI RES SCROLLING {2120} 26 | 14: MOUSE POINTER {2200} 27 | 15: FN INVERSION {40A0} 28 | 16: NEW FN INVERSION {40A2} 29 | 17: ENCRYPTION {4100} 30 | 18: KEYBOARD LAYOUT {4520} 31 | 19: TOUCHPAD FW ITEMS {6010} 32 | 20: TOUCHPAD SW ITEMS {6011} 33 | 21: TOUCHPAD WIN8 FW ITEMS {6012} 34 | Has 18 reprogrammable keys: 35 | 0: SHOW DESKTOP => ShowDesktop is FN, reprogrammable 36 | 1: METRO APPSWITCH => MetroAppSwitch is FN, reprogrammable 37 | 2: METRO SEARCH => MetroSearch is FN, reprogrammable 38 | 3: METRO SHARE => MetroShare is FN, reprogrammable 39 | 4: METRO DEVICES => MetroDevices is FN, reprogrammable 40 | 5: METRO SETTINGS => MetroSettings is FN, reprogrammable 41 | 6: Previous => Previous is FN 42 | 7: Play/Pause => Play/Pause is FN 43 | 8: Next => Next is FN 44 | 9: Mute => Mute is FN 45 | 10: Volume Down => Volume Down is FN 46 | 11: Volume Up => Volume Up is FN 47 | 12: MEDIA PLAYER => Music nonstandard, reprogrammable 48 | 13: Lock PC => WindowsLock nonstandard, reprogrammable 49 | 14: SLEEP => Sleep nonstandard, reprogrammable 50 | 15: LEFT CLICK => LeftClick mse 51 | 16: LEFT CLICK => LeftClick mse 52 | 17: RIGHT CLICK => RightClick mse 53 | Battery: 90%, discharging. 54 | -------------------------------------------------------------------------------- /docs/devices/Wireless Trackball M570 1028.txt: -------------------------------------------------------------------------------- 1 | 1: Wireless Trackball M570 2 | Codename : M570 3 | Kind : mouse 4 | Wireless PID : 1028 5 | Protocol : HID++ 1.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 891DC05A 8 | Firmware: 26.00.B0003 9 | Bootloader: 02.06 10 | Other: 00.01 11 | The power switch is located on the base. 12 | Notifications: battery status (0x100000). 13 | Battery: 100%, discharging. 14 | -------------------------------------------------------------------------------- /docs/devices/Zone Touch Mouse T400 4026.txt: -------------------------------------------------------------------------------- 1 | 1: Zone Touch Mouse T400 2 | Codename : T400 3 | Kind : mouse 4 | Wireless PID : 4026 5 | Protocol : HID++ 2.0 6 | Polling rate : 8 ms (125Hz) 7 | Serial number: 131A3093 8 | Firmware: RQM 39.00.B0029 9 | Bootloader: BL 03.00 10 | Hardware: 72 11 | Other: 12 | The power switch is located on the base. 13 | Supports 28 HID++ 2.0 features: 14 | 0: ROOT {0000} 15 | 1: FEATURE SET {0001} 16 | 2: FEATURE INFO {0002} 17 | 3: DEVICE FW VERSION {0003} 18 | 4: DEVICE NAME {0005} 19 | 5: DFUCONTROL {00C0} 20 | 6: BATTERY STATUS {1000} 21 | 7: unknown:1802 {1802} internal, hidden 22 | 8: unknown:1810 {1810} internal, hidden 23 | 9: unknown:1830 {1830} internal, hidden 24 | 10: unknown:1850 {1850} internal, hidden 25 | 11: unknown:1860 {1860} internal, hidden 26 | 12: unknown:1890 {1890} internal, hidden 27 | 13: unknown:18A0 {18A0} internal, hidden 28 | 14: unknown:18E3 {18E3} internal, hidden 29 | 15: REPROG CONTROLS {1B00} 30 | 16: WIRELESS DEVICE STATUS {1D4B} 31 | 17: unknown:1DF3 {1DF3} internal, hidden 32 | 18: unknown:1E00 {1E00} hidden 33 | 19: unknown:1E80 {1E80} internal, hidden 34 | 20: unknown:1F03 {1F03} internal, hidden 35 | 21: unknown:1F04 {1F04} internal, hidden 36 | 22: VERTICAL SCROLLING {2100} 37 | 23: unknown:2101 {2101} hidden 38 | 24: HI RES SCROLLING {2120} 39 | 25: MOUSE POINTER {2200} 40 | 26: TOUCHMOUSE RAW POINTS {6110} hidden 41 | 27: REPROG CONTROLS V3 {1B03} 42 | Has 7 reprogrammable keys: 43 | 0: LEFT CLICK => LeftClick mse, reprogrammable 44 | 1: RIGHT CLICK => RightClick mse, reprogrammable 45 | 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 46 | 3: METRO START SCREEN => MetroStartScreen mse, reprogrammable 47 | 4: ZOOMIN => Do Nothing mse, reprogrammable 48 | 5: ZOOMOUT => Do Nothing mse, reprogrammable 49 | 6: BACK HSCROLL => TouchBackForwardHorzScroll 50 | Battery: 100%, discharging. 51 | -------------------------------------------------------------------------------- /docs/devices/anywhere-mx.txt: -------------------------------------------------------------------------------- 1 | Receiver 2 | LZ301AR-DJ 3 | M/N:C-U0007 4 | (ltunify) 5 | Serial number: D1759614 6 | Firmware version: 012.001.00019 7 | Bootloader version: BL.002.014 8 | 9 | Supported notification flags: 00 09 00 10 | - 01: Wireless Notifications 11 | - 08: Software Present 12 | 13 | Mouse 14 | (ltunify) 15 | HID++ version: 1.0 16 | Device index 1 17 | Mouse 18 | Name: Anywhere MX 19 | Wireless Product ID: 1017 20 | Serial number: 13865F99 21 | Firmware version: 016.001.00040 22 | Bootloader version: BL.002.010 23 | (solaar) 24 | Unifying Receiver 25 | Device path : /dev/hidraw2 26 | USB id : 046d:c52b 27 | Serial : D1759614 28 | Firmware : 12.01.B0019 29 | Bootloader : 02.14 30 | Has 1 paired device(s) out of a maximum of 6. 31 | Notifications: (none) 32 | Device activity counters: 1=19 33 | 34 | 1: Anywhere Mouse MX 35 | Codename : Anywhere MX 36 | Kind : mouse 37 | Wireless PID : 1017 38 | Protocol : HID++ 1.0 39 | Polling rate : 8 ms (125Hz) 40 | Serial number: 13865F99 41 | Firmware: 16.01.B0040 42 | Bootloader: 02.10 43 | Other: 00.06 44 | The power switch is located on the base. 45 | Notifications: (none). 46 | Battery: 100%, discharging. 47 | 48 | (scan-registers) 49 | # Old notification flags: 000000 50 | # 00 - Enabled Notifications, supported flags: Battery Status (10) 51 | >> ( 0.792) [10 01 8100 100000] b'\x10\x01\x81\x00\x10\x00\x00' 52 | 53 | # 01 - scrolling settings? 54 | # Flags: 55 | # 0x40 - Enable Smooth Scrolling 56 | # 0x02 - "confuse KDE", see https://github.com/pwr/Solaar/issues/115 57 | << ( 0.011) [10 01 8101 000000] b'\x10\x01\x81\x01\x00\x00\x00' 58 | >> ( 1.710) [10 01 8101 020000] b'\x10\x01\x81\x01\x02\x00\x00' 59 | 60 | # 0D - battery level. first byte is remaining charge in percent; second is 61 | # (guessed) maximum?; third is charge status (30=discharging) 62 | # "10 ix 0D 64 64 30 00" is a battery notification (when enabled) 63 | << ( 9.789) [10 01 810D 000000] b'\x10\x01\x81\r\x00\x00\x00' 64 | >> ( 9.816) [10 01 810D 646430] b'\x10\x01\x81\rdd0' 65 | 66 | # 63 - DPI (range 0x80-0x8e (inclusive)) 67 | << ( 75.521) [10 01 8163 000000] b'\x10\x01\x81c\x00\x00\x00' 68 | >> ( 75.550) [10 01 8163 890000] b'\x10\x01\x81c\x89\x00\x00' 69 | 70 | # D0 - ? 71 | << ( 163.118) [10 01 81D0 000000] b'\x10\x01\x81\xd0\x00\x00\x00' 72 | >> ( 163.148) [10 01 81D0 000000] b'\x10\x01\x81\xd0\x00\x00\x00' 73 | 74 | # D4 - ? 75 | << ( 166.034) [10 01 81D4 000000] b'\x10\x01\x81\xd4\x00\x00\x00' 76 | >> ( 166.063) [10 01 81D4 000008] b'\x10\x01\x81\xd4\x00\x00\x08' 77 | 78 | # F1 - firmware/bootloader version 79 | << ( 187.172) [10 01 81F1 000000] b'\x10\x01\x81\xf1\x00\x00\x00' 80 | >> ( 187.199) [10 01 8F81 F10300] b'\x10\x01\x8f\x81\xf1\x03\x00' 81 | 82 | # F3 - ? 83 | << ( 188.629) [10 01 81F3 000000] b'\x10\x01\x81\xf3\x00\x00\x00' 84 | >> ( 188.661) [10 01 81F3 000000] b'\x10\x01\x81\xf3\x00\x00\x00' 85 | 86 | # FD - ? 87 | << ( 195.715) [10 01 83FD 000000] b'\x10\x01\x83\xfd\x00\x00\x00' 88 | >> ( 195.746) [11 01 83FD 00000000000000000000000000000000] b'\x11\x01\x83\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 89 | -------------------------------------------------------------------------------- /docs/devices/mk700.txt: -------------------------------------------------------------------------------- 1 | # Enabled Notifications 2 | # 10 - battery status 3 | # 02 + 01 - remap FN keys (multimedia + power buttons) 4 | >> ( 1.412) [10 02 8100 130000] '\x10\x02\x81\x00\x13\x00\x00' 5 | << ( 0.011) [10 02 8101 000000] '\x10\x02\x81\x01\x00\x00\x00' 6 | >> ( 0.276) [10 02 8101 000000] '\x10\x02\x81\x01\x00\x00\x00' 7 | 8 | # Battery status 9 | << ( 6.033) [10 02 8107 000000] '\x10\x02\x81\x07\x00\x00\x00' 10 | >> ( 6.344) [10 02 8107 070000] '\x10\x02\x81\x07\x07\x00\x00' 11 | 12 | # FN status 13 | << ( 8.055) [10 02 8109 000000] '\x10\x02\x81\t\x00\x00\x00' 14 | >> ( 8.144) [10 02 8109 000000] '\x10\x02\x81\t\x00\x00\x00' 15 | 16 | # ? 17 | << ( 208.316) [10 02 81D0 000000] '\x10\x02\x81\xd0\x00\x00\x00' 18 | >> ( 208.353) [10 02 81D0 000000] '\x10\x02\x81\xd0\x00\x00\x00' 19 | 20 | # version info 21 | << ( 237.436) [10 02 81F1 000000] '\x10\x02\x81\xf1\x00\x00\x00' 22 | >> ( 237.744) [10 02 8F81 F10300] '\x10\x02\x8f\x81\xf1\x03\x00' 23 | 24 | # ? 25 | << ( 239.459) [10 02 81F3 000000] '\x10\x02\x81\xf3\x00\x00\x00' 26 | >> ( 239.766) [10 02 81F3 000000] '\x10\x02\x81\xf3\x00\x00\x00' 27 | -------------------------------------------------------------------------------- /docs/devices/performance-mx.txt: -------------------------------------------------------------------------------- 1 | # Notifications (r1_bit0 = battery status?) 2 | << ( 0.113) [10 01 8100 000000] '\x10\x01\x81\x00\x00\x00\x00' 3 | >> ( 0.157) [10 01 8100 100000] '\x10\x01\x81\x00\x10\x00\x00' 4 | 5 | # ? 6 | << ( 1.050) [10 01 8101 000000] '\x10\x01\x81\x01\x00\x00\x00' 7 | >> ( 1.097) [10 01 8101 020000] '\x10\x01\x81\x01\x02\x00\x00' 8 | 9 | # battery (07 means full) 10 | << ( 7.335) [10 01 8107 000000] '\x10\x01\x81\x07\x00\x00\x00' 11 | >> ( 7.382) [10 01 8107 070000] '\x10\x01\x81\x07\x07\x00\x00' 12 | 13 | # Set LEDS - ab cd 00, where a/b/c/d values are 1=off, 2=on, 3=flash 14 | # a = lower led 15 | # b = red led 16 | # c = upper led 17 | # d = middle led 18 | # below: all leds are off 19 | << ( 86.592) [10 01 8151 000000] '\x10\x01\x81Q\x00\x00\x00' 20 | >> ( 86.639) [10 01 8151 111100] '\x10\x01\x81Q\x11\x11\x00' 21 | 22 | # DPI (values in range 0x81..0x8F; logical value: 100..1500) 23 | << ( 108.430) [10 01 8163 000000] '\x10\x01\x81c\x00\x00\x00' 24 | >> ( 108.477) [10 01 8163 890000] '\x10\x01\x81c\x89\x00\x00' 25 | 26 | # ? 27 | << ( 240.505) [10 01 81D0 000000] '\x10\x01\x81\xd0\x00\x00\x00' 28 | >> ( 240.550) [10 01 81D0 000000] '\x10\x01\x81\xd0\x00\x00\x00' 29 | 30 | # ? 31 | << ( 245.690) [10 01 81D4 000000] '\x10\x01\x81\xd4\x00\x00\x00' 32 | >> ( 245.737) [10 01 81D4 000012] '\x10\x01\x81\xd4\x00\x00\x12' 33 | 34 | # Firmware/bootloader version 35 | << ( 281.016) [10 01 81F1 000000] '\x10\x01\x81\xf1\x00\x00\x00' 36 | >> ( 282.177) [10 01 8F81 F10300] '\x10\x01\x8f\x81\xf1\x03\x00' 37 | 38 | # ? 39 | << ( 284.106) [10 01 81F3 000000] '\x10\x01\x81\xf3\x00\x00\x00' 40 | >> ( 284.153) [10 01 81F3 000000] '\x10\x01\x81\xf3\x00\x00\x00' 41 | -------------------------------------------------------------------------------- /docs/hidpp-documentation.txt: -------------------------------------------------------------------------------- 1 | Documentation on HID++ can be found in the Google drive directory 2 | https://drive.google.com/drive/folders/0BxbRzx7vEV7eWmgwazJ3NUFfQ28 3 | -------------------------------------------------------------------------------- /docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/img/favicon.ico -------------------------------------------------------------------------------- /docs/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/img/favicon.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-back-divert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-back-divert.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-button-actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-button-actions.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-keyboard.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-mouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-mouse.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-multiple.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-offline.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-receiver-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-receiver-old.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-main-window-receiver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-main-window-receiver.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-menu.png -------------------------------------------------------------------------------- /docs/screenshots/Solaar-rule-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/docs/screenshots/Solaar-rule-editor.png -------------------------------------------------------------------------------- /docs/unistallation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Uninstalling Solaar 3 | layout: page 4 | --- 5 | 6 | # Uninstalling Solaar 7 | 8 | ## Uninstalling from Debian systems 9 | 10 | If you installed Solaar using `apt`, you can remove it by running: 11 | 12 | ```bash 13 | sudo apt remove --purge solaar 14 | ``` 15 | 16 | ## Uninstalling from GitHub 17 | 18 | If you cloned and installed Solaar from GitHub manually, navigate to the cloned directory and run: 19 | 20 | ```bash 21 | sudo make uninstall 22 | ``` 23 | 24 | ## Removing Configuration Files 25 | 26 | Solaar may leave behind configuration files in your home directory. To delete them, run: 27 | 28 | ```bash 29 | rm -rf ~/.config/solaar 30 | ``` 31 | 32 | ## Verifying Uninstallation 33 | 34 | To confirm that Solaar is fully removed, try running: 35 | 36 | ```bash 37 | which solaar 38 | ``` 39 | 40 | If no output is returned, Solaar has been successfully uninstalled. 41 | -------------------------------------------------------------------------------- /lib/hidapi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/lib/hidapi/__init__.py -------------------------------------------------------------------------------- /lib/hidapi/common.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import dataclasses 4 | 5 | 6 | @dataclasses.dataclass 7 | class DeviceInfo: 8 | path: str 9 | bus_id: str | None 10 | vendor_id: str 11 | product_id: str 12 | interface: str | None 13 | driver: str | None 14 | manufacturer: str | None 15 | product: str | None 16 | serial: str | None 17 | release: str | None 18 | isDevice: bool 19 | hidpp_short: str | None 20 | hidpp_long: str | None 21 | -------------------------------------------------------------------------------- /lib/keysyms/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/lib/keysyms/__init__.py -------------------------------------------------------------------------------- /lib/keysyms/generate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """Extract key symbol encodings from X11 header files.""" 3 | 4 | from pathlib import Path 5 | from pprint import pprint 6 | from re import findall 7 | from subprocess import run 8 | from tempfile import TemporaryDirectory 9 | 10 | repo = "https://gitlab.freedesktop.org/xorg/proto/xorgproto.git" 11 | pattern = r"#define XK_(\w+)\s+0x(\w+)(?:\s+/\*\s+U\+(\w+))?" 12 | xf86pattern = r"#define XF86XK_(\w+)\s+0x(\w+)(?:\s+/\*\s+U\+(\w+))?" 13 | 14 | 15 | def main(): 16 | keysymdef = {} 17 | keysym_files = [ 18 | ("include/X11/keysymdef.h", pattern, ""), 19 | ("include/X11/XF86keysym.h", xf86pattern, "XF86_"), 20 | ] 21 | 22 | with TemporaryDirectory() as temp: 23 | run(["git", "clone", repo, "."], cwd=temp) 24 | 25 | for filename, extraction_pattern, prefix in keysym_files: 26 | text = Path(temp, filename).read_text() 27 | for name, sym, _ in findall(extraction_pattern, text): 28 | sym = int(sym, 16) 29 | if keysymdef.get(f"{prefix}{name}", None): 30 | print(f"KEY DUP {prefix}{name}") 31 | keysymdef[f"{prefix}{name}"] = sym 32 | 33 | with open("keysymdef.py", "w") as f: 34 | f.write("# flake8: noqa\nkey_symbols = \\\n") 35 | pprint(keysymdef, f) 36 | 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /lib/logitech_receiver/__init__.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | """Low-level interface for devices using Logitech HID++ protocol. 17 | 18 | Uses the HID api exposed through hidapi_impl.py, a Python thin layer over a native 19 | implementation. 20 | """ 21 | 22 | import logging 23 | 24 | logger = logging.getLogger(__name__) 25 | -------------------------------------------------------------------------------- /lib/logitech_receiver/exceptions.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## Copyright (C) 2014-2024 Solaar Contributors https://pwr-solaar.github.io/Solaar/ 3 | ## 4 | ## This program is free software; you can redistribute it and/or modify 5 | ## it under the terms of the GNU General Public License as published by 6 | ## the Free Software Foundation; either version 2 of the License, or 7 | ## (at your option) any later version. 8 | ## 9 | ## This program is distributed in the hope that it will be useful, 10 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ## GNU General Public License for more details. 13 | ## 14 | ## You should have received a copy of the GNU General Public License along 15 | ## with this program; if not, write to the Free Software Foundation, Inc., 16 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | from .common import KwException 19 | 20 | """Exceptions that may be raised by this API.""" 21 | 22 | 23 | class NoReceiver(KwException): 24 | """Raised when trying to talk through a previously open handle, when the 25 | receiver is no longer available. Should only happen if the receiver is 26 | physically disconnected from the machine, or its kernel driver module is 27 | unloaded.""" 28 | 29 | pass 30 | 31 | 32 | class NoSuchDevice(KwException): 33 | """Raised when trying to reach a device number not paired to the receiver.""" 34 | 35 | pass 36 | 37 | 38 | class DeviceUnreachable(KwException): 39 | """Raised when a request is made to an unreachable (turned off) device.""" 40 | 41 | pass 42 | 43 | 44 | class FeatureNotSupported(KwException): 45 | """Raised when trying to request a feature not supported by the device.""" 46 | 47 | pass 48 | 49 | 50 | class FeatureCallError(KwException): 51 | """Raised if the device replied to a feature call with an error.""" 52 | 53 | pass 54 | -------------------------------------------------------------------------------- /lib/logitech_receiver/i18n.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | # Translation support for the Logitech receivers library 18 | 19 | import gettext 20 | 21 | _ = gettext.gettext 22 | ngettext = gettext.ngettext 23 | 24 | # A few common strings, not always accessible as such in the code. 25 | 26 | _DUMMY = ( 27 | # approximative battery levels 28 | _("empty"), 29 | _("critical"), 30 | _("low"), 31 | _("average"), 32 | _("good"), 33 | _("full"), 34 | # battery charging statuses 35 | _("discharging"), 36 | _("recharging"), 37 | _("charging"), 38 | _("not charging"), 39 | _("almost full"), 40 | _("charged"), 41 | _("slow recharge"), 42 | _("invalid battery"), 43 | _("thermal error"), 44 | _("error"), 45 | _("standard"), 46 | _("fast"), 47 | _("slow"), 48 | # pairing errors 49 | _("device timeout"), 50 | _("device not supported"), 51 | _("too many devices"), 52 | _("sequence timeout"), 53 | # firmware kinds 54 | _("Firmware"), 55 | _("Bootloader"), 56 | _("Hardware"), 57 | _("Other"), 58 | # common button and task names (from special_keys.py) 59 | _("Left Button"), 60 | _("Right Button"), 61 | _("Middle Button"), 62 | _("Back Button"), 63 | _("Forward Button"), 64 | _("Mouse Gesture Button"), 65 | _("Smart Shift"), 66 | _("DPI Switch"), 67 | _("Left Tilt"), 68 | _("Right Tilt"), 69 | _("Left Click"), 70 | _("Right Click"), 71 | _("Mouse Middle Button"), 72 | _("Mouse Back Button"), 73 | _("Mouse Forward Button"), 74 | _("Gesture Button Navigation"), 75 | _("Mouse Scroll Left Button"), 76 | _("Mouse Scroll Right Button"), 77 | # key/button statuses 78 | _("pressed"), 79 | _("released"), 80 | ) 81 | -------------------------------------------------------------------------------- /lib/solaar/__init__.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | import pkgutil 18 | import subprocess 19 | import sys 20 | 21 | NAME = "Solaar" 22 | 23 | try: 24 | __version__ = ( 25 | subprocess.check_output( 26 | [ 27 | "git", 28 | "describe", 29 | "--always", 30 | ], 31 | cwd=sys.path[0], 32 | stderr=subprocess.DEVNULL, 33 | ) 34 | .strip() 35 | .decode() 36 | ) 37 | except Exception: 38 | try: 39 | __version__ = pkgutil.get_data("solaar", "commit").strip().decode() 40 | except Exception: 41 | __version__ = pkgutil.get_data("solaar", "version").strip().decode() 42 | -------------------------------------------------------------------------------- /lib/solaar/cli/profiles.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | import traceback 18 | 19 | import yaml 20 | 21 | from logitech_receiver.hidpp20 import OnboardProfiles 22 | from logitech_receiver.hidpp20 import OnboardProfilesVersion 23 | 24 | 25 | def run(receivers, args, find_receiver, find_device): 26 | assert receivers 27 | assert args.device 28 | 29 | device_name = args.device.lower() 30 | profiles_file = args.profiles 31 | 32 | dev = None 33 | for dev in find_device(receivers, device_name): 34 | if dev.ping(): 35 | break 36 | dev = None 37 | 38 | if not dev: 39 | raise Exception(f"no online device found matching '{device_name}'") 40 | 41 | if not (dev.online and dev.profiles): 42 | print(f"Device {dev.name} is either offline or has no onboard profiles") 43 | elif not profiles_file: 44 | print(f"#Dumping profiles from {dev.name}") 45 | print(yaml.dump(dev.profiles)) 46 | else: 47 | try: 48 | with open(profiles_file, "r") as f: 49 | print(f"Reading profiles from {profiles_file}") 50 | profiles = yaml.safe_load(f) 51 | if not isinstance(profiles, OnboardProfiles): 52 | print("Profiles file does not contain current onboard profiles") 53 | elif getattr(profiles, "version", None) != OnboardProfilesVersion: 54 | version = getattr(profiles, "version", None) 55 | print(f"Missing or incorrect profile version {version} in loaded profile") 56 | elif getattr(profiles, "name", None) != dev.name: 57 | name = getattr(profiles, "name", None) 58 | print(f"Different device name {name} in loaded profile") 59 | else: 60 | print(f"Loading profiles into {dev.name}") 61 | written = profiles.write(dev) 62 | print(f"Wrote {written} sectors to {dev.name}") 63 | except Exception as exc: 64 | print("Profiles not written:", exc) 65 | print(traceback.format_exc()) 66 | -------------------------------------------------------------------------------- /lib/solaar/cli/unpair.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | 18 | def run(receivers, args, find_receiver, find_device): 19 | assert receivers 20 | assert args.device 21 | 22 | device_name = args.device.lower() 23 | dev = next(find_device(receivers, device_name), None) 24 | if not dev: 25 | raise Exception(f"no device found matching '{device_name}'") 26 | 27 | if not dev.receiver.may_unpair: 28 | print( 29 | f"Receiver with USB id {dev.receiver.product_id} for {dev.name} [{dev.wpid}:{dev.serial}] does not unpair,", 30 | "but attempting anyway.", 31 | ) 32 | try: 33 | # query these now, it's last chance to get them 34 | number, codename, wpid, serial = dev.number, dev.codename, dev.wpid, dev.serial 35 | dev.receiver._unpair_device(number, True) # force an unpair 36 | print(f"Unpaired {int(number)}: {dev.name} ({codename}) [{wpid}:{serial}]") 37 | except Exception as e: 38 | raise e 39 | -------------------------------------------------------------------------------- /lib/solaar/custom_logger.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | 4 | class CustomLogger(logging.Logger): 5 | """Logger, that avoids unnecessary string computations. 6 | 7 | Does not compute messages for disabled log levels. 8 | """ 9 | 10 | def debug(self, msg, *args, **kwargs): 11 | if self.isEnabledFor(logging.DEBUG): 12 | super().debug(msg, *args, **kwargs) 13 | 14 | def info(self, msg, *args, **kwargs): 15 | if self.isEnabledFor(logging.INFO): 16 | super().info(msg, *args, **kwargs) 17 | 18 | def warning(self, msg, *args, **kwargs): 19 | if self.isEnabledFor(logging.WARNING): 20 | super().warning(msg, *args, **kwargs) 21 | 22 | def error(self, msg, *args, **kwargs): 23 | if self.isEnabledFor(logging.ERROR): 24 | super().error(msg, *args, **kwargs) 25 | 26 | def critical(self, msg, *args, **kwargs): 27 | if self.isEnabledFor(logging.CRITICAL): 28 | super().critical(msg, *args, **kwargs) 29 | -------------------------------------------------------------------------------- /lib/solaar/dbus.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## Copyright (C) 2014-2024 Solaar Contributors https://pwr-solaar.github.io/Solaar/ 3 | ## 4 | ## This program is free software; you can redistribute it and/or modify 5 | ## it under the terms of the GNU General Public License as published by 6 | ## the Free Software Foundation; either version 2 of the License, or 7 | ## (at your option) any later version. 8 | ## 9 | ## This program is distributed in the hope that it will be useful, 10 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ## GNU General Public License for more details. 13 | ## 14 | ## You should have received a copy of the GNU General Public License along 15 | ## with this program; if not, write to the Free Software Foundation, Inc., 16 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | from __future__ import annotations 18 | 19 | import logging 20 | 21 | from typing import Callable 22 | 23 | logger = logging.getLogger(__name__) 24 | 25 | try: 26 | import dbus 27 | 28 | from dbus.mainloop.glib import DBusGMainLoop # integration into the main GLib loop 29 | 30 | DBusGMainLoop(set_as_default=True) 31 | bus = dbus.SystemBus() 32 | assert bus 33 | 34 | except Exception: 35 | # Either the dbus library is not available or the system dbus is not running 36 | logger.warning("failed to set up dbus") 37 | bus = None 38 | 39 | 40 | _suspend_callback = None 41 | _resume_callback = None 42 | 43 | 44 | def _suspend_or_resume(suspend): 45 | if suspend and _suspend_callback: 46 | _suspend_callback() 47 | if not suspend and _resume_callback: 48 | _resume_callback() 49 | 50 | 51 | _LOGIND_PATH = "/org/freedesktop/login1" 52 | _LOGIND_INTERFACE = "org.freedesktop.login1.Manager" 53 | 54 | 55 | def watch_suspend_resume( 56 | on_resume_callback: Callable[[], None] | None = None, 57 | on_suspend_callback: Callable[[], None] | None = None, 58 | ): 59 | """Register callback for suspend/resume events. 60 | They are called only if the system DBus is running, and the Login daemon is available.""" 61 | global _resume_callback, _suspend_callback 62 | _suspend_callback = on_suspend_callback 63 | _resume_callback = on_resume_callback 64 | if bus is not None and on_resume_callback is not None or on_suspend_callback is not None: 65 | bus.add_signal_receiver( 66 | _suspend_or_resume, 67 | "PrepareForSleep", 68 | dbus_interface=_LOGIND_INTERFACE, 69 | path=_LOGIND_PATH, 70 | ) 71 | logger.info("connected to system dbus, watching for suspend/resume events") 72 | 73 | 74 | _BLUETOOTH_PATH_PREFIX = "/org/bluez/hci0/dev_" 75 | _BLUETOOTH_INTERFACE = "org.freedesktop.DBus.Properties" 76 | 77 | _bluetooth_callbacks = {} 78 | 79 | 80 | def watch_bluez_connect(serial, callback=None): 81 | if _bluetooth_callbacks.get(serial): 82 | _bluetooth_callbacks.get(serial).remove() 83 | path = _BLUETOOTH_PATH_PREFIX + serial.replace(":", "_").upper() 84 | if bus is not None and callback is not None: 85 | _bluetooth_callbacks[serial] = bus.add_signal_receiver( 86 | callback, "PropertiesChanged", path=path, dbus_interface=_BLUETOOTH_INTERFACE 87 | ) 88 | -------------------------------------------------------------------------------- /lib/solaar/i18n.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) 2012-2013 Daniel Pavel 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | import gettext 18 | import locale 19 | import os 20 | import sys 21 | 22 | from glob import glob 23 | 24 | from solaar import NAME 25 | 26 | _LOCALE_DOMAIN = NAME.lower() 27 | 28 | 29 | def _find_locale_path(locale_domain: str) -> str: 30 | prefix_share = os.path.normpath(os.path.join(os.path.realpath(sys.path[0]), "..")) 31 | src_share = os.path.normpath(os.path.join(os.path.realpath(sys.path[0]), "..", "share")) 32 | 33 | for location in prefix_share, src_share: 34 | mo_files = glob(os.path.join(location, "locale", "*", "LC_MESSAGES", f"{locale_domain}.mo")) 35 | if mo_files: 36 | return os.path.join(location, "locale") 37 | raise FileNotFoundError(f"Could not find locale path for {locale_domain}") 38 | 39 | 40 | def set_locale_to_system_default(): 41 | """Sets locale for translations to the system default. 42 | 43 | Set LC_ALL environment variable to enforce a locale setting e.g. 44 | 'de_DE.UTF-8'. Run Solaar with your desired localization, for German 45 | use: 46 | 'LC_ALL=de_DE.UTF-8 solaar' 47 | """ 48 | try: 49 | locale.setlocale(locale.LC_ALL, "") 50 | except Exception: 51 | pass 52 | 53 | try: 54 | path = _find_locale_path(_LOCALE_DOMAIN) 55 | except FileNotFoundError: 56 | path = None 57 | gettext.bindtextdomain(_LOCALE_DOMAIN, path) 58 | gettext.textdomain(_LOCALE_DOMAIN) 59 | gettext.install(_LOCALE_DOMAIN) 60 | 61 | 62 | set_locale_to_system_default() 63 | 64 | _ = gettext.gettext 65 | ngettext = gettext.ngettext 66 | -------------------------------------------------------------------------------- /lib/solaar/tasks.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ## Copyright (C) 2012-2013 Daniel Pavel 4 | ## 5 | ## This program is free software; you can redistribute it and/or modify 6 | ## it under the terms of the GNU General Public License as published by 7 | ## the Free Software Foundation; either version 2 of the License, or 8 | ## (at your option) any later version. 9 | ## 10 | ## This program is distributed in the hope that it will be useful, 11 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ## GNU General Public License for more details. 14 | ## 15 | ## You should have received a copy of the GNU General Public License along 16 | ## with this program; if not, write to the Free Software Foundation, Inc., 17 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | 19 | import logging 20 | 21 | from threading import Thread 22 | 23 | logger = logging.getLogger(__name__) 24 | 25 | try: 26 | from Queue import Queue 27 | except ImportError: 28 | from queue import Queue 29 | 30 | 31 | class TaskRunner(Thread): 32 | def __init__(self, name): 33 | super().__init__(name=name) 34 | self.daemon = True 35 | self.queue = Queue(16) 36 | self.alive = False 37 | 38 | def __call__(self, function, *args, **kwargs): 39 | task = (function, args, kwargs) 40 | self.queue.put(task) 41 | 42 | def stop(self): 43 | self.alive = False 44 | self.queue.put(None) 45 | 46 | def run(self): 47 | self.alive = True 48 | 49 | logger.debug("started") 50 | 51 | while self.alive: 52 | task = self.queue.get() 53 | if task: 54 | function, args, kwargs = task 55 | assert function 56 | try: 57 | function(*args, **kwargs) 58 | except Exception: 59 | logger.exception("calling %s", function) 60 | 61 | logger.debug("stopped") 62 | -------------------------------------------------------------------------------- /lib/solaar/ui/about/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/lib/solaar/ui/about/__init__.py -------------------------------------------------------------------------------- /lib/solaar/ui/about/about.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) Solaar Contributors 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | from solaar.ui.about.model import AboutModel 18 | from solaar.ui.about.presenter import Presenter 19 | from solaar.ui.about.view import AboutView 20 | 21 | 22 | def show(_=None, model=None, view=None): 23 | """Opens the About dialog.""" 24 | if model is None: 25 | model = AboutModel() 26 | if view is None: 27 | view = AboutView() 28 | presenter = Presenter(model, view) 29 | presenter.run() 30 | 31 | 32 | if __name__ == "__main__": 33 | from gi.repository import Gtk 34 | 35 | show(None) 36 | Gtk.main() 37 | -------------------------------------------------------------------------------- /lib/solaar/ui/about/model.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) Solaar Contributors 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | from __future__ import annotations 18 | 19 | from datetime import datetime 20 | from typing import List 21 | from typing import Tuple 22 | 23 | from solaar import __version__ 24 | from solaar.i18n import _ 25 | 26 | 27 | def _get_current_year() -> int: 28 | return datetime.now().year 29 | 30 | 31 | class AboutModel: 32 | def get_version(self) -> str: 33 | return __version__ 34 | 35 | def get_description(self) -> str: 36 | return _("Manages Logitech receivers,\nkeyboards, mice, and tablets.") 37 | 38 | def get_copyright(self) -> str: 39 | return f"© 2012-{_get_current_year()} Daniel Pavel and contributors to the Solaar project" 40 | 41 | def get_authors(self) -> List[str]: 42 | return [ 43 | "Daniel Pavel http://github.com/pwr", 44 | ] 45 | 46 | def get_translators(self) -> List[str]: 47 | return [ 48 | "gogo (croatian)", 49 | "Papoteur, David Geiger, Damien Lallement (français)", 50 | "Michele Olivo (italiano)", 51 | "Adrian Piotrowicz (polski)", 52 | "Drovetto, JrBenito (Portuguese-BR)", 53 | "Daniel Pavel (română)", 54 | "Daniel Zippert, Emelie Snecker (svensk)", 55 | "Dimitriy Ryazantcev (Russian)", 56 | "El Jinete Sin Cabeza (Español)", 57 | "Ferdina Kusumah (Indonesia)", 58 | "John Erling Blad (Norwegian Bokmål, Norwegian Nynorsk)", 59 | ] 60 | 61 | def get_credit_sections(self) -> List[Tuple[str, List[str]]]: 62 | return [ 63 | (_("Additional Programming"), ["Filipe Laíns", "Peter F. Patel-Schneider"]), 64 | (_("GUI design"), ["Julien Gascard", "Daniel Pavel"]), 65 | ( 66 | _("Testing"), 67 | [ 68 | "Douglas Wagner", 69 | "Julien Gascard", 70 | "Peter Wu http://www.lekensteyn.nl/logitech-unifying.html", 71 | ], 72 | ), 73 | ( 74 | _("Logitech documentation"), 75 | [ 76 | "Julien Danjou http://julien.danjou.info/blog/2012/logitech-unifying-upower", 77 | "Nestor Lopez Casado http://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28", 78 | ], 79 | ), 80 | ] 81 | 82 | def get_website(self): 83 | return "https://pwr-solaar.github.io/Solaar" 84 | -------------------------------------------------------------------------------- /lib/solaar/ui/about/presenter.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) Solaar Contributors 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | 17 | from __future__ import annotations 18 | 19 | from typing_extensions import Protocol 20 | 21 | from solaar.ui.about.model import AboutModel 22 | 23 | 24 | class AboutViewProtocol(Protocol): 25 | def init_ui(self) -> None: 26 | ... 27 | 28 | def update_version_info(self, version: str) -> None: 29 | ... 30 | 31 | def update_description(self, comments: str) -> None: 32 | ... 33 | 34 | def update_copyright(self, copyright_text: str) -> None: 35 | ... 36 | 37 | def update_authors(self, authors: list[str]) -> None: 38 | ... 39 | 40 | def update_translators(self, translators: list[str]) -> None: 41 | ... 42 | 43 | def update_website(self, website): 44 | ... 45 | 46 | def update_credits(self, credit_sections: list[tuple[str, list[str]]]) -> None: 47 | ... 48 | 49 | def show(self) -> None: 50 | ... 51 | 52 | 53 | class Presenter: 54 | def __init__(self, model: AboutModel, view: AboutViewProtocol) -> None: 55 | self.model = model 56 | self.view = view 57 | 58 | def update_version_info(self) -> None: 59 | version = self.model.get_version() 60 | self.view.update_version_info(version) 61 | 62 | def update_credits(self) -> None: 63 | credit_sections = self.model.get_credit_sections() 64 | self.view.update_credits(credit_sections) 65 | 66 | def update_description(self) -> None: 67 | comments = self.model.get_description() 68 | self.view.update_description(comments) 69 | 70 | def update_copyright(self) -> None: 71 | copyright_text = self.model.get_copyright() 72 | self.view.update_copyright(copyright_text) 73 | 74 | def update_authors(self) -> None: 75 | authors = self.model.get_authors() 76 | self.view.update_authors(authors) 77 | 78 | def update_translators(self) -> None: 79 | translators = self.model.get_translators() 80 | self.view.update_translators(translators) 81 | 82 | def update_website(self) -> None: 83 | website = self.model.get_website() 84 | self.view.update_website(website) 85 | 86 | def run(self) -> None: 87 | self.view.init_ui() 88 | self.update_version_info() 89 | self.update_description() 90 | self.update_website() 91 | self.update_copyright() 92 | self.update_authors() 93 | self.update_credits() 94 | self.update_translators() 95 | self.view.show() 96 | -------------------------------------------------------------------------------- /lib/solaar/ui/about/view.py: -------------------------------------------------------------------------------- 1 | ## Copyright (C) Solaar Contributors 2 | ## 3 | ## This program is free software; you can redistribute it and/or modify 4 | ## it under the terms of the GNU General Public License as published by 5 | ## the Free Software Foundation; either version 2 of the License, or 6 | ## (at your option) any later version. 7 | ## 8 | ## This program is distributed in the hope that it will be useful, 9 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | ## GNU General Public License for more details. 12 | ## 13 | ## You should have received a copy of the GNU General Public License along 14 | ## with this program; if not, write to the Free Software Foundation, Inc., 15 | ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | from enum import Enum 17 | from typing import List 18 | from typing import Tuple 19 | from typing import Union 20 | 21 | from gi.repository import Gtk 22 | 23 | from solaar import NAME 24 | 25 | 26 | class GtkSignal(Enum): 27 | RESPONSE = "response" 28 | 29 | 30 | class AboutView: 31 | def __init__(self) -> None: 32 | self.view: Union[Gtk.AboutDialog, None] = None 33 | 34 | def init_ui(self) -> None: 35 | self.view = Gtk.AboutDialog() 36 | self.view.set_program_name(NAME) 37 | self.view.set_logo_icon_name(NAME.lower()) 38 | self.view.set_license_type(Gtk.License.GPL_2_0) 39 | 40 | self.view.connect(GtkSignal.RESPONSE.value, lambda x, y: self.handle_close(x)) 41 | 42 | def update_version_info(self, version: str) -> None: 43 | self.view.set_version(version) 44 | 45 | def update_description(self, comments: str) -> None: 46 | self.view.set_comments(comments) 47 | 48 | def update_copyright(self, copyright_text: str): 49 | self.view.set_copyright(copyright_text) 50 | 51 | def update_authors(self, authors: List[str]) -> None: 52 | self.view.set_authors(authors) 53 | 54 | def update_credits(self, credit_sections: List[Tuple[str, List[str]]]) -> None: 55 | for section_name, people in credit_sections: 56 | self.view.add_credit_section(section_name, people) 57 | 58 | def update_translators(self, translators: List[str]) -> None: 59 | translator_credits = "\n".join(translators) 60 | self.view.set_translator_credits(translator_credits) 61 | 62 | def update_website(self, website): 63 | self.view.set_website_label(NAME) 64 | self.view.set_website(website) 65 | 66 | def show(self) -> None: 67 | self.view.present() 68 | 69 | def handle_close(self, event) -> None: 70 | event.hide() 71 | -------------------------------------------------------------------------------- /lib/solaar/version: -------------------------------------------------------------------------------- 1 | 1.1.14 2 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Solaar Documentation 2 | site_description: Linux Device Manager for Logitech Unifying Receivers and Devices. 3 | site_author: pwr-Solaar 4 | repo_url: https://github.com/pwr-Solaar/Solaar 5 | repo_name: Solaar 6 | logo: img/favicon.png 7 | theme: 8 | name: readthedocs 9 | docs_dir: docs 10 | nav: 11 | - Solaar: index.md 12 | - Capabilities: capabilities.md 13 | - Debian: debian.md 14 | - Devices: devices.md 15 | - Features: features.md 16 | - Translation: i18n.md 17 | - Implementation: implementation.md 18 | - Installation: installation.md 19 | - Uninstallation: uninstallation.md 20 | - Rules: rules.md 21 | - Usage: usage.md 22 | 23 | plugins: 24 | - search 25 | # - mkdocstrings: 26 | # handlers: 27 | # python: 28 | # setup_commands: 29 | # - python -m pip install . 30 | - mermaid2 31 | markdown_extensions: 32 | - pymdownx.superfences 33 | -------------------------------------------------------------------------------- /po/README: -------------------------------------------------------------------------------- 1 | See docs/i18n.md for instructions about creating or updating a translation. 2 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.ruff] 2 | line-length = 127 3 | target-version = "py37" 4 | 5 | [tool.ruff.lint] 6 | select = [ 7 | "F", # Pyflakes 8 | "E", # pycodestyle 9 | "W", # pycodestyle 10 | "B", # flake8-bugbear 11 | "I", # isort 12 | ] 13 | 14 | [tool.ruff.lint.isort] 15 | force-single-line = true 16 | lines-between-types = 1 17 | -------------------------------------------------------------------------------- /rules.d-uinput/42-logitech-unify-permissions.rules: -------------------------------------------------------------------------------- 1 | # This rule was added by Solaar. 2 | # 3 | # Allows non-root users to have raw access to Logitech devices. 4 | # Allowing users to write to the device is potentially dangerous 5 | # because they could perform firmware updates. 6 | KERNEL=="uinput", SUBSYSTEM=="misc", TAG+="uaccess", OPTIONS+="static_node=uinput" 7 | 8 | ACTION != "add", GOTO="solaar_end" 9 | SUBSYSTEM != "hidraw", GOTO="solaar_end" 10 | 11 | # USB-connected Logitech receivers and devices 12 | ATTRS{idVendor}=="046d", GOTO="solaar_apply" 13 | 14 | # Lenovo nano receiver 15 | ATTRS{idVendor}=="17ef", ATTRS{idProduct}=="6042", GOTO="solaar_apply" 16 | 17 | # Bluetooth-connected Logitech devices 18 | KERNELS == "0005:046D:*", GOTO="solaar_apply" 19 | 20 | GOTO="solaar_end" 21 | 22 | LABEL="solaar_apply" 23 | 24 | # Allow any seated user to access the receiver. 25 | # uaccess: modern ACL-enabled udev 26 | TAG+="uaccess" 27 | 28 | # Grant members of the "plugdev" group access to receiver (useful for SSH users) 29 | #MODE="0660", GROUP="plugdev" 30 | 31 | LABEL="solaar_end" 32 | # vim: ft=udevrules 33 | -------------------------------------------------------------------------------- /rules.d/42-logitech-unify-permissions.rules: -------------------------------------------------------------------------------- 1 | # This rule was added by Solaar. 2 | # 3 | # Allows non-root users to have raw access to Logitech devices. 4 | # Allowing users to write to the device is potentially dangerous 5 | # because they could perform firmware updates. 6 | 7 | ACTION != "add", GOTO="solaar_end" 8 | SUBSYSTEM != "hidraw", GOTO="solaar_end" 9 | 10 | # USB-connected Logitech receivers and devices 11 | ATTRS{idVendor}=="046d", GOTO="solaar_apply" 12 | 13 | # Lenovo nano receiver 14 | ATTRS{idVendor}=="17ef", ATTRS{idProduct}=="6042", GOTO="solaar_apply" 15 | 16 | # Bluetooth-connected Logitech devices 17 | KERNELS == "0005:046D:*", GOTO="solaar_apply" 18 | 19 | GOTO="solaar_end" 20 | 21 | LABEL="solaar_apply" 22 | 23 | # Allow any seated user to access the receiver. 24 | # uaccess: modern ACL-enabled udev 25 | TAG+="uaccess" 26 | 27 | # Grant members of the "plugdev" group access to receiver (useful for SSH users) 28 | #MODE="0660", GROUP="plugdev" 29 | 30 | LABEL="solaar_end" 31 | # vim: ft=udevrules 32 | -------------------------------------------------------------------------------- /share/README: -------------------------------------------------------------------------------- 1 | Solaar application icon drawn by me, roughly guided by Logitech's Unifying logo. 2 | 3 | All other images are from the GNOME and Oxygen free icon themes. 4 | -------------------------------------------------------------------------------- /share/applications/solaar.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Solaar 3 | Comment=Logitech Unifying Receiver peripherals manager 4 | Comment[fr]=Gestionnaire de périphériques pour les récepteurs Logitech Unifying 5 | Comment[hr]=Upravitelj Logitechovih uređaja povezanih putem Unifying i Nano prijemnika 6 | Comment[ru]=Управление приёмником Logitech Unifying Receiver 7 | Comment[de]=Logitech Unifying Empfänger Geräteverwaltung 8 | Comment[es]=Administrador de periféricos de Logitech Receptor Unifying 9 | Comment[pl]=Menedżer urządzeń peryferyjnych odbiornika Logitech Unifying 10 | Comment[sv]=Kringutrustningshanterare för Logitech Unifying-mottagare 11 | Comment[zh_CN]=罗技优联设备管理器 12 | Comment[zh_TW]=羅技Unifying 裝置管理器 13 | Comment[zh_HK]=羅技Unifying 裝置管理器 14 | Exec=solaar 15 | Icon=solaar 16 | StartupNotify=true 17 | Terminal=false 18 | Type=Application 19 | Keywords=logitech;unifying;receiver;mouse;keyboard; 20 | Categories=Utility;GTK; 21 | #Categories=Utility;GTK;Settings;HardwareSettings; 22 | X-GNOME-UsesNotifications=true 23 | -------------------------------------------------------------------------------- /share/autostart/solaar.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Solaar 3 | Comment=Logitech Unifying Receiver peripherals manager 4 | Comment[fr]=Gestionnaire de périphériques pour les récepteurs Logitech Unifying 5 | Comment[hr]=Upravitelj Logitechovih uređaja povezanih putem Unifying i Nano prijemnika 6 | Comment[ru]=Управление приёмником Logitech Unifying Receiver 7 | Comment[de]=Logitech Unifying Empfänger Geräteverwaltung 8 | Comment[es]=Administrador de periféricos de Logitech Receptor Unifying 9 | Comment[pl]=Menedżer urządzeń peryferyjnych odbiornika Logitech Unifying 10 | Comment[sv]=Kringutrustningshanterare för Logitech Unifying-mottagare 11 | Comment[zh_CN]=罗技优联设备管理器 12 | Comment[zh_TW]=羅技Unifying 裝置管理器 13 | Comment[zh_HK]=羅技Unifying 裝置管理器 14 | Exec=solaar --window=hide 15 | Icon=solaar 16 | StartupNotify=true 17 | Terminal=false 18 | Type=Application 19 | Keywords=logitech;unifying;receiver;mouse;keyboard; 20 | Categories=Utility;GTK; 21 | #Categories=Utility;GTK;Settings;HardwareSettings; 22 | -------------------------------------------------------------------------------- /share/solaar/icons/solaar-attention.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Solaar attention 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | image/svg+xml 21 | 22 | Solaar attention 23 | 24 | 25 | Daniel Pavel 26 | 27 | 28 | 29 | 2013-06-25 30 | solaar-attention 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /share/solaar/icons/solaar-init.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Solaar init 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | image/svg+xml 17 | 18 | Solaar init 19 | 20 | 21 | Daniel Pavel 22 | 23 | 24 | 25 | 2013-06-25 26 | solaar-init 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_000.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_020.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_040.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_060.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_080.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_100.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-light_unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/share/solaar/icons/solaar-light_unknown.png -------------------------------------------------------------------------------- /share/solaar/icons/solaar-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Solaar 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | image/svg+xml 17 | 18 | Solaar 19 | 20 | 21 | Daniel Pavel 22 | 23 | 24 | 25 | 2013-06-25 26 | solaar 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /share/solaar/icons/solaar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Solaar 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | image/svg+xml 17 | 18 | Solaar 19 | 20 | 21 | Daniel Pavel 22 | 23 | 24 | 25 | 2013-06-25 26 | solaar 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/tests/__init__.py -------------------------------------------------------------------------------- /tests/hid_parser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/tests/hid_parser/__init__.py -------------------------------------------------------------------------------- /tests/hid_parser/test_data.py: -------------------------------------------------------------------------------- 1 | from hid_parser.data import Button 2 | from hid_parser.data import Consumer 3 | 4 | 5 | def test_consumer(): 6 | consumer = Consumer() 7 | 8 | assert consumer.PLAY_PAUSE == 0xCD 9 | 10 | 11 | def test_button(): 12 | button = Button() 13 | 14 | assert button.NO_BUTTON == 0x0 15 | assert button.BUTTON_1 == 0x1 16 | -------------------------------------------------------------------------------- /tests/hidapi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/tests/hidapi/__init__.py -------------------------------------------------------------------------------- /tests/hidapi/test_hidapi.py: -------------------------------------------------------------------------------- 1 | import platform 2 | 3 | from unittest import mock 4 | 5 | if platform.system() == "Linux": 6 | import hidapi.udev_impl as hidapi 7 | else: 8 | import hidapi.hidapi_impl as hidapi 9 | 10 | 11 | def test_find_paired_node(): 12 | hidapi.enumerate(mock.Mock()) 13 | -------------------------------------------------------------------------------- /tests/logitech_receiver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/tests/logitech_receiver/__init__.py -------------------------------------------------------------------------------- /tests/logitech_receiver/test_base_usb.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from logitech_receiver import base_usb 4 | from logitech_receiver.common import LOGITECH_VENDOR_ID 5 | 6 | 7 | def test_ensure_known_receivers_mappings_are_valid(): 8 | for key, receiver in base_usb.KNOWN_RECEIVERS.items(): 9 | assert key == receiver["product_id"] 10 | 11 | 12 | def test_get_receiver_info(): 13 | expected = { 14 | "vendor_id": LOGITECH_VENDOR_ID, 15 | "product_id": 0xC548, 16 | "usb_interface": 2, 17 | "name": "Bolt Receiver", 18 | "receiver_kind": "bolt", 19 | "max_devices": 6, 20 | "may_unpair": True, 21 | } 22 | 23 | res = base_usb.get_receiver_info(0xC548) 24 | 25 | assert res == expected 26 | 27 | 28 | def test_get_receiver_info_unknown_device_fails(): 29 | with pytest.raises(ValueError): 30 | base_usb.get_receiver_info(0xC500) 31 | -------------------------------------------------------------------------------- /tests/logitech_receiver/test_desktop_notifications.py: -------------------------------------------------------------------------------- 1 | from unittest import mock 2 | 3 | from logitech_receiver import desktop_notifications 4 | 5 | # depends on external environment, so make some tests dependent on availability 6 | 7 | 8 | def test_init(): 9 | result = desktop_notifications.init() 10 | 11 | assert result == desktop_notifications.available 12 | 13 | 14 | def test_uninit(): 15 | assert desktop_notifications.uninit() is None 16 | 17 | 18 | class MockDevice(mock.Mock): 19 | name = "MockDevice" 20 | 21 | def close(): 22 | return True 23 | 24 | 25 | def test_show(): 26 | dev = MockDevice() 27 | reason = "unknown" 28 | result = desktop_notifications.show(dev, reason) 29 | assert result is not None if desktop_notifications.available else result is None 30 | -------------------------------------------------------------------------------- /tests/logitech_receiver/test_settings_validator.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from logitech_receiver import settings_validator 4 | 5 | 6 | @pytest.mark.parametrize( 7 | "current, new, expected", 8 | [ 9 | (False, "toggle", True), 10 | (True, "~", False), 11 | ("don't care", True, True), 12 | ("don't care", "true", True), 13 | ("don't care", "false", False), 14 | ("don't care", "no", False), 15 | ("don't care", "off", False), 16 | ("don't care", "True", True), 17 | ("don't care", "yes", True), 18 | ("don't care", "on", True), 19 | ("anything", "anything", None), 20 | ], 21 | ) 22 | def test_bool_or_toggle(current, new, expected): 23 | result = settings_validator.bool_or_toggle(current=current, new=new) 24 | 25 | assert result == expected 26 | -------------------------------------------------------------------------------- /tests/solaar/test_gtk.py: -------------------------------------------------------------------------------- 1 | from solaar.gtk import create_parser 2 | 3 | 4 | def test_arg_parse(): 5 | parser = create_parser() 6 | res = parser.parse_args([]) 7 | 8 | assert res.debug == 0 9 | assert res.hidraw_path is None 10 | assert res.restart_on_wake_up is False 11 | assert res.window is None 12 | assert res.battery_icons is None 13 | assert res.tray_icon_size is None 14 | 15 | 16 | def test_arg_parse_debug(): 17 | parser = create_parser() 18 | res = parser.parse_args(["--debug"]) 19 | 20 | assert res.debug == 1 21 | 22 | 23 | def test_arg_parse_version(): 24 | parser = create_parser() 25 | res = parser.parse_args(["version"]) 26 | 27 | assert res 28 | -------------------------------------------------------------------------------- /tests/solaar/ui/test_about_dialog.py: -------------------------------------------------------------------------------- 1 | from solaar.ui.about import about 2 | from solaar.ui.about.model import AboutModel 3 | 4 | 5 | def test_about_model(): 6 | expected_name = "Daniel Pavel" 7 | model = AboutModel() 8 | 9 | authors = model.get_authors() 10 | 11 | assert expected_name in authors[0] 12 | 13 | 14 | def test_about_dialog(mocker): 15 | view_mock = mocker.Mock() 16 | 17 | about.show(view=view_mock) 18 | 19 | assert view_mock.init_ui.call_count == 1 20 | assert view_mock.update_version_info.call_count == 1 21 | assert view_mock.update_description.call_count == 1 22 | assert view_mock.update_authors.call_count == 1 23 | assert view_mock.update_credits.call_count == 1 24 | assert view_mock.update_copyright.call_count == 1 25 | assert view_mock.update_translators.call_count == 1 26 | assert view_mock.update_website.call_count == 1 27 | assert view_mock.show.call_count == 1 28 | -------------------------------------------------------------------------------- /tests/solaar/ui/test_common.py: -------------------------------------------------------------------------------- 1 | from unittest import mock 2 | from unittest.mock import PropertyMock 3 | 4 | import pytest 5 | 6 | from solaar.ui import common 7 | 8 | 9 | @pytest.mark.parametrize( 10 | "reason, expected_in_title, expected_in_text", 11 | [ 12 | ( 13 | common.ErrorReason.PERMISSIONS, 14 | "Permissions error", 15 | "not have permission to open", 16 | ), 17 | (common.ErrorReason.NO_DEVICE, "connect to device error", "error connecting"), 18 | (common.ErrorReason.UNPAIR, "Unpairing failed", "receiver returned an error"), 19 | ], 20 | ) 21 | def test_create_error_text(reason, expected_in_title, expected_in_text): 22 | obj = mock.Mock() 23 | obj.name = PropertyMock(return_value="test") 24 | 25 | title, text = common._create_error_text(reason, obj) 26 | 27 | assert expected_in_title in title 28 | assert expected_in_text in text 29 | -------------------------------------------------------------------------------- /tests/solaar/ui/test_desktop_notifications.py: -------------------------------------------------------------------------------- 1 | from unittest import mock 2 | 3 | from solaar.ui import desktop_notifications 4 | 5 | # depends on external environment, so make some tests dependent on availability 6 | 7 | 8 | def test_init(): 9 | result = desktop_notifications.init() 10 | 11 | assert result == desktop_notifications.available 12 | 13 | 14 | def test_uninit(): 15 | assert desktop_notifications.uninit() is None 16 | 17 | 18 | def test_alert(): 19 | reason = "unknown" 20 | assert desktop_notifications.alert(reason) is None 21 | 22 | 23 | class MockDevice(mock.Mock): 24 | name = "MockDevice" 25 | 26 | def close(): 27 | return True 28 | 29 | 30 | def test_show(): 31 | dev = MockDevice() 32 | reason = "unknown" 33 | available = desktop_notifications.init() 34 | 35 | result = desktop_notifications.show(dev, reason) 36 | if available: 37 | assert result is not None 38 | else: 39 | assert result is None 40 | -------------------------------------------------------------------------------- /tests/solaar/ui/test_i18n.py: -------------------------------------------------------------------------------- 1 | import locale 2 | import os 3 | import platform 4 | 5 | import pytest 6 | 7 | from solaar import i18n 8 | 9 | 10 | @pytest.fixture 11 | def set_locale_de(): 12 | backup_lang = os.environ.get("LC_ALL", "") 13 | try: 14 | yield 15 | finally: 16 | os.environ["LC_ALL"] = backup_lang 17 | i18n.set_locale_to_system_default() 18 | 19 | 20 | @pytest.mark.skipif(platform.system() == "Linux", reason="Adapt test for Linux") 21 | def test_set_locale_to_system_default(set_locale_de): 22 | os.environ["LC_ALL"] = "de_DE.UTF-8" 23 | i18n.set_locale_to_system_default() 24 | 25 | language, encoding = locale.getlocale() 26 | 27 | assert language == "de_DE" 28 | assert encoding == "UTF-8" 29 | -------------------------------------------------------------------------------- /tests/solaar/ui/test_probe.py: -------------------------------------------------------------------------------- 1 | from unittest import mock 2 | 3 | from logitech_receiver.hidpp10_constants import ErrorCode 4 | from logitech_receiver.hidpp10_constants import Registers 5 | from solaar.cli.probe import run 6 | 7 | 8 | # Mock receiver class 9 | class MockReceiver: 10 | handle = 1 11 | isDevice = False 12 | 13 | def read_register(self, register, *args): 14 | return 0 if register == Registers.RECEIVER_INFO else b"\x01\x03" 15 | 16 | 17 | def test_run_register_errors(): 18 | mock_args = mock.Mock() 19 | mock_args.receiver = False 20 | 21 | mock_receiver = MockReceiver() 22 | 23 | # Define expected addresses to be called in order 24 | expected_addresses = [] 25 | 26 | for reg in range(0, 0xFF): 27 | expected_addresses.append((0x8100 | reg, 0)) # First short call, returns invalid_value (continue) 28 | expected_addresses.append((0x8100 | reg, 1)) # Second short call, returns invalid_address (stop here) 29 | 30 | expected_addresses.append((0x8100 | (0x200 + reg), 0)) # First long call, returns invalid_value (continue) 31 | expected_addresses.append((0x8100 | (0x200 + reg), 1)) # Second long call, returns invalid_address (stop here) 32 | 33 | # To record the actual addresses called 34 | called_addresses = [] 35 | 36 | def mock_base_request(handle, devnumber, reg, sub, return_error=False): 37 | called_addresses.append((reg, sub)) 38 | if sub == 0: 39 | return ErrorCode.INVALID_VALUE 40 | elif sub == 1: 41 | return ErrorCode.INVALID_ADDRESS 42 | return b"\x01\x02" 43 | 44 | with mock.patch("logitech_receiver.base.request", side_effect=mock_base_request), mock.patch( 45 | "solaar.cli.probe._print_receiver", return_value=None 46 | ): 47 | # Call the run function with mocked receivers and args (passing real find_receiver function) 48 | run([mock_receiver], mock_args, None, None) 49 | 50 | # Evaluate that the addresses called match the expected addresses 51 | assert ( 52 | called_addresses == expected_addresses 53 | ), f"Called addresses {called_addresses} do not match expected {expected_addresses}" 54 | -------------------------------------------------------------------------------- /tests/test_keysyms/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pwr-Solaar/Solaar/694513832d7ade6e85cebfd813a6cde9a6b60a24/tests/test_keysyms/__init__.py -------------------------------------------------------------------------------- /tests/test_keysyms/test_keysymdef.py: -------------------------------------------------------------------------------- 1 | from keysyms import keysymdef 2 | 3 | 4 | def test_keysymdef(): 5 | key_mapping = keysymdef.key_symbols 6 | 7 | assert key_mapping["0"] == 48 8 | assert key_mapping["A"] == 65 9 | assert key_mapping["a"] == 97 10 | -------------------------------------------------------------------------------- /tools/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd "$(dirname "$0")/.." 4 | 5 | find . -type f -name '*.py[co]' -delete 6 | find . -type d -name '__pycache__' -delete 7 | 8 | /bin/rm --force po/*~ 9 | /bin/rm --force --recursive share/locale/ 10 | -------------------------------------------------------------------------------- /tools/hidconsole: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- python-mode -*- 3 | """Takes care of starting the main function.""" 4 | 5 | from __future__ import absolute_import 6 | 7 | 8 | def init_paths(): 9 | """Make the app work in the source tree.""" 10 | import os.path as _path 11 | import sys 12 | 13 | src_lib = _path.normpath(_path.join(_path.realpath(sys.path[0]), "..", "lib")) 14 | init_py = _path.join(src_lib, "hidapi", "__init__.py") 15 | if _path.exists(init_py): 16 | sys.path[0] = src_lib 17 | 18 | 19 | if __name__ == "__main__": 20 | init_paths() 21 | from hidapi import hidconsole 22 | 23 | hidconsole.main() 24 | -------------------------------------------------------------------------------- /tools/po-compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd "$(readlink -f "$(dirname "$0")/..")" 6 | 7 | find "$PWD/po" -type f -name '*.po' | \ 8 | while read po_file; do 9 | language="$(basename "$po_file")" 10 | language="${language%.po}" 11 | target="$PWD/share/locale/$language/LC_MESSAGES/solaar.mo" 12 | /bin/mkdir --parents "$(dirname "$target")" 13 | /usr/bin/msgfmt \ 14 | --check \ 15 | --output-file="$target" \ 16 | "$po_file" 17 | done 18 | -------------------------------------------------------------------------------- /tools/po-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if test "$1" = "-h" -o "$1" = "--help"; then 6 | echo "Use: $0 []" 7 | echo "Run without arguments to update all translation files." 8 | exit 0 9 | fi 10 | 11 | cd "$(readlink -f "$(dirname "$0")/..")" 12 | 13 | VERSION=$(python setup.py --version) 14 | DOMAIN=$(python setup.py --name) 15 | 16 | SOURCE_FILES=$(/bin/mktemp --tmpdir $DOMAIN-po-update-XXXXXX) 17 | find "lib" -name '*.py' >"$SOURCE_FILES" 18 | 19 | POT_DIR="$PWD/po" 20 | test -d "$POT_DIR" 21 | 22 | POT_FILE="$POT_DIR/$DOMAIN.pot" 23 | 24 | /usr/bin/xgettext \ 25 | --package-name "$DOMAIN" \ 26 | --package-version "$VERSION" \ 27 | --default-domain="$L_NAME" \ 28 | --language=Python --from-code=UTF-8 --files-from="$SOURCE_FILES" \ 29 | --no-escape --indent --add-location --sort-by-file \ 30 | --add-comments=I18N \ 31 | --output="$POT_FILE" 32 | 33 | /bin/sed --in-place --expression="s/charset=CHARSET/charset=UTF-8/" "$POT_FILE" 34 | 35 | 36 | unfmt() { 37 | local SOURCE="/usr/share/locale/$LL_CC/LC_MESSAGES/$1.mo" 38 | if test ! -f "$SOURCE"; then 39 | SOURCE="/usr/share/locale-langpack/$LL_CC/LC_MESSAGES/$1.mo" 40 | fi 41 | local TARGET="$(mktemp --tmpdir $1-$LL_CC-XXXXXX.po)" 42 | /usr/bin/msgunfmt \ 43 | --no-escape --indent \ 44 | --output-file="$TARGET" \ 45 | "$SOURCE" 46 | echo "$TARGET" 47 | } 48 | 49 | update_po() { 50 | local LL_CC="$1" 51 | local PO_FILE="$POT_DIR/$LL_CC.po" 52 | 53 | test -r "$PO_FILE" || /usr/bin/msginit \ 54 | --no-translator --locale="$LL_CC" \ 55 | --input="$POT_FILE" \ 56 | --output-file="$PO_FILE" 57 | 58 | /usr/bin/msgmerge \ 59 | --update --no-fuzzy-matching \ 60 | --no-escape --indent --add-location --sort-by-file \ 61 | --lang="$LL_CC" \ 62 | --compendium="$(unfmt gtk30)" \ 63 | --compendium="$(unfmt gtk30-properties)" \ 64 | "$PO_FILE" "$POT_FILE" 65 | 66 | # /bin/sed --in-place --expression="s/Language: \\\\n/Language: $L_NAME\\\\n/" "$PO_FILE" 67 | echo "Updated $PO_FILE" 68 | } 69 | 70 | if test "$1"; then 71 | update_po "$1" 72 | else 73 | for l in $(ls -1 "$POT_DIR"/??.po); do 74 | l="$(basename "$l")" 75 | update_po "${l%.po}" 76 | done 77 | fi 78 | -------------------------------------------------------------------------------- /tools/scan-registers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if test -z "$1"; then 4 | echo "Use: $0 []" 5 | exit 2 6 | fi 7 | 8 | HC="$(dirname "$(readlink -f "$0")")/hidconsole" 9 | if test "$1" = "FF" -o "$1" = "ff"; then 10 | DEVNUMBER=FF 11 | else 12 | DEVNUMBER=0$1 13 | fi 14 | HIDRAW=$2 15 | 16 | do_req() { 17 | "$HC" --hidpp $HIDRAW | grep "^>> " | grep -v "\[1. .. 8F.. " 18 | } 19 | 20 | req00="$(mktemp --tmpdir req00-XXXXXX)" 21 | echo "10 ${DEVNUMBER} 8100 000000" | do_req >"$req00" 22 | oldflags=$(grep -Po "^>> \([0-9. ]*\) \[10 ${DEVNUMBER} 8100 \K[0-9a-f]{6}(?=\])" "$req00") 23 | if [ -n "$oldflags" ]; then 24 | echo "# Old notification flags: $oldflags" 25 | cat >"$req00-flags" <<-_CHECK_NOTIFICATIONS 26 | 10 ${DEVNUMBER} 8000 ffffff 27 | 10 ${DEVNUMBER} 8100 000000 28 | 10 ${DEVNUMBER} 8000 ${oldflags} 29 | _CHECK_NOTIFICATIONS 30 | # set all possible flags, read the new value, then restore the old value 31 | # this will show all supported notification flags by this device 32 | cat "$req00-flags" | do_req | grep "^>>.* ${DEVNUMBER} 8100 " 33 | else 34 | echo "# Warning: hidconsole API got changed - unrecognized output" 35 | cat "$req00" 36 | fi 37 | rm --force "$req00" "$req00-flags" & 38 | 39 | echo SHORT REGISTERS 40 | # read all short registers, skipping 00 41 | for n in $(seq 1 255); do 42 | printf "10 ${DEVNUMBER} 81%02x 000000\n" $n 43 | done | do_req 44 | 45 | echo LONG REGISTERS 46 | # read all long registers 47 | for n in $(seq 0 255); do 48 | printf "10 ${DEVNUMBER} 83%02x 000000\n" $n 49 | done | do_req 50 | 51 | echo PAIRING INFORMAITON # read all pairing information 52 | for n in $(seq 0 255); do 53 | printf "10 ${DEVNUMBER} 83B5 %02x0000\n" $n 54 | done | do_req 55 | --------------------------------------------------------------------------------