1
0
forked from drath/libratbag

Compare commits

...

70 Commits
v0.12 ... v0.14

Author SHA1 Message Date
Filipe Laíns
1231415470 libratbag 0.14
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-05-17 21:23:57 +01:00
Filipe Laíns
660da27021 data: add Logitech G935
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-05-17 21:19:32 +01:00
Dylan Baker
481b6f029a meson: make finding python more robust
This code assumes that there is a python3 or python3-embed pkg-config
file on the system, which may or may not be true. On Gentoo for example,
only python-X.Y pkg-config files are available and this will fail to
build.

This makes use of the new py_installation.dependency(embed : true) if
possible, and falls back to trying to find a python that matches the
version of python found by the python3 or python module.
2020-05-17 19:19:42 +01:00
Filipe Laíns
768d93a45a github: add device info to bug report template
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-29 14:23:47 +01:00
ksv1986
1c6e039d01 hidpp10: fix handling of hidpp10_device_new() failures
Signed-off-by: ksv1986 <ksv0x07c2@gmail.com>
2020-04-26 15:07:23 +01:00
ksv1986
d16df8d100 hidpp10: fix crash if device failed to initialize properly
Signed-off-by: ksv1986 <ksv0x07c2@gmail.com>
2020-04-26 15:07:23 +01:00
Filipe Laíns
4b1e49d522 hidpp20: fix report type in ColorLedEffects (0x8070) set_zone_effect
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-26 15:07:06 +01:00
Filipe Laíns
786cebcb0b hidpp20: cleanup, use short reports when possible
libratbag has a quite communication-intensive setup routine. This patch
uses short reports when possible. Using short reports will speed up the
setup process and have a lower power consumption, which is relevant for
wireless devices.

