diff --git a/doc/dbus.rst b/doc/dbus.rst index 9bce5516..d62ddbac 100644 --- a/doc/dbus.rst +++ b/doc/dbus.rst @@ -359,38 +359,27 @@ org.freedesktop.ratbag1.Button Index of the button -.. attribute:: ButtonMapping +.. attribute:: Mapping - :type: u + :type: (uv) :flags: read-write, mutable - uint of the current button mapping (if mapping to button) + The current button mapping. The first element is the ActionType + selected for this button. -.. attribute:: SpecialMapping + If the ActionType is Button, the variant is an unsigned integer + (``u``) denoting the button number to map to. - :type: u - :flags: read-write, mutable + If the ActionType is Special, the variant is an unsigned integer + (``u``) denoting the special value to map to. - Enum describing the current special mapping (if mapped to special) - -.. attribute:: Macro - - :type: a(uu) - :flags: read-write, mutable - - Array of (type, keycode), where type may be one of - :cpp:enumerator:`RATBAG_MACRO_EVENT_KEY_PRESSED` or + If the ActionType is Macro, the variant is an array of integer + tuples (``a(uu)``) where each tuple is ``(type, keycode)`` and the + type is one of :cpp:enumerator:`RATBAG_MACRO_EVENT_KEY_PRESSED` or :cpp:enumerator:`RATBAG_MACRO_EVENT_KEY_RELEASED`. -.. attribute:: ActionType - - :type: u - :flags: read-only, mutable - - An enum describing the action type of the button, see - :cpp:enum:`ratbag_button_action_type` for the list of enums. - This decides which one of :attr:`ButtonMapping`, - :attr:`SpecialMapping` and :attr:`Macro` has a value. + If the ActionType is Unknown, the variant is an unsigned integer + (``u``) of value 0. .. attribute:: ActionTypes @@ -398,7 +387,7 @@ org.freedesktop.ratbag1.Button :flags: read-only, constant Array of :cpp:enum:`ratbag_button_action_type`, possible values - for ActionType on the current device + for ActionType on the current device. .. function:: Disable() → () diff --git a/ratbagd/ratbagd-button.c b/ratbagd/ratbagd-button.c index f6b2d486..341d4390 100644 --- a/ratbagd/ratbagd-button.c +++ b/ratbagd/ratbagd-button.c @@ -60,7 +60,9 @@ static int ratbagd_button_get_button(sd_bus *bus, verify_unsigned_int(b); - return sd_bus_message_append(reply, "u", b); + return sd_bus_message_append(reply, "(uv)", + RATBAG_BUTTON_ACTION_TYPE_BUTTON, + "u", b); } static int ratbagd_button_set_button(sd_bus *bus, @@ -75,7 +77,7 @@ static int ratbagd_button_set_button(sd_bus *bus, unsigned int map; int r; - r = sd_bus_message_read(m, "u", &map); + r = sd_bus_message_read(m, "v", "u", &map); if (r < 0) return r; @@ -119,7 +121,10 @@ static int ratbagd_button_get_special(sd_bus *bus, verify_unsigned_int(special); - CHECK_CALL(sd_bus_message_append(reply, "u", special)); + CHECK_CALL(sd_bus_message_append(reply, "(uv)", + RATBAG_BUTTON_ACTION_TYPE_SPECIAL, + "u", + special)); return 0; } @@ -136,7 +141,7 @@ static int ratbagd_button_set_special(sd_bus *bus, enum ratbag_button_action_special special; int r; - CHECK_CALL(sd_bus_message_read(m, "u", &special)); + CHECK_CALL(sd_bus_message_read(m, "v", "u", &special)); r = ratbag_button_set_special(button->lib_button, special); @@ -172,6 +177,9 @@ static int ratbagd_button_get_macro(sd_bus *bus, _cleanup_(ratbag_button_macro_unrefp) struct ratbag_button_macro *macro = NULL; unsigned int idx; + CHECK_CALL(sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "uv")); + CHECK_CALL(sd_bus_message_append(reply, "u", RATBAG_BUTTON_ACTION_TYPE_MACRO)); + CHECK_CALL(sd_bus_message_open_container(reply, 'v', "a(uu)")); CHECK_CALL(sd_bus_message_open_container(reply, 'a', "(uu)")); macro = ratbag_button_get_macro(button->lib_button); @@ -207,7 +215,9 @@ static int ratbagd_button_get_macro(sd_bus *bus, } out: - CHECK_CALL(sd_bus_message_close_container(reply)); + CHECK_CALL(sd_bus_message_close_container(reply)); /* a(uu) */ + CHECK_CALL(sd_bus_message_close_container(reply)); /* v */ + CHECK_CALL(sd_bus_message_close_container(reply)); /* ) */ return 0; } @@ -225,6 +235,7 @@ static int ratbagd_button_set_macro(sd_bus *bus, int r, idx = 0; _cleanup_(ratbag_button_macro_unrefp) struct ratbag_button_macro *macro = NULL; + CHECK_CALL(sd_bus_message_enter_container(m, 'v', "a(uu)")); CHECK_CALL(sd_bus_message_enter_container(m, 'a', "(uu)")); macro = ratbag_button_macro_new("macro"); @@ -239,7 +250,8 @@ static int ratbagd_button_set_macro(sd_bus *bus, if (r < 0) return r; - CHECK_CALL(sd_bus_message_exit_container(m)); + CHECK_CALL(sd_bus_message_exit_container(m)); /* (uu) */ + CHECK_CALL(sd_bus_message_exit_container(m)); /* a(uu) */ r = ratbag_button_set_macro(button->lib_button, macro); if (r < 0) { @@ -266,13 +278,13 @@ static int ratbagd_button_set_macro(sd_bus *bus, return 0; } -static int ratbagd_button_get_action_type(sd_bus *bus, - const char *path, - const char *interface, - const char *property, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error) +static int ratbagd_button_get_mapping(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { struct ratbagd_button *button = userdata; enum ratbag_button_action_type type; @@ -280,14 +292,64 @@ static int ratbagd_button_get_action_type(sd_bus *bus, type = ratbag_button_get_action_type(button->lib_button); if (type == RATBAG_BUTTON_ACTION_TYPE_KEY) type = RATBAG_BUTTON_ACTION_TYPE_UNKNOWN; - verify_unsigned_int(type); - CHECK_CALL(sd_bus_message_append(reply, "u", type)); + switch (type) { + case RATBAG_BUTTON_ACTION_TYPE_BUTTON: + return ratbagd_button_get_button(bus, path, interface, property, + reply, userdata, error); + case RATBAG_BUTTON_ACTION_TYPE_SPECIAL: + return ratbagd_button_get_special(bus, path, interface, property, + reply, userdata, error); + case RATBAG_BUTTON_ACTION_TYPE_MACRO: + return ratbagd_button_get_macro(bus, path, interface, property, + reply, userdata, error); + default: + return sd_bus_message_append(reply, "(uv)", + RATBAG_BUTTON_ACTION_TYPE_UNKNOWN, + "u", 0); + } return 0; } +static int ratbagd_button_set_mapping(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *m, + void *userdata, + sd_bus_error *error) +{ + enum ratbag_button_action_type type; + + CHECK_CALL(sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "uv")); + CHECK_CALL(sd_bus_message_read(m, "u", &type)); + + switch (type) { + case RATBAG_BUTTON_ACTION_TYPE_BUTTON: + CHECK_CALL(ratbagd_button_set_button(bus, path, interface, property, + m, userdata, error)); + break; + case RATBAG_BUTTON_ACTION_TYPE_SPECIAL: + CHECK_CALL(ratbagd_button_set_special(bus, path, interface, property, + m, userdata, error)); + break; + case RATBAG_BUTTON_ACTION_TYPE_MACRO: + CHECK_CALL(ratbagd_button_set_macro(bus, path, interface, property, + m, userdata, error)); + break; + default: + /* FIXME */ + return 1; + } + + CHECK_CALL(sd_bus_message_exit_container(m)); + + return 0; + +} + static int ratbagd_button_get_action_types(sd_bus *bus, const char *path, const char *interface, @@ -345,19 +407,10 @@ static int ratbagd_button_disable(sd_bus_message *m, const sd_bus_vtable ratbagd_button_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Index", "u", NULL, offsetof(struct ratbagd_button, index), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_WRITABLE_PROPERTY("ButtonMapping", "u", - ratbagd_button_get_button, - ratbagd_button_set_button, + SD_BUS_WRITABLE_PROPERTY("Mapping", "(uv)", + ratbagd_button_get_mapping, + ratbagd_button_set_mapping, 0, SD_BUS_VTABLE_UNPRIVILEGED | SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_WRITABLE_PROPERTY("SpecialMapping", "u", - ratbagd_button_get_special, - ratbagd_button_set_special, - 0, SD_BUS_VTABLE_UNPRIVILEGED | SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_WRITABLE_PROPERTY("Macro", "a(uu)", - ratbagd_button_get_macro, - ratbagd_button_set_macro, - 0, SD_BUS_VTABLE_UNPRIVILEGED | SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("ActionType", "u", ratbagd_button_get_action_type, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("ActionTypes", "au", ratbagd_button_get_action_types, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_METHOD("Disable", "", "u", ratbagd_button_disable, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END, diff --git a/tools/ratbagd.py b/tools/ratbagd.py index fbd13b84..6ea36fc4 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -678,6 +678,9 @@ class RatbagdButton(_RatbagdDBus): if "ActionType" in changed_props.keys(): self.notify("action-type") + def _mapping(self): + return self._get_dbus_property("Mapping") + @GObject.Property def index(self): """The index of this button.""" @@ -685,8 +688,12 @@ class RatbagdButton(_RatbagdDBus): @GObject.Property def mapping(self): - """An integer of the current button mapping, if mapping to a button.""" - return self._get_dbus_property("ButtonMapping") + """An integer of the current button mapping, if mapping to a button + or None otherwise.""" + type, button = self._mapping() + if type != RatbagdButton.ACTION_TYPE_BUTTON: + return None + return button @mapping.setter def mapping(self, button): @@ -694,12 +701,18 @@ class RatbagdButton(_RatbagdDBus): @param button The button to map to, as int """ - self._set_dbus_property("ButtonMapping", "u", button) + button = GLib.Variant("u", button) + self._set_dbus_property("Mapping", "(uv)", + (RatbagdButton.ACTION_TYPE_BUTTON, button)) @GObject.Property def macro(self): - """A RatbagdMacro object representing the currently set macro.""" - return RatbagdMacro.from_ratbag(self._get_dbus_property("Macro")) + """A RatbagdMacro object representing the currently set macro or + None otherwise.""" + type, macro = self._mapping() + if type != RatbagdButton.ACTION_TYPE_MACRO: + return None + return RatbagdMacro.from_ratbag(macro) @macro.setter def macro(self, macro): @@ -709,12 +722,18 @@ class RatbagdButton(_RatbagdDBus): @param macro A RatbagdMacro object representing the macro to apply to the button, as RatbagdMacro. """ - self._set_dbus_property("Macro", "a(uu)", macro.keys) + macro = GLib.Variant("a(uu)", macro.keys) + self._set_dbus_property("Mapping", "(uv)", + (RatbagdButton.ACTION_TYPE_MACRO, macro)) @GObject.Property def special(self): - """An enum describing the current special mapping, if mapped to special.""" - return self._get_dbus_property("SpecialMapping") + """An enum describing the current special mapping, if mapped to + special or None otherwise.""" + type, special = self._mapping() + if type != RatbagdButton.ACTION_TYPE_SPECIAL: + return None + return special @special.setter def special(self, special): @@ -722,7 +741,9 @@ class RatbagdButton(_RatbagdDBus): @param special The special entry, as one of RatbagdButton.ACTION_SPECIAL_* """ - self._set_dbus_property("SpecialMapping", "u", special) + special = GLib.Variant("u", special) + self._set_dbus_property("Mapping", "(uv)", + (RatbagdButton.ACTION_TYPE_SPECIAL, special)) @GObject.Property def action_type(self): @@ -731,7 +752,8 @@ class RatbagdButton(_RatbagdDBus): ACTION_TYPE_MACRO. This decides which *Mapping property has a value. """ - return self._get_dbus_property("ActionType") + type, mapping = self._mapping() + return type @GObject.Property def action_types(self):