forked from drath/libratbag
Merge pull request #74 from whot/wip/macro-rewrite
Rewrite the macro API, which contains PR #72 (Some more cleanup) and PR #73 (Use error enums)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -424,13 +429,17 @@ const char *
|
||||
ratbag_device_get_udev_property(const struct ratbag_device* device,
|
||||
const char *name);
|
||||
|
||||
struct ratbag_driver *
|
||||
ratbag_find_driver(struct ratbag_device *device,
|
||||
const struct input_id *dev_id,
|
||||
struct ratbag_test_device *test_device);
|
||||
bool
|
||||
ratbag_assign_driver(struct ratbag_device *device,
|
||||
const struct input_id *dev_id,
|
||||
struct ratbag_test_device *test_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 */
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ ratbag_device_new_test_device(struct ratbag *ratbag,
|
||||
|
||||
device = ratbag_device_new(ratbag, NULL, "Test device", &id);
|
||||
|
||||
if (!ratbag_find_driver(device, &device->ids, test_device)) {
|
||||
if (!ratbag_assign_driver(device, &device->ids, test_device)) {
|
||||
ratbag_device_destroy(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
324
src/libratbag.c
324
src/libratbag.c
@@ -37,6 +37,23 @@
|
||||
#include "libratbag-private.h"
|
||||
#include "libratbag-util.h"
|
||||
|
||||
static enum ratbag_error_code
|
||||
error_code(enum ratbag_error_code code)
|
||||
{
|
||||
switch(code) {
|
||||
case RATBAG_SUCCESS:
|
||||
case RATBAG_ERROR_DEVICE:
|
||||
case RATBAG_ERROR_CAPABILITY:
|
||||
case RATBAG_ERROR_VALUE:
|
||||
case RATBAG_ERROR_SYSTEM:
|
||||
case RATBAG_ERROR_IMPLEMENTATION:
|
||||
break;
|
||||
default:
|
||||
assert(!"Invalid error code. This is a library bug.");
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static void
|
||||
ratbag_profile_destroy(struct ratbag_profile *profile);
|
||||
static void
|
||||
@@ -266,10 +283,10 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct ratbag_driver *
|
||||
ratbag_find_driver(struct ratbag_device *device,
|
||||
const struct input_id *dev_id,
|
||||
struct ratbag_test_device *test_device)
|
||||
bool
|
||||
ratbag_assign_driver(struct ratbag_device *device,
|
||||
const struct input_id *dev_id,
|
||||
struct ratbag_test_device *test_device)
|
||||
{
|
||||
struct ratbag *ratbag = device->ratbag;
|
||||
struct ratbag_driver *driver;
|
||||
@@ -279,7 +296,7 @@ ratbag_find_driver(struct ratbag_device *device,
|
||||
if (!test_device) {
|
||||
driver_name = udev_prop_value(device->udev_device, "RATBAG_DRIVER");
|
||||
if (!driver_name)
|
||||
return NULL;
|
||||
return false;
|
||||
} else {
|
||||
driver_name = "test_driver";
|
||||
}
|
||||
@@ -294,7 +311,7 @@ ratbag_find_driver(struct ratbag_device *device,
|
||||
if (!device->driver) {
|
||||
log_error(ratbag, "%s: driver '%s' does not exist\n",
|
||||
device->name, driver_name);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test_device)
|
||||
@@ -303,21 +320,19 @@ ratbag_find_driver(struct ratbag_device *device,
|
||||
rc = device->driver->probe(device);
|
||||
if (rc == 0) {
|
||||
if (!ratbag_sanity_check_device(device)) {
|
||||
return NULL;
|
||||
return false;
|
||||
} else {
|
||||
log_debug(ratbag, "driver match found: %s\n", driver->name);
|
||||
return device->driver;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
device->driver = NULL;
|
||||
|
||||
if (rc == -ENODEV) {
|
||||
if (rc == -ENODEV)
|
||||
log_error(ratbag, "%s: no hidraw device found\n", device->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline char*
|
||||
@@ -353,52 +368,44 @@ get_product_id(struct udev_device *device, struct input_id *id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_device*
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_device_new_from_udev_device(struct ratbag *ratbag,
|
||||
struct udev_device *udev_device)
|
||||
struct udev_device *udev_device,
|
||||
struct ratbag_device **device_out)
|
||||
{
|
||||
struct ratbag_device *device = NULL;
|
||||
struct ratbag_driver *driver;
|
||||
char *name = NULL;
|
||||
enum ratbag_error_code error = RATBAG_ERROR_DEVICE;
|
||||
_cleanup_free_ char *name = NULL;
|
||||
struct input_id id;
|
||||
|
||||
if (!ratbag) {
|
||||
fprintf(stderr, "ratbag is NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!udev_device) {
|
||||
log_bug_client(ratbag, "udev device is NULL.\n");
|
||||
return NULL;
|
||||
}
|
||||
assert(ratbag != NULL);
|
||||
assert(udev_device != NULL);
|
||||
assert(device_out != NULL);
|
||||
|
||||
if (get_product_id(udev_device, &id) != 0)
|
||||
goto out_err;
|
||||
|
||||
name = get_device_name(udev_device);
|
||||
if (!name) {
|
||||
errno = ENOMEM;
|
||||
if (!name)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
device = ratbag_device_new(ratbag, udev_device, name, &id);
|
||||
free(name);
|
||||
|
||||
if (!device)
|
||||
goto out_err;
|
||||
|
||||
driver = ratbag_find_driver(device, &device->ids, NULL);
|
||||
if (!driver) {
|
||||
errno = ENOTSUP;
|
||||
if (!ratbag_assign_driver(device, &device->ids, NULL))
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
return device;
|
||||
error = RATBAG_SUCCESS;
|
||||
|
||||
out_err:
|
||||
ratbag_device_destroy(device);
|
||||
|
||||
return NULL;
|
||||
if (error != RATBAG_SUCCESS)
|
||||
ratbag_device_destroy(device);
|
||||
else
|
||||
*device_out = device;
|
||||
|
||||
return error_code(error);
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_device *
|
||||
@@ -464,10 +471,9 @@ ratbag_create_context(const struct ratbag_interface *interface,
|
||||
{
|
||||
struct ratbag *ratbag;
|
||||
|
||||
if (interface == NULL ||
|
||||
interface->open_restricted == NULL ||
|
||||
interface->close_restricted == NULL)
|
||||
return NULL;
|
||||
assert(interface != NULL);
|
||||
assert(interface->open_restricted != NULL);
|
||||
assert(interface->close_restricted != NULL);
|
||||
|
||||
ratbag = zalloc(sizeof(*ratbag));
|
||||
ratbag->refcount = 1;
|
||||
@@ -653,8 +659,10 @@ ratbag_device_get_profile(struct ratbag_device *device, unsigned int index)
|
||||
{
|
||||
struct ratbag_profile *profile;
|
||||
|
||||
if (index >= ratbag_device_get_num_profiles(device))
|
||||
if (index >= ratbag_device_get_num_profiles(device)) {
|
||||
log_bug_client(device->ratbag, "Requested invalid profile %d\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each(profile, &device->profiles, link) {
|
||||
if (profile->index == index)
|
||||
@@ -701,31 +709,31 @@ ratbag_device_has_capability(const struct ratbag_device *device,
|
||||
return !!(device->capabilities & (1UL << cap));
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_profile_set_active(struct ratbag_profile *profile)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct ratbag_profile *p;
|
||||
int rc;
|
||||
|
||||
if (!ratbag_device_has_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE))
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
assert(device->driver->write_profile);
|
||||
rc = device->driver->write_profile(profile);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (ratbag_device_has_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE)) {
|
||||
assert(device->driver->set_active_profile);
|
||||
rc = device->driver->set_active_profile(device, profile->index);
|
||||
}
|
||||
return RATBAG_ERROR_DEVICE;
|
||||
|
||||
assert(device->driver->set_active_profile);
|
||||
rc = device->driver->set_active_profile(device, profile->index);
|
||||
if (rc)
|
||||
return rc;
|
||||
return RATBAG_ERROR_DEVICE;
|
||||
|
||||
list_for_each(p, &device->profiles, link)
|
||||
p->is_active = false;
|
||||
|
||||
profile->is_active = true;
|
||||
return rc;
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT unsigned int
|
||||
@@ -740,8 +748,11 @@ ratbag_profile_get_resolution(struct ratbag_profile *profile, unsigned int idx)
|
||||
struct ratbag_resolution *res;
|
||||
unsigned max = ratbag_profile_get_num_resolutions(profile);
|
||||
|
||||
if (idx >= max)
|
||||
if (idx >= max) {
|
||||
log_bug_client(profile->device->ratbag,
|
||||
"Requested invalid resolution %d\n", idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = &profile->resolution.modes[idx];
|
||||
|
||||
@@ -787,42 +798,48 @@ ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
return !!(resolution->capabilities & (1 << cap));
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
unsigned int dpi)
|
||||
{
|
||||
struct ratbag_profile *profile = resolution->profile;
|
||||
int rc;
|
||||
|
||||
resolution->dpi_x = dpi;
|
||||
resolution->dpi_y = dpi;
|
||||
|
||||
assert(profile->device->driver->write_resolution_dpi);
|
||||
return profile->device->driver->write_resolution_dpi(resolution, dpi, dpi);
|
||||
rc = profile->device->driver->write_resolution_dpi(resolution, dpi, dpi);
|
||||
|
||||
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
|
||||
unsigned int x, unsigned int y)
|
||||
{
|
||||
struct ratbag_profile *profile = resolution->profile;
|
||||
int rc;
|
||||
|
||||
if (!ratbag_resolution_has_capability(resolution,
|
||||
RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION))
|
||||
return -1;
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
if ((x == 0 && y != 0) || (x != 0 && y == 0))
|
||||
return -1;
|
||||
return RATBAG_ERROR_VALUE;
|
||||
|
||||
assert(profile->device->driver->write_resolution_dpi);
|
||||
return profile->device->driver->write_resolution_dpi(resolution, x, y);
|
||||
rc = profile->device->driver->write_resolution_dpi(resolution, x, y);
|
||||
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
unsigned int hz)
|
||||
{
|
||||
resolution->hz = hz;
|
||||
/* FIXME: call into the driver */
|
||||
return 0;
|
||||
return RATBAG_ERROR_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
@@ -855,12 +872,12 @@ ratbag_resolution_is_active(const struct ratbag_resolution *resolution)
|
||||
return resolution->is_active;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_resolution_set_active(struct ratbag_resolution *resolution)
|
||||
{
|
||||
resolution->is_active = true;
|
||||
/* FIXME: call into the driver */
|
||||
return 0;
|
||||
return RATBAG_ERROR_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
|
||||
@@ -870,12 +887,12 @@ ratbag_resolution_is_default(const struct ratbag_resolution *resolution)
|
||||
return resolution->is_default;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_resolution_set_default(struct ratbag_resolution *resolution)
|
||||
{
|
||||
resolution->is_default = true;
|
||||
/* FIXME: call into the driver */
|
||||
return 0;
|
||||
return RATBAG_ERROR_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_button*
|
||||
@@ -885,8 +902,10 @@ ratbag_profile_get_button(struct ratbag_profile *profile,
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct ratbag_button *button;
|
||||
|
||||
if (index >= ratbag_device_get_num_buttons(device))
|
||||
if (index >= ratbag_device_get_num_buttons(device)) {
|
||||
log_bug_client(device->ratbag, "Requested invalid button %d\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each(button, &profile->buttons, link) {
|
||||
if (button->index == index)
|
||||
@@ -937,14 +956,14 @@ ratbag_button_get_button(struct ratbag_button *button)
|
||||
return button->action.action.button;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_button_set_button(struct ratbag_button *button, unsigned int btn)
|
||||
{
|
||||
struct ratbag_button_action action;
|
||||
int rc;
|
||||
|
||||
if (!button->profile->device->driver->write_button)
|
||||
return -ENOTSUP;
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
action.type = RATBAG_BUTTON_ACTION_TYPE_BUTTON;
|
||||
action.action.button = btn;
|
||||
@@ -954,7 +973,7 @@ ratbag_button_set_button(struct ratbag_button *button, unsigned int btn)
|
||||
if (rc == 0)
|
||||
button->action = action;
|
||||
|
||||
return rc;
|
||||
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_button_action_special
|
||||
@@ -966,7 +985,7 @@ ratbag_button_get_special(struct ratbag_button *button)
|
||||
return button->action.action.special;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_button_set_special(struct ratbag_button *button,
|
||||
enum ratbag_button_action_special act)
|
||||
{
|
||||
@@ -976,7 +995,7 @@ ratbag_button_set_special(struct ratbag_button *button,
|
||||
/* FIXME: range checks */
|
||||
|
||||
if (!button->profile->device->driver->write_button)
|
||||
return -1;
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
action.type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL;
|
||||
action.action.special = act;
|
||||
@@ -986,7 +1005,7 @@ ratbag_button_set_special(struct ratbag_button *button,
|
||||
if (rc == 0)
|
||||
button->action = action;
|
||||
|
||||
return rc;
|
||||
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT unsigned int
|
||||
@@ -1002,7 +1021,7 @@ ratbag_button_get_key(struct ratbag_button *button,
|
||||
return button->action.action.key.key;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_button_set_key(struct ratbag_button *button,
|
||||
unsigned int key,
|
||||
unsigned int *modifiers,
|
||||
@@ -1014,7 +1033,7 @@ ratbag_button_set_key(struct ratbag_button *button,
|
||||
/* FIXME: range checks */
|
||||
|
||||
if (!button->profile->device->driver->write_button)
|
||||
return -1;
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
/* FIXME: modifiers */
|
||||
|
||||
@@ -1025,17 +1044,17 @@ ratbag_button_set_key(struct ratbag_button *button,
|
||||
if (rc == 0)
|
||||
button->action = action;
|
||||
|
||||
return rc;
|
||||
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_button_disable(struct ratbag_button *button)
|
||||
{
|
||||
struct ratbag_button_action action;
|
||||
int rc;
|
||||
|
||||
if (!button->profile->device->driver->write_button)
|
||||
return -1;
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
action.type = RATBAG_BUTTON_ACTION_TYPE_NONE;
|
||||
rc = button->profile->device->driver->write_button(button, &action);
|
||||
@@ -1043,7 +1062,7 @@ ratbag_button_disable(struct ratbag_button *button)
|
||||
if (rc == 0)
|
||||
button->action = action;
|
||||
|
||||
return rc;
|
||||
return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_button *
|
||||
@@ -1142,8 +1161,25 @@ 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, 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));
|
||||
@@ -1154,24 +1190,36 @@ 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 0;
|
||||
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 int
|
||||
ratbag_button_set_macro_event(struct ratbag_button *button,
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
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)
|
||||
return -EINVAL;
|
||||
|
||||
macro = button->action.macro;
|
||||
if (index >= MAX_MACRO_EVENTS)
|
||||
return RATBAG_ERROR_VALUE;
|
||||
|
||||
switch (type) {
|
||||
case RATBAG_MACRO_EVENT_KEY_PRESSED:
|
||||
@@ -1187,39 +1235,28 @@ ratbag_button_set_macro_event(struct ratbag_button *button,
|
||||
macro->events[index].type = type;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
return RATBAG_ERROR_VALUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_button_write_macro(struct ratbag_button *button)
|
||||
{
|
||||
return button->profile->device->driver->write_button(button, &button->action);
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -1229,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;
|
||||
}
|
||||
|
||||
263
src/libratbag.h
263
src/libratbag.h
@@ -125,6 +125,59 @@ 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
|
||||
*
|
||||
* Error codes used by libratbag.
|
||||
*/
|
||||
enum ratbag_error_code {
|
||||
RATBAG_SUCCESS = 0,
|
||||
|
||||
/**
|
||||
* An error occured on the device. Either the device is not a
|
||||
* libratbag device or communication with the device failed.
|
||||
*/
|
||||
RATBAG_ERROR_DEVICE = -1000,
|
||||
|
||||
/**
|
||||
* Insufficient capabilities. This error occurs when a requestd change is
|
||||
* beyond the device's capabilities.
|
||||
*/
|
||||
RATBAG_ERROR_CAPABILITY = -1001,
|
||||
|
||||
/**
|
||||
* Invalid value or value range. The provided value or value range
|
||||
* is outside of the legal or supported range.
|
||||
*/
|
||||
RATBAG_ERROR_VALUE = -1002,
|
||||
|
||||
/**
|
||||
* A low-level system error has occured, e.g. a failure to access
|
||||
* files that should be there. This error is usually unrecoverable
|
||||
* and libratbag will print a log message with details about the
|
||||
* error.
|
||||
*/
|
||||
RATBAG_ERROR_SYSTEM = -1003,
|
||||
|
||||
/**
|
||||
* Implementation bug, either in libratbag or in the caller. This
|
||||
* error is usually unrecoverable and libratbag will print a log
|
||||
* message with details about the
|
||||
* error.
|
||||
*/
|
||||
RATBAG_ERROR_IMPLEMENTATION = -1004,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
@@ -325,12 +378,18 @@ ratbag_unref(struct ratbag *ratbag);
|
||||
* The device is refcounted with an initial value of at least 1.
|
||||
* Use ratbag_device_unref() to release the device.
|
||||
*
|
||||
* @return A new device based on the udev device, or NULL in case of
|
||||
* failure.
|
||||
* @param ratbag A previously initialized ratbag context
|
||||
* @param udev_device The udev device that points at the device
|
||||
* @param device Set to a new device based on the udev device.
|
||||
*
|
||||
* @return 0 on success or the error.
|
||||
* @retval RATBAG_ERROR_DEVICE The given device does not exist or is not
|
||||
* supported by libratbag.
|
||||
*/
|
||||
struct ratbag_device*
|
||||
enum ratbag_error_code
|
||||
ratbag_device_new_from_udev_device(struct ratbag *ratbag,
|
||||
struct udev_device *device);
|
||||
struct udev_device *udev_device,
|
||||
struct ratbag_device **device);
|
||||
|
||||
/**
|
||||
* @ingroup device
|
||||
@@ -600,9 +659,9 @@ ratbag_profile_is_active(struct ratbag_profile *profile);
|
||||
*
|
||||
* @param profile The profile to make the active profile.
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise.
|
||||
* @return 0 on success or an error code otherwise
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_profile_set_active(struct ratbag_profile *profile);
|
||||
|
||||
/**
|
||||
@@ -740,9 +799,9 @@ ratbag_resolution_has_capability(struct ratbag_resolution *resolution,
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
* @param dpi Set to the resolution in dpi, 0 to disable
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
unsigned int dpi);
|
||||
|
||||
@@ -766,9 +825,9 @@ ratbag_resolution_set_dpi(struct ratbag_resolution *resolution,
|
||||
* @param x The x resolution in dpi
|
||||
* @param y The y resolution in dpi
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution,
|
||||
unsigned int x, unsigned int y);
|
||||
|
||||
@@ -836,9 +895,9 @@ ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution);
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
* @param hz Set to the report rate in Hz, may be 0
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
unsigned int hz);
|
||||
|
||||
@@ -856,7 +915,7 @@ ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution,
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return The report rate for this resolution in Hz
|
||||
*/
|
||||
int
|
||||
ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution);
|
||||
@@ -872,9 +931,9 @@ ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution);
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_active(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
@@ -906,9 +965,9 @@ ratbag_resolution_is_active(const struct ratbag_resolution *resolution);
|
||||
*
|
||||
* @param resolution A previously initialized ratbag resolution
|
||||
*
|
||||
* @return zero on success, non-zero otherwise
|
||||
* @return zero on success or an error code on failure
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_resolution_set_default(struct ratbag_resolution *resolution);
|
||||
|
||||
/**
|
||||
@@ -1165,12 +1224,12 @@ ratbag_button_get_button(struct ratbag_button *button);
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param btn The logical button number to assign to this button.
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_BUTTON.
|
||||
*
|
||||
* @see ratbag_button_get_button
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_button(struct ratbag_button *button,
|
||||
unsigned int btn);
|
||||
|
||||
@@ -1197,12 +1256,12 @@ ratbag_button_get_special(struct ratbag_button *button);
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
* @param action The special action to assign to this button.
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_SPECIAL.
|
||||
*
|
||||
* @see ratbag_button_get_button
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_special(struct ratbag_button *button,
|
||||
enum ratbag_button_action_special action);
|
||||
|
||||
@@ -1243,10 +1302,10 @@ ratbag_button_get_key(struct ratbag_button *button,
|
||||
* @param sz The size of the modifiers array. sz may be 0 if no modifiers
|
||||
* are required.
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_KEY.
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_key(struct ratbag_button *button,
|
||||
unsigned int key,
|
||||
unsigned int *modifiers,
|
||||
@@ -1257,10 +1316,10 @@ ratbag_button_set_key(struct ratbag_button *button,
|
||||
*
|
||||
* @param button A previously initialized ratbag button
|
||||
*
|
||||
* @return 0 on success or nonzero otherwise. On success, the button's
|
||||
* @return 0 on success or an error code otherwise. On success, the button's
|
||||
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_NONE.
|
||||
*/
|
||||
int
|
||||
enum ratbag_error_code
|
||||
ratbag_button_disable(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
@@ -1279,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
|
||||
*/
|
||||
int
|
||||
ratbag_button_set_macro(struct ratbag_button *button, const char *name);
|
||||
enum ratbag_error_code
|
||||
ratbag_button_set_macro(struct ratbag_button *button,
|
||||
const struct ratbag_button_macro *macro);
|
||||
|
||||
int
|
||||
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.
|
||||
*/
|
||||
int
|
||||
ratbag_button_set_macro_event(struct ratbag_button *button,
|
||||
enum ratbag_error_code
|
||||
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
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* in alphabetical order! */
|
||||
|
||||
LIBRATBAG_0.2.0 {
|
||||
LIBRATBAG_0.3.0 {
|
||||
global:
|
||||
ratbag_create_context;
|
||||
ratbag_button_disable;
|
||||
@@ -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;
|
||||
|
||||
@@ -26,12 +26,16 @@
|
||||
#include <check.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libratbag.h"
|
||||
|
||||
#define _unused_ __attribute__ ((unused))
|
||||
|
||||
static int
|
||||
open_restricted(const char *path, int flags, void *user_data)
|
||||
{
|
||||
@@ -65,23 +69,40 @@ END_TEST
|
||||
|
||||
START_TEST(context_init_bad_iface)
|
||||
{
|
||||
struct ratbag *lr;
|
||||
struct ratbag *lr _unused_;
|
||||
struct ratbag_interface iface = {
|
||||
.open_restricted = NULL,
|
||||
.close_restricted = NULL,
|
||||
};
|
||||
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
ck_assert(lr == NULL);
|
||||
/* abort */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
iface.open_restricted = open_restricted;
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
ck_assert(lr == NULL);
|
||||
START_TEST(context_init_bad_iface_open)
|
||||
{
|
||||
struct ratbag *lr _unused_;
|
||||
struct ratbag_interface iface = {
|
||||
.open_restricted = open_restricted,
|
||||
.close_restricted = NULL,
|
||||
};
|
||||
|
||||
iface.open_restricted = NULL;
|
||||
iface.close_restricted = close_restricted;
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
ck_assert(lr == NULL);
|
||||
/* abort */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(context_init_bad_iface_close)
|
||||
{
|
||||
struct ratbag *lr _unused_;
|
||||
struct ratbag_interface iface = {
|
||||
.open_restricted = NULL,
|
||||
.close_restricted = close_restricted,
|
||||
};
|
||||
|
||||
lr = ratbag_create_context(&iface, NULL);
|
||||
/* abort */
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@@ -115,15 +136,19 @@ START_TEST(context_ref)
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
test_context_suite(void)
|
||||
test_context_suite(bool using_valgrind)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s;
|
||||
|
||||
s = suite_create("context");
|
||||
tc = tcase_create("init");
|
||||
tcase_add_test(tc, context_init_NULL);
|
||||
tcase_add_test(tc, context_init_bad_iface);
|
||||
if (!using_valgrind) {
|
||||
tcase_add_test_raise_signal(tc, context_init_NULL, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, context_init_bad_iface, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, context_init_bad_iface_open, SIGABRT);
|
||||
tcase_add_test_raise_signal(tc, context_init_bad_iface_close, SIGABRT);
|
||||
}
|
||||
tcase_add_test(tc, context_init);
|
||||
tcase_add_test(tc, context_ref);
|
||||
suite_add_tcase(s, tc);
|
||||
@@ -136,9 +161,14 @@ int main(void)
|
||||
int nfailed;
|
||||
Suite *s;
|
||||
SRunner *sr;
|
||||
bool using_valgrind;
|
||||
|
||||
s = test_context_suite();
|
||||
sr = srunner_create(s);
|
||||
/* when running under valgrind we're using nofork mode, so a
|
||||
* signal raised by a test will fail in valgrind */
|
||||
using_valgrind = !!getenv("USING_VALGRIND");
|
||||
|
||||
s = test_context_suite(using_valgrind);
|
||||
sr = srunner_create(s);
|
||||
|
||||
srunner_run_all(sr, CK_ENV);
|
||||
nfailed = srunner_ntests_failed(sr);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -236,13 +240,17 @@ ratbag_cmd_open_device(struct ratbag *ratbag, const char *path)
|
||||
struct ratbag_device *device;
|
||||
_cleanup_udev_unref_ struct udev *udev = NULL;
|
||||
_cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
|
||||
enum ratbag_error_code error;
|
||||
|
||||
udev = udev_new();
|
||||
udev_device = udev_device_from_path(udev, path);
|
||||
if (!udev_device)
|
||||
return NULL;
|
||||
|
||||
device = ratbag_device_new_from_udev_device(ratbag, udev_device);
|
||||
error = ratbag_device_new_from_udev_device(ratbag, udev_device,
|
||||
&device);
|
||||
if (error != RATBAG_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user