mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42787ee422 | ||
|
|
611dd9be0d | ||
|
|
fd20f9e642 | ||
|
|
9be5576967 | ||
|
|
9fe511fcc5 | ||
|
|
f0b69aab19 | ||
|
|
7610b80ced | ||
|
|
f0a05bb522 | ||
|
|
2669cc28b2 | ||
|
|
302702d94a | ||
|
|
e1136c4d30 | ||
|
|
0012853a1d | ||
|
|
afb85f868c | ||
|
|
b76fcdadde | ||
|
|
ba7c092ee2 | ||
|
|
3483bd8c14 | ||
|
|
0fb0eb3d42 | ||
|
|
5fb1f4429d | ||
|
|
5f5e294598 | ||
|
|
b4218737cd | ||
|
|
3875bb70fd | ||
|
|
e9d67b7235 | ||
|
|
8a476a8724 | ||
|
|
d67cbec5f8 | ||
|
|
f82c6f72b6 | ||
|
|
af30fc28cd | ||
|
|
3fb8a51456 | ||
|
|
ceaa3c3ad5 | ||
|
|
551b918ba8 | ||
|
|
3105428ba1 | ||
|
|
b3f2406180 | ||
|
|
902160f430 | ||
|
|
fd6d0b6198 | ||
|
|
5ed98fdb22 | ||
|
|
e0e73c2971 | ||
|
|
0d3b4f1b64 | ||
|
|
20b6e3deeb | ||
|
|
ffcdee912d |
@@ -1,5 +1,10 @@
|
||||
# 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
|
||||
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
|
||||
default_settings: &default_settings
|
||||
working_directory: ~/libratbag
|
||||
environment:
|
||||
@@ -52,10 +57,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 ]
|
||||
@@ -78,11 +80,13 @@ fedora_prep_cache: &fedora_prep_cache
|
||||
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
|
||||
command: dnf install -y --downloadonly git ${FEDORA_DEP_BUILD} ${FEDORA_DEP_TEST} ${FEDORA_DEP_DOC}
|
||||
- persist_to_workspace:
|
||||
root: /var/cache/
|
||||
paths:
|
||||
- dnf/*
|
||||
environment:
|
||||
*build_dependencies
|
||||
|
||||
fedora_fetch_cache: &fedora_fetch_cache
|
||||
attach_workspace:
|
||||
@@ -93,8 +97,7 @@ fedora_install: &fedora_install
|
||||
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
|
||||
@@ -111,7 +114,8 @@ fedora_settings: &fedora_settings
|
||||
- *build_buildtype_plain
|
||||
- *build_buildtype_release
|
||||
- *export_logs
|
||||
|
||||
environment:
|
||||
*build_dependencies
|
||||
|
||||
ubuntu_settings: &ubuntu_settings
|
||||
<<: *default_settings
|
||||
@@ -124,7 +128,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 +138,8 @@ ubuntu_settings: &ubuntu_settings
|
||||
- *build_buildtype_plain
|
||||
- *build_buildtype_release
|
||||
- *export_logs
|
||||
environment:
|
||||
*build_dependencies
|
||||
|
||||
doc_build: &doc_build
|
||||
<<: *default_settings
|
||||
@@ -142,7 +148,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 +158,8 @@ doc_build: &doc_build
|
||||
root: build
|
||||
paths:
|
||||
- doc/html/*
|
||||
environment:
|
||||
*build_dependencies
|
||||
|
||||
docs_deploy: &docs_deploy
|
||||
<<: *default_settings
|
||||
|
||||
20
.editorconfig
Normal file
20
.editorconfig
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -175,9 +173,8 @@ def check_section_hidpp20(section):
|
||||
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
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim: set expandtab shiftwidth=4 tabstop=4:
|
||||
#
|
||||
# Copyright © 2018 Red Hat, Inc.
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
8
data/devices/logitech-g-powerplay.device
Normal file
8
data/devices/logitech-g-powerplay.device
Normal file
@@ -0,0 +1,8 @@
|
||||
[Device]
|
||||
Name=Logitech G Powerplay
|
||||
DeviceMatch=usb:046d:405f
|
||||
LedTypes=logo
|
||||
Driver=hidpp20
|
||||
|
||||
[Driver/hidpp20]
|
||||
DeviceIndex=7
|
||||
5
data/devices/logitech-g513.device
Normal file
5
data/devices/logitech-g513.device
Normal file
@@ -0,0 +1,5 @@
|
||||
[Device]
|
||||
Name=Logitech G513
|
||||
DeviceMatch=usb:046d:c33c
|
||||
LedTypes=switches
|
||||
Driver=hidpp20
|
||||
5
data/devices/logitech-g815.device
Normal file
5
data/devices/logitech-g815.device
Normal file
@@ -0,0 +1,5 @@
|
||||
[Device]
|
||||
Name=Logitech G815
|
||||
DeviceMatch=usb:046d:c33f
|
||||
LedTypes=logo;switches
|
||||
Driver=hidpp20
|
||||
8
data/devices/logitech-g910.device
Normal file
8
data/devices/logitech-g910.device
Normal file
@@ -0,0 +1,8 @@
|
||||
[Device]
|
||||
Name=Logitech G910
|
||||
DeviceMatch=usb:046d:c335
|
||||
LedTypes=logo;switches
|
||||
Driver=hidpp20
|
||||
|
||||
[Driver/hidpp20]
|
||||
DeviceIndex=ff
|
||||
8
data/devices/logitech-g915.device
Normal file
8
data/devices/logitech-g915.device
Normal file
@@ -0,0 +1,8 @@
|
||||
[Device]
|
||||
Name=Logitech G915
|
||||
DeviceMatch=usb:046d:c33e
|
||||
LedTypes=logo;switches
|
||||
Driver=hidpp20
|
||||
|
||||
[Driver/hidpp20]
|
||||
DeviceIndex=1
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim: set expandtab shiftwidth=4 tabstop=4:
|
||||
#
|
||||
# Copyright © 2018 Red Hat, Inc.
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
project('libratbag', 'c',
|
||||
version : '0.12',
|
||||
version : '0.13',
|
||||
license : 'MIT/Expat',
|
||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||
meson_version : '>= 0.40.0')
|
||||
@@ -291,6 +291,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 +311,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 +326,9 @@ 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-g9x-Call-of-Duty-MW3-Edition.device',
|
||||
'data/devices/logitech-g9x-Original.device',
|
||||
'data/devices/logitech-Marathon-M705.device',
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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\n");
|
||||
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\n");
|
||||
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\n");
|
||||
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\n");
|
||||
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\n");
|
||||
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);
|
||||
@@ -1592,7 +1706,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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
178
src/hidpp20.c
178
src/hidpp20.c
@@ -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;
|
||||
}
|
||||
@@ -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_SHORT,
|
||||
.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 */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -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)
|
||||
@@ -1641,6 +1720,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 +2532,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 +2572,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 +2632,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 +2648,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 +2664,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 +2675,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 +2862,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 +2881,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 +2953,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 +3052,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) &&
|
||||
|
||||
@@ -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,
|
||||
@@ -599,6 +618,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 +719,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,27 +748,48 @@ 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
|
||||
@@ -919,6 +965,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 */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@@ -346,6 +346,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;
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ enum ratbag_led_type {
|
||||
RATBAG_LED_TYPE_BATTERY,
|
||||
RATBAG_LED_TYPE_DPI,
|
||||
RATBAG_LED_TYPE_WHEEL,
|
||||
RATBAG_LED_TYPE_SWITCHES,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# vim: set expandtab shiftwidth=4 tabstop=4:
|
||||
#
|
||||
# This file is part of libratbag.
|
||||
#
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
|
||||
Reference in New Issue
Block a user