Revamp the button macro code

The previous API was inconsistent and different to the rest of libratbag's
API. Replace with one where a macro is a separate struct, can be initialized
and then written to the device with a set_macro() call. The device copies the
contents, the macro is otherwise unmodified and can be re-used by the client
if need be.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2016-03-11 15:18:08 +10:00
parent 578142964d
commit 4054616190
10 changed files with 303 additions and 122 deletions

View File

@@ -430,6 +430,7 @@ etekcity_read_button(struct ratbag_button *button)
{
const struct ratbag_button_action *action;
struct ratbag_device *device;
struct ratbag_button_macro *m;
struct etekcity_macro *macro;
struct etekcity_data *drv_data;
uint8_t *buf;
@@ -464,7 +465,7 @@ etekcity_read_button(struct ratbag_button *button)
button->index, button->profile->index,
rc < 0 ? strerror(-rc) : "not read enough", rc);
} else {
ratbag_button_set_macro(button, macro->name);
m = ratbag_button_macro_new(macro->name);
log_raw(device->ratbag,
"macro on button %d of profile %d is named '%s', and contains %d events:\n",
button->index, button->profile->index,
@@ -472,7 +473,7 @@ etekcity_read_button(struct ratbag_button *button)
for (j = 0; j < macro->length; j++) {
unsigned int keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
macro->keys[j].keycode);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
j,
macro->keys[j].flag & 0x80 ? RATBAG_MACRO_EVENT_KEY_RELEASED : RATBAG_MACRO_EVENT_KEY_PRESSED,
keycode);
@@ -481,6 +482,8 @@ etekcity_read_button(struct ratbag_button *button)
libevdev_event_code_get_name(EV_KEY, keycode),
macro->keys[j].flag & 0x80 ? "released" : "pressed");
}
ratbag_button_copy_macro(button, m);
ratbag_button_macro_unref(m);
}
msleep(10);
}

View File

@@ -76,6 +76,7 @@ hidpp10drv_read_macro(struct ratbag_button *button,
union hidpp10_button *binding)
{
struct ratbag_device *device = button->profile->device;
struct ratbag_button_macro *m;
const char *name;
union hidpp10_macro_data *macro;
unsigned int i, keycode;
@@ -84,13 +85,13 @@ hidpp10drv_read_macro(struct ratbag_button *button,
macro = profile->macros[binding->macro.address];
name = binding->macro.address > 1 ? (const char *)profile->macro_names[binding->macro.address - 2] : "";
ratbag_button_set_macro(button, name);
i = 0;
m = ratbag_button_macro_new(name);
while (macro && macro->any.type != HIDPP10_MACRO_END && i < MAX_MACRO_EVENTS) {
switch (macro->any.type) {
case HIDPP10_MACRO_DELAY:
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
macro->delay.time);
@@ -99,11 +100,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
case HIDPP10_MACRO_KEY_PRESS:
keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device, macro->key.key);
if (!delay)
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
1);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_KEY_PRESSED,
keycode);
@@ -112,11 +113,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
case HIDPP10_MACRO_KEY_RELEASE:
keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device, macro->key.key);
if (!delay)
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
1);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_KEY_RELEASED,
keycode);
@@ -125,11 +126,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
case HIDPP10_MACRO_MOD_PRESS:
keycode = hidpp10drv_read_macro_modifier(device, macro);
if (!delay)
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
1);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_KEY_PRESSED,
keycode);
@@ -138,11 +139,11 @@ hidpp10drv_read_macro(struct ratbag_button *button,
case HIDPP10_MACRO_MOD_RELEASE:
keycode = hidpp10drv_read_macro_modifier(device, macro);
if (!delay)
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
1);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_KEY_RELEASED,
keycode);
@@ -151,6 +152,9 @@ hidpp10drv_read_macro(struct ratbag_button *button,
}
macro++;
}
ratbag_button_copy_macro(button, m);
ratbag_button_macro_unref(m);
}
static void

View File

