From 8e9dd6f392502b3c29e11ded416ae1cc83949e08 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 26 Feb 2019 16:35:20 +1000 Subject: [PATCH] ratbagd: change the Resolution property to a variant Instead of a fixed (uu) with an extra capability flag, let's just make this a variant defined to be a u or a (uu), depending on whether we have a single or a separate resolution. In the ratbagd.py bindings we return a tuple for both, but a simple len() check will tell us which one it is. Signed-off-by: Peter Hutterer --- doc/dbus.rst | 19 +++++++++++++------ ratbagd/ratbagd-resolution.c | 21 ++++++++++++--------- tools/ratbagc.py.in | 3 ++- tools/ratbagctl.in | 11 +++++++---- tools/ratbagd.py | 20 ++++++++++++++++---- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/doc/dbus.rst b/doc/dbus.rst index 10591f77..59fd518f 100644 --- a/doc/dbus.rst +++ b/doc/dbus.rst @@ -298,15 +298,22 @@ org.freedesktop.ratbag1.Resolution .. attribute:: Resolution - :type: uu + :type: v :flags: read-write, mutable - uint for the x and y resolution assigned to this entry, - respectively. The value for the resolution must be equal to - one of the values in :attr:`Resolutions`. + The resolution for this entry in dpi. - If the resolution does not support separate x/y resolutions, - x and y must be the same value. + If the variant is a single unsigned integer (``u``), the value is + the resolution for both the x- and the y- axis. + + If the variant is a unsigned integer tuple (``(uu)``), the value is + the resolution for the x- and y- axis separately. + + A client must leave the type intact, assigning a single ``u`` to a + resolution object previously exporting ``(uu)`` is invalid. + + The value for the resolution must be equal to one of the values in + :attr:`Resolutions`. .. attribute:: Resolutions diff --git a/ratbagd/ratbagd-resolution.c b/ratbagd/ratbagd-resolution.c index 5663d3da..33673cde 100644 --- a/ratbagd/ratbagd-resolution.c +++ b/ratbagd/ratbagd-resolution.c @@ -249,13 +249,18 @@ ratbagd_resolution_get_resolution(sd_bus *bus, struct ratbag_resolution *lib_resolution = resolution->lib_resolution; int xres, yres; + xres = ratbag_resolution_get_dpi_x(lib_resolution); yres = ratbag_resolution_get_dpi_y(lib_resolution); verify_unsigned_int(xres); verify_unsigned_int(yres); - return sd_bus_message_append(reply, "(uu)", xres, yres); + if (ratbag_resolution_has_capability(lib_resolution, + RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION)) + return sd_bus_message_append(reply, "v", "(uu)", xres, yres); + else + return sd_bus_message_append(reply, "v", "u", xres); } static int @@ -273,15 +278,13 @@ ratbagd_resolution_set_resolution(sd_bus *bus, int xres, yres; int r; - r = sd_bus_message_read(m, "(uu)", &xres, &yres); - if (r < 0) - return r; - - if (!ratbag_resolution_has_capability(lib_resolution, cap)) { - r = ratbag_resolution_set_dpi(resolution->lib_resolution, xres); - } else { + if (ratbag_resolution_has_capability(lib_resolution, cap)) { + CHECK_CALL(sd_bus_message_read(m, "v", "(uu)", &xres, &yres)); r = ratbag_resolution_set_dpi_xy(resolution->lib_resolution, xres, yres); + } else { + CHECK_CALL(sd_bus_message_read(m, "v", "u", &xres)); + r = ratbag_resolution_set_dpi(resolution->lib_resolution, xres); } if (r == 0) { @@ -391,7 +394,7 @@ const sd_bus_vtable ratbagd_resolution_vtable[] = { 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_WRITABLE_PROPERTY("Resolution", "(uu)", + SD_BUS_WRITABLE_PROPERTY("Resolution", "v", ratbagd_resolution_get_resolution, ratbagd_resolution_set_resolution, 0, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), diff --git a/tools/ratbagc.py.in b/tools/ratbagc.py.in index 802371d2..9a99d0bd 100644 --- a/tools/ratbagc.py.in +++ b/tools/ratbagc.py.in @@ -440,7 +440,8 @@ class RatbagdResolution(metaclass=MetaRatbag): dpi_y = dpi_x = libratbag.ratbag_resolution_get_dpi_x(self._res) if libratbag.RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION in self._capabilities: dpi_y = libratbag.ratbag_resolution_get_dpi_y(self._res) - return (dpi_x, dpi_y) + return (dpi_x, dpi_y) + return (dpi_x, ) @resolution.setter def resolution(self, res): diff --git a/tools/ratbagctl.in b/tools/ratbagctl.in index b168531d..8a36e045 100755 --- a/tools/ratbagctl.in +++ b/tools/ratbagctl.in @@ -189,7 +189,7 @@ def print_resolution(d, p, r, level): if r.resolution == (0, 0): print(" " * level + "{}: ".format(r.index)) return - if RatbagdResolution.CAP_SEPARATE_XY_RESOLUTION in r.capabilities: + if len(r.resolution) == 2: dpi = "{}x{}".format(r.resolution[0], r.resolution[1]) else: dpi = "{}".format(r.resolution[0]) @@ -383,7 +383,7 @@ def func_button_count(r, args): def func_dpi_get(r, args): r, p, d = find_resolution(r, args) - if RatbagdResolution.CAP_SEPARATE_XY_RESOLUTION in r.capabilities: + if len(r.resolution) == 2: print("{}x{}dpi".format(r.resolution[0], r.resolution[1])) else: print("{}dpi".format(r.resolution[0])) @@ -397,7 +397,10 @@ def func_dpi_get_all(r, args): def func_dpi_set(r, args): r, p, d = find_resolution(r, args) - r.resolution = (args.dpi_n[0], args.dpi_n[1]) + dpi = args.dpi_n + if len(r.resolution) > len(dpi): + dpi = (dpi[0], dpi[0]) + r.resolution = dpi commit(d, args) @@ -593,7 +596,7 @@ def dpi(string): except ValueError: pass else: - return (int_value, int_value) + return (int_value, ) if string.endswith("dpi"): string = string[:-3] x, y = string.split("x") diff --git a/tools/ratbagd.py b/tools/ratbagd.py index f4c0ab7d..fbc10ac9 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -534,16 +534,28 @@ class RatbagdResolution(_RatbagdDBus): @GObject.Property def resolution(self): - """The tuple (xres, yres) with each resolution in DPI.""" - return self._get_dbus_property("Resolution") + """The resolution in DPI, either as single value tuple ``(res, )`` + or as tuple ``(xres, yres)``. + """ + res = self._get_dbus_property("Resolution") + if isinstance(res, int): + res = tuple([res]) + return res @resolution.setter - def resolution(self, res): + def resolution(self, resolution): """Set the x- and y-resolution using the given (xres, yres) tuple. @param res The new resolution, as (int, int) """ - self._set_dbus_property("Resolution", "(uu)", res) + res = self.resolution + if len(res) != len(resolution) or len(res) > 2: + raise ValueError('invalid resolution precision') + if len(res) == 1: + variant = GLib.Variant('u', resolution[0]); + else: + variant = GLib.Variant('(uu)', resolution); + self._set_dbus_property("Resolution", "v", variant) @GObject.Property def report_rate(self):