We now check the report descriptor for the supported report IDs and
adjust the report type used based on the device capabilities. Because of
that, this patch should work without any issues as the report type will
get overwritten if it not supported.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-26 15:07:06 +01:00
Filipe Laíns
d53454bcb3 hidpp10: fix circular loop on hidpp10_onboard_profiles_read_macro
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-26 15:06:25 +01:00
Filipe Laíns
a0def65b64 hidpp10: add debug log on hidpp10_onboard_profiles_parse_macro fail
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-26 15:06:25 +01:00
Stephan Lachnit
2a40279903 doc: replace some tabs with spaces
Signed-off-by: Stephan Lachnit <stephanlachnit@protonmail.com>
2020-04-26 15:06:08 +01:00
Filipe Laíns
02c95422f0 hidpp20: fix mapping button to consumer usages
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-18 02:31:17 +01:00
Filipe Laíns
4ce1cf2807 hidpp10: convert key actions to macro
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-18 02:31:17 +01:00
Filipe Laíns
89168f2187 hidpp10: add support from writting simple macro actions
Fixes #900

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-18 02:31:17 +01:00
Filipe Laíns
bb92337268 ci: remove dbus policy dir hack in arch
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-18 02:29:05 +01:00
Filipe Laíns
a8316c07f3 ratbagd: create path if not present before installing dbus policy dir
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-18 02:29:05 +01:00
Filipe Laíns
39769c57dd ci: save cache between jobs for fedora and arch
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-17 05:57:38 +01:00
Filipe Laíns
200a8af7a7 ci: cache packages in arch
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-17 05:57:38 +01:00
FFY00
fcf9f7745d ci: add arch
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-17 05:57:38 +01:00
Filipe Laíns
633c9fc55d libratbag-data: add missing header entry (#958)
Dicovered in #957

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-16 15:59:50 +02:00
Peter Hutterer
ee73434ead circleci: bump to use ubuntu 19.10
The 19.04 repos give us 404s, so let's update to the next version.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-04-16 08:01:53 +10:00
Filipe Laíns
d60b1c9d71 data: overwrite led count in G305
Fixes #949

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-14 19:00:12 +01:00
Filipe Laíns
88a60f55b4 hidpp20: allow overwritting the led count
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-14 19:00:12 +01:00
D33M0N
dba202ae8b data: added bluetooth ID to the MX Anywhere 2 2020-04-03 19:27:02 +01:00
Filipe Laíns
6cdcce9de4 hidpp20: log error number when commiting
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-03 17:02:44 +02:00
Filipe Laíns
e2c3373145 hidpp10: log errors when comitting
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-04-03 17:02:44 +02:00
Filipe Laíns
02575a9008 hidpp20: add button/macro opcodes
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-03-22 19:17:47 +00:00
Filipe Laíns
1097b1ba68 meson: silence swig warnings
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-03-22 19:13:58 +00:00
Filipe Laíns
77b67775da ratbagctl: don't print empty properties
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-03-22 19:08:58 +00:00
Filipe Laíns
5b23c9ebae data: add Logitech M720
Fixes #939

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-03-22 18:58:07 +00:00
Stephan Lachnit
6d0974be25 circleci: add diffutils dependency for fedora
Signed-off-by: Stephan Lachnit <stephanlachnit@protonmail.com>
2020-02-21 15:21:42 +01:00
simrat39
ea9111a2a6 devices: Set g402 LedTypes
Signed-off-by: simrat39 <simrats169169@gmail.com>
2020-02-10 15:49:45 +00:00
Filipe Laíns
42787ee422 meson: libratbag 0.13
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:32:55 +00:00
Filipe Laíns
611dd9be0d hidpp20: keep unsupported effects
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:31:42 +00:00
Filipe Laíns
fd20f9e642 hidpp20: simplify hidpp20_onboard_profiles_write_led
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:31:42 +00:00
Filipe Laíns
9be5576967 hidpp20: add some missing led effects
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:31:42 +00:00
Filipe Laíns
9fe511fcc5 hidpp20: add profile field to special bindings in onboard profiles
New devices define a profile field in the button configuration. This
allows us to map a button to set the target profile as active. Even
though we don't support configuring this right now, some devices, such
as the G915/G815, come pre-configured with this action on th M-Keys.
This patch makes us able to read and write those settings, this way they
don't get lost when we write a profile to the device.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:31:42 +00:00
Filipe Laíns
f0b69aab19 hidpp20: only set active resolution if there are resolutions on 0x8100
This prevents us from trying to set a resolution on keyboards.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:31:42 +00:00
Filipe Laíns
7610b80ced hidpp20: log errors when failed to write sector
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-09 23:31:42 +00:00
Filipe Laíns
f0a05bb522 data: add the Logitech G Powerplay
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-02-10 08:24:10 +10:00
Torbjørn Fylling
2669cc28b2 data: add support for Logitech G815 keyboard 2020-01-31 10:13:37 +00:00
Peter Hutterer
302702d94a Declare a bunch of structs as extern
gcc 10 complains about multiple definitions of these when linking.

/usr/bin/ld: libhidpp.a(src_hidpp-generic.c.o):/builddir/build/BUILD/libratbag-0.12/x86_64-redhat-linux-gnu/../src/libratbag-private.h:588:
multiple definition of `etekcity_driver';
libutil.a(src_libratbag-util.c.o):/builddir/build/BUILD/libratbag-0.12/x86_64-redhat-linux-gnu/../src/libratbag-private.h:588:
first defined here

Special case here is the test_driver struct, without the extern gcc seems to
think it's a new struct with all zeros, causing a segfault when we then try to
strcmp the test driver name.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-01-29 02:12:28 +00:00
Filipe Laíns
e1136c4d30 hidpp20: add debug log when failed to read led (8070, getZoneEffects)
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-28 21:41:45 +01:00
Filipe Laíns
0012853a1d hidpp20: make sure getZoneEffect (8070) is supported
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-28 21:41:45 +01:00
Filipe Laíns
afb85f868c hidpp20: change unsupported effect log msg to debug verbosity
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-28 21:41:45 +01:00
Filipe Laíns
b76fcdadde hidpp20: enable 0x8070 (ColorLedEffects) standalone use
0x8071 is still missing but as of now we don't have any device that
needs it.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-28 21:41:45 +01:00
Stephan Lachnit
ba7c092ee2 driver-hidpp20: replace goto with return
Signed-off-by: Stephan Lachnit <stephanlachnit@protonmail.com>
2020-01-08 07:36:52 +10:00
Stephan Lachnit
3483bd8c14 driver-hidpp20: minor cleanup
Removes useless setting of the dpi index when updating resolutions.
Removes weird empty line.

Signed-off-by: Stephan Lachnit <stephanlachnit@protonmail.com>
2020-01-08 07:36:52 +10:00
Filipe Laíns
0fb0eb3d42 hidpp20: log errors in hidpp20drv_commit
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-06 19:22:57 +00:00
Filipe Laíns
5fb1f4429d ratbagd: log error if failed to commit
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-06 19:22:57 +00:00
Filipe Laíns
5f5e294598 hidpp20: add support for reading/writing the report rate via 0x8060
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-06 19:18:06 +00:00
Filipe Laíns
b4218737cd hidpp20: fix bug that was unsetting some capabilities
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-06 19:18:06 +00:00
Filipe Laíns
3875bb70fd hidpp20: implement dirty flag for report rate
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-06 19:13:01 +00:00
Filipe Laíns
e9d67b7235 ratbag: add dirty flag for report rate
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-06 19:13:01 +00:00
Filipe Laíns
8a476a8724 hidpp: fix supported_report_types data type
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2020-01-03 22:40:03 +00:00
Sadika Sumanapala
d67cbec5f8 Add M590 bluetooth ID 2020-01-03 08:17:43 +10:00
Stephan Lachnit
f82c6f72b6 Use EditorConfig instead of vim comments
Signed-off-by: Stephan Lachnit <stephanlachnit@protonmail.com>
2019-12-24 08:04:11 +10:00
Stephan Lachnit
af30fc28cd CircleCI: use variables for dependencies
Use separate variable lists for dependencies.
Uninstall check merged in upstream meson, so it can be simplified.
`libsolv` doesn't need to be updated any more with Fedora 31.

Signed-off-by: Stephan Lachnit <stephanlachnit@protonmail.com>
2019-12-24 07:34:18 +10:00
Filipe Laíns
3fb8a51456 docs: adjust description to say we support other devices than mice
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-23 06:26:55 +10:00
Matthias Bach
ceaa3c3ad5 Reorder the initialisation of the ratbagd client
When the API version mismatches we want to fail early before performing
any more complex initialisation. We do however have to check for
devices first so that we can distinguish cases where we cannot access
the daemon from those where it is too old to provide an API version.
2019-12-22 16:58:20 +00:00
Matthias Bach
551b918ba8 Give a more specific error message if user cannot reach ratbagd via D-BUS
If access failed, e.g. due to insufficient permissions, don't confuse
the user by reporting an API mismatch.

This is a minimal improvement to target issue #802. As, if access is
restricted to a group, that group is known in Meson, it would even be
possible to report that group in the error message. But, that would
require converting ratbagd.py to a template or finding some other way to
inject that information at build time.
2019-12-22 16:58:20 +00:00
Filipe Laíns
3105428ba1 tests: fix data parse for hidpp index
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-20 10:30:10 +01:00
Benjamin Tissoires
b3f2406180 data: add G910
Same situation than the G513, 0x8100 is not present.
But heh.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2019-12-20 09:15:24 +00:00
Benjamin Tissoires
902160f430 ratbag-command fixes
- File "./build/ratbag-command", line 2289, in open_ratbagd
    r = Ratbagd(1)
  TypeError: __init__() takes 1 positional argument but 2 were given
- AttributeError: module 'libratbag' has no attribute
  'ratbag_device_get_bus'
- File "./build/ratbag-command", line 267, in model
    return "{}:{04x}:{04x}:{d}".format(bus, vid, pid, version)
  KeyError: '04x'
- swig/python detected a memory leak of type 'uint32_t *', no destructor
  found.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2019-12-19 15:56:52 +01:00
Filipe Laíns
fd6d0b6198 data: add G513
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-19 13:58:02 +01:00
Filipe Laíns
5ed98fdb22 hidpp20: only enable 0x8070 or 0x8071 if 0x8100 is present
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-19 13:58:02 +01:00
Filipe Laíns
e0e73c2971 data: add G915
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-19 12:06:15 +00:00
Filipe Laíns
0d3b4f1b64 libratbag: add 'switches' led type
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-19 12:06:15 +00:00
Filipe Laíns
20b6e3deeb hidpp20: only populate resolutions if the device supports
This patch moves the 0x8100 initialization routine out of
hidpp20drv_init_feature because it needs the capabilities to be
processed first.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-19 12:05:54 +00:00
Filipe Laíns
ffcdee912d libratbag: allow no resolutions
Signed-off-by: Filipe Laíns <lains@archlinux.org>
2019-12-19 12:05:54 +00:00
50 changed files with 872 additions and 242 deletions

View File

@@ -1,5 +1,12 @@
# vim: set expandtab shiftwidth=2 tabstop=8:
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:
@@ -52,10 +59,7 @@ libratbag_references:
name: Checking if any files are left after uninstall
command: |
PREFIX=/root/test_install
# workaround until https://github.com/mesonbuild/meson/pull/2033 is merged
# and a new release appears
git clone https://github.com/whot/meson -b wip/remove-directories-on-uninstall
./meson/meson.py build_install --prefix=$PREFIX
meson build_install --prefix=$PREFIX
ninja -C build_install install
ninja -C build_install uninstall
if [ -d $PREFIX ]
@@ -73,33 +77,34 @@ libratbag_references:
mkdir /run/dbus
/usr/bin/dbus-daemon --system --fork
fedora_prep_cache: &fedora_prep_cache
<<: *default_settings
steps:
- run:
name: Initializing Fedora dnf cache
command: dnf install -y --downloadonly libsolv tree git gcc gcc-c++ meson check-devel libudev-devel libevdev-devel valgrind python3-gobject python3-evdev glib2-devel python3-lxml libunistring-devel dbus-daemon json-glib-devel diffutils
- persist_to_workspace:
root: /var/cache/
paths:
- dnf/*
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
attach_workspace:
at: /var/cache/
restore_cache:
keys:
- fedora-cache-v1
fedora_install: &fedora_install
run:
name: Install prerequisites
command: |
echo keepcache=1 >> /etc/dnf/dnf.conf
dnf upgrade -y libsolv
dnf install -y tree git gcc gcc-c++ meson check-devel libudev-devel libevdev-devel valgrind python3-gobject python3-evdev glib2-devel python3-lxml python3-devel swig libunistring-devel dbus-daemon json-glib-devel diffutils
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
@@ -111,7 +116,39 @@ fedora_settings: &fedora_settings
- *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
@@ -124,7 +161,7 @@ ubuntu_settings: &ubuntu_settings
apt-get remove -y libnss-systemd
add-apt-repository universe
apt-get update
apt-get install -y tree git gcc g++ pkg-config meson check libudev-dev libevdev-dev libsystemd-dev valgrind python3-gi python3-evdev libglib2.0-dev python3-lxml python3-dev swig systemd libunistring-dev libjson-glib-dev
apt-get install -y git ${UBUNTU_DEP_BUILD} ${UBUNTU_DEP_TEST}
- checkout
- *start_dbus
- *build_and_test
@@ -134,6 +171,8 @@ ubuntu_settings: &ubuntu_settings
- *build_buildtype_plain
- *build_buildtype_release
- *export_logs
environment:
*build_dependencies
doc_build: &doc_build
<<: *default_settings
@@ -142,7 +181,7 @@ doc_build: &doc_build
- *fedora_install
- run:
name: Install documentation build-deps
command: dnf install -y python3-sphinx python3-sphinx_rtd_theme
command: dnf install -y ${FEDORA_DEP_DOC}
- checkout
- *build_with_docs
- *export_logs
@@ -152,6 +191,8 @@ doc_build: &doc_build
root: build
paths:
- doc/html/*
environment:
*build_dependencies
docs_deploy: &docs_deploy
<<: *default_settings
@@ -193,18 +234,18 @@ docs_deploy: &docs_deploy
version: 2
jobs:
fedora_cache:
<<: *fedora_prep_cache
docker:
- image: fedora:31
fedora_31:
<<: *fedora_settings
docker:
- image: fedora:31
ubuntu_19_04:
arch:
<<: *arch_settings
docker:
- image: archlinux
ubuntu_19_10:
<<: *ubuntu_settings
docker:
- image: ubuntu:19.04
- image: ubuntu:19.10
doc_build:
<<: *doc_build
docker:
@@ -219,17 +260,12 @@ workflows:
version: 2
compile_and_test:
jobs:
- fedora_cache
- ubuntu_19_04
- fedora_31:
requires:
- fedora_cache
- doc_build:
requires:
- fedora_cache
- ubuntu_19_10
- arch
- fedora_31
- doc_build
- doc_deploy:
requires:
- fedora_cache
- doc_build
filters:
branches:

20
.editorconfig Normal file
View File

@@ -0,0 +1,20 @@
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{c,h}]
indent_style = tab
tab_width = 8
trim_trailing_whitespace = true
[{*.{py,py.in},tools/ratbagctl.*.in}]
indent_style = space
indent_size = 4
[*.{yml,xsl}]
indent_style = space
indent_size = 2

View File

@@ -13,6 +13,12 @@ assignees: ''
- Distribution:
- Kernel version (ex. `uname -srmo`): `KERNEL VERSION HERE`
Device info (if applicable):
```
$ ratbagctl <device> info
OUTPUT HERE
```
**Describe the bug**
A clear and concise description of what the bug is.

View File

@@ -3,9 +3,10 @@ libratbag
<img src="https://libratbag.github.io/_images/logo.svg" alt="" width="30%" align="right">
libratbag provides **ratbagd**, a DBus daemon to configure gaming mice.
The daemon provides a generic way to access the various features exposed by
these mice and abstracts away hardware-specific and kernel-specific quirks.
libratbag provides **ratbagd**, a DBus daemon to configure input devices,
mainly gaming mice. The daemon provides a generic way to access the various
features exposed by these mice and abstracts away hardware-specific and
kernel-specific quirks.
libratbag currently supports devices from Logitech, Etekcity, GSkill,
Roccat, Steelseries. See [the device

View File

@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# Copyright © 2017 Red Hat, Inc.
#
@@ -58,7 +57,7 @@ def check_match_str(string):
def check_ledtypes_str(string):
permitted_types = ['logo', 'side', 'battery', 'dpi']
permitted_types = ['logo', 'side', 'battery', 'dpi', 'switches']
types = string.split(';')
for t in types:
@@ -138,9 +137,8 @@ def check_section_hidpp10(section):
pass
try:
index = int(section['DeviceIndex'])
# 10 is arbitrarily chosen
assert(index > 0 and index < 10)
index = int(section['DeviceIndex'], 16)
assert(index > 0 and index <= 0xff)
except KeyError:
pass
@@ -170,14 +168,13 @@ def check_section_hidpp10(section):
def check_section_hidpp20(section):
permitted = ['DeviceIndex', 'Quirk']
permitted = ['DeviceIndex', 'Leds', 'Quirk']
for key in section.keys():
assertIn(key, permitted)
try:
index = int(section['DeviceIndex'])
# 10 is arbitrarily chosen
assert(index > 0 and index < 10)
index = int(section['DeviceIndex'], 16)
assert(index > 0 and index <= 0xff)
except KeyError:
pass

View File

@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# Copyright © 2018 Red Hat, Inc.
#

View File

@@ -1,5 +1,5 @@
# Logitech M585/M590
[Device]
Name=Logitech M585/M590
DeviceMatch=usb:046d:406b
DeviceMatch=usb:046d:406b;bluetooth:046d:b01b
Driver=hidpp20

View File

@@ -0,0 +1,4 @@
[Device]
Name=Logitech M720
DeviceMatch=usb:046d:405e
Driver=hidpp20

View File

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

View File

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

View File

@@ -4,4 +4,5 @@ DeviceMatch=usb:046d:4074
Driver=hidpp20
[Driver/hidpp20]
Leds=0
Quirk=G305

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,8 @@
[Device]
Name=Logitech G915
DeviceMatch=usb:046d:c33e
LedTypes=logo;switches
Driver=hidpp20
[Driver/hidpp20]
DeviceIndex=1

View File

@@ -0,0 +1,5 @@
[Device]
Name=Logitech G935
DeviceMatch=usb:046d:0a87
LedTypes=logo;side
Driver=hidpp20

View File

@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# Copyright © 2018 Red Hat, Inc.
#

View File

@@ -85,13 +85,13 @@ interact with ratbagd.
:type: i
:flags: read-only,constant
The DBus API version. This is a stopgap feature while the DBus API
is still in flux. The version has no backwards or
forward-compatibilty guarantees - your client must understand
**exactly** the same version, it is not enough to support an older
or a newer version.
The DBus API version. This is a stopgap feature while the DBus API
is still in flux. The version has no backwards or
forward-compatibilty guarantees - your client must understand
**exactly** the same version, it is not enough to support an older
or a newer version.
This API will be removed once the DBus API is declared stable.
This API will be removed once the DBus API is declared stable.
.. attribute:: Devices

View File

@@ -1,5 +1,5 @@
project('libratbag', 'c',
version : '0.12',
version : '0.14',
license : 'MIT/Expat',
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
meson_version : '>= 0.40.0')
@@ -284,6 +284,7 @@ data_files = files(
'data/devices/logitech-M570.device',
'data/devices/logitech-M585-M590.device',
'data/devices/logitech-M705.device',
'data/devices/logitech-M720.device',
'data/devices/logitech-MX-Ergo.device',
'data/devices/logitech-MX-Master.device',
'data/devices/logitech-MX-Master-2S.device',
@@ -291,6 +292,7 @@ data_files = files(
'data/devices/logitech-MX518.device',
'data/devices/logitech-T650.device',
'data/devices/logitech-Wireless-Touchpad.device',
'data/devices/logitech-g-powerplay.device',
'data/devices/logitech-g-pro-wireless.device',
'data/devices/logitech-g-pro.device',
'data/devices/logitech-g102-g203.device',
@@ -310,6 +312,7 @@ data_files = files(
'data/devices/logitech-g502-hero.device',
'data/devices/logitech-g502-proteus-core.device',
'data/devices/logitech-g502-proteus-spectrum.device',
'data/devices/logitech-g513.device',
'data/devices/logitech-g600.device',
'data/devices/logitech-g602.device',
'data/devices/logitech-g603.device',
@@ -324,6 +327,10 @@ data_files = files(
'data/devices/logitech-g900.device',
'data/devices/logitech-g903-hero.device',
'data/devices/logitech-g903.device',
'data/devices/logitech-g815.device',
'data/devices/logitech-g910.device',
'data/devices/logitech-g915.device',
'data/devices/logitech-g935.device',
'data/devices/logitech-g9x-Call-of-Duty-MW3-Edition.device',
'data/devices/logitech-g9x-Original.device',
'data/devices/logitech-Marathon-M705.device',
@@ -532,12 +539,28 @@ configure_file(input : 'dbus/org.freedesktop.ratbag1.conf.in',
#### tools ####
# This is a special idiomatic construct in meson to get a fast dependency that
# doesn't exist and isn't logged as "not found".
dep_python3 = dependency('', required : false)
if meson.version().version_compare('<0.48.0')
python = import('python3')
py3 = python.find_python()
else
pymod = import('python')
py3 = pymod.find_installation()
if meson.version().version_compare('>= 0.53.0')
dep_python3 = py3.dependency(embed : true)
endif
endif
# From python 3.8 we neeed python3-embed
py_version = py3.language_version()
embed = py_version.version_compare('>= 3.8') ? '-embed' : ''
if not dep_python3.found()
dep_python3 = dependency('python-@0@@1@'.format(py_version, embed), required : false)
if not dep_python3.found()
dep_python3 = dependency('python3@0@'.format(embed))
endif
endif
config_ratbagctl = configuration_data()
@@ -601,12 +624,6 @@ swig_gen = generator(
'@INPUT@'],
)
# From python 3.8 we neeed python3-embed
dep_python3 = dependency('python3-embed', required: false)
if not dep_python3.found()
dep_python3 = dependency('python3')
endif
wrapper_deps = [
dep_python3,
dep_libratbag,
@@ -619,7 +636,9 @@ shared_library(
'libratbag',
c_source,
name_prefix: '_',
c_args : ['-Wno-missing-prototypes', '-Wno-format-nonliteral'],
c_args : ['-Wno-missing-prototypes',
'-Wno-format-nonliteral',
'-Wno-missing-field-initializers'],
extra_files: [ i_source ] + src_libratbag ,
dependencies: deps_libratbag + wrapper_deps,
include_directories : include_directories('src', 'tools'),
@@ -632,7 +651,10 @@ shared_library(
'hidpp',
c_source,
name_prefix: '_',
c_args : ['-Wno-missing-prototypes', '-Wno-format-nonliteral'],
c_args : ['-Wno-missing-prototypes',
'-Wno-format-nonliteral',
'-Wno-missing-field-initializers',
'-Wno-strict-prototypes'],
extra_files: [ i_source ] + src_libratbag ,
dependencies: deps_libratbag + wrapper_deps,
include_directories : include_directories('src', 'tools'),

View File

@@ -172,6 +172,8 @@ static void ratbagd_device_commit_pending(void *data)
int r;
r = ratbag_device_commit(device->lib_device);
if (r)
log_error("error committing device (%d)\n", r);
if (r < 0)
ratbagd_device_resync(device, device->ctx->bus);
ratbagd_device_unref(device);

View File

@@ -170,7 +170,7 @@ static void parse_led_member(JsonObject *obj, const gchar *name,
if (streq(name, "type")) {
gboolean v = json_object_get_int_member(obj, name);
if (v < 0 || v > RATBAG_LED_TYPE_WHEEL)
if (v < 0 || v > RATBAG_LED_TYPE_SWITCHES)
parser_error("type");
led->type = v;

View File

@@ -29,6 +29,7 @@
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <libratbag.h>
#include <libudev.h>
#include <stdio.h>
@@ -547,6 +548,13 @@ static bool install_ratbagd_devel_dbus_policy(void)
log_error("Failed to source policy file: %m\n");
goto out;
}
if (mkdir_p(dirname(strdupa(DBUS_POLICY_DST)), 0755)) {
log_error("Failed to create destination path: %m\n");
goto out;
}
out = open(DBUS_POLICY_DST, O_CREAT|O_WRONLY, 0644);
if (out == -1) {
log_error("Failed to open destination: %m\n");

View File

@@ -164,6 +164,7 @@ hidpp10drv_map_button(struct ratbag_device *device,
{
struct hidpp10_profile profile;
int ret;
unsigned int modifiers = 0;
ret = hidpp10_get_profile(hidpp10, button->profile->index, &profile);
if (ret)
@@ -178,6 +179,7 @@ hidpp10drv_map_button(struct ratbag_device *device,
button->action.type = RATBAG_BUTTON_ACTION_TYPE_KEY;
button->action.action.key.key = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
profile.buttons[button->index].keys.key);
modifiers = profile.buttons[button->index].keys.modifier_flags;
break;
case PROFILE_BUTTON_TYPE_CONSUMER_CONTROL:
button->action.type = RATBAG_BUTTON_ACTION_TYPE_KEY;
@@ -199,6 +201,14 @@ hidpp10drv_map_button(struct ratbag_device *device,
}
}
if (button->action.type == RATBAG_BUTTON_ACTION_TYPE_KEY) {
ret = ratbag_button_macro_new_from_keycode(button, button->action.action.key.key, modifiers);
if (ret < 0) {
log_error(device->ratbag, "hidpp10: error while reading button %d\n", button->index);
button->action.type = RATBAG_BUTTON_ACTION_TYPE_NONE;
}
}
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
}
@@ -299,6 +309,8 @@ hidpp10drv_write_button(struct hidpp10_profile *profile,
struct hidpp10drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp10_device *hidpp10 = drv_data->dev;
uint8_t code;
unsigned int modifiers, key;
int rc;
if (hidpp10->profile_type == HIDPP10_PROFILE_UNKNOWN)
return -ENOTSUP;
@@ -330,6 +342,26 @@ hidpp10drv_write_button(struct hidpp10_profile *profile,
profile->buttons[button->index].special.special = code;
break;
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
rc = ratbag_action_keycode_from_macro(action, &key, &modifiers);
if (rc < 0) {
log_error(device->ratbag, "hidpp10: can't convert macro action to keycode in button %d\n", button->index);
return -EINVAL;
}
code = ratbag_hidraw_get_keyboard_usage_from_keycode(device, key);
if (code == 0) {
code = ratbag_hidraw_get_consumer_usage_from_keycode(device, key);
if (code == 0)
return -EINVAL;
profile->buttons[button->index].consumer_control.type = PROFILE_BUTTON_TYPE_CONSUMER_CONTROL;
profile->buttons[button->index].consumer_control.consumer_control = code;
} else {
profile->buttons[button->index].keys.type = PROFILE_BUTTON_TYPE_KEYS;
profile->buttons[button->index].keys.key = code;
profile->buttons[button->index].keys.modifier_flags = modifiers;
}
break;
default:
return -ENOTSUP;
}
@@ -558,8 +590,10 @@ hidpp10drv_commit(struct ratbag_device *device)
continue;
rc = hidpp10drv_write_button(&p, button, &action);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp10: failed to update buttons (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
}
ratbag_profile_for_each_led(profile, led)
@@ -567,8 +601,10 @@ hidpp10drv_commit(struct ratbag_device *device)
if (dev->profile_type != HIDPP10_PROFILE_UNKNOWN) {
rc = hidpp10_set_profile(dev, profile->index, &p);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp10: failed to set profile (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
}
/* Update the current resolution in case it changed */
@@ -576,8 +612,10 @@ hidpp10drv_commit(struct ratbag_device *device)
rc = hidpp10_set_current_resolution(dev,
active_resolution->dpi_x,
active_resolution->dpi_y);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp10: failed to set active resolution (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
active_resolution = NULL;
}
@@ -631,9 +669,9 @@ hidpp10drv_probe(struct ratbag_device *device)
* If there is a special need like for G700(s), then add a DeviceIndex
* entry to the .device file.
*/
dev = hidpp10_device_new(&base, device_idx, type, profile_count);
rc = hidpp10_device_new(&base, device_idx, type, profile_count, &dev);
if (!dev) {
if (rc) {
log_error(device->ratbag,
"Failed to get HID++1.0 device for %s\n",
device->name);
@@ -714,14 +752,14 @@ static void
hidpp10drv_remove(struct ratbag_device *device)
{
struct hidpp10drv_data *drv_data;
struct hidpp10_device *dev;
ratbag_close_hidraw(device);
drv_data = ratbag_get_drv_data(device);
dev = drv_data->dev;
if (!drv_data)
return;
hidpp10_device_destroy(dev);
hidpp10_device_destroy(drv_data->dev);
free(drv_data);
}

View File

@@ -69,6 +69,7 @@ struct hidpp20drv_data {
unsigned num_controls;
struct hidpp20_control_id *controls;
struct hidpp20_profiles *profiles;
struct hidpp20_led *leds;
union hidpp20_generic_led_zone_info led_infos;
unsigned int report_rates[4];
@@ -334,14 +335,24 @@ static void
hidpp20drv_read_led_8070(struct ratbag_led *led, struct hidpp20drv_data* drv_data)
{
struct hidpp20_profile *profile;
struct hidpp20_led *h_led;
struct hidpp20_led h_led_val;
struct hidpp20_led *h_led = &h_led_val;
struct hidpp20_color_led_zone_info* led_info;
struct hidpp20_color_led_info info;
int rc;
led_info = &drv_data->led_infos.color_leds_8070[led->index];
profile = &drv_data->profiles->profiles[led->profile->index];
h_led = &profile->leds[led->index];
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
profile = &drv_data->profiles->profiles[led->profile->index];
h_led = &profile->leds[led->index];
} else {
rc = hidpp20_color_led_effects_get_zone_effect(drv_data->dev, led->index, h_led);
if (rc) {
log_debug(led->profile->device->ratbag,
"Failed to read led settings\n");
}
}
switch (h_led->mode) {
case HIDPP20_LED_ON:
@@ -397,10 +408,10 @@ hidpp20drv_read_led_8070(struct ratbag_led *led, struct hidpp20drv_data* drv_dat
ratbag_led_set_mode_capability(led, RATBAG_LED_BREATHING);
break;
default:
log_bug_libratbag(led->profile->device->ratbag,
"%s: Unknown effect id %d\n",
led->profile->device->name,
ei.effect_id);
log_debug(led->profile->device->ratbag,
"%s: Unsupported effect (%d)\n",
led->profile->device->name,
ei.effect_id);
break;
}
}
@@ -472,10 +483,10 @@ hidpp20drv_read_led_8071(struct ratbag_led *led, struct hidpp20drv_data* drv_dat
ratbag_led_set_mode_capability(led, RATBAG_LED_BREATHING);
break;
default:
log_bug_libratbag(led->profile->device->ratbag,
"%s: Unknown effect id %d\n",
led->profile->device->name,
ei.effect_id);
log_debug(led->profile->device->ratbag,
"%s: Unsupported effect (%d)\n",
led->profile->device->name,
ei.effect_id);
break;
}
}
@@ -564,7 +575,7 @@ hidpp20drv_update_button_8100(struct ratbag_button *button)
code = ratbag_hidraw_get_keyboard_usage_from_keycode(device, key);
if (code == 0) {
subtype = HIDPP20_BUTTON_HID_TYPE_CONSUMER_CONTROL;
code = ratbag_hidraw_get_consumer_usage_from_keycode(device, action->action.key.key);
code = ratbag_hidraw_get_consumer_usage_from_keycode(device, key);
if (code == 0)
return -EINVAL;
}
@@ -691,11 +702,13 @@ hidpp20drv_update_led_8070_8071(struct ratbag_led *led, struct ratbag_profile* p
struct hidpp20drv_data *drv_data)
{
struct hidpp20_profile *h_profile;
struct hidpp20_led *h_led;
struct hidpp20_led h_led_val;
struct hidpp20_led *h_led = &h_led_val;
h_profile = &drv_data->profiles->profiles[profile->index];
h_led = &(h_profile->leds[led->index]);
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
h_profile = &drv_data->profiles->profiles[profile->index];
h_led = &(h_profile->leds[led->index]);
}
if (!h_led)
return -EINVAL;
@@ -720,6 +733,13 @@ hidpp20drv_update_led_8070_8071(struct ratbag_led *led, struct ratbag_profile* p
h_led->period = led->ms;
h_led->brightness = led->brightness * 100 / 255;
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)) {
if (drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070)
hidpp20_color_led_effects_set_zone_effect(drv_data->dev,
led->index,
h_led_val);
}
return RATBAG_SUCCESS;
}
@@ -822,9 +842,12 @@ hidpp20drv_read_report_rate_8060(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag *ratbag = device->ratbag;
struct ratbag_profile *profile;
uint8_t bitflags_ms;
int nrates = 0;
int rc;
uint8_t rate_ms;
unsigned rate_hz;
rc = hidpp20_adjustable_report_rate_get_report_rate_list(drv_data->dev,
&bitflags_ms);
@@ -843,6 +866,37 @@ hidpp20drv_read_report_rate_8060(struct ratbag_device *device)
drv_data->num_report_rates = nrates;
if (!hidpp20_adjustable_report_rate_get_report_rate(drv_data->dev, &rate_ms)) {
switch (rate_ms)
{
case 1:
rate_hz = 1000;
break;
case 2:
case 3: /* 3ms = 333.(3)Hz, we round to 500Hz */
rate_hz = 500;
break;
case 4:
case 5: /* 5ms = 200Hz, we round to 250Hz */
rate_hz = 250;
break;
case 6: /* 6ms = 166.(6)Hz, we round to 125Hz */
case 7: /* 7ms = 142Hz, we round to 125Hz */
case 8:
rate_hz = 125;
break;
default:
rate_hz = 0;
break;
}
if (rate_hz) {
log_debug(ratbag, "report rate is %u\n", rate_hz);
ratbag_device_for_each_profile(device, profile)
profile->hz = rate_hz;
}
}
log_debug(ratbag, "device has %d report rates\n", nrates);
return 0;
@@ -943,7 +997,7 @@ hidpp20drv_update_resolution_dpi(struct ratbag_resolution *resolution,
struct ratbag_device *device = profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp20_sensor *sensor;
int rc, i;
int i;
int dpi = dpi_x; /* dpi_x == dpi_y if we don't have the individual resolution cap */
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)
@@ -959,14 +1013,13 @@ hidpp20drv_update_resolution_dpi(struct ratbag_resolution *resolution,
sensor = &drv_data->sensors[0];
/* validate that the sensor accepts the given DPI */
rc = -EINVAL;
if (dpi < sensor->dpi_min || dpi > sensor->dpi_max)
goto out;
return -EINVAL;
if (sensor->dpi_steps) {
for (i = sensor->dpi_min; i < dpi; i += sensor->dpi_steps) {
}
if (i != dpi)
goto out;
return -EINVAL;
} else {
i = 0;
while (sensor->dpi_list[i]) {
@@ -974,13 +1027,24 @@ hidpp20drv_update_resolution_dpi(struct ratbag_resolution *resolution,
break;
}
if (sensor->dpi_list[i] != dpi)
goto out;
return -EINVAL;
}
rc = hidpp20_adjustable_dpi_set_sensor_dpi(drv_data->dev, sensor, dpi);
return hidpp20_adjustable_dpi_set_sensor_dpi(drv_data->dev, sensor, dpi);
}
out:
return rc;
static int
hidpp20drv_update_report_rate_8060(struct ratbag_profile *profile, int hz)
{
struct ratbag_device *device = profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
int rc;
rc = hidpp20_adjustable_report_rate_set_report_rate(drv_data->dev, 1000/hz);
if (rc)
return rc;
return RATBAG_SUCCESS;
}
static int
@@ -1001,12 +1065,20 @@ hidpp20drv_update_report_rate(struct ratbag_profile *profile, int hz)
{
struct ratbag_device *device = profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
int rc;
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)
return hidpp20drv_update_report_rate_8100(profile, hz);
if (drv_data->capabilities & HIDPP_CAP_ADJUSTIBLE_REPORT_RATE_8060)
return -ENOTSUP;
if (drv_data->capabilities & HIDPP_CAP_ADJUSTIBLE_REPORT_RATE_8060) {
rc = hidpp20drv_update_report_rate_8060(profile, hz);
/* re-populate the profile with the correct value if we fail */
if (rc)
hidpp20drv_read_report_rate_8060(profile->device);
return rc;
}
return -ENOTSUP;
}
@@ -1179,6 +1251,60 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile)
ratbag_profile_set_report_rate(profile, p->report_rate);
}
static int
hidpp20drv_init_leds_8070_8071(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag *ratbag = device->ratbag;
/* we only support 0x8071 via 0x8100 */
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) &&
drv_data->capabilities & HIDPP_CAP_RGB_EFFECTS_8071) {
log_debug(ratbag, "disabling 0x8071 (RGB Effects) feature because the device doesn't have 0x8100 (Onboard Memory Profiles)\n");
drv_data->capabilities &= ~HIDPP_CAP_RGB_EFFECTS_8071;
}
if (drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070 ||
drv_data->capabilities & HIDPP_CAP_RGB_EFFECTS_8071) {
/* we read the profile once to get the correct number of
* supported leds. */
if (hidpp20drv_read_color_leds(device))
return 0;
device->num_leds = drv_data->num_leds;
}
return 0;
}
static int
hidpp20drv_init_profile_8100(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag *ratbag = device->ratbag;
int rc;
log_debug(ratbag, "initializing onboard profiles\n");
rc = hidpp20_onboard_profiles_allocate(drv_data->dev, &drv_data->profiles);
if (rc < 0)
return rc;
rc = hidpp20_onboard_profiles_initialize(drv_data->dev, drv_data->profiles);
if (rc < 0)
return rc;
drv_data->num_profiles = drv_data->profiles->num_profiles;
drv_data->num_buttons = drv_data->profiles->num_buttons;
if (drv_data->capabilities & HIDPP_CAP_SWITCHABLE_RESOLUTION_2201)
drv_data->num_resolutions = drv_data->profiles->num_modes;
/* We ignore the profile's num_leds and require
* HIDPP_PAGE_COLOR_LED_EFFECTS to succeed instead
*/
return 0;
}
static void
hidpp20drv_read_profile(struct ratbag_profile *profile)
{
@@ -1313,25 +1439,11 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
log_debug(ratbag, "device has color effects\n");
drv_data->capabilities |= HIDPP_CAP_COLOR_LED_EFFECTS_8070;
/* we read the profile once to get the correct number of
* supported leds. */
if (hidpp20drv_read_color_leds(device))
return 0;
device->num_leds = drv_data->num_leds;
break;
}
case HIDPP_PAGE_RGB_EFFECTS: {
log_debug(ratbag, "device has color effects\n");
drv_data->capabilities |= HIDPP_CAP_RGB_EFFECTS_8071;
/* we read the profile once to get the correct number of
* supported leds. */
if (hidpp20drv_read_color_leds(device))
return 0;
device->num_leds = drv_data->num_leds;
break;
}
case HIDPP_PAGE_LED_SW_CONTROL: {
@@ -1349,22 +1461,6 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
case HIDPP_PAGE_ONBOARD_PROFILES: {
log_debug(ratbag, "device has onboard profiles\n");
drv_data->capabilities |= HIDPP_CAP_ONBOARD_PROFILES_8100;
rc = hidpp20_onboard_profiles_allocate(drv_data->dev, &drv_data->profiles);
if (rc < 0)
return rc;
rc = hidpp20_onboard_profiles_initialize(drv_data->dev, drv_data->profiles);
if (rc < 0)
return rc;
drv_data->num_profiles = drv_data->profiles->num_profiles;
drv_data->num_resolutions = drv_data->profiles->num_modes;
drv_data->num_buttons = drv_data->profiles->num_buttons;
/* We ignore the profile's num_leds and require
* HIDPP_PAGE_COLOR_LED_EFFECTS to succeed instead
*/
break;
}
case HIDPP_PAGE_MOUSE_BUTTON_SPY: {
@@ -1386,27 +1482,27 @@ hidpp20drv_commit(struct ratbag_device *device)
struct ratbag_led *led;
struct ratbag_resolution *resolution;
int rc;
unsigned int dpi_index = 0;
list_for_each(profile, &device->profiles, link) {
if (!profile->dirty)
continue;
rc = hidpp20drv_update_report_rate(profile, profile->hz);
if (rc)
return RATBAG_ERROR_DEVICE;
if (profile->rate_dirty) {
rc = hidpp20drv_update_report_rate(profile, profile->hz);
if (rc) {
log_error(device->ratbag, "hidpp20: failed to update report rate (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
}
ratbag_profile_for_each_resolution(profile, resolution) {
if (resolution->is_active) {
log_raw(device->ratbag, "dpi index: %d, profile %d\n", resolution->index, profile->index);
dpi_index = resolution->index;
}
rc = hidpp20drv_update_resolution_dpi(resolution,
resolution->dpi_x,
resolution->dpi_y);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp20: failed to update resolution (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
}
list_for_each(button, &profile->buttons, link) {
@@ -1414,8 +1510,10 @@ hidpp20drv_commit(struct ratbag_device *device)
continue;
rc = hidpp20drv_update_button(button);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp20: failed to update button (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
}
list_for_each(led, &profile->leds, link) {
@@ -1423,10 +1521,11 @@ hidpp20drv_commit(struct ratbag_device *device)
continue;
rc = hidpp20drv_update_led(led);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp20: failed to update led (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
}
}
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
@@ -1435,17 +1534,18 @@ hidpp20drv_commit(struct ratbag_device *device)
rc = hidpp20_onboard_profiles_commit(drv_data->dev,
drv_data->profiles);
if (rc)
if (rc) {
log_error(device->ratbag, "hidpp20: failed to commit profile (%d)\n", rc);
return RATBAG_ERROR_DEVICE;
}
list_for_each(profile, &device->profiles, link) {
if (profile->is_active) {
ratbag_profile_for_each_resolution(profile, resolution) {
if (resolution->is_active)
dpi_index = resolution->index;
hidpp20_onboard_profiles_set_current_dpi_index(drv_data->dev,
resolution->index);
}
hidpp20_onboard_profiles_set_current_dpi_index(drv_data->dev,
dpi_index);
}
}
}
@@ -1476,8 +1576,21 @@ hidpp20drv_20_probe(struct ratbag_device *device)
return rc;
}
return 0;
/* initializations that depend on other features */
if (drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070 ||
drv_data->capabilities & HIDPP_CAP_RGB_EFFECTS_8071) {
rc = hidpp20drv_init_leds_8070_8071(device);
if (rc < 0)
return rc;
}
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
rc = hidpp20drv_init_profile_8100(device);
if (rc < 0)
return rc;
}
return 0;
}
static int
@@ -1511,6 +1624,7 @@ hidpp20drv_remove(struct ratbag_device *device)
free(drv_data->led_infos.color_leds_8070);
free(drv_data->controls);
free(drv_data->sensors);
free(drv_data->leds);
if (drv_data->dev)
hidpp20_device_destroy(drv_data->dev);
free(drv_data);
@@ -1522,6 +1636,11 @@ hidpp20drv_init_device(struct ratbag_device *device,
{
struct ratbag_profile *profile;
bool active_profile = false;
int num;
num = ratbag_device_data_hidpp20_get_led_count(device->data);
if (num >= 0)
drv_data->num_leds = num;
ratbag_device_init_profiles(device,
drv_data->num_profiles,
@@ -1592,7 +1711,7 @@ hidpp20drv_probe(struct ratbag_device *device)
/* add some defaults that will be overwritten by the device */
drv_data->num_profiles = 1;
drv_data->num_resolutions = 1;
drv_data->num_resolutions = 0;
drv_data->num_buttons = 8;
drv_data->num_leds = 0;

View File

@@ -106,7 +106,7 @@ struct hidpp_device {
void *userdata;
hidpp_log_handler log_handler;
enum hidpp_log_priority log_priority;
uint8_t supported_report_types;
unsigned supported_report_types;
};
#define HIDPP_REPORT_SHORT (1 << 0)

View File

@@ -1144,6 +1144,9 @@ hidpp10_onboard_profiles_read_macro(struct hidpp10_device *device,
}
if (rc == -ENOMEM) {
if ((unsigned) offset + mem_index > 0xff)
goto out_err;
offset += mem_index;
if (offset & 0x01)
offset--;
@@ -1198,8 +1201,10 @@ hidpp10_onboard_profiles_parse_macro(struct hidpp10_device *device,
hidpp_log_raw(&device->base, "*** macro starts at (0x%02x, 0x%04x) ***\n", page, offset);
rc = hidpp10_onboard_profiles_read_macro(device, page, offset, &macro);
if (rc)
if (rc) {
hidpp_log_raw(&device->base, "hidpp10: failed to read macro\n");
return rc;
}
count = rc;
@@ -2754,12 +2759,14 @@ hidpp10_get_device_info(struct hidpp10_device *dev)
return hidpp10_get_current_profile(dev, &current_profile);
}
struct hidpp10_device*
int
hidpp10_device_new(const struct hidpp_device *base,
int idx,
enum hidpp10_profile_type type,
unsigned int profile_count)
unsigned int profile_count,
struct hidpp10_device **out)
{
int rc;
struct hidpp10_device *dev;
dev = zalloc(sizeof(*dev));
@@ -2770,12 +2777,14 @@ hidpp10_device_new(const struct hidpp_device *base,
dev->profile_count = profile_count;
dev->profiles = zalloc(dev->profile_count * sizeof(struct hidpp10_profile));
if (hidpp10_get_device_info(dev) != 0) {
if ((rc = hidpp10_get_device_info(dev)) != 0) {
hidpp10_device_destroy(dev);
dev = NULL;
}
return dev;
*out = dev;
return rc;
}
int

View File

@@ -69,11 +69,12 @@ struct hidpp10_device {
unsigned int profile_count;
};
struct hidpp10_device*
int
hidpp10_device_new(const struct hidpp_device *base,
int idx,
enum hidpp10_profile_type type,
unsigned int profile_count);
unsigned int profile_count,
struct hidpp10_device **out);
int
hidpp10_device_read_profiles(struct hidpp10_device *dev);

View File

@@ -260,7 +260,7 @@ hidpp_root_get_feature(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = HIDPP_PAGE_ROOT_IDX,
.msg.address = CMD_ROOT_GET_FEATURE,
@@ -287,7 +287,7 @@ hidpp20_root_get_protocol_version(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = HIDPP_PAGE_ROOT_IDX,
.msg.address = CMD_ROOT_GET_PROTOCOL_VERSION,
@@ -321,7 +321,7 @@ hidpp20_feature_set_get_count(struct hidpp20_device *device, uint8_t reg)
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_FEATURE_SET_GET_COUNT,
@@ -343,7 +343,7 @@ hidpp20_feature_set_get_feature_id(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_FEATURE_SET_GET_FEATURE_ID,
@@ -429,7 +429,7 @@ hidpp20_batterylevel_get_battery_level(struct hidpp20_device *device,
{
uint8_t feature_index;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS,
};
@@ -566,7 +566,7 @@ int hidpp20_led_sw_control_get_led_count(struct hidpp20_device* device)
{
union hidpp20_message msg = {
.msg = {
.report_id = REPORT_ID_LONG,
.report_id = REPORT_ID_SHORT,
.address = CMD_LED_SW_CONTROL_GET_LED_COUNT,
.device_idx = device->index,
},
@@ -594,7 +594,7 @@ int hidpp20_led_sw_control_get_led_info(struct hidpp20_device* device,
{
union hidpp20_message msg = {
.msg = {
.report_id = REPORT_ID_LONG,
.report_id = REPORT_ID_SHORT,
.address = CMD_LED_SW_CONTROL_GET_LED_INFO,
.device_idx = device->index,
},
@@ -682,7 +682,7 @@ int hidpp20_led_sw_control_get_led_state(struct hidpp20_device* device,
uint8_t feature_idx;
union hidpp20_message msg = {
.msg = {
.report_id = REPORT_ID_LONG,
.report_id = REPORT_ID_SHORT,
.address = CMD_LED_SW_CONTROL_GET_LED_STATE,
.device_idx = device->index,
}
@@ -767,7 +767,7 @@ static int
hidpp20_kbd_reprogrammable_keys_get_count(struct hidpp20_device *device, uint8_t reg)
{
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_KBD_REPROGRAMMABLE_KEYS_GET_COUNT,
@@ -788,7 +788,7 @@ hidpp20_kbd_reprogrammable_keys_get_info(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_KBD_REPROGRAMMABLE_KEYS_GET_CTRL_ID_INFO,
@@ -868,6 +868,8 @@ err:
#define CMD_COLOR_LED_EFFECTS_GET_INFO 0x00
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO 0x10
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_EFFECT_INFO 0x20
#define CMD_COLOR_LED_EFFECTS_SET_ZONE_EFFECT 0x30
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_EFFECT 0xe0
int
hidpp20_color_led_effects_get_info(struct hidpp20_device *device,
@@ -893,6 +895,7 @@ hidpp20_color_led_effects_get_info(struct hidpp20_device *device,
return rc;
*info = *(struct hidpp20_color_led_info *)msg.msg.parameters;
device->led_ext_caps = info->ext_caps;
return 0;
}
@@ -905,7 +908,7 @@ hidpp20_color_led_effects_get_zone_info(struct hidpp20_device *device,
int rc;
struct hidpp20_color_led_zone_info *msg_info;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO,
@@ -1012,6 +1015,80 @@ hidpp20_color_led_effect_get_zone_effect_info(struct hidpp20_device *device,
return 0;
}
int
hidpp20_color_led_effects_set_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led led)
{
uint8_t feature_index;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.address = CMD_COLOR_LED_EFFECTS_SET_ZONE_EFFECT,
.msg.device_idx = device->index,
.msg.parameters[0] = zone_index,
.msg.parameters[12] = 1, /* write to RAM and flash */
};
int rc;
struct hidpp20_internal_led *internal_led = (struct hidpp20_internal_led*) &msg.msg.parameters[1];
hidpp20_onboard_profiles_write_led(internal_led, &led);
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_COLOR_LED_EFFECTS);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
return 0;
}
int
hidpp20_color_led_effects_get_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led *led)
{
uint8_t feature_index;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_SHORT,
.msg.address = CMD_COLOR_LED_EFFECTS_GET_ZONE_EFFECT,
.msg.device_idx = device->index,
.msg.parameters[0] = zone_index,
};
struct hidpp20_internal_led *internal_led;
int rc;
/* hidpp20_color_led_effects_get_info() must be called first to set the capabilities */
if (!(device->led_ext_caps & HIDPP20_COLOR_LED_INFO_EXT_CAP_HAS_ZONE_EFFECT))
return -ENOTSUP;
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_COLOR_LED_EFFECTS);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
if (msg.msg.parameters[0] != zone_index)
return -EPROTO;
internal_led = (struct hidpp20_internal_led*) &msg.msg.parameters[1];
hidpp20_onboard_profiles_read_led(led, *internal_led);
hidpp_log_debug(&device->base, "zone %u has effect %u\n", zone_index, led->mode);
return 0;
}
/* -------------------------------------------------------------------------- */
/* 0x8071: RGB Effects */
/* -------------------------------------------------------------------------- */
@@ -1032,7 +1109,7 @@ hidpp20_rgb_effects_get_device_info(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_RGB_EFFECTS_GET_INFO,
.msg.parameters[0] = HIDPP20_RGB_EFFECTS_INDEX_ALL,
@@ -1069,7 +1146,7 @@ hidpp20_rgb_effects_get_cluster_info(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_RGB_EFFECTS_GET_INFO,
.msg.parameters[0] = cluster_index,
@@ -1152,7 +1229,7 @@ hidpp20_rgb_effects_get_effect_info(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_RGB_EFFECTS_GET_INFO,
.msg.parameters[0] = cluster_index,
@@ -1196,7 +1273,7 @@ hidpp20_special_keys_buttons_get_count(struct hidpp20_device *device, uint8_t re
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_SPECIAL_KEYS_BUTTONS_GET_COUNT,
@@ -1216,7 +1293,7 @@ hidpp20_special_keys_buttons_get_info(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_SPECIAL_KEYS_BUTTONS_GET_INFO,
@@ -1246,7 +1323,7 @@ hidpp20_special_keys_buttons_get_reporting(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_SPECIAL_KEYS_BUTTONS_GET_REPORTING,
@@ -1387,7 +1464,7 @@ hidpp20_mousepointer_get_mousepointer_info(struct hidpp20_device *device,
{
uint8_t feature_index;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_MOUSE_POINTER_BASIC_GET_INFO,
};
@@ -1424,7 +1501,7 @@ hidpp20_adjustable_dpi_get_count(struct hidpp20_device *device, uint8_t reg)
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_ADJUSTABLE_DPI_GET_SENSOR_COUNT,
@@ -1445,7 +1522,7 @@ hidpp20_adjustable_dpi_get_dpi_list(struct hidpp20_device *device,
int rc;
unsigned i = 1, dpi_index = 0;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_ADJUSTABLE_DPI_GET_SENSOR_DPI_LIST,
@@ -1493,7 +1570,7 @@ hidpp20_adjustable_dpi_get_dpi(struct hidpp20_device *device,
{
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.sub_id = reg,
.msg.address = CMD_ADJUSTABLE_DPI_GET_SENSOR_DPI,
@@ -1576,7 +1653,7 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
uint16_t returned_parameters;
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_ADJUSTABLE_DPI_SET_SENSOR_DPI,
.msg.parameters[0] = sensor->index,
@@ -1612,6 +1689,8 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
/* -------------------------------------------------------------------------- */
#define CMD_ADJUSTABLE_REPORT_RATE_GET_REPORT_RATE_LIST 0x00
#define CMD_ADJUSTABLE_REPORT_RATE_GET_REPORT_RATE 0x10
#define CMD_ADJUSTABLE_REPORT_RATE_SET_REPORT_RATE 0x20
int hidpp20_adjustable_report_rate_get_report_rate_list(struct hidpp20_device *device,
uint8_t *bitflags_ms)
@@ -1619,10 +1698,9 @@ int hidpp20_adjustable_report_rate_get_report_rate_list(struct hidpp20_device *d
uint8_t feature_index;
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_ADJUSTABLE_REPORT_RATE_GET_REPORT_RATE_LIST,
.msg.parameters[0] = 0,
};
feature_index = hidpp_root_get_feature_idx(device,
@@ -1641,6 +1719,60 @@ int hidpp20_adjustable_report_rate_get_report_rate_list(struct hidpp20_device *d
return 0;
}
int hidpp20_adjustable_report_rate_get_report_rate(struct hidpp20_device *device,
uint8_t *rate_ms)
{
uint8_t feature_index;
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_ADJUSTABLE_REPORT_RATE_GET_REPORT_RATE,
.msg.parameters[0] = 0,
};
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_ADJUSTABLE_REPORT_RATE);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
*rate_ms = msg.msg.parameters[0];
return 0;
}
int hidpp20_adjustable_report_rate_set_report_rate(struct hidpp20_device *device,
uint8_t rate_ms)
{
uint8_t feature_index;
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_SHORT,
.msg.device_idx = device->index,
.msg.address = CMD_ADJUSTABLE_REPORT_RATE_SET_REPORT_RATE,
.msg.parameters[0] = rate_ms,
};
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_ADJUSTABLE_REPORT_RATE);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
return 0;
}
/* -------------------------------------------------------------------------- */
/* 0x8100 - Onboard Profiles */
/* -------------------------------------------------------------------------- */
@@ -2399,6 +2531,9 @@ hidpp20_onboard_profiles_write_dict(struct hidpp20_device *device,
sector_size,
data,
true);
if (rc)
hidpp_log_error(&device->base, "failed to write profile dictionary\n");
return rc;
}
@@ -2436,6 +2571,7 @@ hidpp20_buttons_to_cpu(struct hidpp20_device *device,
break;
case HIDPP20_BUTTON_SPECIAL:
button->special.special = b->special.special;
button->special.profile = b->special.profile;
break;
case HIDPP20_BUTTON_MACRO:
if (profile->macros[i]) {
@@ -2495,6 +2631,7 @@ hidpp20_buttons_from_cpu(struct hidpp20_profile *profile,
break;
case HIDPP20_BUTTON_SPECIAL:
button->special.special = b->special.special;
button->special.profile = b->special.profile;
break;
case HIDPP20_BUTTON_DISABLED:
break;
@@ -2510,7 +2647,7 @@ hidpp20_buttons_from_cpu(struct hidpp20_profile *profile,
}
}
static void
void
hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led)
{
@@ -2526,6 +2663,10 @@ hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
if (brightness == 0)
brightness = 100;
break;
case HIDPP20_LED_STARLIGHT:
led->color = internal_led.effect.starlight.color_sky;
led->extra_color = internal_led.effect.starlight.color_star;
break;
case HIDPP20_LED_BREATHING:
period = hidpp_be_u16_to_cpu(internal_led.effect.breath.period_or_speed);
brightness = internal_led.effect.breath.intensity;
@@ -2533,11 +2674,18 @@ hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
brightness = 100;
led->color = internal_led.effect.breath.color;
break;
case HIDPP20_LED_RIPPLE:
period = hidpp_be_u16_to_cpu(internal_led.effect.breath.period_or_speed);
led->color = internal_led.effect.ripple.color;
break;
case HIDPP20_LED_ON:
led->color = internal_led.effect.fixed.color;
break;
case HIDPP20_LED_OFF:
break;
default:
memcpy(led->original, &internal_led, sizeof(internal_led));
break;
}
led->period = period;
@@ -2713,7 +2861,7 @@ read_profiles:
return profiles->num_profiles;
}
static void
void
hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led)
{
@@ -2732,24 +2880,31 @@ hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led,
else
internal_led->effect.cycle.intensity = 0;
break;
case HIDPP20_LED_STARLIGHT:
internal_led->effect.starlight.color_sky = led->color;
internal_led->effect.starlight.color_star = led->extra_color;
break;
case HIDPP20_LED_BREATHING:
internal_led->effect.breath.color.red = led->color.red;
internal_led->effect.breath.color.blue = led->color.blue;
internal_led->effect.breath.color.green = led->color.green;
internal_led->effect.breath.color = led->color;
internal_led->effect.breath.period_or_speed = hidpp_cpu_to_be_u16(period);
if (brightness < 100)
internal_led->effect.breath.intensity = brightness;
else
internal_led->effect.breath.intensity = 0;
break;
case HIDPP20_LED_RIPPLE:
internal_led->effect.ripple.color = led->color;
internal_led->effect.ripple.period = hidpp_cpu_to_be_u16(period);
break;
case HIDPP20_LED_ON:
internal_led->effect.fixed.color.red = led->color.red;
internal_led->effect.fixed.color.blue = led->color.blue;
internal_led->effect.fixed.color.green = led->color.green;
internal_led->effect.fixed.color = led->color;
internal_led->effect.fixed.effect = 0;
break;
case HIDPP20_LED_OFF:
break;
default:
memcpy(internal_led, led->original, sizeof(*internal_led));
break;
}
}
@@ -2797,8 +2952,10 @@ hidpp20_onboard_profiles_write_profile(struct hidpp20_device *device,
memcpy(pdata->profile.name.txt, profile->name, sizeof(profile->name));
rc = hidpp20_onboard_profiles_write_sector(device, sector, sector_size, data, true);
if (rc < 0)
if (rc < 0) {
hidpp_log_error(&device->base, "failed to write profile\n");
return rc;
}
return 0;
}
@@ -2894,6 +3051,8 @@ hidpp20_device_new(const struct hidpp_device *base, unsigned int idx, struct hid
dev->proto_major = 1;
dev->proto_minor = 0;
dev->led_ext_caps = 0;
hidpp_get_supported_report_types(&(dev->base), reports, num_reports);
if (!(dev->base.supported_report_types & HIDPP_REPORT_SHORT) &&

View File

@@ -65,6 +65,7 @@ struct hidpp20_device {
unsigned feature_count;
struct hidpp20_feature *feature_list;
enum hidpp20_quirk quirk;
unsigned int led_ext_caps;
};
int hidpp20_request_command(struct hidpp20_device *dev, union hidpp20_message *msg);
@@ -432,6 +433,12 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
int hidpp20_adjustable_report_rate_get_report_rate_list(struct hidpp20_device *device,
uint8_t *bitflags_ms);
int hidpp20_adjustable_report_rate_get_report_rate(struct hidpp20_device *device,
uint8_t *rate_ms);
int hidpp20_adjustable_report_rate_set_report_rate(struct hidpp20_device *device,
uint8_t rate_ms);
/* -------------------------------------------------------------------------- */
/* 0x8070v4 - Color LED effects */
/* -------------------------------------------------------------------------- */
@@ -495,6 +502,18 @@ hidpp20_rgb_effects_get_effect_info(struct hidpp20_device *device,
uint8_t effect_index,
struct hidpp20_rgb_effect_info *info);
struct hidpp20_led;
int
hidpp20_color_led_effects_set_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led led);
int
hidpp20_color_led_effects_get_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led *led);
enum hidpp20_color_led_location {
HIDPP20_COLOR_LED_LOCATION_UNDEFINED = 0,
HIDPP20_COLOR_LED_LOCATION_PRIMARY,
@@ -558,14 +577,42 @@ enum hidpp20_color_led_zone_effect {
#define HIDPP_PAGE_ONBOARD_PROFILES 0x8100
/* type */
#define HIDPP20_BUTTON_HID_TYPE 0x80
#define HIDPP20_BUTTON_SPECIAL 0x90
/* standard opcodes (0x80) */
#define HIDPP20_BUTTON_HID_TYPE_NOOP 0x00
#define HIDPP20_BUTTON_HID_TYPE_MOUSE 0x01
#define HIDPP20_BUTTON_HID_TYPE_KEYBOARD 0x02
#define HIDPP20_BUTTON_HID_TYPE_CONSUMER_CONTROL 0x03
#define HIDPP20_BUTTON_SPECIAL 0x90
/* special opcodes (0x90) */
#define HIDPP20_BUTTON_SPECIAL_NOOP 0x00
#define HIDPP20_BUTTON_SPECIAL_TILT_LEFT 0x01
#define HIDPP20_BUTTON_SPECIAL_TILT_RIGHT 0x02
#define HIDPP20_BUTTON_SPECIAL_NEXT_DPI 0x03
#define HIDPP20_BUTTON_SPECIAL_PREV_DPI 0x04
#define HIDPP20_BUTTON_SPECIAL_CYCLE_DPI 0x05
#define HIDPP20_BUTTON_SPECIAL_DEFAULT_DPI 0x06
#define HIDPP20_BUTTON_SPECIAL_SHIFT_DPI 0x07
#define HIDPP20_BUTTON_SPECIAL_NEXT_PROFILE 0x08
#define HIDPP20_BUTTON_SPECIAL_PREV_PROFILE 0x09
#define HIDPP20_BUTTON_SPECIAL_CYCLE_PROFILE 0x0a
#define HIDPP20_BUTTON_SPECIAL_GSHIFT 0x0b
/* memory model >= 3 */
#define HIDPP20_BUTTON_SPECIAL_BATTERY_INDICATOR 0x0c
#define HIDPP20_BUTTON_SPECIAL_ENABLE_PROFILE 0x0d
#define HIDPP20_BUTTON_SPECIAL_PERFORMANCE_SWITCH 0x0e
#define HIDPP20_BUTTON_SPECIAL_HOST 0x0f
#define HIDPP20_BUTTON_SPECIAL_SCROLL_DOWN 0x10
#define HIDPP20_BUTTON_SPECIAL_SCROLL_UP 0x11
/* buttons */
#define HIDPP20_BUTTON_MACRO 0x00
#define HIDPP20_BUTTON_DISABLED 0xFF
/* modifiers */
#define HIDPP20_MODIFIER_KEY_CTRL 0x01
#define HIDPP20_MODIFIER_KEY_SHIFT 0x02
@@ -599,6 +646,8 @@ union hidpp20_button_binding {
struct {
uint8_t type; /* HIDPP20_BUTTON_SPECIAL */
uint8_t special;
uint8_t reserved;
uint8_t profile;
} __attribute__((packed)) special;
struct {
uint8_t type; /* HIDPP20_BUTTON_MACRO */
@@ -698,7 +747,11 @@ enum hidpp20_led_mode {
HIDPP20_LED_OFF = 0x00,
HIDPP20_LED_ON = 0x01,
HIDPP20_LED_CYCLE = 0x03,
HIDPP20_LED_COLOR_WAVE = 0x04,
HIDPP20_LED_STARLIGHT = 0x05,
HIDPP20_LED_BREATHING = 0x0a,
HIDPP20_LED_RIPPLE = 0x0b,
HIDPP20_LED_CUSTOM = 0x0c,
};
enum hidpp20_led_waveform {
@@ -723,35 +776,76 @@ struct hidpp20_internal_led {
uint16_t period_or_speed; /* period in ms, speed is device dependent */
uint8_t intensity; /* 1 - 100 percent, 0 means 100 */
} __attribute__((packed)) cycle;
struct hidpp20_led_starlight {
struct hidpp20_color color_sky;
struct hidpp20_color color_star;
} __attribute__((packed)) starlight;
struct hidpp20_led_breath {
struct hidpp20_color color;
uint16_t period_or_speed; /* period in ms, speed is device dependent */
uint8_t waveform; /* enum hidpp20_led_waveform */
uint8_t intensity; /* 1 - 100 percent, 0 means 100 */
} __attribute__((packed)) breath;
struct hidpp20_led_ripple {
struct hidpp20_color color;
uint8_t reserved;
uint16_t period;
} __attribute__((packed)) ripple;
struct hidpp20_led_custom {
uint8_t slot;
uint16_t init_frame;
uint16_t lenght;
uint16_t frame_period;
uint8_t intensity;
} __attribute__((packed)) custom;
uint8_t padding[10];
} __attribute__((packed)) effect;
};
_Static_assert(sizeof(struct hidpp20_led_fixed) == 4, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_cycle) == 8, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_starlight) == 6, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_breath) == 7, "Invalid size");
_Static_assert(sizeof(struct hidpp20_internal_led) == 11, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_ripple) == 6, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_custom) == 8, "Invalid size");
typedef uint8_t percent_t;
struct hidpp20_led {
enum hidpp20_led_mode mode;
struct hidpp20_color color;
struct hidpp20_color extra_color;
uint16_t period;
percent_t brightness;
uint8_t original[sizeof(struct hidpp20_internal_led)];
};
#define HIDPP20_MACRO_NOOP 0x01
/* macro opcodes */
/* control commands */
#define HIDPP20_MACRO_WAIT_FOR_RELEASE 0x01
#define HIDPP20_MACRO_REPEAT_WHILE_PRESSED 0x02
#define HIDPP20_MACRO_REPEAT_UNTIL_CANCELED 0x03
#define HIDPP20_MACRO_END 0xff
/* delay & jump commands */
#define HIDPP20_MACRO_NOOP 0x00 /* wait the duration of a macro step */
#define HIDPP20_MACRO_DELAY 0x40
#define HIDPP20_MACRO_JUMP 0x60
/* button & key event generation */
#define HIDPP20_MACRO_BUTTON_DOWN 0x41
#define HIDPP20_MACRO_BUTTON_UP 0x42
#define HIDPP20_MACRO_KEY_PRESS 0x43
#define HIDPP20_MACRO_KEY_RELEASE 0x44
#define HIDPP20_MACRO_JUMP 0x60
#define HIDPP20_MACRO_END 0xff
#define HIDPP20_MACRO_CONS_DOWN 0x45
#define HIDPP20_MACRO_CONS_UP 0x46
/* analog commands */
#define HIDPP20_MACRO_ROLLER 0x20
#define HIDPP20_MACRO_ACPAN 0x21
#define HIDPP20_MACRO_XY 0x61
union hidpp20_macro_data {
struct {
@@ -919,6 +1013,14 @@ hidpp20_onboard_profiles_allocate_sector(struct hidpp20_profiles *profiles)
return zalloc(profiles->sector_size);
}
void
hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led);
void
hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led);
/* -------------------------------------------------------------------------- */
/* 0x8110 - Mouse Button Spy */
/* -------------------------------------------------------------------------- */

View File

@@ -140,20 +140,21 @@ hidraw_is_receiver(int fd)
return true;
}
static struct hidpp10_device *
hidpp10_init(int fd)
static int
hidpp10_init(int fd, struct hidpp10_device **out)
{
struct hidpp_device base;
hidpp_device_init(&base, fd);
return hidpp10_device_new(&base, HIDPP_RECEIVER_IDX,
HIDPP10_PROFILE_UNKNOWN, 1);
HIDPP10_PROFILE_UNKNOWN, 1, out);
}
_EXPORT_ int
lur_receiver_new_from_hidraw(int fd, void *userdata, struct lur_receiver **out)
{
int rc;
struct lur_receiver *receiver;
if (!hidraw_is_receiver(fd))
@@ -165,8 +166,8 @@ lur_receiver_new_from_hidraw(int fd, void *userdata, struct lur_receiver **out)
receiver->userdata = userdata;
list_init(&receiver->devices);
receiver->hidppdev = hidpp10_init(fd);
if (!receiver->hidppdev)
rc = hidpp10_init(fd, &receiver->hidppdev);
if (rc)
goto error;
*out = receiver;
@@ -174,8 +175,7 @@ lur_receiver_new_from_hidraw(int fd, void *userdata, struct lur_receiver **out)
error:
free(receiver);
return -errno;
return rc;
}
_EXPORT_ int
@@ -203,7 +203,7 @@ lur_receiver_enumerate(struct lur_receiver *lur,
uint32_t serial;
bool is_new_device = true;
d = hidpp10_device_new(&base, i, HIDPP10_PROFILE_UNKNOWN, 1);
rc = hidpp10_device_new(&base, i, HIDPP10_PROFILE_UNKNOWN, 1, &d);
if (!d)
continue;

View File

@@ -56,6 +56,7 @@ enum driver {
struct data_hidpp20 {
int index;
enum hidpp20_quirk quirk;
int led_count;
};
struct data_hidpp10 {
@@ -157,6 +158,7 @@ init_data_hidpp20(struct ratbag *ratbag,
char *str;
data->hidpp20.index = -1;
data->hidpp20.led_count = -1;
num = g_key_file_get_integer(keyfile, group, "DeviceIndex", &error);
if (num != 0 || !error)
@@ -164,6 +166,13 @@ init_data_hidpp20(struct ratbag *ratbag,
if (error)
g_error_free(error);
error = NULL;
num = g_key_file_get_integer(keyfile, group, "Leds", &error);
if (!error)
data->hidpp20.led_count = num;
if (error)
g_error_free(error);
str = g_key_file_get_string(keyfile, group, "Quirk", NULL);
data->hidpp20.quirk = HIDPP20_QUIRK_NONE;
if (str) {
@@ -346,6 +355,8 @@ parse_ledtypes(char **strv, enum ratbag_led_type *types, size_t ntypes)
types[i] = RATBAG_LED_TYPE_SIDE;
else if (streq(s, "wheel"))
types[i] = RATBAG_LED_TYPE_WHEEL;
else if (streq(s, "switches"))
types[i] = RATBAG_LED_TYPE_SWITCHES;
else
return -1;
@@ -574,6 +585,14 @@ ratbag_device_data_hidpp20_get_index(const struct ratbag_device_data *data)
return data->hidpp20.index;
}
int
ratbag_device_data_hidpp20_get_led_count(const struct ratbag_device_data *data)
{
assert(data->drivertype == HIDPP20);
return data->hidpp20.led_count;
}
enum hidpp20_quirk
ratbag_device_data_hidpp20_get_quirk(const struct ratbag_device_data *data)
{

View File

@@ -80,6 +80,9 @@ ratbag_device_data_hidpp10_get_led_count(const struct ratbag_device_data *data);
int
ratbag_device_data_hidpp20_get_index(const struct ratbag_device_data *data);
int
ratbag_device_data_hidpp20_get_led_count(const struct ratbag_device_data *data);
enum hidpp20_quirk
ratbag_device_data_hidpp20_get_quirk(const struct ratbag_device_data *data);

View File

@@ -293,6 +293,7 @@ enum ratbag_led_type {
RATBAG_LED_TYPE_BATTERY,
RATBAG_LED_TYPE_DPI,
RATBAG_LED_TYPE_WHEEL,
RATBAG_LED_TYPE_SWITCHES,
};
/**

View File

@@ -295,6 +295,7 @@ struct ratbag_profile {
unsigned int hz; /**< report rate in Hz */
unsigned int rates[8]; /**< report rates available */
size_t nrates; /**< number of entries in rates */
bool rate_dirty;
unsigned int num_resolutions;
@@ -585,14 +586,14 @@ ratbag_led_set_mode_capability(struct ratbag_led *led,
}
/* list of all supported drivers */
struct ratbag_driver etekcity_driver;
struct ratbag_driver hidpp20_driver;
struct ratbag_driver hidpp10_driver;
struct ratbag_driver logitech_g300_driver;
struct ratbag_driver logitech_g600_driver;
struct ratbag_driver roccat_driver;
struct ratbag_driver gskill_driver;
struct ratbag_driver steelseries_driver;
extern struct ratbag_driver etekcity_driver;
extern struct ratbag_driver hidpp20_driver;
extern struct ratbag_driver hidpp10_driver;
extern struct ratbag_driver logitech_g300_driver;
extern struct ratbag_driver logitech_g600_driver;
extern struct ratbag_driver roccat_driver;
extern struct ratbag_driver gskill_driver;
extern struct ratbag_driver steelseries_driver;
struct ratbag_device*
ratbag_device_new(struct ratbag *ratbag, struct udev_device *udev_device,

View File

@@ -31,7 +31,7 @@
#include "libratbag-util.h"
#include "libratbag-test.h"
struct ratbag_driver test_driver;
extern struct ratbag_driver test_driver;
static inline void
ratbag_register_test_drivers(struct ratbag *ratbag)

View File

@@ -37,6 +37,8 @@
#include <stdlib.h>
#include <iconv.h>
#include <errno.h>
#include <libgen.h>
#include <sys/stat.h>
#include "libratbag-util.h"
#include "libratbag-private.h"
@@ -188,3 +190,18 @@ err:
iconv_close(converter);
return ret;
}
int mkdir_p(char *dir, mode_t mode)
{
struct stat sb;
if (!dir)
return EINVAL;
if (!stat(dir, &sb))
return 0;
mkdir_p(dirname(strdupa(dir)), mode);
return mkdir(dir, mode);
}

View File

@@ -62,6 +62,8 @@ int list_empty(const struct list *list);
pos = tmp, \
tmp = container_of(pos->member.next, tmp, member))
int mkdir_p(char *dir, mode_t mode);
static inline char*
strncpy_safe(char *dest, const char *src, size_t n)
{

View File

@@ -268,7 +268,7 @@ ratbag_sanity_check_device(struct ratbag_device *device)
}
nres = ratbag_profile_get_num_resolutions(profile);
if (nres == 0 || nres > 16) {
if (nres > 16) {
log_bug_libratbag(ratbag,
"%s: invalid number of resolutions (%d)\n",
device->name,
@@ -949,6 +949,8 @@ ratbag_device_commit(struct ratbag_device *device)
list_for_each(profile, &device->profiles, link) {
profile->dirty = false;
profile->rate_dirty = false;
list_for_each(button, &profile->buttons, link)
button->dirty = false;
@@ -1117,6 +1119,7 @@ ratbag_profile_set_report_rate(struct ratbag_profile *profile,
if (profile->hz != hz) {
profile->hz = hz;
profile->dirty = true;
profile->rate_dirty = true;
}
return RATBAG_SUCCESS;

View File

@@ -52,6 +52,28 @@
%typemap(freearg) (unsigned int *rates, size_t nrates) = (unsigned int *resolutions, size_t nres);
/* END OF custom typemap for handling ratbag_resolution_get_report_rate_list */
/* uintXX_t mapping: Python -> C */
%typemap(in) uint8_t {
$1 = (uint8_t) PyInt_AsLong($input);
}
%typemap(in) uint16_t {
$1 = (uint16_t) PyInt_AsLong($input);
}
%typemap(in) uint32_t {
$1 = (uint32_t) PyInt_AsLong($input);
}
/* uintXX_t mapping: C -> Python */
%typemap(out) uint8_t {
$result = PyInt_FromLong((long) $1);
}
%typemap(out) uint16_t {
$result = PyInt_FromLong((long) $1);
}
%typemap(out) uint32_t {
$result = PyInt_FromLong((long) $1);
}
/* Parse the header file to generate wrappers */
%include "libratbag.h"
%include "libratbag-enums.h"

View File

@@ -98,7 +98,9 @@ main(int argc, char **argv)
error(1, errno, "Failed to open path %s", path);
hidpp_device_init(&base, fd);
dev = hidpp10_device_new(&base, HIDPP_WIRED_DEVICE_IDX, HIDPP10_PROFILE_UNKNOWN, 5);
rc = hidpp10_device_new(&base, HIDPP_WIRED_DEVICE_IDX, HIDPP10_PROFILE_UNKNOWN, 5, &dev);
if (rc)
return rc;
if (argc == 2)
rc = dump_all_pages(dev);

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env python3
#
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# Copyright 2017 Red Hat, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a

View File

@@ -1,5 +1,3 @@
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# Copyright 2017-2019 Red Hat, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
@@ -137,7 +135,7 @@ class Ratbagd(object):
"""
def __init__(self):
def __init__(self, apiversion):
os.environ['LIBRATBAG_DATA_DIR'] = LIBRATBAG_DATA_DIR
self._ratbag = libratbag.ratbag_create_context(libratbag.interface, None)
self._devices = {}
@@ -251,13 +249,13 @@ class RatbagdDevice(metaclass=MetaRatbag):
@property
def model(self):
"""The unique identifier for this device model."""
bus = libratbag.ratbag_device_get_bus(self._device)
bus = libratbag.ratbag_device_get_bustype(self._device)
if not bus:
return "unknown"
vid = libratbag.ratbag_device_get_vendor_id(self._device)
pid = libratbag.ratbag_device_get_product_id(self._device)
version = libratbag.ratbag_device_get_product_version(self._device)
return "{}:{04x}:{04x}:{d}".format(bus, vid, pid, version)
return "{}:{:04x}:{:04x}:{:d}".format(bus, vid, pid, version)
@property
def name(self):

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env python3
#
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# This file is part of libratbag.
#
# Copyright 2017 Red Hat, Inc.

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env python3
#
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# Copyright 2016 Red Hat, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
@@ -195,14 +193,18 @@ def print_profile(d, p, level):
" (active)" if p.is_active else ""))
if p.enabled:
print(" " * level + "Name: {}".format(p.name or 'n/a'))
print(" " * level + "Report Rate: {}Hz".format(p.report_rate))
print(" " * level + "Resolutions:")
for r in p.resolutions:
print_resolution(d, p, r, level + 2)
for b in p.buttons:
print_button(d, p, b, level)
for l in p.leds:
print_led(d, p, l, level)
if p.report_rate:
print(" " * level + "Report Rate: {}Hz".format(p.report_rate))
if p.resolutions:
print(" " * level + "Resolutions:")
for r in p.resolutions:
print_resolution(d, p, r, level + 2)
if p.buttons:
for b in p.buttons:
print_button(d, p, b, level)
if p.leds:
for l in p.leds:
print_led(d, p, l, level)
def print_device(d, level):

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env python3
#
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# This file is part of libratbag.
#
# Copyright 2017 Red Hat, Inc.

View File

@@ -250,11 +250,13 @@ class Ratbagd(_RatbagdDBus):
def __init__(self, api_version):
super().__init__("Manager", None)
result = self._get_dbus_property("Devices") or []
self._devices = [RatbagdDevice(objpath) for objpath in result]
self._proxy.connect("notify::g-name-owner", self._on_name_owner_changed)
result = self._get_dbus_property("Devices")
if result is None and not self._proxy.get_cached_property_names():
raise RatbagdUnavailable("Make sure it is running and your user is in the required groups.")
if self.api_version != api_version:
raise RatbagdIncompatible(self.api_version or -1, api_version)
self._devices = [RatbagdDevice(objpath) for objpath in result or []]
self._proxy.connect("notify::g-name-owner", self._on_name_owner_changed)
def _on_name_owner_changed(self, *kwargs):
self.emit("daemon-disappeared")

View File

@@ -74,6 +74,9 @@ led_type_to_str(enum ratbag_led_type type)
case RATBAG_LED_TYPE_WHEEL:
str = "wheel";
break;
case RATBAG_LED_TYPE_SWITCHES:
str = "switches";
break;
default:
assert(!"Invalid LED type");
break;

View File

@@ -88,4 +88,4 @@ str_to_special_action(const char *str);
struct ratbag_device *
ratbag_cmd_open_device(struct ratbag *ratbag, const char *path);
const struct ratbag_interface interface;
extern const struct ratbag_interface interface;

View File

@@ -1,5 +1,3 @@
# vim: set expandtab shiftwidth=4 tabstop=4:
#
# This file is part of libratbag.
#
# Copyright 2017 Red Hat, Inc.