@@ -123,32 +123,34 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
union hidpp20_button_binding *binding)
{
struct ratbag_device *device = button->profile->device;
struct ratbag_button_macro *m;
union hidpp20_macro_data *macro;
unsigned int i, keycode;
bool delay = true;
macro = profile->macros[binding->macro.page];
ratbag_button_set_macro(button, "macro");
i = 0;
m = ratbag_button_macro_new("macro");
while (macro && macro->any.type != HIDPP20_MACRO_END && i < MAX_MACRO_EVENTS) {
switch (macro->any.type) {
case HIDPP20_MACRO_DELAY:
ratbag_button_set_macro_event(button,
i++,
RATBAG_MACRO_EVENT_WAIT,
macro->delay.time);
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
macro->delay.time);
delay = true;
break;
case HIDPP20_MACRO_KEY_PRESS:
keycode = hidpp20drv_read_macro_key_8100(device, macro);
if (!delay)
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
1);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_KEY_PRESSED,
keycode);
@@ -157,11 +159,11 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
case HIDPP20_MACRO_KEY_RELEASE:
keycode = hidpp20drv_read_macro_key_8100(device, macro);
if (!delay)
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_WAIT,
1);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i++,
RATBAG_MACRO_EVENT_KEY_RELEASED,
keycode);
@@ -170,6 +172,9 @@ hidpp20drv_read_macro_8100(struct ratbag_button *button,
}
macro++;
}
ratbag_button_copy_macro(button, m);
ratbag_button_macro_unref(m);
}
static void

View File

@@ -532,6 +532,7 @@ roccat_read_button(struct ratbag_button *button)
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
if (action && action->type == RATBAG_BUTTON_ACTION_TYPE_MACRO) {
struct ratbag_button_macro *m = NULL;
roccat_set_config_profile(device,
button->profile->index,
@@ -566,7 +567,7 @@ roccat_read_button(struct ratbag_button *button)
goto out_macro;
}
ratbag_button_set_macro(button, macro->name);
m = ratbag_button_macro_new(macro->name);
log_raw(device->ratbag,
"macro on button %d of profile %d is named '%s', and contains %d events:\n",
button->index, button->profile->index,
@@ -574,7 +575,7 @@ roccat_read_button(struct ratbag_button *button)
for (j = 0; j < macro->length; j++) {
unsigned int keycode = ratbag_hidraw_get_keycode_from_keyboard_usage(device,
macro->keys[j].keycode);
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
j * 2,
macro->keys[j].flag & 0x01 ? RATBAG_MACRO_EVENT_KEY_PRESSED : RATBAG_MACRO_EVENT_KEY_RELEASED,
keycode);
@@ -582,7 +583,7 @@ roccat_read_button(struct ratbag_button *button)
time = macro->keys[j].time;
else
time = macro->keys[j].flag & 0x01 ? 10 : 50;
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
j * 2 + 1,
RATBAG_MACRO_EVENT_WAIT,
time);
@@ -592,9 +593,11 @@ roccat_read_button(struct ratbag_button *button)
libevdev_event_code_get_name(EV_KEY, keycode),
macro->keys[j].flag & 0x80 ? "released" : "pressed");
}
ratbag_button_copy_macro(button, m);
}
out_macro:
msleep(10);
ratbag_button_macro_unref(m);
}
}

View File

