1
0
forked from drath/libratbag

Compare commits

...

47 Commits
v0.4 ... v0.5

Author SHA1 Message Date
Benjamin Tissoires
821e2798b9 configure.ac: libratbag 0.5
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-09-16 11:45:31 +02:00
Benjamin Tissoires
3a0dc8f8a5 hwdb: add svg file for the new G502
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-08-31 11:38:00 +02:00
bentiss
f75152f074 Merge pull request #95 from cvuchener/g502rgb
Added G502 support and small fix
2016-08-31 11:37:08 +02:00
Clément Vuchener
f72c96914b hidpp20: fix reading has_dpi_shift
The comparison was always false because of missing bit shift.

Signed-off-by: Clément Vuchener <clement.vuchener@gmail.com>
2016-08-30 16:50:18 +02:00
Clément Vuchener
23036eec08 hwdb: Add new version for the G502
The new version is called "G502 Proteus Spectrum", so the older version comment is changed to "G502 Proteus Core" (its complete name) to avoid confusion.

Signed-off-by: Clément Vuchener <clement.vuchener@gmail.com>
2016-08-30 16:42:41 +02:00
bentiss
045a46aa9d Merge pull request #94 from whot/master
hidpp10: fix fetching of serial number
2016-07-27 11:00:44 +02:00
Peter Hutterer
01876023bb hidpp10: fix fetching of serial number
Was off by one, the message content only includes one byte of extra information
before the serial number. And add a BE 32-bit helper while we're at it.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-07-14 10:17:49 +10:00
Peter Hutterer
e2ae29efdc configure.ac: place udev files into $prefix/udev
$libdir is /usr/lib64 on some distros

