2 Commits

Author SHA1 Message Date
Thomas H.P. Andersen
84b1519ebd steelseries: port to using the firmware field in device 2020-09-29 00:54:01 +02:00
Thomas H.P. Andersen
99b8c80aee device: add firmware major/minor
This adds fields to the device struct to store the
firmware version on the device. It is also exposed
over dbus to the clients.

The firmware of a device can define the protocol
or memory layout that should be used to talk to
the device. Several devices can query the firmware
version via separate commands and we can use this
information in the drivers to change behavior of the
driver based on the device firmware.

The firmware version is also exposed over dbus so that
it is easily available for users via e.g. ratbagctl. It
can also be used in piper to warn users that a known bug
in a firmware version can cause problems when trying to
configure with libratbag.
2020-09-29 00:53:52 +02:00
225 changed files with 4649 additions and 12917 deletions

269
.circleci/config.yml Normal file
View File

@@ -0,0 +1,269 @@
libratbag_references:
build_dependencies: &build_dependencies
FEDORA_DEP_BUILD: gcc gcc-c++ meson dbus-daemon glib2-devel json-glib-devel libevdev-devel libudev-devel libunistring-devel python3-devel python3-evdev swig
FEDORA_DEP_TEST: check-devel python3-gobject python3-lxml valgrind diffutils
FEDORA_DEP_DOC: python3-sphinx python3-sphinx_rtd_theme
UBUNTU_DEP_BUILD: gcc g++ meson pkg-config systemd libevdev-dev libglib2.0-dev libjson-glib-dev libsystemd-dev libudev-dev libunistring-dev python3-dev python3-evdev swig
UBUNTU_DEP_TEST: check python3-gi python3-lxml valgrind
ARCH_DEP_BUILD: meson swig glib2 libevdev libudev.so libunistring json-glib python python-evdev python-gobject
ARCH_DEP_TEST: check valgrind python-lxml
default_settings: &default_settings
working_directory: ~/libratbag
environment:
LANG: C.UTF-8
build_default: &build_default
name: Build
command: |
rm -rf build
meson build ${MESON_PARAMS}
meson configure build
ninja -v -C build ${NINJA_ARGS}
environment:
MESON_PARAMS: --prefix=/usr
build_buildtype_plain: &build_buildtype_plain
run:
<<: *build_default
name: Build with buildtype plain
environment:
MESON_PARAMS: --prefix=/usr -Dbuildtype=plain
build_buildtype_release: &build_buildtype_release
run:
<<: *build_default
name: Build with buildtype release
environment:
MESON_PARAMS: --prefix=/usr -Dbuildtype=release
build_and_test: &build_and_test
run:
<<: *build_default
name: Build and test
environment:
NINJA_ARGS: test
build_with_docs: &build_with_docs
run:
<<: *build_default
name: Build with documentation
environment:
MESON_PARAMS: -Ddocumentation=true
install: &install
run:
name: Installing
command: ninja -C build install
check_install: &check_install
run:
name: Checking installation
command: |
PREFIX=/usr/local/
diff -u <(cd data/devices; ls *.device) <(cd $PREFIX/share/libratbag; ls *.device)
check_uninstall: &check_uninstall
run:
name: Checking if any files are left after uninstall
command: |
PREFIX=/root/test_install
meson build_install --prefix=$PREFIX
ninja -C build_install install
ninja -C build_install uninstall
if [ -d $PREFIX ]
then
tree $PREFIX
exit 1
fi
export_logs: &export_logs
store_artifacts:
path: ~/libratbag/build/meson-logs
start_dbus: &start_dbus
run:
name: Start dbus daemon
command: |
mkdir /run/dbus
/usr/bin/dbus-daemon --system --fork
save_date: &save_date
run:
name: Save date
command: date +%F > /tmp/date
fedora_save_cache: &fedora_save_cache
save_cache:
key: fedora-cache-v1-{{ checksum "/tmp/date" }}
paths:
- /var/cache/dnf
fedora_fetch_cache: &fedora_fetch_cache
restore_cache:
keys:
- fedora-cache-v1
fedora_install: &fedora_install
run:
name: Install prerequisites
command: |
echo keepcache=1 >> /etc/dnf/dnf.conf
dnf install -y git ${FEDORA_DEP_BUILD} ${FEDORA_DEP_TEST}
sed -i 's/systemd//' /etc/nsswitch.conf
fedora_settings: &fedora_settings
<<: *default_settings
steps:
- *save_date
- *fedora_fetch_cache
- *fedora_install
- checkout
- *start_dbus
- *build_and_test
- *install
- *check_install
- *check_uninstall
- *build_buildtype_plain
- *build_buildtype_release
- *export_logs
- *fedora_save_cache
environment:
*build_dependencies
arch_save_cache: &arch_save_cache
save_cache:
key: arch-cache-v1-{{ checksum "/tmp/date" }}
paths:
- /var/cache/pacman/pkg
arch_fetch_cache: &arch_fetch_cache
restore_cache:
keys:
- arch-cache-v1
arch_settings: &arch_settings
<<: *default_settings
steps:
- *save_date
- *arch_fetch_cache
- run:
name: Install prerequisites
command: pacman -Syu --noconfirm --noprogressbar --needed base-devel git tree ${ARCH_DEP_BUILD} ${ARCH_DEP_TEST}
- *start_dbus
- checkout
- *build_and_test
- *install
- *check_install
- *check_uninstall
- *export_logs
- *arch_save_cache
environment:
*build_dependencies
ubuntu_settings: &ubuntu_settings
<<: *default_settings
steps:
- run:
name: Install prerequisites
command: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y git ${UBUNTU_DEP_BUILD} ${UBUNTU_DEP_TEST}
- checkout
- *start_dbus
- *build_and_test
- *install
- *check_install
- *check_uninstall
- *build_buildtype_plain
- *build_buildtype_release
- *export_logs
environment:
*build_dependencies
doc_build: &doc_build
<<: *default_settings
steps:
- *fedora_fetch_cache
- *fedora_install
- run:
name: Install documentation build-deps
command: dnf install -y ${FEDORA_DEP_DOC}
- checkout
- *build_with_docs
- *export_logs
- store_artifacts:
path: ~/libratbag/build/doc/html
- persist_to_workspace:
root: build
paths:
- doc/html/*
environment:
*build_dependencies
docs_deploy: &docs_deploy
<<: *default_settings
steps:
- *fedora_fetch_cache
- run:
name: Install prerequisites
command: dnf install -y git tree
- checkout
- attach_workspace:
at: build
- run:
name: Setup the deploy SSH key
command: |
ssh-add -L | tail -n1 > ~/.ssh/deploy.pub
cat <<EOF > ~/.ssh/config
Host github.com
IdentityFile /root/.ssh/deploy.pub
IdentitiesOnly yes
EOF
- run:
name: Clone doc repository
command: |
cd ~
git clone ssh://git@github.com/${CIRCLE_PROJECT_REPONAME}/${CIRCLE_PROJECT_REPONAME}.github.io
- run:
name: Copy the doc, commit and push
command: |
set +e
cd ~/${CIRCLE_PROJECT_REPONAME}.github.io
\cp -r ~/${CIRCLE_PROJECT_REPONAME}/build/doc/html/* .
if ! git diff-index --quiet HEAD --; then
git config --global user.email "libratbag@librabtag.github.io"
git config --global user.name "The libratbag crew"
git add .
git commit -m "update docs from ${CIRCLE_SHA1}"
git push
fi
version: 2
jobs:
fedora_31:
<<: *fedora_settings
docker:
- image: fedora:31
arch:
<<: *arch_settings
docker:
- image: archlinux
ubuntu_20_04:
<<: *ubuntu_settings
docker:
- image: ubuntu:20.04
doc_build:
<<: *doc_build
docker:
- image: fedora:31
doc_deploy:
<<: *docs_deploy
docker:
- image: fedora:31
workflows:
version: 2
compile_and_test:
jobs:
- ubuntu_20_04
- arch
- fedora_31
- doc_build
- doc_deploy:
requires:
- doc_build
filters:
branches:
only: master

3
.flake8 Normal file
View File

@@ -0,0 +1,3 @@
[flake8]
ignore = E402,E501
exclude = .git,__pycache__,build,data,piper/piper.py

View File

@@ -1,39 +0,0 @@
# A Github Action to build a repository with meson
name: "Setup and run meson"
description: "Setup and run meson"
inputs:
builddir:
description: "The build directory"
default: "builddir"
srcdir:
description: "The source directory"
default: "."
meson_args:
description: "Arguments passed to meson setup"
default: ""
meson_skip_test:
description: "Set to a nonempty string to skip meson test"
default: ""
meson_test_args:
description: "Arguments passed to meson test"
default: ""
meson_precmd:
description: "Set to 'sudo' to run with sudo"
default: ""
ninja_args:
description: "Arguments passed to ninja"
default: ""
ninja_precmd:
description: "Set to 'sudo' to run with sudo"
default: ""
runs:
using: "composite"
steps:
- run: |
${{inputs.meson_precmd}} meson setup ${{inputs.builddir}} ${{inputs.srcdir}} ${{inputs.meson_args}}
${{inputs.meson_precmd}} meson configure ${{inputs.builddir}}
${{inputs.ninja_precmd}} ninja -C ${{inputs.builddir}} ${{inputs.ninja_args}}
if [[ -z "${{inputs.meson_skip_test}}" ]]; then
${{inputs.meson_precmd}} meson test -C ${{inputs.builddir}} --print-errorlogs ${{inputs.meson_test_args}};
fi
shell: bash

View File

@@ -1,17 +0,0 @@
name: "Install packages"
description: "Install a set of packages from sources"
inputs:
apt:
description: "The package list to install with apt"
pip:
description: "The package list to install with pip"
pip_precmd:
description: "Set to the string 'sudo' to run through sudo"
default: ""
runs:
using: "composite"
steps:
- run: sudo ${{ github.action_path }}/install-apt.sh ${{ inputs.apt }}
shell: bash
- run: ${{inputs.pip_precmd}} ${{ github.action_path }}/install-pip.sh ${{ inputs.pip }}
shell: bash

View File

@@ -1,14 +0,0 @@
#!/bin/bash -x
# If called without arguments, just skip the rest
if [[ -z "$@" ]]; then
exit
fi
# Don't care about these bits
echo 'path-exclude=/usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft
echo 'path-exclude=/usr/share/locale/*' >> /etc/dpkg/dpkg.cfg.d/99-exclude-cruft
echo 'path-exclude=/usr/share/man/*' >> /etc/dpkg/dpkg.cfg.d/99-exclude-cruft
apt-get update
apt-get install -yq --no-install-suggests --no-install-recommends $@

View File

@@ -1,9 +0,0 @@
#!/bin/bash -x
# If called without arguments, just skip the rest
if [[ -z "$@" ]]; then
exit
fi
python -m pip install --upgrade pip
python -m pip install --upgrade "$@"

View File

@@ -1,50 +0,0 @@
name: linux
on: [ push, pull_request ]
env:
UBUNTU_DEP_BUILD: |
gcc g++ pkg-config systemd libevdev-dev libglib2.0-dev
libjson-glib-dev libsystemd-dev libudev-dev libunistring-dev
python3-dev python3-evdev swig python3-sphinx
UBUNTU_DEP_TEST: check python3-gi python3-lxml valgrind
PIP_PACKAGES: meson ninja libevdev pyudev pytest sphinx_rtd_theme black ruff
jobs:
build-and-dist:
runs-on: ubuntu-20.04
strategy:
matrix:
meson_args:
- ''
- '-Dbuildtype=plain'
- '-Dbuildtype=release'
- '-Ddocumentation=true'
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/pkginstall
with:
apt: $UBUNTU_DEP_BUILD $UBUNTU_DEP_TEST
pip: $PIP_PACKAGES
- name: meson test ${{matrix.meson_args}}
uses: ./.github/actions/meson
with:
meson_args: --prefix=$PWD/_instdir ${{matrix.meson_args}}
ninja_args: install
- name: check installation of data files
run: diff -u <(cd data/devices; ls *.device) <(cd _instdir/share/libratbag; ls *.device)
- name: ninja uninstall
uses: ./.github/actions/meson
with:
meson_args: --prefix=$PWD/_instdir
ninja_args: uninstall
- name: check if any files are left after uninstall
run: (test -d _instdir && tree _instdir && exit 1) || exit 0
# Capture all the meson logs, even if we failed
- uses: actions/upload-artifact@v3
if: ${{ always() }} # even if we fail
with:
name: meson test logs
path: |
builddir/meson-logs/testlog*.txt
builddir/meson-logs/meson-log.txt

View File

@@ -1,31 +0,0 @@
name: pages
on:
push:
branches:
- master
env:
UBUNTU_DEP_BUILD: gcc g++ pkg-config systemd libevdev-dev libglib2.0-dev libjson-glib-dev libsystemd-dev libudev-dev libunistring-dev python3-dev python3-evdev python3-pip swig python3-sphinx python3-sphinx-rtd-theme
PIP_PACKAGES: meson ninja
jobs:
deploy:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/pkginstall
with:
apt: $UBUNTU_DEP_BUILD
pip: $PIP_PACKAGES
- name: Build docs
uses: ./.github/actions/meson
with:
meson_args: -Ddocumentation=true -Dtests=false
meson_skip_test: yes
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./builddir/doc/html/
allow_empty_commit: true

View File

@@ -45,10 +45,6 @@ And to build or re-build after code-changes, run:
ninja -C builddir ninja -C builddir
sudo ninja -C builddir install sudo ninja -C builddir install
To remove/uninstall simply run:
sudo ninja -C builddir uninstall
Note: `builddir` is the build output directory and can be changed to any Note: `builddir` is the build output directory and can be changed to any
other directory name. To set configure-time options, use e.g. other directory name. To set configure-time options, use e.g.
@@ -173,3 +169,5 @@ libratbag is licensed under the MIT license.
> Software is furnished to do so, subject to the following conditions: [...] > Software is furnished to do so, subject to the following conditions: [...]
See the COPYING file for the full license information. See the COPYING file for the full license information.
[![Build Status](https://circleci.com/gh/libratbag/libratbag.svg?style=shield&circle-token=d7c782e10d2d934b176da754f11b5105ea074f4a)](https://circleci.com/gh/libratbag/libratbag)

View File

@@ -1,12 +0,0 @@
[Device]
Name=ASUS ROG GX860 Buzzard Mouse
DeviceMatch=usb:0b05:1816
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=10
Leds=0
Dpis=2
DpiRange=100:8200@100

View File

@@ -1,14 +0,0 @@
# ASUS ROG Chakram, but corded
[Device]
Name=ASUS ROG Chakram Core
DeviceMatch=usb:0b05:1958
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=5
Leds=3
Dpis=4
DpiRange=100:16000@100
Quirks=DOUBLE_DPI;STRIX_PROFILE

View File

@@ -1,14 +0,0 @@
[Device]
Name=ASUS ROG Chakram X
DeviceMatch=usb:0b05:1a18
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=5
Leds=3
Dpis=4
Wireless=1
DpiRange=100:36000@100
Quirks=DOUBLE_DPI

View File

@@ -1,14 +0,0 @@
[Device]
Name=ASUS ROG Chakram
DeviceMatch=usb:0b05:18e3;usb:0b05:18e5
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=5
Leds=3
Dpis=4
Wireless=1
DpiRange=100:16000@100
Quirks=DOUBLE_DPI;STRIX_PROFILE

View File

@@ -1,13 +0,0 @@
[Device]
Name=ASUS ROG Gladius II Origin PNK LTD
DeviceMatch=usb:0b05:18cd
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=8
Leds=3
Dpis=2
DpiRange=100:12000@100
Quirks=DOUBLE_DPI

View File

@@ -1,14 +0,0 @@
# "ASUS ROG Gladius II" without "DPI target button"
[Device]
Name=ASUS ROG Gladius II Origin
DeviceMatch=usb:0b05:1877
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=8
Leds=3
Dpis=2
DpiRange=100:12000@100
Quirks=DOUBLE_DPI

View File

@@ -1,13 +0,0 @@
[Device]
Name=ASUS ROG Gladius II
DeviceMatch=usb:0b05:1845
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=9
Leds=3
Dpis=2
DpiRange=100:12000@100
ButtonMapping=f0;f1;f2;e4;e5;e6;e7;e8;e9

View File

@@ -1,13 +0,0 @@
[Device]
Name=ASUS ROG Harpe Wireless
DeviceMatch=usb:0b05:1a92
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=5
Buttons=5
Leds=1
Dpis=4
Wireless=1
DpiRange=100:36000@50

View File

@@ -1,13 +0,0 @@
[Device]
Name=ASUS ROG Keris Wireless AimPoint
DeviceMatch=usb:0b05:1a68
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=5
Buttons=7
Leds=1
Dpis=4
Wireless=1
DpiRange=100:36000@50

View File

@@ -1,14 +0,0 @@
[Device]
Name=ASUS ROG Keris Wireless
DeviceMatch=usb:0b05:195e;usb:0b05:1960
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=8
Leds=2
Dpis=4
Wireless=1
DpiRange=100:16000@100
Quirks=DOUBLE_DPI

View File

@@ -1,13 +0,0 @@
[Device]
Name=ASUS ROG Pugio
DeviceMatch=usb:0b05:1846
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=10
Leds=3
Dpis=2
DpiRange=100:7200@100
ButtonMapping=f0;f1;f2;e4;e5;e6;0;e8;e9;e1;e2

View File

@@ -1,14 +0,0 @@
[Device]
Name=ASUS ROG Spatha X
DeviceMatch=usb:0b05:1979;usb:0b05:1977
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=5
Buttons=14
Leds=3
Dpis=4
Wireless=1
DpiRange=100:19000@50
ButtonMapping=f0;f1;f2;e4;e5;e6;e8;e9;ea;eb;ec;ed;ee;ef

View File

@@ -1,14 +0,0 @@
[Device]
Name=ASUS ROG Strix Carry
DeviceMatch=usb:0b05:18b4
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=8
Leds=0
Dpis=2
Wireless=1
DpiRange=100:7200@100
Quirks=STRIX_PROFILE

View File

@@ -1,12 +0,0 @@
[Device]
Name=ASUS ROG Strix Impact
DeviceMatch=usb:0b05:1847
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=1
Buttons=6
Leds=1
Dpis=2
DpiRange=100:5000@100

View File

@@ -1,13 +0,0 @@
[Device]
Name=ASUS ROG Strix Impact II Wireless
DeviceMatch=usb:0b05:1947;usb:0b05:1949
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=8
Leds=3
Dpis=4
Wireless=1
DpiRange=100:16000@100

View File

@@ -1,12 +0,0 @@
[Device]
Name=ASUS ROG Strix Impact II
DeviceMatch=usb:0b05:18e1
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=8
Leds=3
Dpis=4
DpiRange=200:6200@100

227
data/devices/data-parse-test.py Executable file
View File

@@ -0,0 +1,227 @@
#!/usr/bin/env python3
#
# Copyright © 2017 Red Hat, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Device data verification script
#
import argparse
import configparser
import re
def assertIn(element, l):
if element not in l:
raise AssertionError('{} must be in {}'.format(element, l))
def assertNotIn(element, l):
if element in l:
raise AssertionError('{} must not be in {}'.format(element, l))
def check_match_str(string):
bustypes = ['usb', 'bluetooth']
matches = string.split(';')
for match in matches:
if not match: # empty string if trailing ;
continue
parts = match.split(':')
assert(len(parts) == 3)
assertIn(parts[0], bustypes)
vid = parts[1]
assert(vid == '{:04x}'.format(int(vid, 16)))
pid = parts[2]
assert(pid == '{:04x}'.format(int(pid, 16)))
def check_ledtypes_str(string):
permitted_types = ['logo', 'side', 'battery', 'dpi', 'switches']
types = string.split(';')
for t in types:
if not t: # emtpy string if trailing ;
continue
assertIn(t, permitted_types)
def check_section_device(section):
required_keys = ['Name', 'Driver', 'DeviceMatch']
permitted_keys = required_keys + ['LedTypes']
for key in section.keys():
assertIn(key, permitted_keys)
for r in required_keys:
assertIn(r, section)
try:
check_ledtypes_str(section['LedTypes'])
except KeyError:
pass
check_match_str(section['DeviceMatch'])
def check_dpi_range_str(string):
import re
m = re.search('^([0-9]+):([0-9]+)@([0-9.]+)$', string)
assert(m is not None)
min = int(m.group(1))
max = int(m.group(2))
steps = float(m.group(3))
assert(min >= 0 and min <= 400)
assert(max >= 2000 and max <= 12000)
assert(steps > 0 and steps <= 100)
if int(steps) == steps:
steps = int(steps)
assert(string == '{}:{}@{}'.format(min, max, steps))
def check_dpi_list_str(string):
entries = string.split(';')
# Remove possible empty last entry if trailing with a ;
if not entries[len(entries) - 1]:
entries = entries[:-1]
for idx, entry in enumerate(entries):
dpi = int(entry)
assert(dpi >= 0 and dpi <= 12000)
if idx > 0:
prev = entries[idx - 1]
prev_dpi = int(prev)
assert(dpi > prev_dpi)
def check_profile_type_str(string):
types = ['G9', 'G500', 'G700']
assertIn(string, types)
def check_section_hidpp10(section):
permitted = ['Profiles', 'ProfileType', 'DpiRange', 'DpiList', 'DeviceIndex', 'Leds']
for key in section.keys():
assertIn(key, permitted)
try:
nprofiles = int(section['Profiles'])
# 10 is arbitrarily chosen
assert(nprofiles > 0 and nprofiles < 10)
except KeyError:
pass
try:
index = int(section['DeviceIndex'], 16)
assert(index > 0 and index <= 0xff)
except KeyError:
pass
try:
check_dpi_range_str(section['DpiRange'])
assertNotIn('DpiList', section.keys())
except KeyError:
pass
try:
check_dpi_list_str(section['DpiList'])
assertNotIn('DpiRange', section.keys())
except KeyError:
pass
try:
check_profile_type_str(section['ProfileType'])
except KeyError:
pass
try:
leds = int(section['Leds'])
# 10 is arbitrarily chosen
assert(leds > 0 and leds < 10)
except KeyError:
pass
def check_section_hidpp20(section):
permitted = ['DeviceIndex', 'Leds', 'Quirk']
for key in section.keys():
assertIn(key, permitted)
try:
index = int(section['DeviceIndex'], 16)
assert(index > 0 and index <= 0xff)
except KeyError:
pass
def check_section_driver(driver, section):
if driver == 'hidpp10':
check_section_hidpp10(section)
elif driver == 'hidpp20':
check_section_hidpp20(section)
else:
assert('Unsupported driver section {}'.format(driver))
def validate_data_file_name(path):
# Matching any of the characters in the regular expression will throw an
# error. Currently only tests the square brackets [], parentheses, and curly
# braces.
illegal_characters_regex = '([\[\]\{\}\(\)])'
found_characters = re.findall(illegal_characters_regex, path)
if found_characters:
raise AssertionError("data file name '{}' contains illegal characters: '{}'".format(path, ''.join(found_characters)))
def parse_data_file(path):
print('Parsing file {}'.format(path))
data = configparser.ConfigParser(strict=True)
# Don't convert to lowercase
data.optionxform = lambda option: option
data.read(path)
assertIn('Device', data.sections())
check_section_device(data['Device'])
driver = data['Device']['Driver']
driver_section = 'Driver/{}'.format(driver)
permitted_sections = ['Device', driver_section]
for s in data.sections():
assertIn(s, permitted_sections)
if data.has_section(driver_section):
check_section_driver(driver, data[driver_section])
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Device data-file checker")
parser.add_argument('file', nargs='+')
args = parser.parse_args()
for path in args.file:
validate_data_file_name(path)
parse_data_file(path)

View File

@@ -15,8 +15,10 @@ DeviceMatch=usb:12ab:00f2
# The libratbag driver backend # The libratbag driver backend
Driver=hidpp10 Driver=hidpp10
# The type of this Device: either 'mouse', 'keyboard' or 'other' # The types of the LEDs, in the indexed order they appear in, separated by a
DeviceType=mouse # semicolon.
# Allowed values: logo, side, battery, dpi
LedTypes=logo;side
# Only one group of driver-specific properties is permitted and it must be # Only one group of driver-specific properties is permitted and it must be
# [Driver/<drivername>]. It is a bug do have any other [Driver/foo] group in # [Driver/<drivername>]. It is a bug do have any other [Driver/foo] group in
@@ -50,60 +52,3 @@ Leds=1
# The HID++ 2.0 device index # The HID++ 2.0 device index
# Should be unset unless required # Should be unset unless required
# DeviceIndex=1 # DeviceIndex=1
[Driver/asus]
# Number of profiles
Profiles=3
# Number of buttons
Buttons=8
# Number of LEDs
Leds=3
# Number of DPI presets
Dpis=2
# Set if device is wireless
# Wireless=1
# DPI range in format min:max@step
DpiRange=100:16000@100
# Button mapping
# ButtonMapping=f0;f1;f2;e4;e5;e6;e8;e9
# Device quirks
# Quirk=DOUBLE_DPI;STRIX_PROFILE
# Replace `FEED` in the group name with firmware version of the device.
# To find the right value, see the output of ratbagd and search a message like:
# "ratbag error: Device with firmware version FEED is not supported"
# Official software utility configuration file key: `PSD` (converted from
# ASCII codes).
[Driver/sinowealth/devices/FEED]
# Number of buttons.
# Official software utility configuration file key: `KM` (divided by 2).
# Default: 0.
Buttons=6
# Device name.
DeviceName=CoolVendor CoolMouse
# The order of LED pins on the mouse.
# Change this to `RBG` if LED colors are weird.
# Use `None` if there are no LEDs on the mouse.
# Permitted values: ("RGB", "RBG", "None").
LedType=RGB
# Number of profiles, called "modes" in official software utilities.
# If you are unsure what the "mode" thing is about, don't set this field.
# Official software utility configuration file key: `MDNUM` (divided by 3).
# Default: 1.
Profiles=1
# Sensor type.
# This field is unused, only used for book-keeping purposes.
# Official software utility configuration file key: `Sensor`.
SensorType=PMW3289

View File

@@ -24,7 +24,6 @@
import argparse import argparse
import os import os
import pathlib
import sys import sys
import configparser import configparser
@@ -35,22 +34,22 @@ def parse_data_file(path):
data.optionxform = lambda option: option data.optionxform = lambda option: option
data.read(path) data.read(path)
matches = data["Device"]["DeviceMatch"] matches = data['Device']['DeviceMatch']
return matches.split(";") return matches.split(';')
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Device duplicate match checker") parser = argparse.ArgumentParser(description='Device duplicate match checker')
parser.add_argument("directory") parser.add_argument('file', nargs='+')
args = parser.parse_args() args = parser.parse_args()
device_matches = {} device_matches = {}
duplicates = False duplicates = False
for path in pathlib.Path(args.directory).glob("*.device"): for path in args.file:
matches = parse_data_file(path) matches = parse_data_file(path)
fname = os.path.basename(path) fname = os.path.basename(path)
for m in matches: for m in matches:
if m in device_matches: if m in device_matches:
print(f"Duplicate DeviceMatch={m} in {fname} and {device_matches[m]}") print('Duplicate DeviceMatch={} in {} and {}'.format(m, fname, device_matches[m]))
duplicates = True duplicates = True
device_matches[m] = fname device_matches[m] = fname

View File

@@ -2,4 +2,3 @@
Name=Etekcity Scroll Alpha Name=Etekcity Scroll Alpha
DeviceMatch=usb:1ea7:4011 DeviceMatch=usb:1ea7:4011
Driver=etekcity Driver=etekcity
DeviceType=mouse

View File

@@ -1,11 +1,5 @@
[Device] [Device]
Name=Glorious Model D Name=Glorious Model D
DeviceMatch=usb:258a:0033 DeviceMatch=usb:258a:0033
DeviceType=mouse
Driver=sinowealth Driver=sinowealth
[Driver/sinowealth/devices/V102]
Buttons=6
DeviceName=Glorious Model D
LedType=RBG
SensorType=PMW3360

View File

@@ -1,11 +1,5 @@
[Device] [Device]
Name=Glorious Model O/O- Name=Glorious Model O
DeviceMatch=usb:258a:0036 DeviceMatch=usb:258a:0036
DeviceType=mouse
Driver=sinowealth Driver=sinowealth
[Driver/sinowealth/devices/V103]
Buttons=6
DeviceName=Glorious Model O/O- (updated firmware)
LedType=RBG
SensorType=PMW3360

View File

@@ -3,4 +3,3 @@
Name=G.Skill MX-780 Name=G.Skill MX-780
DeviceMatch=usb:28da:3101 DeviceMatch=usb:28da:3101
Driver=gskill Driver=gskill
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech M325 Name=Logitech M325
DeviceMatch=usb:046d:400a DeviceMatch=usb:046d:400a
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,6 +0,0 @@
# Logitech M500s
[Device]
Name=Logitech M500s
DeviceMatch=usb:046d:c093
DeviceType=mouse
Driver=hidpp20

View File

@@ -1,6 +0,0 @@
# Logitech M545
[Device]
Name=Logitech M545
DeviceMatch=usb:046d:4052
DeviceType=mouse
Driver=hidpp20

View File

@@ -3,4 +3,3 @@
Name=Logitech M570 Name=Logitech M570
DeviceMatch=usb:046d:1028 DeviceMatch=usb:046d:1028
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech M585/M590 Name=Logitech M585/M590
DeviceMatch=usb:046d:406b;bluetooth:046d:b01b DeviceMatch=usb:046d:406b;bluetooth:046d:b01b
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech M705 Name=Logitech M705
DeviceMatch=usb:046d:101b DeviceMatch=usb:046d:101b
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech M720 Name=Logitech M720
DeviceMatch=usb:046d:405e;bluetooth:046d:b015 DeviceMatch=usb:046d:405e;bluetooth:046d:b015
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,6 +0,0 @@
# Logitech MX Anywhere 3
[Device]
Name=Logitech MX Anywhere 3
DeviceMatch=bluetooth:046d:b025;usb:046d:4090
DeviceType=mouse
Driver=hidpp20

View File

@@ -1,6 +0,0 @@
# Logitech MX Anywhere 3S
[Device]
Name=Logitech MX Anywhere 3S
DeviceMatch=bluetooth:046d:b037
DeviceType=mouse
Driver=hidpp20

View File

@@ -1,5 +1,4 @@
[Device] [Device]
Name=Logitech MX Anywhere 2 Name=Logitech MX Anywhere 2
DeviceMatch=usb:046d:404a;usb:046d:4072;usb:046d:4063;bluetooth:046d:b013;bluetooth:046d:b018;bluetooth:046d:b01f DeviceMatch=usb:046d:404a;bluetooth:046d:b013;bluetooth:046d:b018;bluetooth:046d:b01f
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech MX Anywhere 2S Name=Logitech MX Anywhere 2S
DeviceMatch=bluetooth:046d:b01a;usb:046d:406a DeviceMatch=bluetooth:046d:b01a;usb:046d:406a
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,6 +0,0 @@
# Logitech MX Anywhere 3B
[Device]
Driver=hidpp20
Name=Logitech MX Anywhere 3B
DeviceType=mouse
DeviceMatch=bluetooth:046d:b02d

View File

@@ -3,4 +3,3 @@
Name=Logitech MX Ergo Name=Logitech MX Ergo
DeviceMatch=bluetooth:046d:b01d;usb:046d:406f DeviceMatch=bluetooth:046d:b01d;usb:046d:406f
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech MX Master 2S Name=Logitech MX Master 2S
DeviceMatch=bluetooth:046d:b019;usb:046d:4069 DeviceMatch=bluetooth:046d:b019;usb:046d:4069
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech MX Master 3 Name=Logitech MX Master 3
DeviceMatch=bluetooth:046d:b023;usb:046d:4082 DeviceMatch=bluetooth:046d:b023;usb:046d:4082
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,5 +0,0 @@
[Device]
DeviceMatch=bluetooth:046d:b035
DeviceType=mouse
Driver=hidpp20
Name=Logitech MX Master 3S for Business

View File

@@ -1,5 +0,0 @@
[Device]
DeviceMatch=bluetooth:046d:b034
DeviceType=mouse
Driver=hidpp20
Name=Logitech MX Master 3S

View File

@@ -3,4 +3,3 @@
Name=Logitech MX Master Name=Logitech MX Master
DeviceMatch=usb:046d:4041;bluetooth:046d:b012;usb:046d:4060;bluetooth:046d:b017;bluetooth:046d:b01e;usb:046d:4071 DeviceMatch=usb:046d:4041;bluetooth:046d:b012;usb:046d:4060;bluetooth:046d:b017;bluetooth:046d:b01e;usb:046d:4071
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,5 +1,4 @@
[Device] [Device]
Name=Logitech MX Vertical Name=Logitech MX Vertical
DeviceMatch=bluetooth:046d:b020;usb:046d:407b;usb:046d:c08a DeviceMatch=bluetooth:046d:b020;usb:046d:407b
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=MX518 Name=MX518
DeviceMatch=usb:046d:c08e DeviceMatch=usb:046d:c08e
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech Marathon M705 Name=Logitech Marathon M705
DeviceMatch=usb:046d:406d DeviceMatch=usb:046d:406d
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech T650 Name=Logitech T650
DeviceMatch=usb:046d:4101 DeviceMatch=usb:046d:4101
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -3,4 +3,3 @@
Name=Logitech Wireless Touchpad Name=Logitech Wireless Touchpad
DeviceMatch=usb:046d:4011 DeviceMatch=usb:046d:4011
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,8 +1,8 @@
[Device] [Device]
Name=Logitech G Powerplay Name=Logitech G Powerplay
DeviceMatch=usb:046d:405f DeviceMatch=usb:046d:405f
LedTypes=logo
Driver=hidpp20 Driver=hidpp20
DeviceType=other
[Driver/hidpp20] [Driver/hidpp20]
DeviceIndex=7 DeviceIndex=7

View File

@@ -1,5 +0,0 @@
[Device]
DeviceMatch=usb:046d:c339
DeviceType=keyboard
Driver=hidpp20
Name=Logitech G PRO Keyboard

View File

@@ -1,8 +1,8 @@
[Device] [Device]
Name=Logitech G Pro Wireless Name=Logitech G Pro Wireless
DeviceMatch=usb:046d:4079;usb:046d:c088 DeviceMatch=usb:046d:4079;usb:046d:c088
LedTypes=logo;battery;dpi;
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse
[Driver/hidpp20] [Driver/hidpp20]
DeviceIndex=1 DeviceIndex=1

View File

@@ -1,5 +0,0 @@
[Device]
Name=Logitech G Pro X Wireless Superlight
DeviceMatch=usb:046d:4093;usb:046d:c094
DeviceType=mouse
Driver=hidpp20

View File

@@ -2,4 +2,4 @@
Name=Logitech Gaming Mouse G Pro Name=Logitech Gaming Mouse G Pro
DeviceMatch=usb:046d:c085;usb:046d:c08c DeviceMatch=usb:046d:c085;usb:046d:c08c
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse LedTypes=logo;side

View File

@@ -1,6 +1,6 @@
# G102, G103 and G203 (USB) # G102, G103 and G203 (USB)
[Device] [Device]
Name=Logitech Gaming Mouse G102/G103/G203 Name=Logitech Gaming Mouse G102/G103/G203
DeviceMatch=usb:046d:c084;usb:046d:c092;usb:046d:c09d DeviceMatch=usb:046d:c084;usb:046d:c092
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse LedTypes=logo;side;

View File

@@ -3,4 +3,3 @@
Name=Logitech G300 Name=Logitech G300
DeviceMatch=usb:046d:c246 DeviceMatch=usb:046d:c246
Driver=logitech_g300 Driver=logitech_g300
DeviceType=mouse

View File

@@ -3,4 +3,4 @@
Name=Logitech Gaming Mouse G302 Name=Logitech Gaming Mouse G302
DeviceMatch=usb:046d:c07f DeviceMatch=usb:046d:c07f
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse LedTypes=logo;side;

View File

@@ -1,5 +0,0 @@
[Device]
Name=Logitech G303 Shroud Edition
DeviceMatch=usb:046d:c097
DeviceType=mouse
Driver=hidpp20

View File

@@ -3,4 +3,4 @@
Name=Logitech Gaming Mouse G303 Name=Logitech Gaming Mouse G303
DeviceMatch=usb:046d:c080 DeviceMatch=usb:046d:c080
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse LedTypes=logo;side;

View File

@@ -2,7 +2,6 @@
Name=Logitech Gaming Mouse G305 Name=Logitech Gaming Mouse G305
DeviceMatch=usb:046d:4074 DeviceMatch=usb:046d:4074
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse
[Driver/hidpp20] [Driver/hidpp20]
Leds=0 Leds=0

View File

@@ -2,5 +2,5 @@
[Device] [Device]
Name=Logitech G402 Gaming Mouse Name=Logitech G402 Gaming Mouse
DeviceMatch=usb:046d:c07e DeviceMatch=usb:046d:c07e
LedTypes=logo
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G403 Hero Name=Logitech G403 Hero
DeviceMatch=usb:046d:c08f DeviceMatch=usb:046d:c08f
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G403 Wireless Name=Logitech G403 Wireless
DeviceMatch=usb:046d:405d;usb:046d:c082 DeviceMatch=usb:046d:405d;usb:046d:c082
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G403 Name=Logitech G403
DeviceMatch=usb:046d:c083 DeviceMatch=usb:046d:c083
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,5 +0,0 @@
[Device]
DeviceMatch=usb:046d:c33a
DeviceType=keyboard
Driver=hidpp20
Name=Logitech G413

View File

@@ -3,7 +3,6 @@
Name=Logitech G5 Name=Logitech G5
DeviceMatch=usb:046d:c049 DeviceMatch=usb:046d:c049
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiList=400;800;1600;2000 DpiList=400;800;1600;2000

View File

@@ -2,7 +2,6 @@
Name=G5 Name=G5
DeviceMatch=usb:046d:c041 DeviceMatch=usb:046d:c041
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiList=400;800;1600;2000 DpiList=400;800;1600;2000

View File

@@ -2,7 +2,6 @@
Name=Logitech G500 Name=Logitech G500
DeviceMatch=usb:046d:c068 DeviceMatch=usb:046d:c068
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiRange=0:5700@23.53 DpiRange=0:5700@23.53

View File

@@ -2,7 +2,6 @@
Name=Logitech G500s Name=Logitech G500s
DeviceMatch=usb:046d:c24e DeviceMatch=usb:046d:c24e
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiRange=0:8200@50 DpiRange=0:8200@50

View File

@@ -2,4 +2,3 @@
Name=Logitech G502 Hero Wireless Name=Logitech G502 Hero Wireless
DeviceMatch=usb:046d:407f;usb:046d:c08d DeviceMatch=usb:046d:407f;usb:046d:c08d
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G502 Hero Name=Logitech G502 Hero
DeviceMatch=usb:046d:c08b DeviceMatch=usb:046d:c08b
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G502 Proteus Core Name=Logitech G502 Proteus Core
DeviceMatch=usb:046d:c07d DeviceMatch=usb:046d:c07d
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G502 Proteus Spectrum Name=Logitech G502 Proteus Spectrum
DeviceMatch=usb:046d:c332 DeviceMatch=usb:046d:c332
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,5 +0,0 @@
[Device]
Name=Logitech G502 X Wireless
DeviceMatch=usb:046d:c098
DeviceType=mouse
Driver=hidpp20

View File

@@ -1,5 +0,0 @@
[Device]
Name=Logitech G502 X
DeviceMatch=usb:046d:c099
DeviceType=mouse
Driver=hidpp20

View File

@@ -1,5 +1,5 @@
[Device] [Device]
Name=Logitech G513 Name=Logitech G513
DeviceMatch=usb:046d:c33c DeviceMatch=usb:046d:c33c
LedTypes=switches
Driver=hidpp20 Driver=hidpp20
DeviceType=keyboard

View File

@@ -3,4 +3,3 @@
Name=Logitech G600 Name=Logitech G600
DeviceMatch=usb:046d:c24a DeviceMatch=usb:046d:c24a
Driver=logitech_g600 Driver=logitech_g600
DeviceType=mouse

View File

@@ -3,7 +3,6 @@
Name=Logitech G602 Name=Logitech G602
DeviceMatch=usb:046d:402c DeviceMatch=usb:046d:402c
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse
[Driver/hidpp20] [Driver/hidpp20]
DeviceIndex=1 DeviceIndex=1

View File

@@ -3,4 +3,3 @@
Name=Logitech G603 Name=Logitech G603
DeviceMatch=usb:046d:406c;bluetooth:046d:b01c DeviceMatch=usb:046d:406c;bluetooth:046d:b01c
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G604 Name=Logitech G604
DeviceMatch=usb:046d:4085;bluetooth:046d:b024 DeviceMatch=usb:046d:4085;bluetooth:046d:b024
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,8 +0,0 @@
[Device]
Name=Logitech G635
DeviceMatch=usb:046d:0a89
DeviceType=mouse
Driver=hidpp20
[Driver/hidpp20]
Buttons=0

View File

@@ -4,7 +4,6 @@
Name=Logitech G7 Name=Logitech G7
DeviceMatch=usb:046d:c51a DeviceMatch=usb:046d:c51a
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
Profiles=1 Profiles=1

View File

@@ -4,7 +4,6 @@
Name=Logitech G700 Name=Logitech G700
DeviceMatch=usb:046d:c531 DeviceMatch=usb:046d:c531
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiRange=0:5700@23.53 DpiRange=0:5700@23.53

View File

@@ -4,7 +4,6 @@
Name=Logitech G700 Name=Logitech G700
DeviceMatch=usb:046d:c06b DeviceMatch=usb:046d:c06b
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiRange=0:5700@23.53 DpiRange=0:5700@23.53

View File

@@ -4,7 +4,6 @@
Name=Logitech G700s Name=Logitech G700s
DeviceMatch=usb:046d:c07c DeviceMatch=usb:046d:c07c
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiRange=0:8200@50 DpiRange=0:8200@50

View File

@@ -2,4 +2,4 @@
Name=Logitech G703 Hero Name=Logitech G703 Hero
DeviceMatch=usb:046d:4086;usb:046d:c090 DeviceMatch=usb:046d:4086;usb:046d:c090
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,4 @@
Name=Logitech G703 Name=Logitech G703
DeviceMatch=usb:046d:c087;usb:046d:4070 DeviceMatch=usb:046d:c087;usb:046d:4070
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,8 +0,0 @@
[Device]
Name=Logitech G733 Gaming Headset
DeviceMatch=usb:046d:0ab5;usb:046d:0afe
DeviceType=mouse
Driver=hidpp20
[Driver/hidpp20]
Buttons=0

View File

@@ -1,5 +1,5 @@
[Device] [Device]
Name=Logitech G815 Name=Logitech G815
DeviceMatch=usb:046d:c33f DeviceMatch=usb:046d:c33f
LedTypes=logo;switches
Driver=hidpp20 Driver=hidpp20
DeviceType=keyboard

View File

@@ -3,8 +3,8 @@
[Device] [Device]
Name=Logitech G9 Name=Logitech G9
DeviceMatch=usb:046d:c048 DeviceMatch=usb:046d:c048
LedTypes=dpi
Driver=hidpp10 Driver=hidpp10
DeviceType=mouse
[Driver/hidpp10] [Driver/hidpp10]
DpiList=200;400;600;800;1000;1200;1400;1600;1800;2000;2200;2400;2600;2800;3000;3200 DpiList=200;400;600;800;1000;1200;1400;1600;1800;2000;2200;2400;2600;2800;3000;3200

View File

@@ -3,4 +3,3 @@
Name=Logitech G900 Name=Logitech G900
DeviceMatch=usb:046d:c081;usb:046d:4053 DeviceMatch=usb:046d:c081;usb:046d:4053
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G903 Hero Name=Logitech G903 Hero
DeviceMatch=usb:046d:c091;usb:046d:4087 DeviceMatch=usb:046d:c091;usb:046d:4087
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -2,4 +2,3 @@
Name=Logitech G903 Name=Logitech G903
DeviceMatch=usb:046d:c086;usb:046d:4067 DeviceMatch=usb:046d:c086;usb:046d:4067
Driver=hidpp20 Driver=hidpp20
DeviceType=mouse

View File

@@ -1,8 +1,8 @@
[Device] [Device]
Name=Logitech G910 Name=Logitech G910
DeviceMatch=usb:046d:c335 DeviceMatch=usb:046d:c335
LedTypes=logo;switches
Driver=hidpp20 Driver=hidpp20
DeviceType=keyboard
[Driver/hidpp20] [Driver/hidpp20]
DeviceIndex=ff DeviceIndex=ff

Some files were not shown because too many files have changed in this diff Show More