@@ -250,6 +250,11 @@ struct ratbag_macro {
struct ratbag_macro_event events[MAX_MACRO_EVENTS];
};
struct ratbag_button_macro {
int refcount;
struct ratbag_macro macro;
};
struct ratbag_button_action {
enum ratbag_button_action_type type;
union ratbag_btn_action {
@@ -432,5 +437,9 @@ ratbag_assign_driver(struct ratbag_device *device,
void
ratbag_register_driver(struct ratbag *ratbag, struct ratbag_driver *driver);
void
ratbag_button_copy_macro(struct ratbag_button *button,
const struct ratbag_button_macro *macro);
#endif /* LIBRATBAG_PRIVATE_H */

View File

@@ -1161,8 +1161,25 @@ ratbag_resolution_get_user_data(const struct ratbag_resolution *ratbag_resolutio
return ratbag_resolution->userdata;
}
LIBRATBAG_EXPORT enum ratbag_error_code
ratbag_button_set_macro(struct ratbag_button *button, const char *name)
LIBRATBAG_EXPORT struct ratbag_button_macro *
ratbag_button_get_macro(struct ratbag_button *button)
{
struct ratbag_button_macro *macro;
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO)
return NULL;
macro = ratbag_button_macro_new(button->action.macro->name);
memcpy(macro->macro.events,
button->action.macro->events,
sizeof(macro->macro.events));
return macro;
}
void
ratbag_button_copy_macro(struct ratbag_button *button,
const struct ratbag_button_macro *macro)
{
if (!button->action.macro)
button->action.macro = zalloc(sizeof(struct ratbag_macro));
@@ -1173,25 +1190,37 @@ ratbag_button_set_macro(struct ratbag_button *button, const char *name)
}
button->action.type = RATBAG_BUTTON_ACTION_TYPE_MACRO;
button->action.macro->name = strdup_safe(name);
return RATBAG_SUCCESS;
memcpy(button->action.macro->events,
macro->macro.events,
sizeof(macro->macro.events));
button->action.macro->name = strdup_safe(macro->macro.name);
button->action.macro->group = strdup_safe(macro->macro.group);
}
LIBRATBAG_EXPORT enum ratbag_error_code
ratbag_button_set_macro_event(struct ratbag_button *button,
ratbag_button_set_macro(struct ratbag_button *button,
const struct ratbag_button_macro *macro)
{
int rc;
ratbag_button_copy_macro(button, macro);
rc = button->profile->device->driver->write_button(button, &button->action);
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
}
LIBRATBAG_EXPORT enum ratbag_error_code
ratbag_button_macro_set_event(struct ratbag_button_macro *m,
unsigned int index,
enum ratbag_macro_event_type type,
unsigned int data)
{
struct ratbag_macro *macro;
struct ratbag_macro *macro = &m->macro;
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
index >= MAX_MACRO_EVENTS)
if (index >= MAX_MACRO_EVENTS)
return RATBAG_ERROR_VALUE;
macro = button->action.macro;
switch (type) {
case RATBAG_MACRO_EVENT_KEY_PRESSED:
case RATBAG_MACRO_EVENT_KEY_RELEASED:
@@ -1212,36 +1241,22 @@ ratbag_button_set_macro_event(struct ratbag_button *button,
return 0;
}
LIBRATBAG_EXPORT enum ratbag_error_code
ratbag_button_write_macro(struct ratbag_button *button)
{
int rc;
rc = button->profile->device->driver->write_button(button, &button->action);
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
}
LIBRATBAG_EXPORT enum ratbag_macro_event_type
ratbag_button_get_macro_event_type(struct ratbag_button *button, unsigned int index)
ratbag_button_macro_get_event_type(struct ratbag_button_macro *macro, unsigned int index)
{
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
index >= MAX_MACRO_EVENTS)
if (index >= MAX_MACRO_EVENTS)
return RATBAG_MACRO_EVENT_INVALID;
return button->action.macro->events[index].type;
return macro->macro.events[index].type;
}
LIBRATBAG_EXPORT int
ratbag_button_get_macro_event_key(struct ratbag_button *button, unsigned int index)
ratbag_button_macro_get_event_key(struct ratbag_button_macro *m, unsigned int index)
{
struct ratbag_macro *macro;
struct ratbag_macro *macro = &m->macro;
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
index >= MAX_MACRO_EVENTS)
return -EINVAL;
macro = button->action.macro;
if (index >= MAX_MACRO_EVENTS)
return 0;
if (macro->events[index].type != RATBAG_MACRO_EVENT_KEY_PRESSED &&
macro->events[index].type != RATBAG_MACRO_EVENT_KEY_RELEASED)
@@ -1251,27 +1266,72 @@ ratbag_button_get_macro_event_key(struct ratbag_button *button, unsigned int ind
}
LIBRATBAG_EXPORT int
ratbag_button_get_macro_event_timeout(struct ratbag_button *button, unsigned int index)
ratbag_button_macro_get_event_timeout(struct ratbag_button_macro *m,
unsigned int index)
{
struct ratbag_macro *macro;
struct ratbag_macro *macro = &m->macro;
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
index >= MAX_MACRO_EVENTS)
return -EINVAL;
macro = button->action.macro;
if (index >= MAX_MACRO_EVENTS)
return 0;
if (macro->events[index].type != RATBAG_MACRO_EVENT_WAIT)
return -EINVAL;
return 0;
return macro->events[index].event.timeout;
}
LIBRATBAG_EXPORT const char *
ratbag_button_get_macro_name(struct ratbag_button *button)
LIBRATBAG_EXPORT unsigned int
ratbag_button_macro_get_num_events(struct ratbag_button_macro *macro)
{
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO)
return MAX_MACRO_EVENTS;
}
LIBRATBAG_EXPORT const char *
ratbag_button_macro_get_name(struct ratbag_button_macro *macro)
{
return macro->macro.name;
}
static void
ratbag_button_macro_destroy(struct ratbag_button_macro *macro)
{
assert(macro->refcount == 0);
free(macro->macro.name);
free(macro->macro.group);
free(macro);
}
LIBRATBAG_EXPORT struct ratbag_button_macro *
ratbag_button_macro_ref(struct ratbag_button_macro *macro)
{
assert(macro->refcount < INT_MAX);
macro->refcount++;
return macro;
}
LIBRATBAG_EXPORT struct ratbag_button_macro *
ratbag_button_macro_unref(struct ratbag_button_macro *macro)
{
if (macro == NULL)
return NULL;
return button->action.macro->name;
assert(macro->refcount > 0);
macro->refcount--;
if (macro->refcount == 0)
ratbag_button_macro_destroy(macro);
return NULL;
}
LIBRATBAG_EXPORT struct ratbag_button_macro *
ratbag_button_macro_new(const char *name)
{
struct ratbag_button_macro *macro;
macro = zalloc(sizeof *macro);
macro->refcount = 1;
macro->macro.name = strdup_safe(name);
return macro;
}

