forked from drath/libratbag
macro: add first implementation
The doctext needs fixes and the API might not be final. This however works and allow to read the macro. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
@@ -598,15 +598,20 @@ etekcity_read_button(struct ratbag_button *button)
|
||||
button->index, button->profile->index,
|
||||
rc < 0 ? strerror(-rc) : "not read enough", rc);
|
||||
} else {
|
||||
log_info(device->ratbag,
|
||||
"macro on button %d of profile %d is named '%s', and contains %d events:\n",
|
||||
button->index, button->profile->index,
|
||||
macro->name, macro->length);
|
||||
ratbag_button_set_macro(button);
|
||||
log_raw(device->ratbag,
|
||||
"macro on button %d of profile %d is named '%s', and contains %d events:\n",
|
||||
button->index, button->profile->index,
|
||||
macro->name, macro->length);
|
||||
for (j = 0; j < macro->length; j++) {
|
||||
log_info(device->ratbag,
|
||||
" - %s %s\n",
|
||||
libevdev_event_code_get_name(EV_KEY, macro_mapping[macro->keys[j].keycode]),
|
||||
macro->keys[j].flag & 0x80 ? "released" : "pressed");
|
||||
ratbag_button_set_macro_event(button,
|
||||
j,
|
||||
macro->keys[j].flag & 0x80 ? RATBAG_MACRO_EVENT_KEY_RELEASED : RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
macro_mapping[macro->keys[j].keycode]);
|
||||
log_raw(device->ratbag,
|
||||
" - %s %s\n",
|
||||
libevdev_event_code_get_name(EV_KEY, macro_mapping[macro->keys[j].keycode]),
|
||||
macro->keys[j].flag & 0x80 ? "released" : "pressed");
|
||||
}
|
||||
}
|
||||
msleep(10);
|
||||
|
||||
@@ -247,6 +247,21 @@ struct ratbag_profile {
|
||||
{ .type = RATBAG_BUTTON_ACTION_TYPE_MACRO, \
|
||||
/* FIXME: add the macro keys */ }
|
||||
|
||||
struct ratbag_macro_event {
|
||||
enum ratbag_macro_event_type type;
|
||||
union ratbag_macro_evnt {
|
||||
unsigned int key;
|
||||
unsigned int timeout;
|
||||
} event;
|
||||
};
|
||||
|
||||
#define MAX_MACRO_EVENTS 64
|
||||
struct ratbag_macro {
|
||||
const char *name;
|
||||
const char *group;
|
||||
struct ratbag_macro_event events[MAX_MACRO_EVENTS];
|
||||
};
|
||||
|
||||
struct ratbag_button_action {
|
||||
enum ratbag_button_action_type type;
|
||||
union ratbag_btn_action {
|
||||
@@ -256,8 +271,8 @@ struct ratbag_button_action {
|
||||
unsigned int key; /* action_type == key */
|
||||
/* FIXME: modifiers */
|
||||
} key;
|
||||
/* FIXME: MACRO */
|
||||
} action;
|
||||
struct ratbag_macro *macro; /* dynamically allocated, so kept aside */
|
||||
};
|
||||
|
||||
struct ratbag_button {
|
||||
@@ -338,7 +353,7 @@ ratbag_button_action_match(const struct ratbag_button_action *action,
|
||||
case RATBAG_BUTTON_ACTION_TYPE_SPECIAL:
|
||||
return match->action.special == action->action.special;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO:
|
||||
/* FIXME: currently, do nothing */
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1204,6 +1204,8 @@ static void
|
||||
ratbag_button_destroy(struct ratbag_button *button)
|
||||
{
|
||||
list_remove(&button->link);
|
||||
if (button->action.macro)
|
||||
free(button->action.macro);
|
||||
free(button);
|
||||
}
|
||||
|
||||
@@ -1284,3 +1286,97 @@ ratbag_resolution_get_user_data(const struct ratbag_resolution *ratbag_resolutio
|
||||
{
|
||||
return ratbag_resolution->userdata;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_button_set_macro(struct ratbag_button *button)
|
||||
{
|
||||
struct ratbag_macro *macro;
|
||||
|
||||
if (!button->action.macro)
|
||||
button->action.macro = zalloc(sizeof(*macro));
|
||||
else
|
||||
memset(button->action.macro, 0, sizeof(*macro));
|
||||
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_MACRO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_button_set_macro_event(struct ratbag_button *button,
|
||||
unsigned int index,
|
||||
enum ratbag_macro_event_type type,
|
||||
unsigned int data)
|
||||
{
|
||||
struct ratbag_macro *macro;
|
||||
|
||||
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
|
||||
index >= MAX_MACRO_EVENTS)
|
||||
return -EINVAL;
|
||||
|
||||
macro = button->action.macro;
|
||||
|
||||
switch (type) {
|
||||
case RATBAG_MACRO_EVENT_KEY_PRESSED:
|
||||
case RATBAG_MACRO_EVENT_KEY_RELEASED:
|
||||
macro->events[index].type = type;
|
||||
macro->events[index].event.key = data;
|
||||
break;
|
||||
case RATBAG_MACRO_EVENT_WAIT:
|
||||
macro->events[index].type = type;
|
||||
macro->events[index].event.timeout = data;
|
||||
break;
|
||||
case RATBAG_MACRO_EVENT_NONE:
|
||||
macro->events[index].type = type;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_macro_event_type
|
||||
ratbag_button_get_macro_event_type(struct ratbag_button *button, unsigned int index)
|
||||
{
|
||||
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
|
||||
index >= MAX_MACRO_EVENTS)
|
||||
return RATBAG_MACRO_EVENT_INVALID;
|
||||
|
||||
return button->action.macro->events[index].type;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_button_get_macro_event_key(struct ratbag_button *button, unsigned int index)
|
||||
{
|
||||
struct ratbag_macro *macro;
|
||||
|
||||
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
|
||||
index >= MAX_MACRO_EVENTS)
|
||||
return -EINVAL;
|
||||
|
||||
macro = button->action.macro;
|
||||
|
||||
if (macro->events[index].type != RATBAG_MACRO_EVENT_KEY_PRESSED &&
|
||||
macro->events[index].type != RATBAG_MACRO_EVENT_KEY_RELEASED)
|
||||
return -EINVAL;
|
||||
|
||||
return macro->events[index].event.key;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_button_get_macro_event_timeout(struct ratbag_button *button, unsigned int index)
|
||||
{
|
||||
struct ratbag_macro *macro;
|
||||
|
||||
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO ||
|
||||
index >= MAX_MACRO_EVENTS)
|
||||
return -EINVAL;
|
||||
|
||||
macro = button->action.macro;
|
||||
|
||||
if (macro->events[index].type != RATBAG_MACRO_EVENT_WAIT)
|
||||
return -EINVAL;
|
||||
|
||||
return macro->events[index].event.timeout;
|
||||
}
|
||||
|
||||
@@ -1259,19 +1259,95 @@ ratbag_button_disable(struct ratbag_button *button);
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* FIXME: no idea at this point
|
||||
* Macro event types describing the event.
|
||||
*/
|
||||
unsigned int
|
||||
ratbag_button_get_macro(struct ratbag_button *button);
|
||||
enum ratbag_macro_event_type {
|
||||
RATBAG_MACRO_EVENT_INVALID = -1,
|
||||
RATBAG_MACRO_EVENT_NONE = 0,
|
||||
RATBAG_MACRO_EVENT_KEY_PRESSED,
|
||||
RATBAG_MACRO_EVENT_KEY_RELEASED,
|
||||
RATBAG_MACRO_EVENT_WAIT,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
* FIXME: no idea at this point
|
||||
* 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
|
||||
* given index.
|
||||
*
|
||||
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_MACRO,
|
||||
* this function returns @ref RATBAG_MACRO_EVENT_INVALID.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param index An index of the event within the macro we are interested in.
|
||||
*
|
||||
* @return The type of the event at the given index
|
||||
*/
|
||||
unsigned int
|
||||
enum ratbag_macro_event_type
|
||||
ratbag_button_get_macro_event_type(struct ratbag_button *button, 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 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.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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 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.
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param index An index of the event within the macro we are interested in.
|
||||
*
|
||||
* @return The tiemout of the event at the given index
|
||||
*/
|
||||
int
|
||||
ratbag_button_get_macro_event_timeout(struct ratbag_button *button, 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.
|
||||
*/
|
||||
int
|
||||
ratbag_button_set_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.
|
||||
*/
|
||||
int
|
||||
ratbag_button_set_macro_event(struct ratbag_button *button,
|
||||
unsigned int index,
|
||||
enum ratbag_macro_event_type type,
|
||||
unsigned int data);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
|
||||
@@ -8,12 +8,17 @@ 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_special;
|
||||
ratbag_button_get_user_data;
|
||||
ratbag_button_has_action_type;
|
||||
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;
|
||||
|
||||
@@ -145,6 +145,48 @@ button_action_key_to_str(struct ratbag_button *button)
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
static const char *strip_ev_key(int key)
|
||||
{
|
||||
const char *str = libevdev_event_code_get_name(EV_KEY, key);
|
||||
|
||||
if (!strncmp(str, "KEY_", 4))
|
||||
return str + 4;
|
||||
return str;
|
||||
};
|
||||
|
||||
char *
|
||||
button_action_macro_to_str(struct ratbag_button *button)
|
||||
{
|
||||
char str[4096] = {0};
|
||||
int offset;
|
||||
unsigned int i;
|
||||
|
||||
offset = snprintf(str, sizeof(str), "macro:");
|
||||
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);
|
||||
|
||||
if (type == RATBAG_MACRO_EVENT_NONE)
|
||||
break;
|
||||
|
||||
switch (type) {
|
||||
case RATBAG_MACRO_EVENT_KEY_PRESSED:
|
||||
offset += snprintf(str + offset, sizeof(str) - offset, " %s↓", strip_ev_key(key));
|
||||
break;
|
||||
case RATBAG_MACRO_EVENT_KEY_RELEASED:
|
||||
offset += snprintf(str + offset, sizeof(str) - offset, " %s↑", strip_ev_key(key));
|
||||
break;
|
||||
case RATBAG_MACRO_EVENT_WAIT:
|
||||
offset += snprintf(str + offset, sizeof(str) - offset, " %d.%d⏱", timeout / 1000, timeout % 1000);
|
||||
default:
|
||||
offset += snprintf(str + offset, sizeof(str) - offset, " ###");
|
||||
}
|
||||
}
|
||||
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
char *
|
||||
button_action_to_str(struct ratbag_button *button)
|
||||
{
|
||||
@@ -157,7 +199,7 @@ button_action_to_str(struct ratbag_button *button)
|
||||
case RATBAG_BUTTON_ACTION_TYPE_BUTTON: str = button_action_button_to_str(button); break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_KEY: str = button_action_key_to_str(button); break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_SPECIAL: str = strdup(button_action_special_to_str(button)); break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO: str = strdup("macro"); break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_MACRO: str = button_action_macro_to_str(button); break;
|
||||
case RATBAG_BUTTON_ACTION_TYPE_NONE: str = strdup("none"); break;
|
||||
default:
|
||||
error("type %d unknown\n", type);
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#include <libratbag-util.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
|
||||
#define MAX_MACRO_EVENTS 64
|
||||
|
||||
LIBRATBAG_ATTRIBUTE_PRINTF(1, 2)
|
||||
static inline void
|
||||
error(const char *format, ...)
|
||||
|
||||
Reference in New Issue
Block a user