diff --git a/src/driver-etekcity.c b/src/driver-etekcity.c index 294dfaa3..e9af6fbd 100644 --- a/src/driver-etekcity.c +++ b/src/driver-etekcity.c @@ -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, diff --git a/src/driver-hidpp10.c b/src/driver-hidpp10.c index 0cd6082b..5fa93dc8 100644 --- a/src/driver-hidpp10.c +++ b/src/driver-hidpp10.c @@ -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, diff --git a/src/driver-hidpp20.c b/src/driver-hidpp20.c index 8f0b1f41..1ac3ca4f 100644 --- a/src/driver-hidpp20.c +++ b/src/driver-hidpp20.c @@ -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, diff --git a/src/driver-roccat.c b/src/driver-roccat.c index 97b65c41..ef563265 100644 --- a/src/driver-roccat.c +++ b/src/driver-roccat.c @@ -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, diff --git a/src/driver-test.c b/src/driver-test.c index fb52d520..7447e8a5 100644 --- a/src/driver-test.c +++ b/src/driver-test.c @@ -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, diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 74794128..c6e5b9ca 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -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) { diff --git a/src/libratbag.c b/src/libratbag.c index c6cedde9..bfd7068b 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -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