mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
remove .has_capability() driver hook
Most of the capabilities can be inferred from ratbag_device_init_profiles(): - if a device has more than one profile, we should be able to switch between its profiles - likewise, more than one profile means that the buttons can be remapped - more than one resolution means that we can change the resolution. We need to add a stub in driver-test for .set_active_profile() now that RATBAG_DEVICE_CAP_SWITCHABLE_PROFILES is correctly set. We manually add the macro capability for all drivers that present it. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
@@ -250,24 +250,6 @@ etekcity_button_action_to_raw(const struct ratbag_button_action *action)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
etekcity_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case RATBAG_DEVICE_CAP_NONE:
|
||||
return 0;
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION:
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_KEY:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_MACROS:
|
||||
return 1;
|
||||
case RATBAG_DEVICE_CAP_DEFAULT_PROFILE:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
etekcity_current_profile(struct ratbag_device *device)
|
||||
{
|
||||
@@ -685,6 +667,8 @@ etekcity_probe(struct ratbag_device *device)
|
||||
ETEKCITY_NUM_DPI,
|
||||
ETEKCITY_BUTTON_MAX + 1);
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
active_idx = etekcity_current_profile(device);
|
||||
if (active_idx < 0) {
|
||||
log_error(device->ratbag,
|
||||
@@ -731,7 +715,6 @@ struct ratbag_driver etekcity_driver = {
|
||||
.write_profile = etekcity_write_profile,
|
||||
.set_active_profile = etekcity_set_current_profile,
|
||||
.set_default_profile = etekcity_set_default_profile,
|
||||
.has_capability = etekcity_has_capability,
|
||||
.read_button = etekcity_read_button,
|
||||
.write_button = etekcity_write_button,
|
||||
.write_resolution_dpi = etekcity_write_resolution_dpi,
|
||||
|
||||
@@ -317,28 +317,6 @@ hidpp10drv_write_button(struct ratbag_button *button,
|
||||
return hidpp10_set_profile(drv_data->dev, button->profile->index, &profile);
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp10drv_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
/* we force a non const device to shut up a warning, but we won't change anything */
|
||||
struct hidpp10drv_data *drv_data = ratbag_get_drv_data((struct ratbag_device *)device);
|
||||
struct hidpp10_device *hidpp10 = drv_data->dev;
|
||||
|
||||
switch (cap) {
|
||||
case RATBAG_DEVICE_CAP_NONE:
|
||||
abort();
|
||||
break;
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE:
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_KEY:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_MACROS:
|
||||
case RATBAG_DEVICE_CAP_DEFAULT_PROFILE:
|
||||
return (hidpp10->profile_type != HIDPP10_PROFILE_UNKNOWN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp10drv_set_current_profile(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
@@ -471,6 +449,9 @@ hidpp10drv_fill_from_profile(struct ratbag_device *device, struct hidpp10_device
|
||||
profile.num_dpi_modes,
|
||||
profile.num_buttons);
|
||||
|
||||
if (dev->profile_type != HIDPP10_PROFILE_UNKNOWN)
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -632,7 +613,6 @@ struct ratbag_driver hidpp10_driver = {
|
||||
.write_profile = hidpp10drv_write_profile,
|
||||
.set_active_profile = hidpp10drv_set_current_profile,
|
||||
.set_default_profile = hidpp10drv_set_default_profile,
|
||||
.has_capability = hidpp10drv_has_capability,
|
||||
.read_button = hidpp10drv_read_button,
|
||||
.write_button = hidpp10drv_write_button,
|
||||
.write_resolution_dpi = hidpp10drv_write_resolution_dpi,
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
struct hidpp20drv_data {
|
||||
struct hidpp20_device *dev;
|
||||
unsigned long capabilities;
|
||||
unsigned long exported_capabilities;
|
||||
unsigned num_sensors;
|
||||
struct hidpp20_sensor *sensors;
|
||||
unsigned num_controls;
|
||||
@@ -331,31 +330,6 @@ hidpp20drv_write_button(struct ratbag_button *button,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
/*
|
||||
* We need to force the non const, but we will not change anything,
|
||||
* promise!
|
||||
*/
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data((struct ratbag_device *)device);
|
||||
|
||||
if (cap == RATBAG_DEVICE_CAP_NONE)
|
||||
abort();
|
||||
|
||||
return !!(drv_data->exported_capabilities & (1UL << cap));
|
||||
}
|
||||
|
||||
static inline void
|
||||
hidpp20drv_set_exported_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data((struct ratbag_device *)device);
|
||||
|
||||
drv_data->exported_capabilities |= (1UL << cap);
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_current_profile(struct ratbag_device *device)
|
||||
{
|
||||
@@ -683,7 +657,7 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
}
|
||||
case HIDPP_PAGE_ADJUSTABLE_DPI: {
|
||||
log_debug(ratbag, "device has adjustable dpi\n");
|
||||
hidpp20drv_set_exported_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
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. */
|
||||
@@ -695,7 +669,7 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
|
||||
case HIDPP_PAGE_SPECIAL_KEYS_BUTTONS: {
|
||||
log_debug(ratbag, "device has programmable keys/buttons\n");
|
||||
drv_data->capabilities |= HIDPP_CAP_BUTTON_KEY_1b04;
|
||||
hidpp20drv_set_exported_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
/* we read the profile once to get the correct number of
|
||||
* supported buttons. */
|
||||
if (!hidpp20drv_read_special_key_mouse(device))
|
||||
@@ -738,9 +712,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;
|
||||
hidpp20drv_set_exported_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
hidpp20drv_set_exported_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
hidpp20drv_set_exported_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE);
|
||||
|
||||
rc = hidpp20_onboard_profiles_allocate(drv_data->dev, &drv_data->profiles);
|
||||
if (rc < 0)
|
||||
@@ -884,7 +855,6 @@ struct ratbag_driver hidpp20_driver = {
|
||||
.write_profile = hidpp20drv_write_profile,
|
||||
.set_active_profile = hidpp20drv_set_current_profile,
|
||||
.set_default_profile = hidpp20drv_set_default_profile,
|
||||
.has_capability = hidpp20drv_has_capability,
|
||||
.read_button = hidpp20drv_read_button,
|
||||
.write_button = hidpp20drv_write_button,
|
||||
.write_resolution_dpi = hidpp20drv_write_resolution_dpi,
|
||||
|
||||
@@ -307,23 +307,6 @@ roccat_wait_ready(struct ratbag_device *device)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int
|
||||
roccat_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case RATBAG_DEVICE_CAP_NONE:
|
||||
case RATBAG_DEVICE_CAP_DEFAULT_PROFILE:
|
||||
return 0;
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION:
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_KEY:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_MACROS:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
roccat_current_profile(struct ratbag_device *device)
|
||||
{
|
||||
@@ -816,6 +799,8 @@ roccat_probe(struct ratbag_device *device)
|
||||
ROCCAT_NUM_DPI,
|
||||
ROCCAT_BUTTON_MAX + 1);
|
||||
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
active_idx = roccat_current_profile(device);
|
||||
if (active_idx < 0) {
|
||||
log_error(device->ratbag,
|
||||
@@ -861,7 +846,6 @@ struct ratbag_driver roccat_driver = {
|
||||
.read_profile = roccat_read_profile,
|
||||
.write_profile = roccat_write_profile,
|
||||
.set_active_profile = roccat_set_current_profile,
|
||||
.has_capability = roccat_has_capability,
|
||||
.read_button = roccat_read_button,
|
||||
.write_button = roccat_write_button,
|
||||
.write_resolution_dpi = roccat_write_resolution_dpi,
|
||||
|
||||
@@ -28,24 +28,6 @@
|
||||
#include "libratbag-private.h"
|
||||
#include "libratbag-test.h"
|
||||
|
||||
static int
|
||||
test_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case RATBAG_DEVICE_CAP_NONE:
|
||||
abort();
|
||||
break;
|
||||
case RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_KEY:
|
||||
case RATBAG_DEVICE_CAP_BUTTON_MACROS:
|
||||
return (device->num_profiles > 1);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_profile(struct ratbag_profile *profile, unsigned int index)
|
||||
{
|
||||
@@ -81,6 +63,17 @@ test_write_profile(struct ratbag_profile *profile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_set_active_profile(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
struct ratbag_test_device *d = ratbag_get_drv_data(device);
|
||||
|
||||
/* check if the device is still valid */
|
||||
assert(d != NULL);
|
||||
assert(index < d->num_profiles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_fake_probe(struct ratbag_device *device)
|
||||
{
|
||||
@@ -97,6 +90,9 @@ test_probe(struct ratbag_device *device, void *data)
|
||||
test_device->num_profiles,
|
||||
test_device->num_resolutions,
|
||||
test_device->num_buttons);
|
||||
if (test_device->num_profiles > 1)
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,8 +116,7 @@ struct ratbag_driver test_driver = {
|
||||
.remove = test_remove,
|
||||
.read_profile = test_read_profile,
|
||||
.write_profile = test_write_profile,
|
||||
.set_active_profile = NULL,
|
||||
.has_capability = test_has_capability,
|
||||
.set_active_profile = test_set_active_profile,
|
||||
.read_button = NULL,
|
||||
.write_button = NULL,
|
||||
.write_resolution_dpi = NULL,
|
||||
|
||||
@@ -89,6 +89,7 @@ struct ratbag_device {
|
||||
struct input_id ids;
|
||||
struct ratbag_driver *driver;
|
||||
struct ratbag *ratbag;
|
||||
unsigned long capabilities;
|
||||
|
||||
unsigned num_profiles;
|
||||
struct list profiles;
|
||||
@@ -162,17 +163,6 @@ struct ratbag_driver {
|
||||
*/
|
||||
int (*set_default_profile)(struct ratbag_device *device, unsigned int index);
|
||||
|
||||
/**
|
||||
* This should return a boolean whether or not the device
|
||||
* supports the given capability.
|
||||
*
|
||||
* In most cases, the .probe() should store a list of capabilities
|
||||
* for each device, but most of the time, it can be statically
|
||||
* stored.
|
||||
*/
|
||||
int (*has_capability)(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap);
|
||||
|
||||
/**
|
||||
* For the given button, fill in the struct ratbag_button
|
||||
* with the available information.
|
||||
@@ -334,6 +324,10 @@ ratbag_device_init_profiles(struct ratbag_device *device,
|
||||
unsigned int num_resolutions,
|
||||
unsigned int num_buttons);
|
||||
|
||||
void
|
||||
ratbag_device_set_capability(struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap);
|
||||
|
||||
static inline void
|
||||
ratbag_profile_set_drv_data(struct ratbag_profile *profile, void *drv_data)
|
||||
{
|
||||
|
||||
@@ -606,6 +606,17 @@ ratbag_device_init_profiles(struct ratbag_device *device,
|
||||
|
||||
device->num_profiles = num_profiles;
|
||||
|
||||
if (num_profiles > 1) {
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE);
|
||||
|
||||
/* having more than one profile means we can remap the buttons
|
||||
* at least */
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
|
||||
}
|
||||
|
||||
if (num_resolutions > 1)
|
||||
ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -694,12 +705,21 @@ ratbag_device_get_num_buttons(struct ratbag_device *device)
|
||||
return device->num_buttons;
|
||||
}
|
||||
|
||||
void
|
||||
ratbag_device_set_capability(struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
device->capabilities |= (1UL << cap);
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_device_has_capability(const struct ratbag_device *device,
|
||||
enum ratbag_device_capability cap)
|
||||
{
|
||||
assert(device->driver->has_capability);
|
||||
return device->driver->has_capability(device, cap);
|
||||
if (cap == RATBAG_DEVICE_CAP_NONE)
|
||||
abort();
|
||||
|
||||
return !!(device->capabilities & (1UL << cap));
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
|
||||
Reference in New Issue
Block a user