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:
Benjamin Tissoires
2016-02-10 15:08:35 +01:00
parent 80fd187c3c
commit 960ee73da9
7 changed files with 51 additions and 125 deletions

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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)
{

View File

@@ -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