From 70f3da98db0dacde25381e0d8aa650dacc56cedc Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 20 Jul 2017 09:18:55 +1000 Subject: [PATCH] ratbagd: add IsActive/IsDefault to Resolution This replaces the calls in the profile. Signed-off-by: Peter Hutterer --- DBusInterface.md | 28 +++++++++---- ratbagd/ratbagd-profile.c | 69 ++++++------------------------ ratbagd/ratbagd-resolution.c | 81 +++++++++++++++++++++++++++--------- ratbagd/ratbagd.h | 7 ++-- tools/ratbagctl.in | 17 ++++++-- tools/ratbagd.py | 43 ++++++------------- 6 files changed, 124 insertions(+), 121 deletions(-) diff --git a/DBusInterface.md b/DBusInterface.md index a94729e6..2a9a3ab9 100644 --- a/DBusInterface.md +++ b/DBusInterface.md @@ -155,6 +155,27 @@ Index of the resolution - type: `au`, read-only, constant Array of uints with the capabilities enum from libratbag + +#### `IsActive` +- type: `b`, read-only, mutable + +True if this is the currently active resolution, false otherwise. + +Resolutions can only be set to active, but never to not active - at least +one resoultion must be active at all times. This property is read-only, use the +`SetActive()` method to set a resolution as the active resolution. + +#### `IsDefault` +- type: `b`, read-only, mutable + +True if this is the currently default resolution, false otherwise. If the +device does not have the default resolution capability, this property is +always false. + +Resolutions can only be set to default, but never to not default - at least +one resolution must be default at all times. This property is read-only, use the +`SetDefault()` method to set a resolution as the default resolution. + #### `XResolution` - type: `u`, read-only, mutable @@ -188,13 +209,6 @@ uint for the report rate to assign Set this resolution to be the default -### Signals: - -#### `ActiveResolutionChanged(u)` -Active resolution changed, carries index of the new active resolution -#### `DefaultResolutionChanged(u)` -Default resolution changed, carries index of the new default resolution - org.freedesktop.ratbag1.Button ============================== diff --git a/ratbagd/ratbagd-profile.c b/ratbagd/ratbagd-profile.c index f2868664..adca758c 100644 --- a/ratbagd/ratbagd-profile.c +++ b/ratbagd/ratbagd-profile.c @@ -187,33 +187,6 @@ static int ratbagd_profile_get_leds(sd_bus *bus, return sd_bus_message_close_container(reply); } -static int ratbagd_profile_get_active_resolution(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 ratbagd_resolution *resolution; - unsigned int i; - - for (i = 0; i < profile->n_resolutions; ++i) { - resolution = profile->resolutions[i]; - if (!resolution) - continue; - if (!ratbagd_resolution_is_active(resolution)) - continue; - - return sd_bus_message_append(reply, "u", i); - } - - log_error("Unable to find active resolution for %s\n", - ratbagd_device_get_name(profile->device)); - return sd_bus_message_append(reply, "u", 0); -} - static int ratbagd_profile_is_active(sd_bus *bus, const char *path, const char *interface, @@ -230,33 +203,6 @@ static int ratbagd_profile_is_active(sd_bus *bus, return sd_bus_message_append(reply, "b", is_active); } -static int ratbagd_profile_get_default_resolution(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 ratbagd_resolution *resolution; - unsigned int i; - - for (i = 0; i < profile->n_resolutions; ++i) { - resolution = profile->resolutions[i]; - if (!resolution) - continue; - if (!ratbagd_resolution_is_default(resolution)) - continue; - - return sd_bus_message_append(reply, "u", i); - } - - log_error("Unable to find default resolution for %s\n", - ratbagd_device_get_name(profile->device)); - return sd_bus_message_append(reply, "u", 0); -} - static int ratbagd_profile_find_button(sd_bus *bus, const char *path, const char *interface, @@ -383,9 +329,7 @@ const sd_bus_vtable ratbagd_profile_vtable[] = { 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), - SD_BUS_PROPERTY("ActiveResolution", "u", ratbagd_profile_get_active_resolution, 0, 0), SD_BUS_PROPERTY("IsActive", "b", ratbagd_profile_is_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("DefaultResolution", "u", ratbagd_profile_get_default_resolution, 0, 0), SD_BUS_METHOD("SetActive", "", "u", ratbagd_profile_set_active, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("GetResolutionByIndex", "u", "o", ratbagd_profile_get_resolution_by_index, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END, @@ -727,3 +671,16 @@ int ratbagd_profile_register_leds(struct sd_bus *bus, return 0; } + +int ratbagd_for_each_resolution_signal(sd_bus *bus, + struct ratbagd_profile *profile, + int (*func)(sd_bus *bus, + struct ratbagd_resolution *resolution)) +{ + int rc = 0; + + for (size_t i = 0; rc == 0 && i < profile->n_resolutions; i++) + rc = func(bus, profile->resolutions[i]); + + return rc; +} diff --git a/ratbagd/ratbagd-resolution.c b/ratbagd/ratbagd-resolution.c index 0054ccbc..0e04d50a 100644 --- a/ratbagd/ratbagd-resolution.c +++ b/ratbagd/ratbagd-resolution.c @@ -38,6 +38,7 @@ #include "libratbag-util.h" struct ratbagd_resolution { + struct ratbagd_profile *profile; struct ratbag_resolution *lib_resolution; unsigned int index; char *path; @@ -105,6 +106,24 @@ static int ratbagd_resolution_set_resolution(sd_bus_message *m, return sd_bus_reply_method_return(m, "u", r); } +static int ratbagd_resolution_default_signal_cb(sd_bus *bus, + struct ratbagd_resolution *resolution) +{ + struct ratbag_resolution *lib_resolution = resolution->lib_resolution; + + /* FIXME: we should cache is default and only send the signal for + * those resolutions where it changed */ + + (void) sd_bus_emit_signal(bus, + resolution->path, + RATBAGD_NAME_ROOT ".Resolution", + "IsDefault", + "b", + ratbag_resolution_is_default(lib_resolution)); + + return 0; +} + static int ratbagd_resolution_set_default(sd_bus_message *m, void *userdata, sd_bus_error *error) @@ -116,12 +135,9 @@ static int ratbagd_resolution_set_default(sd_bus_message *m, if (r < 0) return r; - (void) sd_bus_emit_signal(sd_bus_message_get_bus(m), - resolution->path, - RATBAGD_NAME_ROOT ".Resolution", - "DefaultResolutionChanged", - "u", - resolution->index); + ratbagd_for_each_resolution_signal(sd_bus_message_get_bus(m), + resolution->profile, + ratbagd_resolution_default_signal_cb); return sd_bus_reply_method_return(m, "u", r); } @@ -161,6 +177,42 @@ ratbagd_resolution_get_capabilities(sd_bus *bus, return sd_bus_message_close_container(reply); } +static int +ratbagd_resolution_is_active(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd_resolution *resolution = userdata; + struct ratbag_resolution *lib_resolution = resolution->lib_resolution; + bool is_active; + + is_active = !!ratbag_resolution_is_active(lib_resolution); + + return sd_bus_message_append(reply, "b", is_active); +} + +static int +ratbagd_resolution_is_default(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd_resolution *resolution = userdata; + struct ratbag_resolution *lib_resolution = resolution->lib_resolution; + bool is_default; + + is_default = !!ratbag_resolution_is_default(lib_resolution); + + return sd_bus_message_append(reply, "b", is_default); +} + static int ratbagd_resolution_get_resolution_x(sd_bus *bus, const char *path, @@ -250,6 +302,8 @@ const sd_bus_vtable ratbagd_resolution_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Index", "u", NULL, offsetof(struct ratbagd_resolution, index), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Capabilities", "au", ratbagd_resolution_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("IsActive", "b", ratbagd_resolution_is_active, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_PROPERTY("IsDefault", "b", ratbagd_resolution_is_default, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("XResolution", "u", ratbagd_resolution_get_resolution_x, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("YResolution", "u", ratbagd_resolution_get_resolution_y, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("ReportRate", "u", ratbagd_resolution_get_rate, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), @@ -258,8 +312,6 @@ const sd_bus_vtable ratbagd_resolution_vtable[] = { SD_BUS_METHOD("SetReportRate", "u", "u", ratbagd_resolution_set_report_rate, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("SetResolution", "uu", "u", ratbagd_resolution_set_resolution, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("SetDefault", "", "u", ratbagd_resolution_set_default, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_SIGNAL("ActiveResolutionChanged", "u", 0), - SD_BUS_SIGNAL("DefaultResolutionChanged", "u", 0), SD_BUS_VTABLE_END, }; @@ -281,6 +333,7 @@ int ratbagd_resolution_new(struct ratbagd_resolution **out, if (!resolution) return -ENOMEM; + resolution->profile = profile; resolution->lib_resolution = lib_resolution; resolution->index = index; @@ -315,15 +368,3 @@ struct ratbagd_resolution *ratbagd_resolution_free(struct ratbagd_resolution *re return mfree(resolution); } - -bool ratbagd_resolution_is_active(struct ratbagd_resolution *resolution) -{ - assert(resolution); - return ratbag_resolution_is_active(resolution->lib_resolution) != 0; -} - -bool ratbagd_resolution_is_default(struct ratbagd_resolution *resolution) -{ - assert(resolution); - return ratbag_resolution_is_default(resolution->lib_resolution) != 0; -} diff --git a/ratbagd/ratbagd.h b/ratbagd/ratbagd.h index 7517f0ab..341d74a1 100644 --- a/ratbagd/ratbagd.h +++ b/ratbagd/ratbagd.h @@ -85,7 +85,10 @@ int ratbagd_for_each_profile_signal(sd_bus *bus, struct ratbagd_device *device, int (*func)(sd_bus *bus, struct ratbagd_profile *profile)); - +int ratbagd_for_each_resolution_signal(sd_bus *bus, + struct ratbagd_profile *profile, + int (*func)(sd_bus *bus, + struct ratbagd_resolution *resolution)); DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_profile *, ratbagd_profile_free); @@ -101,8 +104,6 @@ int ratbagd_resolution_new(struct ratbagd_resolution **out, unsigned int index); struct ratbagd_resolution *ratbagd_resolution_free(struct ratbagd_resolution *resolution); const char *ratbagd_resolution_get_path(struct ratbagd_resolution *resolution); -bool ratbagd_resolution_is_active(struct ratbagd_resolution *resolution); -bool ratbagd_resolution_is_default(struct ratbagd_resolution *resolution); DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_resolution *, ratbagd_resolution_free); diff --git a/tools/ratbagctl.in b/tools/ratbagctl.in index 630ad68e..cf63128e 100755 --- a/tools/ratbagctl.in +++ b/tools/ratbagctl.in @@ -70,7 +70,11 @@ def find_resolution(r, args): print("Invalid resolution index {}".format(args.resolution_n)) sys.exit(1) except AttributeError: - r = p.active_resolution + for r in p.resolutions: + if r.is_active: + break + else: + r = None return r, p, d @@ -155,8 +159,8 @@ def print_resolution(d, p, r, level): print(" " * level + "{}: {}dpi @ {}Hz{}{}".format(r.index, dpi, r.report_rate, - " (active)" if p.active_resolution == r else "", - " (default)" if p.default_resolution == r else "", + " (active)" if r.is_active else "", + " (default)" if r.is_default else "", )) @@ -322,7 +326,12 @@ def func_resolution_get(r, args): def func_resolution_active_get(r, args): p, d = find_profile(r, args) - print(p.active_resolution.index) + for r in p.resolutions: + if r.is_active: + break + else: + r = None + print(r.index) def func_profile_get(r, args): diff --git a/tools/ratbagd.py b/tools/ratbagd.py index bc2b157a..04d66a69 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -338,22 +338,6 @@ class RatbagdProfile(_RatbagdDBus): leds = [RatbagdLed(objpath) for objpath in result] return leds - @GObject.Property - def active_resolution(self): - """The currently active resolution. This function returns a - RatbagdResolution object or None.""" - resolutions = self.resolutions - active_index = self._get_dbus_property("ActiveResolution") - return resolutions[active_index] if len(resolutions) > active_index else None - - @GObject.Property - def default_resolution(self): - """The default resolution. This function returns a RatbagdResolution - object or None.""" - resolutions = self.resolutions - default_index = self._get_dbus_property("DefaultResolution") - return resolutions[default_index] if len(resolutions) > default_index else None - @GObject.Property def is_active(self): """Returns True if the profile is currenly active, false otherwise.""" @@ -375,23 +359,8 @@ class RatbagdResolution(_RatbagdDBus): CAP_INDIVIDUAL_REPORT_RATE = 1 CAP_SEPARATE_XY_RESOLUTION = 2 - __gsignals__ = { - "active-resolution-changed": - (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, [int]), - "default-resolution-changed": - (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, [int]), - } - def __init__(self, object_path): _RatbagdDBus.__init__(self, "Resolution", object_path) - self._proxy.connect("g-signal", self._on_g_signal) - - def _on_g_signal(self, proxy, sender, signal, params): - params = params.unpack() - if signal == "ActiveResolutionChanged": - self.emit("active-resolution-changed", params[0]) - elif signal == "DefaultResolutionChanged": - self.emit("default-resolution-changed", params[0]) @GObject.Property def index(self): @@ -448,6 +417,18 @@ class RatbagdResolution(_RatbagdDBus): self._set_dbus_property("ReportRate", "u", rate) return ret + @GObject.Property + def is_active(self): + """True if this is the currently active resolution, False + otherwise""" + return self._get_dbus_property("IsActive") + + @GObject.Property + def is_default(self): + """True if this is the currently default resolution, False + otherwise""" + return self._get_dbus_property("IsDefault") + def set_default(self): """Set this resolution to be the default.""" return self._dbus_call("SetDefault", "")