View File

@@ -125,6 +125,17 @@ struct ratbag_button;
*/
struct ratbag_resolution;
/**
* @ingroup button
* @struct ratbag_macro
*
* Represents a macro that can be assigned to a button.
*
* This struct is refcounted, use ratbag_button_macro_ref() and
* ratbag_button_macro_unref().
*/
struct ratbag_button_macro;
/**
* @ingroup base
*
@@ -1327,101 +1338,175 @@ enum ratbag_macro_event_type {
/**
* @ingroup button
*
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* this function returns the macro name.
* @param macro A previously initialized ratbag button macro
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* this function returns NULL.
*
* @param button A previously initialized ratbag button
*
* @return The name of the macro associated to the button.
* @return The name of the macro
*/
const char *
ratbag_button_get_macro_name(struct ratbag_button *button);
ratbag_button_macro_get_name(struct ratbag_button_macro *macro);
/**
* @ingroup button
*
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* this function returns the macro event type configured for the event at the
* @param macro A previously initialized ratbag button macro
*
* @return The maximum number of events that can be assigned to this macro
*/
unsigned int
ratbag_button_macro_get_num_events(struct ratbag_button_macro *macro);
/**
* @ingroup button
*
* Returns the macro event type configured for the event at the
* given index.
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* this function returns @ref RATBAG_MACRO_EVENT_INVALID.
* The behavior of this function for an index equal to or greater than the
* return value of ratbag_button_macro_get_num_events() is undefined.
*
* @param button A previously initialized ratbag button
* @param macro A previously initialized ratbag button macro
* @param index An index of the event within the macro we are interested in.
*
* @return The type of the event at the given index
*/
enum ratbag_macro_event_type
ratbag_button_get_macro_event_type(struct ratbag_button *button, unsigned int index);
ratbag_button_macro_get_event_type(struct ratbag_button_macro *macro,
unsigned int index);
/**
* @ingroup button
*
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO, and if the
* event stored at the given index is @ref RATBAG_MACRO_EVENT_KEY_PRESSED or
* @ref RATBAG_MACRO_EVENT_KEY_RELEASED, this function returns the key code
* configured for the event at the given index.
* If the event stored at the given index is @ref
* RATBAG_MACRO_EVENT_KEY_PRESSED or @ref RATBAG_MACRO_EVENT_KEY_RELEASED,
* this function returns the key code configured for the event at the given
* index.
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* or if the event stored at the given index is not
* @ref RATBAG_MACRO_EVENT_KEY_PRESSED or @ref RATBAG_MACRO_EVENT_KEY_RELEASED,
* this function returns -EINVAL.
* The behavior of this function for an index equal to or greater than the
* return value of ratbag_button_macro_get_num_events() is undefined.
*
* @param button A previously initialized ratbag button
* @param macro A previously initialized ratbag button macro
* @param index An index of the event within the macro we are interested in.
*
* @return The key of the event at the given index
*/
int
ratbag_button_get_macro_event_key(struct ratbag_button *button, unsigned int index);
ratbag_button_macro_get_event_key(struct ratbag_button_macro*macro,
unsigned int index);
/**
* @ingroup button
*
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO, and if the
* event stored at the given index is @ref RATBAG_MACRO_EVENT_WAIT, this
* function returns the timeout configured for the event at the given index.
* If the event stored at the given index is @ref RATBAG_MACRO_EVENT_WAIT,
* this function returns the timeout configured for the event at the given
* index.
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* or if the event stored at the given index is not
* @ref RATBAG_MACRO_EVENT_WAIT, this function returns -EINVAL.
* The behavior of this function for an index equal to or greater than the
* return value of ratbag_button_macro_get_num_events() is undefined.
*
* @param button A previously initialized ratbag button
* @param macro A previously initialized ratbag button macro
* @param index An index of the event within the macro we are interested in.
*
* @return The timeout of the event at the given index
*/
int
ratbag_button_get_macro_event_timeout(struct ratbag_button *button, unsigned int index);
ratbag_button_macro_get_event_timeout(struct ratbag_button_macro *macro,
unsigned int index);
/**
* @ingroup button
*
* Sets the button's action to @ref RATBAG_BUTTON_ACTION_TYPE_MACRO and
* allocates the required memory to store the macro.
* assigns the given macro to this button.
*
* libratbag does not use the macro struct passed in, it extracts the
* required information from the struct. Changes to the macro after a call
* to ratbag_button_set_macro() are not reflected in the device until a
* subsequent call to ratbag_button_set_macro().
*
* @param button A previously intialized ratbag button
* @param macro A fully initialized macro
*
* @return 0 on success or nonzero otherwise
*/
enum ratbag_error_code
ratbag_button_set_macro(struct ratbag_button *button, const char *name);
ratbag_button_set_macro(struct ratbag_button *button,
const struct ratbag_button_macro *macro);
enum ratbag_error_code
ratbag_button_write_macro(struct ratbag_button *button);
/**
* @ingroup button
*
* Initialize a new button macro.
*
* The macro is refcounted with an initial value of at least 1.
* Use ratbag_button_macro_unref() to release the macro.
*
* Note that some devices have limited storage for the macro names.
* libratbag silently shortens macro names to the longest string the device
* is capable of storing.
*
* @param name The name to assign to this macro.
*
* @return An "empty" button macro
*/
struct ratbag_button_macro *
ratbag_button_macro_new(const char *name);
/**
* @ingroup button
*
* If a button's action is @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* this function returns the current button macro. The macro is a copy of
* the one used on the device, changes to the macro are not reflected on the
* device until a subsequent call to ratbag_button_set_macro().
*
* If a button's action is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
* this function returns NULL.
*
* @param button A previously initialized ratbag button
*/
struct ratbag_button_macro *
ratbag_button_get_macro(struct ratbag_button *button);
/**
* @ingroup button
*
* Sets the macro's event at the given index to the given type with the
* key code or timeout given.
*
* The behavior of this function for an index equal to or greater than the
* return value of ratbag_button_macro_get_num_events() is undefined.
*/
enum ratbag_error_code
ratbag_button_set_macro_event(struct ratbag_button *button,
ratbag_button_macro_set_event(struct ratbag_button_macro *macro,
unsigned int index,
enum ratbag_macro_event_type type,
unsigned int data);
/**
* @ingroup button
*
* Add a reference to the macro. A macro is destroyed whenever the
* reference count reaches 0. See @ref ratbag_button_macro_unref.
*
* @param macro A previously initialized valid ratbag button macro
* @return The passed ratbag macro
*/
struct ratbag_button_macro *
ratbag_button_macro_ref(struct ratbag_button_macro *macro);
/**
* @ingroup button
*
* Dereference the ratbag button macro. When the internal refcount reaches
* zero, all resources associated with this object are released. The object
* must be considered invalid once unref is called.
*
* @param macro A previously initialized ratbag button macro
* @return Always NULL
*/
struct ratbag_button_macro *
ratbag_button_macro_unref(struct ratbag_button_macro *macro);
/**
* @ingroup button
*

View File

@@ -8,22 +8,26 @@ global:
ratbag_button_get_type;
ratbag_button_get_button;
ratbag_button_get_key;
ratbag_button_get_macro_event_type;
ratbag_button_get_macro_event_key;
ratbag_button_get_macro_event_timeout;
ratbag_button_get_macro_name;
ratbag_button_get_macro;
ratbag_button_get_special;
ratbag_button_get_user_data;
ratbag_button_has_action_type;
ratbag_button_macro_get_event_key;
ratbag_button_macro_get_event_timeout;
ratbag_button_macro_get_event_type;
ratbag_button_macro_get_name;
ratbag_button_macro_get_num_events;
ratbag_button_macro_new;
ratbag_button_macro_ref;
ratbag_button_macro_set_event;
ratbag_button_macro_unref;
ratbag_button_ref;
ratbag_button_set_button;
ratbag_button_set_key;
ratbag_button_set_macro;
ratbag_button_set_macro_event;
ratbag_button_set_special;
ratbag_button_set_user_data;
ratbag_button_unref;
ratbag_button_write_macro;
ratbag_device_get_name;
ratbag_device_get_num_buttons;
ratbag_device_get_num_profiles;

View File

@@ -556,6 +556,7 @@ ratbag_cmd_change_button(const struct ratbag_cmd *cmd,
struct ratbag_device *device;
struct ratbag_button *button = NULL;
struct ratbag_profile *profile = NULL;
struct ratbag_button_macro *m = NULL;
int button_index;
enum ratbag_button_action_type action_type;
int rc = ERR_DEVICE;
@@ -630,17 +631,18 @@ ratbag_cmd_change_button(const struct ratbag_cmd *cmd,
rc = ratbag_button_set_special(button, special);
break;
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
rc = ratbag_button_set_macro(button, macro.name);
m = ratbag_button_macro_new(macro.name);
for (i = 0; i < ARRAY_LENGTH(macro.events); i++) {
if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE)
break;
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i,
macro.events[i].type,
macro.events[i].data);
}
rc = ratbag_button_write_macro(button);
rc = ratbag_button_set_macro(button, m);
ratbag_button_macro_unref(m);
break;
default:
error("well, that shouldn't have happened\n");
@@ -1265,6 +1267,7 @@ ratbag_cmd_button_set_macro(const struct ratbag_cmd *cmd,
{
struct ratbag_device *device;
struct ratbag_button *button;
struct ratbag_button_macro *m;
struct macro macro = {0};
int rc;
int i;
@@ -1289,17 +1292,18 @@ ratbag_cmd_button_set_macro(const struct ratbag_cmd *cmd,
return ERR_UNSUPPORTED;
button = options->button;
rc = ratbag_button_set_macro(button, macro.name);
m = ratbag_button_macro_new(macro.name);
for (i = 0; i < ARRAY_LENGTH(macro.events); i++) {
if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE)
break;
ratbag_button_set_macro_event(button,
ratbag_button_macro_set_event(m,
i,
macro.events[i].type,
macro.events[i].data);
}
rc = ratbag_button_write_macro(button);
rc = ratbag_button_set_macro(button, m);
ratbag_button_macro_unref(m);
if (rc != 0)
return ERR_DEVICE;

View File

@@ -174,18 +174,20 @@ static const char *strip_ev_key(int key)
char *
button_action_macro_to_str(struct ratbag_button *button)
{
struct ratbag_button_macro *macro;
char str[4096] = {0};
const char *name;
int offset;
unsigned int i;
name = ratbag_button_get_macro_name(button);
macro = ratbag_button_get_macro(button);
name = ratbag_button_macro_get_name(macro);
offset = snprintf(str, sizeof(str), "macro \"%s\":",
name ? name : "UNKNOWN");
for (i = 0; i < MAX_MACRO_EVENTS; i++) {
enum ratbag_macro_event_type type = ratbag_button_get_macro_event_type(button, i);
int key = ratbag_button_get_macro_event_key(button, i);
int timeout = ratbag_button_get_macro_event_timeout(button, i);
enum ratbag_macro_event_type type = ratbag_button_macro_get_event_type(macro, i);
int key = ratbag_button_macro_get_event_key(macro, i);
int timeout = ratbag_button_macro_get_event_timeout(macro, i);
if (type == RATBAG_MACRO_EVENT_NONE)
break;
@@ -205,6 +207,8 @@ button_action_macro_to_str(struct ratbag_button *button)
}
}
ratbag_button_macro_unref(macro);
return strdup_safe(str);
}