From 97a927bb7de27dcd795fa69c98bc7715330353de Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 2 Aug 2017 13:56:06 +0200 Subject: [PATCH] profiles: add a per profile capabilities field Doesn't do much now without the next commit Signed-off-by: Benjamin Tissoires --- ratbagd/ratbagd-profile.c | 34 ++++++++++++++++++++++++++++++++++ src/driver-test.c | 4 ++++ src/libratbag-private.h | 10 ++++++++++ src/libratbag-test.h | 1 + src/libratbag.c | 10 ++++++++++ src/libratbag.h | 17 +++++++++++++++++ src/libratbag.sym | 1 + tools/ratbagd.py | 10 ++++++++++ 8 files changed, 87 insertions(+) diff --git a/ratbagd/ratbagd-profile.c b/ratbagd/ratbagd-profile.c index 40cbd137..f640ad62 100644 --- a/ratbagd/ratbagd-profile.c +++ b/ratbagd/ratbagd-profile.c @@ -347,6 +347,39 @@ ratbagd_profile_is_enabled(sd_bus *bus, return sd_bus_message_append(reply, "b", enabled); } +static int +ratbagd_profile_get_capabilities(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd_profile *profile = userdata; + struct ratbag_profile *lib_profile = profile->lib_profile; + enum ratbag_profile_capability cap; + enum ratbag_profile_capability caps[] = { + }; + int r; + size_t i; + + r = sd_bus_message_open_container(reply, 'a', "u"); + if (r < 0) + return r; + + for (i = 0; i < ELEMENTSOF(caps); i++) { + cap = caps[i]; + if (ratbag_profile_has_capability(lib_profile, cap)) { + r = sd_bus_message_append(reply, "u", cap); + if (r < 0) + return r; + } + } + + return sd_bus_message_close_container(reply); +} + const sd_bus_vtable ratbagd_profile_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_WRITABLE_PROPERTY("Enabled", "b", @@ -354,6 +387,7 @@ const sd_bus_vtable ratbagd_profile_vtable[] = { ratbagd_profile_set_enabled, 0, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("Index", "u", NULL, offsetof(struct ratbagd_profile, index), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Capabilities", "au", ratbagd_profile_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Resolutions", "ao", ratbagd_profile_get_resolutions, 0, 0), SD_BUS_PROPERTY("Buttons", "ao", ratbagd_profile_get_buttons, 0, 0), SD_BUS_PROPERTY("Leds", "ao", ratbagd_profile_get_leds, 0, 0), diff --git a/src/driver-test.c b/src/driver-test.c index 30748dda..fb77abc4 100644 --- a/src/driver-test.c +++ b/src/driver-test.c @@ -70,6 +70,10 @@ test_read_profile(struct ratbag_profile *profile, unsigned int index) profile->is_active = p->active; profile->is_enabled = !p->disabled; + + for (i = 0; i < ARRAY_LENGTH(p->caps) && p->caps[i]; i++) { + ratbag_profile_set_cap(profile, p->caps[i]); + } } static int diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 426ddba5..98764f0d 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -277,6 +277,7 @@ struct ratbag_profile { bool is_active; /**< profile is the currently active one */ bool is_enabled; bool dirty; /**< profile changed since last commit */ + unsigned long capabilities[NLONGS(MAX_CAP)]; }; #define BUTTON_ACTION_NONE \ @@ -397,6 +398,15 @@ ratbag_profile_get_drv_data(struct ratbag_profile *profile) return profile->drv_data; } +static inline void +ratbag_profile_set_cap(struct ratbag_profile *profile, + enum ratbag_profile_capability cap) +{ + assert(cap <= MAX_CAP); + + long_set_bit(profile->capabilities, cap); +} + static inline int ratbag_button_action_match(const struct ratbag_button_action *action, const struct ratbag_button_action *match) diff --git a/src/libratbag-test.h b/src/libratbag-test.h index 784dc26b..ef883e89 100644 --- a/src/libratbag-test.h +++ b/src/libratbag-test.h @@ -76,6 +76,7 @@ struct ratbag_test_profile { bool active; bool dflt; bool disabled; + uint32_t caps[10]; }; struct ratbag_test_device { diff --git a/src/libratbag.c b/src/libratbag.c index d7eb3d80..7e49e018 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -634,6 +634,16 @@ ratbag_profile_init_leds(struct ratbag_profile *profile, unsigned int count) return 0; } +LIBRATBAG_EXPORT int +ratbag_profile_has_capability(const struct ratbag_profile *profile, + enum ratbag_profile_capability cap) +{ + if (cap == RATBAG_PROFILE_CAP_NONE || cap >= MAX_CAP) + abort(); + + return long_bit_is_set(profile->capabilities, cap); +} + static struct ratbag_profile * ratbag_create_profile(struct ratbag_device *device, unsigned int index, diff --git a/src/libratbag.h b/src/libratbag.h index 0a44d9f9..a85d3697 100644 --- a/src/libratbag.h +++ b/src/libratbag.h @@ -646,6 +646,12 @@ ratbag_device_get_num_buttons(struct ratbag_device *device); unsigned int ratbag_device_get_num_leds(struct ratbag_device *device); +/** + * @ingroup profile + */ +enum ratbag_profile_capability { + RATBAG_PROFILE_CAP_NONE = 0, +}; /** * @ingroup profile * @@ -671,6 +677,17 @@ ratbag_profile_ref(struct ratbag_profile *profile); struct ratbag_profile * ratbag_profile_unref(struct ratbag_profile *profile); +/** + * @ingroup profile + * + * Check if a profile has a specific capability. + * + * @return non-zero if the capability is available, zero otherwise. + */ +int +ratbag_profile_has_capability(const struct ratbag_profile *profile, + enum ratbag_profile_capability cap); + /** * @ingroup profile * diff --git a/src/libratbag.sym b/src/libratbag.sym index bdf30f69..7235ee5d 100644 --- a/src/libratbag.sym +++ b/src/libratbag.sym @@ -62,6 +62,7 @@ global: ratbag_profile_get_num_resolutions; ratbag_profile_get_resolution; ratbag_profile_get_user_data; + ratbag_profile_has_capability; ratbag_profile_is_active; ratbag_profile_is_enabled; ratbag_profile_ref; diff --git a/tools/ratbagd.py b/tools/ratbagd.py index af8e23c2..2da9b8a0 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -293,6 +293,16 @@ class RatbagdProfile(_RatbagdDBus): _RatbagdDBus.__init__(self, "Profile", object_path) @GObject.Property + def capabilities(self): + """The capabilities of this profile as an array. Capabilities not + present on the profile are not in the list. Thus use e.g. + + if RatbagdPorfile.CAP_WRITABLE_NAME is in profile.capabilities: + do something + """ + return self._get_dbus_property("Capabilities") + + @GObject.property def index(self): """The index of this profile.""" return self._get_dbus_property("Index")