Fixes #93

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-07-01 20:19:29 +10:00
Peter Hutterer
f67389c017 lur: fix the index parsing for disconnect
argv[3] is the /dev/hidraw path

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-06-23 16:13:57 +10:00
Peter Hutterer
20a57b76a8 Merge pull request #91 from bentiss/g602-fixes
G602 fixes
2016-05-18 15:53:59 +10:00
Benjamin Tissoires
d54d77c395 hidpp20drv: ignore errors of PAGE_ADJUSTABLE_DPI
The G602 seems to fail here, but it is safe to continue.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-17 17:19:55 +02:00
Benjamin Tissoires
a8897ca8ca tools: hidpp20-dump: prevent segfault when called on non HID++ device
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-17 17:19:55 +02:00
bentiss
4e62a3bdd9 Merge pull request #90 from ntzrmtthihu777/master
Added hwdb entry for G602 (046d:c537)
2016-05-15 09:15:21 +02:00
Marty Plummer
d8a60eca94 Added hwdb entry for G602 (046d:c537)
Signed-off-by: Marty Plummer <ntzrmtthihu777@gmail.com>
2016-05-14 15:09:17 -05:00
Benjamin Tissoires
9aa2120c7d hidpp20: prevent segfault if hidpp20_adjustable_dpi_get_dpi() fails
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-14 09:43:35 +02:00
Peter Hutterer
f7e3f51b54 Merge pull request #89 from bentiss/g900
G900
2016-05-12 12:39:37 +10:00
Benjamin Tissoires
aef7b3e9bb hidpp20drv: add support for the G900 over wireless
We need the same setting that we have on the hidpp10 side.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-11 14:01:15 +02:00
Benjamin Tissoires
21d0219809 hidpp20: add new special action in G900
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-11 14:01:15 +02:00
Peter Hutterer
3cf59af3e9 Merge pull request #85 from bentiss/g900
G900
2016-05-11 09:07:34 +10:00
Benjamin Tissoires
28438e638b hidpp20-drv: actually retrieve the current resolution value
The onboard profile do not store the current value but the default.
To retrieve the current value, we need to access the switchable resolution
feature.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-10 11:35:17 +02:00
Benjamin Tissoires
c1bf3be48e hidpp20: read/write the whole dictionary, not just the first 16 bytes
The G900 advertises 5 profiles, which do not fit in only 16 bytes.
We need to read at least 32 bytes, so be it.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-10 11:13:34 +02:00
Benjamin Tissoires
27293a22df hidpp20: enable G900 profile type
The profile is retro-compatible with the rest, so we can access it
in the same way.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-09 20:09:24 +02:00
Benjamin Tissoires
fc07672983 hidpp20: prevent invalid ROM access
The device can report how much rom it has through profile_count_oob.
Make sure we have something in ROM before accessing it.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-09 20:08:18 +02:00
Benjamin Tissoires
c14a0ca2a1 hidpp20-drv: prevent an empty profile to try to read a null macro
If the macro has not been retrieved, it's more likely that the button
is not bound to anything.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-09 19:52:56 +02:00
Benjamin Tissoires
64037febdc hidpp20: fix return path for hidpp20_onboard_profiles_read
A negative error means a communication error, while a positive one means
a HID++ one. Make sure we abort early enough.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-05-09 19:51:46 +02:00
bentiss
fd10ebbc87 Merge pull request #83 from whot/ignore-keyboard-devices
Ignore devices that don't have ID_INPUT_MOUSE set
2016-05-09 10:37:11 +02:00
Peter Hutterer
91eefb9a3f Ignore devices that don't have ID_INPUT_MOUSE set
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-05-05 12:57:11 +10:00
Benjamin Tissoires
1da0180e0f hidraw: do not return success if match failed
rc is set to 0 by ratbag_open_hidraw_node(), and if matched failed, we
close the hidraw node and end the loop.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
2016-04-29 12:10:41 +02:00
bentiss
22abddc9d4 Merge pull request #82 from whot/wip/logitech-auto-detect
Wip/logitech auto detect
2016-04-29 12:04:59 +02:00
Peter Hutterer
e912f56c26 driver-hidpp20: don't log an error if we can't init a hidpp20 device
Once we start probing devices for multiple drivers we shouldn't just print
error messages for every failed driver. In the hidpp20 case an error would be
printed for any hidpp10 logitech device.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-29 10:14:11 +10:00
Peter Hutterer
a715679f1f Add a fallback for Logitech's HID++ devices
If a device is not specifically assigned a driver, try hidpp20 and then
hidpp10 hoping that one of them will work.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-29 10:02:42 +10:00
Peter Hutterer
55673442f1 Split the driver search + testing into a helper function
Prep work for being able to probe multiple drivers on a device. The function
that tests the actual driver simply takes a const char * with the driver name,
so in the future we can loop through multiple driver names easily.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-29 10:01:24 +10:00
Peter Hutterer
b6294d4f93 Add a new header for PID/VIDs that we need to care about
Beats having the same #define in multiple places

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-29 09:56:22 +10:00
Peter Hutterer
40112e6061 driver-hidpp20: re-use the destroy function for cleanup during init
No need for two separate cleanup blocks, they're doing the same thing anyway.
Just make the function more robust to uninitalized fields and we're good to
go.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-29 09:55:58 +10:00
Peter Hutterer
0785bf138d hidpp20: fail for hidpp10 devices
hidpp10 devices have their own driver, let's not initialize them here and just
fail. If a hidpp10 device is assigned the hidpp20 driver this is a bug.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-29 09:50:20 +10:00
Peter Hutterer
e18e25d685 hwdb: Add Logitech Wireless Touchpad
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-04-21 14:13:46 +10:00
Peter Hutterer
85fdea19c2 Link to the github-pages generated documentation
To update the documentation, do the following:

  	# delete current documentation
	pushd doc/html
	rm -rf $PWD/*
	# clone into current directory, checkout gh-pages
	git clone git@github.com:libratbag/libratbag .
	git checkout -b gh-pages
	# delete master branch so we don't accidentally push that one
	git branch -d master
	# return to main, generate docs
	popd
	make
	# commit updated docs, push
	pushd doc/html
	git commit -asm "Updated documentation"
	git push origin gh-pages
	popd

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-03-17 15:21:06 +10:00
bentiss
792b6c28df Merge pull request #79 from whot/master
Fix a couple of error messages
2016-03-16 10:17:06 +01:00
Peter Hutterer
5c68164d48 etekcity/roccat: fix error message when we can't talk to the mouse
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-03-16 10:00:09 +10:00
Peter Hutterer
b1d99a744b Standardize the error on device open failures
No reason for the drivers to have their own printf each, just return the
negative errno and let the common code print it.

This now also means that we only return -ENODEV on something that's not really
an error, for anything else we print the strerror.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-03-16 10:00:09 +10:00
Peter Hutterer
9f544cbe1c Revert "Fix error message on ENODEV"
We now get an error message for all devices that have duplicate event nodes
because we use -ENODEV for 'device not found', 'device is a duplicates' and
'device doesn't have the hidraw report'.

The original commit was triggered by a misunderstanding of the error message,
will be fixed in a follow-up.

This reverts commit 855a6bd831.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-03-16 10:00:09 +10:00
bentiss
ad06d29140 Merge pull request #77 from whot/master
configure.ac: udev basedir should be relative to prefix
2016-03-15 08:34:54 +01:00
Peter Hutterer
c12cb66824 configure.ac: udev basedir should be relative to prefix
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-03-15 09:48:52 +10:00
Peter Hutterer
c476cd0654 Merge pull request #76 from r3pek/master
Fix supported resolutions from G700s
2016-03-15 07:38:56 +10:00
Carlos Silva
98315343b0 Fix supported resolutions from G700s
I was under the impression that G700 and G700s had the same sensor.
Comparing the specs on the Logitech website, i found myself wrong.
2016-03-14 20:56:00 +00:00
bentiss
eb6787181d Merge pull request #75 from r3pek/master
Add Logitech G700s
2016-03-14 20:48:26 +01:00
Carlos Silva
f7d9ca63e2 Add Logitech G700s 2016-03-14 19:14:16 +00:00
18 changed files with 297 additions and 129 deletions

View File

@@ -7,6 +7,13 @@ libratbag is a configuration library for gaming mice. It provides a generic
way to access the various features exposed by these mice and abstracts away
hardware-specific and kernel-specific quirks.
Documentation
-------------
API documentation is available here:
http://libratbag.github.io/libratbag/
Architecture
------------

View File

@@ -1,7 +1,7 @@
AC_PREREQ([2.64])
m4_define([libratbag_major_version], [0])
m4_define([libratbag_minor_version], [4])
m4_define([libratbag_minor_version], [5])
m4_define([libratbag_micro_version], [0])
m4_define([libratbag_version],
[libratbag_major_version.libratbag_minor_version.libratbag_micro_version])
@@ -30,8 +30,8 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
# b) If interfaces have been changed or added, but binary compatibility has
# been preserved, change to C+1:0:A+1
# c) If the interface is the same as the previous version, change to C:R+1:A
LIBRATBAG_LT_VERSION=3:0:0
LIBLUR_LT_VERSION=3:0:0
LIBRATBAG_LT_VERSION=3:1:0
LIBLUR_LT_VERSION=3:1:0
AC_SUBST(LIBRATBAG_LT_VERSION)
AC_SUBST(LIBLUR_LT_VERSION)
@@ -62,7 +62,7 @@ AC_ARG_WITH(udev-base-dir, AS_HELP_STRING([--with-udev-base-dir=DIR], [where ude
if test -n "$with_udev_base_dir" ; then
UDEV_BASE_DIR="$with_udev_base_dir"
else
UDEV_BASE_DIR="/usr/lib/udev"
UDEV_BASE_DIR="$prefix/lib/udev"
fi
AC_SUBST(UDEV_BASE_DIR)

View File

@@ -108,11 +108,16 @@ mouse:usb:v046dpc24e:name:*:
RATBAG_HIDPP10_DPI=0:8200@50
RATBAG_HIDPP10_PROFILE=G500
# G502 over USB
# G502 Proteus Core over USB
mouse:usb:v046dpc07d:name:*:
RATBAG_DRIVER=hidpp20
RATBAG_SVG=logitech-g502.svg
# G502 Proteus Spectrum over USB
mouse:usb:v046dpc332:name:*:
RATBAG_DRIVER=hidpp20
RATBAG_SVG=logitech-g502.svg
# G700 over USB
mouse:usb:v046dpc06b:name:*:
RATBAG_DRIVER=hidpp10
@@ -127,6 +132,21 @@ mouse:usb:v046dpc531:name:*:
RATBAG_HIDPP10_PROFILE=G700
RATBAG_HIDPP10_INDEX=1
# G700s over USB
mouse:usb:v046dpc07c:name:*:
RATBAG_DRIVER=hidpp10
RATBAG_SVG=logitech-g700.svg
RATBAG_HIDPP10_DPI=0:8200@50
RATBAG_HIDPP10_PROFILE=G700
# G700s over wireless USB
mouse:usb:v046dpc531:name:*:
RATBAG_DRIVER=hidpp10
RATBAG_SVG=logitech-g700.svg
RATBAG_HIDPP10_DPI=0:8200@50
RATBAG_HIDPP10_PROFILE=G700
RATBAG_HIDPP10_INDEX=1
# MX Master over unifying
mouse:usb:v046dp4041:name:*:
# MX Master over bluetooth
@@ -146,6 +166,20 @@ mouse:usb:v046dp400a:name:*:
mouse:usb:v046dpc080:name:*:
RATBAG_DRIVER=hidpp20
# Wireless Touchpad (Unifying)
mouse:usb:v046dp4011:name:*:
RATBAG_DRIVER=hidpp20
# G602 over wireless USB
mouse:usb:v046dpc537:name:*:
RATBAG_HIDPP20_INDEX=1
# G900 over wireless USB
mouse:usb:v046dpc539:name:*:
RATBAG_DRIVER=hidpp20
RATBAG_HIDPP20_INDEX=1
##########################################
# Roccat
##########################################

View File

@@ -19,7 +19,8 @@ libratbag_la_SOURCES = \
libratbag-hidraw.h \
libratbag-private.h \
libratbag-test.c \
libratbag-test.h
libratbag-test.h \
usb-ids.h
libratbag_la_LIBADD = \
libhidpp.la \
@@ -66,7 +67,8 @@ libhidpp_la_SOURCES = \
hidpp10.h \
hidpp10.c \
hidpp20.h \
hidpp20.c
hidpp20.c \
usb-ids.h
libhidpp_la_LDFLAGS = -lm
libutil_la_SOURCES = \
libratbag-util.c \

View File

@@ -636,13 +636,8 @@ etekcity_probe(struct ratbag_device *device)
int active_idx;
rc = ratbag_open_hidraw(device);
if (rc) {
log_error(device->ratbag,
"Can't open corresponding hidraw node: '%s' (%d)\n",
strerror(-rc),
rc);
return -ENODEV;
}
if (rc)
return rc;
if (!ratbag_hidraw_has_report(device, ETEKCITY_REPORT_ID_KEY_MAPPING)) {
ratbag_close_hidraw(device);
@@ -670,8 +665,8 @@ etekcity_probe(struct ratbag_device *device)
if (active_idx < 0) {
log_error(device->ratbag,
"Can't talk to the mouse: '%s' (%d)\n",
strerror(-rc),
rc);
strerror(-active_idx),
active_idx);
rc = -ENODEV;
goto err;
}

View File

@@ -35,8 +35,6 @@
#include "config.h"
#define USB_VENDOR_ID_LOGITECH 0x046d
#include <linux/types.h>
#include <errno.h>
#include <stdbool.h>
@@ -45,6 +43,7 @@
#include <unistd.h>
#include "hidpp10.h"
#include "usb-ids.h"
#include "libratbag-private.h"
#include "libratbag-hidraw.h"
@@ -504,16 +503,8 @@ hidpp10drv_probe(struct ratbag_device *device)
int nread = 0;
rc = ratbag_find_hidraw(device, hidpp10drv_test_hidraw);
if (rc == -ENODEV) {
return rc;
} else if (rc) {
log_error(device->ratbag,
"Can't open corresponding hidraw node: '%s' (%d)\n",
strerror(-rc),
rc);
rc = -ENODEV;
if (rc)
goto err;
}
drv_data = zalloc(sizeof(*drv_data));
hidpp_device_init(&base, device->hidraw.fd);

View File

@@ -117,7 +117,7 @@ hidpp20drv_read_macro_key_8100(struct ratbag_device *device, union hidpp20_macro
return ratbag_hidraw_get_keycode_from_keyboard_usage(device, macro->key.key);
}
static void
static int
hidpp20drv_read_macro_8100(struct ratbag_button *button,
struct hidpp20_profile *profile,
union hidpp20_button_binding *binding)
@@ -130,6 +130,9 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
macro = profile->macros[binding->macro.page];
if (!macro)
return -EINVAL;
i = 0;
m = ratbag_button_macro_new("macro");
@@ -175,6 +178,8 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
ratbag_button_copy_macro(button, m);
ratbag_button_macro_unref(m);
return 0;
}
static void
@@ -183,6 +188,7 @@ hidpp20drv_read_button_8100(struct ratbag_button *button)
struct ratbag_device *device = button->profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp20_profile *profile;
int rc;
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
return;
@@ -213,7 +219,9 @@ hidpp20drv_read_button_8100(struct ratbag_button *button)
button->action.action.special = hidpp20_onboard_profiles_get_special(profile->buttons[button->index].special.special);
break;
case HIDPP20_BUTTON_MACRO:
hidpp20drv_read_macro_8100(button, profile, &profile->buttons[button->index]);
rc = hidpp20drv_read_macro_8100(button, profile, &profile->buttons[button->index]);
if (rc)
button->action.type = RATBAG_BUTTON_ACTION_TYPE_NONE;
break;
default:
button->action.type = RATBAG_BUTTON_ACTION_TYPE_UNKNOWN;
@@ -584,7 +592,7 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index)
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag_resolution *res;
struct hidpp20_profile *p;
unsigned i, dpi;
unsigned i, dpi = 0;
hidpp20drv_read_onboard_profile(device, profile->index);
@@ -592,6 +600,10 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index)
if ((int)index == hidpp20drv_current_profile(device))
profile->is_active = true;
/* retrieve the resolution through 220X as the profile doesn't has it */
if (profile->is_active)
hidpp20drv_read_resolution_dpi(profile);
dpi = ratbag_resolution_get_dpi(profile->resolution.modes);
p = &drv_data->profiles->profiles[index];
@@ -656,13 +668,13 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
}
case HIDPP_PAGE_ADJUSTABLE_DPI: {
log_debug(ratbag, "device has adjustable dpi\n");
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
drv_data->capabilities |= HIDPP_CAP_SWITCHABLE_RESOLUTION_2201;
/* we read the profile once to get the correct number of
* supported resolutions. */
rc = hidpp20drv_read_resolution_dpi_2201(device);
if (rc < 0)
return rc;
return 0; /* this is not a hard failure */
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
drv_data->capabilities |= HIDPP_CAP_SWITCHABLE_RESOLUTION_2201;
break;
}
case HIDPP_PAGE_SPECIAL_KEYS_BUTTONS: {
@@ -773,6 +785,26 @@ hidpp20_log(void *userdata, enum hidpp_log_priority priority, const char *format
log_msg_va(device->ratbag, priority, format, args);
}
static void
hidpp20drv_remove(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp20_device *dev = drv_data->dev;
if (!device)
return;
ratbag_close_hidraw(device);
if (drv_data->profiles)
hidpp20_onboard_profiles_destroy(dev, drv_data->profiles);
free(drv_data->controls);
free(drv_data->sensors);
if (drv_data->dev)
hidpp20_device_destroy(drv_data->dev);
free(drv_data);
}
static int
hidpp20drv_probe(struct ratbag_device *device)
{
@@ -780,28 +812,41 @@ hidpp20drv_probe(struct ratbag_device *device)
struct hidpp20drv_data *drv_data;
struct hidpp_device base;
struct hidpp20_device *dev;
const char *prop;
int device_idx = HIDPP_RECEIVER_IDX;
int nread = 0;
rc = ratbag_find_hidraw(device, hidpp20drv_test_hidraw);
if (rc == -ENODEV) {
if (rc)
return rc;
} else if (rc) {
log_error(device->ratbag,
"Can't open corresponding hidraw node: '%s' (%d)\n",
strerror(-rc),
rc);
return -ENODEV;
}
drv_data = zalloc(sizeof(*drv_data));
ratbag_set_drv_data(device, drv_data);
hidpp_device_init(&base, device->hidraw.fd);
hidpp_device_set_log_handler(&base, hidpp20_log, HIDPP_LOG_PRIORITY_RAW, device);
dev = hidpp20_device_new(&base, HIDPP_RECEIVER_IDX);
prop = ratbag_device_get_udev_property(device, "RATBAG_HIDPP20_INDEX");
if (prop) {
sscanf(prop, "%d%n", &device_idx, &nread);
if (!nread || (prop[nread]) != '\0' || device_idx < 0) {
log_error(device->ratbag,
"Error parsing RATBAG_HIDPP20_INDEX: '%s' for %s\n",
prop,
device->name);
device_idx = HIDPP_RECEIVER_IDX;
}
}
/* In the general case, we can treat all devices as wired devices
* here. If we talk to the correct hidraw device the kernel adjusts
* the device index for us, so even for unifying receiver devices
* we can just use 0xff as device index.
*
* If there is a special need like for G900, we can pass a
* udev prop RATBAG_HIDPP20_INDEX.
*/
dev = hidpp20_device_new(&base, device_idx);
if (!dev) {
log_error(device->ratbag,
"Failed to get HID++2.0 device for %s\n",
device->name);
rc = -ENODEV;
goto err;
}
@@ -815,11 +860,9 @@ hidpp20drv_probe(struct ratbag_device *device)
drv_data->num_resolutions = 1;
drv_data->num_buttons = 8;
if (dev->proto_major >= 2) {
rc = hidpp20drv_20_probe(device);
if (rc)
goto err;
}
rc = hidpp20drv_20_probe(device);
if (rc)
goto err;
ratbag_device_init_profiles(device,
drv_data->num_profiles,
@@ -828,27 +871,10 @@ hidpp20drv_probe(struct ratbag_device *device)
return rc;
err:
free(drv_data);
ratbag_set_drv_data(device, NULL);
hidpp20drv_remove(device);
return rc;
}
static void
hidpp20drv_remove(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct hidpp20_device *dev = drv_data->dev;
ratbag_close_hidraw(device);
if (drv_data->profiles)
hidpp20_onboard_profiles_destroy(dev, drv_data->profiles);
free(drv_data->controls);
free(drv_data->sensors);
hidpp20_device_destroy(drv_data->dev);
free(drv_data);
}
struct ratbag_driver hidpp20_driver = {
.name = "Logitech HID++2.0",
.id = "hidpp20",

View File

@@ -780,13 +780,8 @@ roccat_probe(struct ratbag_device *device)
int active_idx;
rc = ratbag_open_hidraw(device);
if (rc) {
log_error(device->ratbag,
"Can't open corresponding hidraw node: '%s' (%d)\n",
strerror(-rc),
rc);
return -ENODEV;
}
if (rc)
return rc;
if (!ratbag_hidraw_has_report(device, ROCCAT_REPORT_ID_KEY_MAPPING)) {
ratbag_close_hidraw(device);
@@ -808,8 +803,8 @@ roccat_probe(struct ratbag_device *device)
if (active_idx < 0) {
log_error(device->ratbag,
"Can't talk to the mouse: '%s' (%d)\n",
strerror(-rc),
rc);
strerror(-active_idx),
active_idx);
rc = -ENODEV;
goto err;
}

View File

@@ -200,4 +200,10 @@ hidpp_cpu_to_le_u16(uint16_t data)
return result;
}
static inline uint32_t
hidpp_get_unaligned_be_u32(uint8_t *buf)
{
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
#endif /* HIDPP_GENERIC_H */

View File

@@ -2555,8 +2555,7 @@ hidpp10_get_extended_pairing_information(struct hidpp10_device *dev,
if (res)
return -1;
*serial = hidpp_get_unaligned_be_u16(&info.msg.string[2]) << 16;
*serial |= hidpp_get_unaligned_be_u16(&info.msg.string[4]);
*serial = hidpp_get_unaligned_be_u32(&info.msg.string[1]);
return 0;
}

View File

@@ -863,8 +863,9 @@ int hidpp20_adjustable_dpi_get_sensors(struct hidpp20_device *device,
*sensors_list = s_list;
return num_sensors;
err:
num_sensors = 0;
free(s_list);
return rc;
return rc > 0 ? -EPROTO : rc;
}
int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
@@ -929,6 +930,7 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
#define HIDPP20_ONBOARD_PROFILES_MEMORY_TYPE_G402 0x01
#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G402 0x01
#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303 0x02
#define HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G900 0x03
#define HIDPP20_ONBOARD_PROFILES_MACRO_TYPE_G402 0x01
struct hidpp20_onboard_profiles_info {
@@ -1242,7 +1244,8 @@ hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
}
if ((info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G402) &&
(info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303)) {
(info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G303) &&
(info->profile_format_id != HIDPP20_ONBOARD_PROFILES_PROFILE_TYPE_G900)) {
hidpp_log_error(&device->base,
"Profile layout not supported: 0x%02x.\n",
info->profile_format_id);
@@ -1283,10 +1286,11 @@ hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
info->profile_count * sizeof(struct hidpp20_profile));
profiles->num_profiles = info->profile_count;
profiles->num_rom_profiles = info->profile_count_oob;
profiles->num_buttons = msg.msg.parameters[5] <= 16 ? msg.msg.parameters[5] : 16;
profiles->num_modes = HIDPP20_DPI_COUNT;
profiles->has_g_shift = (info->mechanical_layout & 0x03) == 2;
profiles->has_dpi_shift = (info->mechanical_layout & 0x0c) == 2;
profiles->has_dpi_shift = ((info->mechanical_layout & 0x0c) >> 2) == 2;
switch(info->various_info & 0x07) {
case 1:
profiles->corded = 1;
@@ -1300,8 +1304,6 @@ hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
break;
}
*profiles_list = profiles;
return 0;
@@ -1467,13 +1469,29 @@ hidpp20_onboard_profiles_parse_macro(struct hidpp20_device *device,
return 0;
}
static unsigned int
hidpp20_onboard_profiles_compute_dict_size(struct hidpp20_device *device,
struct hidpp20_profiles *profiles)
{
unsigned p, num_offset;
num_offset = 0;
p = profiles->num_profiles;
while (p) {
p >>= 2;
num_offset += 16;
}
return num_offset;
}
int
hidpp20_onboard_profiles_allocate(struct hidpp20_device *device,
struct hidpp20_profiles **profiles_list)
{
unsigned i;
unsigned i, offset, num_offset;
int rc;
uint8_t data[16] = {0};
uint8_t data[HIDPP20_PAGE_SIZE] = {0};
struct hidpp20_profiles *profiles = NULL;
rc = hidpp20_onboard_profiles_initialize(device,
@@ -1483,16 +1501,21 @@ hidpp20_onboard_profiles_allocate(struct hidpp20_device *device,
assert(profiles);
rc = hidpp20_onboard_profiles_read_memory(device,
0x00,
0x00,
0x00,
data);
if (rc < 0)
return rc;
num_offset = hidpp20_onboard_profiles_compute_dict_size(device,
profiles);
for (offset = 0; offset < num_offset; offset += 16) {
rc = hidpp20_onboard_profiles_read_memory(device,
0x00,
0x00,
offset,
data + offset);
if (rc < 0)
return rc;
}
for (i = 0; i < profiles->num_profiles; i++) {
uint8_t *d = data + 4 * i;
uint8_t *d = data + offset + 4 * i;
if (d[0] == 0xFF && d[1] == 0xFF)
break;
@@ -1532,7 +1555,8 @@ hidpp20_onboard_profiles_destroy(struct hidpp20_device *device,
static int
hidpp20_onboard_profiles_find_and_read_profile(struct hidpp20_device *device,
unsigned int index,
uint8_t *data)
uint8_t *data,
unsigned int num_rom_profiles)
{
int rc;
unsigned i;
@@ -1565,13 +1589,19 @@ hidpp20_onboard_profiles_find_and_read_profile(struct hidpp20_device *device,
}
/* something went wrong, the mouse is using the factory profile in ROM */
if (num_rom_profiles == 0)
return -EINVAL;
if (index >= num_rom_profiles)
index = num_rom_profiles - 1;
for (i = 0; i < HIDPP20_PROFILE_SIZE / 0x10; i++) {
rc = hidpp20_onboard_profiles_read_memory(device,
1,
index + 1,
i * 0x10,
data + i * 0x10);
if (rc < 0)
if (rc != 0)
return rc;
}
@@ -1592,7 +1622,7 @@ hidpp20_onboard_profiles_enable_profile(struct hidpp20_device *device,
profiles_list->profiles[index].index = index + 1;
profiles_list->profiles[index].enabled = 0x01;
for (i = 0; i < 3; i++) {
for (i = 0; i < profiles_list->num_profiles; i++) {
data[buffer_index++] = 0x00;
data[buffer_index++] = i + 1;
data[buffer_index++] = profiles_list->profiles[i].enabled;
@@ -1607,7 +1637,11 @@ hidpp20_onboard_profiles_enable_profile(struct hidpp20_device *device,
memset(data + buffer_index, 0xff, sizeof(data) - buffer_index);
hidpp_log_buf_error(&device->base, "dictionary: ", data, 16);
hidpp_log_buf_debug(&device->base,
"dictionary: ",
data,
hidpp20_onboard_profiles_compute_dict_size(device,
profiles_list));
return hidpp20_onboard_profiles_write_page(device, 0x00, data);
}
@@ -1760,8 +1794,11 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
if (index >= profiles_list->num_profiles)
return -EINVAL;
rc = hidpp20_onboard_profiles_find_and_read_profile(device, index, data);
if (rc < 0)
rc = hidpp20_onboard_profiles_find_and_read_profile(device,
index,
data,
profiles_list->num_rom_profiles);
if (rc != 0)
return rc;
profile->report_rate = 1000 / max(1, pdata.profile.report_rate);
@@ -1802,7 +1839,10 @@ int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
if (index >= profiles_list->num_profiles)
return -EINVAL;
rc = hidpp20_onboard_profiles_find_and_read_profile(device, index, data);
rc = hidpp20_onboard_profiles_find_and_read_profile(device,
index,
data,
profiles_list->num_rom_profiles);
if (rc < 0)
return rc;
@@ -1845,8 +1885,9 @@ static const enum ratbag_button_action_special hidpp20_profiles_specials[] = {
[0x09] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
[0x0a] = RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP,
[0x0b] = RATBAG_BUTTON_ACTION_SPECIAL_SECOND_MODE,
[0x0c] = RATBAG_BUTTON_ACTION_SPECIAL_BATTERY_LEVEL,
[0x0c ... 0xff] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
[0x0d ... 0xff] = RATBAG_BUTTON_ACTION_SPECIAL_INVALID,
};
enum ratbag_button_action_special
@@ -1892,6 +1933,9 @@ hidpp20_device_new(const struct hidpp_device *base, unsigned int idx)
goto err;
}
if (dev->proto_major < 2)
goto err;
rc = hidpp20_feature_set_get(dev);
if (rc < 0)
goto err;

View File

@@ -362,6 +362,7 @@ struct hidpp20_profile {
struct hidpp20_profiles {
uint8_t num_profiles;
uint8_t num_rom_profiles;
uint8_t num_buttons;
uint8_t num_modes;
uint8_t has_g_shift;

View File

@@ -30,13 +30,13 @@
#include <sys/ioctl.h>
#include <linux/hidraw.h>
#include "usb-ids.h"
#include "hidpp10.h"
#include "libratbag-util.h"
#include "liblur.h"
#define _EXPORT_ __attribute__ ((visibility("default")))
#define MAX_DEVICES 6
#define VENDOR_ID_LOGITECH 0x046d
struct lur_receiver {
int refcount;
@@ -113,7 +113,7 @@ lur_device_disconnect(struct lur_device *dev)
_EXPORT_ int
lur_is_receiver(uint16_t vid, uint16_t pid)
{
return (vid == VENDOR_ID_LOGITECH && (pid == 0xc52b || pid == 0xc532));
return (vid == USB_VENDOR_ID_LOGITECH && (pid == 0xc52b || pid == 0xc532));
}
static bool
@@ -232,7 +232,7 @@ lur_receiver_enumerate(struct lur_receiver *lur,
lur_receiver_ref(lur);
dev->refcount = 1;
dev->name = strdup_safe(name);
dev->vid = VENDOR_ID_LOGITECH;
dev->vid = USB_VENDOR_ID_LOGITECH;
dev->pid = wpid;
dev->type = type;
dev->serial = serial;

View File

@@ -1417,14 +1417,12 @@ ratbag_find_hidraw_node(struct ratbag_device *device,
goto skip;
matched = match(device);
if (matched == 1) {
rc = 0;
rc = matched ? 0 : -ENODEV;
if (matched == 1)
goto out;
}
skip:
ratbag_close_hidraw(device);
rc = -ENODEV;
}
out:

View File

@@ -34,6 +34,7 @@
#include <unistd.h>
#include <limits.h>
#include "usb-ids.h"
#include "libratbag-private.h"
#include "libratbag-util.h"
@@ -283,23 +284,15 @@ out:
return rc;
}
bool
ratbag_assign_driver(struct ratbag_device *device,
const struct input_id *dev_id,
struct ratbag_test_device *test_device)
static inline bool
ratbag_test_driver(struct ratbag_device *device,
const struct input_id *dev_id,
const char *driver_name,
struct ratbag_test_device *test_device)
{
struct ratbag *ratbag = device->ratbag;
struct ratbag_driver *driver;
int rc;
const char *driver_name;
if (!test_device) {
driver_name = udev_prop_value(device->udev_device, "RATBAG_DRIVER");
if (!driver_name)
return false;
} else {
driver_name = "test_driver";
}
list_for_each(driver, &ratbag->drivers, link) {
if (streq(driver->id, driver_name)) {
@@ -311,7 +304,7 @@ ratbag_assign_driver(struct ratbag_device *device,
if (!device->driver) {
log_error(ratbag, "%s: driver '%s' does not exist\n",
device->name, driver_name);
return false;
goto error;
}
if (test_device)
@@ -320,21 +313,64 @@ ratbag_assign_driver(struct ratbag_device *device,
rc = device->driver->probe(device);
if (rc == 0) {
if (!ratbag_sanity_check_device(device)) {
return false;
goto error;
} else {
log_debug(ratbag, "driver match found: %s\n", driver->name);
log_debug(ratbag,
"driver match found: %s\n",
device->driver->name);
return true;
}
}
if (rc != -ENODEV)
log_error(ratbag, "%s: error opening hidraw node (%s)\n",
device->name, strerror(-rc));
error:
device->driver = NULL;
if (rc == -ENODEV)
log_error(ratbag, "%s: no hidraw device found\n", device->name);
return false;
}
static inline bool
ratbag_driver_fallback_logitech(struct ratbag_device *device,
const struct input_id *dev_id)
{
int rc;
if (dev_id->vendor != USB_VENDOR_ID_LOGITECH)
return false;
rc = ratbag_test_driver(device, dev_id, "hidpp20", NULL);
if (!rc)
rc = ratbag_test_driver(device, dev_id, "hidpp10", NULL);
return rc;
}
bool
ratbag_assign_driver(struct ratbag_device *device,
const struct input_id *dev_id,
struct ratbag_test_device *test_device)
{
bool rc;
const char *driver_name;
if (!test_device) {
driver_name = udev_prop_value(device->udev_device, "RATBAG_DRIVER");
} else {
driver_name = "test_driver";
}
if (driver_name) {
rc = ratbag_test_driver(device, dev_id, driver_name, test_device);
} else {
rc = ratbag_driver_fallback_logitech(device, dev_id);
}
return rc;
}
static inline char*
get_device_name(struct udev_device *device)
{
@@ -382,6 +418,9 @@ ratbag_device_new_from_udev_device(struct ratbag *ratbag,
assert(udev_device != NULL);
assert(device_out != NULL);
if (udev_prop_value(udev_device, "ID_INPUT_MOUSE") == NULL)
goto out_err;
if (get_product_id(udev_device, &id) != 0)
goto out_err;

29
src/usb-ids.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright © 2016 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef USB_IDS_H
#define USB_IDS_H
#define USB_VENDOR_ID_LOGITECH 0x046d
#endif

View File

@@ -111,6 +111,8 @@ main(int argc, char **argv)
hidpp_device_init(&base, fd);
dev = hidpp20_device_new(&base, 0xff);
if (!dev)
error(1, 0, "Failed to open %s as a HID++ 2.0 device", path);
if (argc == 2)
rc = dump_everything(dev);

View File

@@ -243,7 +243,7 @@ main(int argc, char **argv)
return EXIT_FAILURE;
}
index = atoi(argv[3]);
index = atoi(argv[2]);
disconnect_device(receiver, index);
} else {
usage();