diff --git a/ratbagd/ratbagd-button.c b/ratbagd/ratbagd-button.c index eb55bce2..50eef47f 100644 --- a/ratbagd/ratbagd-button.c +++ b/ratbagd/ratbagd-button.c @@ -149,6 +149,60 @@ static int ratbagd_button_set_special(sd_bus *bus, return 0; } +static int ratbagd_button_get_key(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; + unsigned int key; + + unsigned int *modifiers = 0; + size_t *sz = 0; + key = ratbag_button_get_key(button->lib_button, modifiers, sz); + + verify_unsigned_int(key); + + CHECK_CALL(sd_bus_message_append(reply, "(uv)", + RATBAG_BUTTON_ACTION_TYPE_KEY, + "u", + key)); + + return 0; +} + +static int ratbagd_button_set_key(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *m, + void *userdata, + sd_bus_error *error) +{ + struct ratbagd_button *button = userdata; + unsigned int key; + int r; + + CHECK_CALL(sd_bus_message_read(m, "v", "u", &key)); + + unsigned int *modifiers = 0; + size_t sz = 0; + r = ratbag_button_set_key(button->lib_button, key, modifiers, sz); + + if (r == 0) { + sd_bus_emit_properties_changed(bus, + button->path, + RATBAGD_NAME_ROOT ".Button", + "Mapping", + NULL); + } + + return 0; +} + DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbag_button_macro *, ratbag_button_macro_unref); static int ratbagd_button_get_macro(sd_bus *bus, @@ -269,8 +323,6 @@ static int ratbagd_button_get_mapping(sd_bus *bus, enum ratbag_button_action_type type; 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); switch (type) { @@ -280,6 +332,9 @@ static int ratbagd_button_get_mapping(sd_bus *bus, case RATBAG_BUTTON_ACTION_TYPE_SPECIAL: return ratbagd_button_get_special(bus, path, interface, property, reply, userdata, error); + case RATBAG_BUTTON_ACTION_TYPE_KEY: + return ratbagd_button_get_key(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); @@ -314,6 +369,10 @@ static int ratbagd_button_set_mapping(sd_bus *bus, CHECK_CALL(ratbagd_button_set_special(bus, path, interface, property, m, userdata, error)); break; + case RATBAG_BUTTON_ACTION_TYPE_KEY: + CHECK_CALL(ratbagd_button_set_key(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)); @@ -341,6 +400,7 @@ static int ratbagd_button_get_action_types(sd_bus *bus, enum ratbag_button_action_type types[] = { RATBAG_BUTTON_ACTION_TYPE_BUTTON, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, + RATBAG_BUTTON_ACTION_TYPE_KEY, RATBAG_BUTTON_ACTION_TYPE_MACRO }; enum ratbag_button_action_type *t; diff --git a/src/libratbag.c b/src/libratbag.c index 98d945e4..c78585b1 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -1294,7 +1294,8 @@ ratbag_button_get_key(struct ratbag_button *button, return 0; /* FIXME: modifiers */ - *sz = 0; + if (sz != NULL) + *sz = 0; return button->action.action.key.key; } diff --git a/tools/ratbagc.py.in b/tools/ratbagc.py.in index 55e93763..8363a8ad 100644 --- a/tools/ratbagc.py.in +++ b/tools/ratbagc.py.in @@ -500,6 +500,7 @@ class RatbagdButton(metaclass=MetaRatbag): NONE = libratbag.RATBAG_BUTTON_ACTION_TYPE_NONE BUTTON = libratbag.RATBAG_BUTTON_ACTION_TYPE_BUTTON SPECIAL = libratbag.RATBAG_BUTTON_ACTION_TYPE_SPECIAL + KEY = libratbag.RATBAG_BUTTON_ACTION_TYPE_KEY MACRO = libratbag.RATBAG_BUTTON_ACTION_TYPE_MACRO class ActionSpecial(IntEnum): @@ -627,6 +628,14 @@ class RatbagdButton(metaclass=MetaRatbag): """ libratbag.ratbag_button_set_special(self._button, special) + @property + def key(self): + return libratbag.ratbag_button_get_key(self._button, None, None) + + @key.setter + def key(self, key): + libratbag.ratbag_button_set_key(self._button, key, None, 0) + @property def action_type(self): """An enum describing the action type of the button. One of diff --git a/tools/ratbagctl.in.in b/tools/ratbagctl.in.in index 7ba9f73e..ac66f8e7 100755 --- a/tools/ratbagctl.in.in +++ b/tools/ratbagctl.in.in @@ -163,6 +163,8 @@ def print_button(d, p, b, level): print("{}'button {}'".format(header, b.mapping)) elif b.action_type == RatbagdButton.ActionType.SPECIAL: print("{}'{}'".format(header, button_specials_strmap[b.special])) + elif b.action_type == RatbagdButton.ActionType.KEY: + print("{}key '{}'".format(header, str(b.key))) elif b.action_type == RatbagdButton.ActionType.MACRO: print("{}macro '{}'".format(header, str(b.macro))) elif b.action_type == RatbagdButton.ActionType.NONE: @@ -325,6 +327,17 @@ def func_button_action_set_special(r, args): commit(d, args) +def func_button_action_set_key(r, args): + b, p, d = find_button(r, args) + try: + key = args.target_key + except AttributeError: + pass + else: + b.key = key + commit(d, args) + + def func_button_action_set_macro(r, args): b, p, d = find_button(r, args) if not b.ActionType.MACRO in b.action_types: @@ -964,6 +977,20 @@ active profile if none is given.""", ], func: func_button_action_set_special, }, + { + of_type: command, + name: 'key', + help_str: 'Set the button action to key', + pos_args: [ + { + of_type: argument, + name: 'target_key', + metavar: 'S', + help_str: 'The new key value to assign', + }, + ], + func: func_button_action_set_key, + }, { of_type: command, name: 'macro', diff --git a/tools/ratbagd.py b/tools/ratbagd.py index 3041fea6..91fe5e4f 100644 --- a/tools/ratbagd.py +++ b/tools/ratbagd.py @@ -617,6 +617,7 @@ class RatbagdButton(_RatbagdDBus): NONE = 0 BUTTON = 1 SPECIAL = 2 + KEY = 3 MACRO = 4 class ActionSpecial(IntEnum): @@ -755,6 +756,19 @@ class RatbagdButton(_RatbagdDBus): self._set_dbus_property("Mapping", "(uv)", (RatbagdButton.ActionType.SPECIAL, special)) + @GObject.Property + def key(self): + type, key = self._mapping() + if type != RatbagdButton.ActionType.KEY: + return None + return key + + @key.setter + def key(self, key): + key = GLib.Variant("u", key) + self._set_dbus_property("Mapping", "(uv)", + (RatbagdButton.ActionType.KEY, key)) + @GObject.Property def action_type(self): """An enum describing the action type of the button. One of