mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
Add the ability to set LED effects
This commit is contained in:
committed by
Peter Hutterer
parent
3439058a54
commit
0c0a6d39cb
@@ -122,6 +122,34 @@ test_read_button(struct ratbag_button *button)
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_led(struct ratbag_led *led)
|
||||
{
|
||||
struct ratbag_device *device = led->profile->device;
|
||||
struct ratbag_test_device *d = ratbag_get_drv_data(device);
|
||||
struct ratbag_test_profile *p = &d->profiles[led->profile->index];
|
||||
struct ratbag_test_led t_led = p->leds[led->index];
|
||||
|
||||
switch (t_led.mode) {
|
||||
case RATBAG_LED_ON:
|
||||
led->mode = RATBAG_LED_ON;
|
||||
break;
|
||||
case RATBAG_LED_CYCLE:
|
||||
led->mode = RATBAG_LED_CYCLE;
|
||||
break;
|
||||
case RATBAG_LED_BREATHING:
|
||||
led->mode = RATBAG_LED_BREATHING;
|
||||
break;
|
||||
default:
|
||||
led->mode = RATBAG_LED_OFF;
|
||||
}
|
||||
led->color.red = t_led.color.red;
|
||||
led->color.green = t_led.color.green;
|
||||
led->color.blue = t_led.color.blue;
|
||||
led->hz = t_led.hz;
|
||||
led->brightness = t_led.brightness;
|
||||
}
|
||||
|
||||
static int
|
||||
test_write_button(struct ratbag_button *button,
|
||||
const struct ratbag_button_action *action)
|
||||
@@ -131,6 +159,17 @@ test_write_button(struct ratbag_button *button,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_write_led(struct ratbag_led *led,
|
||||
enum ratbag_led_mode mode,
|
||||
struct ratbag_color color, unsigned int hz,
|
||||
unsigned int brightness)
|
||||
{
|
||||
/* check if the device is still valid */
|
||||
assert(ratbag_get_drv_data(led->profile->device) != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_fake_probe(struct ratbag_device *device)
|
||||
{
|
||||
@@ -176,6 +215,8 @@ struct ratbag_driver test_driver = {
|
||||
.write_profile = test_write_profile,
|
||||
.set_active_profile = test_set_active_profile,
|
||||
.read_button = test_read_button,
|
||||
.read_led = test_read_led,
|
||||
.write_button = test_write_button,
|
||||
.write_resolution_dpi = NULL,
|
||||
.write_led = test_write_led,
|
||||
};
|
||||
|
||||
@@ -198,6 +198,21 @@ struct ratbag_driver {
|
||||
int (*write_resolution_dpi)(struct ratbag_resolution *resolution,
|
||||
int dpi_x, int dpi_y);
|
||||
|
||||
/**
|
||||
* For the given led, fill in the struct ratbag_led
|
||||
* with the available information.
|
||||
*/
|
||||
void (*read_led)(struct ratbag_led *led);
|
||||
|
||||
/*
|
||||
* FIXME: This function is deprecated and should be removed. Once
|
||||
* we've updated all the device drivers to stop using it we'll remove
|
||||
* it. Look at commit() instead.
|
||||
*/
|
||||
int (*write_led)(struct ratbag_led *led, enum ratbag_led_mode mode,
|
||||
struct ratbag_color color, unsigned int hz,
|
||||
unsigned int brightness);
|
||||
|
||||
/* private */
|
||||
int (*test_probe)(struct ratbag_device *device, void *data);
|
||||
|
||||
@@ -216,6 +231,20 @@ struct ratbag_resolution {
|
||||
uint32_t capabilities;
|
||||
};
|
||||
|
||||
struct ratbag_led {
|
||||
int refcount;
|
||||
void *userdata;
|
||||
struct list link;
|
||||
struct ratbag_profile *profile;
|
||||
unsigned index;
|
||||
enum ratbag_led_type type;
|
||||
enum ratbag_led_mode mode;
|
||||
struct ratbag_color color;
|
||||
unsigned int hz; /**< rate of action in hz */
|
||||
unsigned int brightness; /**< brightness of the LED */
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
struct ratbag_profile {
|
||||
int refcount;
|
||||
void *userdata;
|
||||
@@ -230,6 +259,7 @@ struct ratbag_profile {
|
||||
struct ratbag_resolution *modes;
|
||||
unsigned int num_modes;
|
||||
} resolution;
|
||||
struct list leds;
|
||||
|
||||
bool is_active; /**< profile is the currently active one */
|
||||
bool is_enabled;
|
||||
|
||||
@@ -49,9 +49,24 @@ struct ratbag_test_resolution {
|
||||
uint32_t caps;
|
||||
};
|
||||
|
||||
struct ratbag_test_color {
|
||||
unsigned short red;
|
||||
unsigned short green;
|
||||
unsigned short blue;
|
||||
};
|
||||
|
||||
struct ratbag_test_led {
|
||||
enum ratbag_led_type type;
|
||||
enum ratbag_led_mode mode;
|
||||
struct ratbag_test_color color;
|
||||
unsigned int hz;
|
||||
unsigned int brightness;
|
||||
};
|
||||
|
||||
struct ratbag_test_profile {
|
||||
struct ratbag_test_button buttons[RATBAG_TEST_MAX_BUTTONS];
|
||||
struct ratbag_test_resolution resolutions[RATBAG_TEST_MAX_RESOLUTIONS];
|
||||
struct ratbag_test_led leds[RATBAG_TEST_MAX_LEDS];
|
||||
bool active;
|
||||
bool dflt;
|
||||
};
|
||||
|
||||
190
src/libratbag.c
190
src/libratbag.c
@@ -59,6 +59,8 @@ static void
|
||||
ratbag_profile_destroy(struct ratbag_profile *profile);
|
||||
static void
|
||||
ratbag_button_destroy(struct ratbag_button *button);
|
||||
static void
|
||||
ratbag_led_destroy(struct ratbag_led *led);
|
||||
|
||||
static void
|
||||
ratbag_default_log_func(struct ratbag *ratbag,
|
||||
@@ -582,6 +584,25 @@ ratbag_create_button(struct ratbag_profile *profile, unsigned int index)
|
||||
return button;
|
||||
}
|
||||
|
||||
static struct ratbag_led *
|
||||
ratbag_create_led(struct ratbag_profile *profile, unsigned int index)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct ratbag_led *led;
|
||||
|
||||
led = zalloc(sizeof(*led));
|
||||
led->refcount = 0;
|
||||
led->profile = profile;
|
||||
led->index = index;
|
||||
|
||||
list_insert(&profile->leds, &led->link);
|
||||
|
||||
if (device->driver->read_led)
|
||||
device->driver->read_led(led);
|
||||
|
||||
return led;
|
||||
}
|
||||
|
||||
static int
|
||||
ratbag_profile_init_buttons(struct ratbag_profile *profile, unsigned int count)
|
||||
{
|
||||
@@ -598,6 +619,11 @@ ratbag_profile_init_buttons(struct ratbag_profile *profile, unsigned int count)
|
||||
static int
|
||||
ratbag_profile_init_leds(struct ratbag_profile *profile, unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
ratbag_create_led(profile, i);
|
||||
|
||||
profile->device->num_leds = count;
|
||||
|
||||
return 0;
|
||||
@@ -624,6 +650,7 @@ ratbag_create_profile(struct ratbag_device *device,
|
||||
|
||||
list_insert(&device->profiles, &profile->link);
|
||||
list_init(&profile->buttons);
|
||||
list_init(&profile->leds);
|
||||
|
||||
for (i = 0; i < num_resolutions; i++)
|
||||
ratbag_resolution_init(profile, i, 0, 0, 0);
|
||||
@@ -682,14 +709,18 @@ ratbag_profile_ref(struct ratbag_profile *profile)
|
||||
static void
|
||||
ratbag_profile_destroy(struct ratbag_profile *profile)
|
||||
{
|
||||
struct ratbag_button *button, *next;
|
||||
struct ratbag_button *button, *b_next;
|
||||
struct ratbag_led *led, *l_next;
|
||||
|
||||
/* if we get to the point where the profile is destroyed, buttons,
|
||||
* resolutions , etc. are at a refcount of 0, so we can destroy
|
||||
* everything */
|
||||
list_for_each_safe(button, next, &profile->buttons, link)
|
||||
list_for_each_safe(button, b_next, &profile->buttons, link)
|
||||
ratbag_button_destroy(button);
|
||||
|
||||
list_for_each_safe(led, l_next, &profile->leds, link)
|
||||
ratbag_led_destroy(led);
|
||||
|
||||
free(profile->resolution.modes);
|
||||
|
||||
list_remove(&profile->link);
|
||||
@@ -790,6 +821,12 @@ ratbag_device_has_capability(const struct ratbag_device *device,
|
||||
return !!(device->capabilities & (1UL << cap));
|
||||
}
|
||||
|
||||
static inline enum ratbag_error_code
|
||||
write_led_helper(struct ratbag_device *device, struct ratbag_led *led)
|
||||
{
|
||||
return device->driver->write_led(led, led->mode, led->color, led->hz, led->brightness);
|
||||
}
|
||||
|
||||
/* FIXME: This is a temporary fix for all of the drivers that have yet to be
|
||||
* converted to the new profile-oriented API. Once all of the drivers have been
|
||||
* converted, this code should be removed.
|
||||
@@ -799,6 +836,7 @@ ratbag_old_write_profile(struct ratbag_device *device)
|
||||
{
|
||||
struct ratbag_profile *profile;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
struct ratbag_resolution *resolution;
|
||||
int rc;
|
||||
unsigned int i;
|
||||
@@ -839,6 +877,17 @@ ratbag_old_write_profile(struct ratbag_device *device)
|
||||
return RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
}
|
||||
|
||||
if (device->driver->write_led) {
|
||||
list_for_each(led, &profile->leds, link) {
|
||||
if (!led->dirty)
|
||||
continue;
|
||||
|
||||
rc = write_led_helper(device, led);
|
||||
if (rc)
|
||||
return RATBAG_ERROR_DEVICE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RATBAG_SUCCESS;
|
||||
@@ -1268,6 +1317,16 @@ ratbag_button_ref(struct ratbag_button *button)
|
||||
return button;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_led *
|
||||
ratbag_led_ref(struct ratbag_led *led)
|
||||
{
|
||||
assert(led->refcount < INT_MAX);
|
||||
|
||||
ratbag_profile_ref(led->profile);
|
||||
led->refcount++;
|
||||
return led;
|
||||
}
|
||||
|
||||
static void
|
||||
ratbag_button_destroy(struct ratbag_button *button)
|
||||
{
|
||||
@@ -1280,6 +1339,13 @@ ratbag_button_destroy(struct ratbag_button *button)
|
||||
free(button);
|
||||
}
|
||||
|
||||
static void
|
||||
ratbag_led_destroy(struct ratbag_led *led)
|
||||
{
|
||||
list_remove(&led->link);
|
||||
free(led);
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_button *
|
||||
ratbag_button_unref(struct ratbag_button *button)
|
||||
{
|
||||
@@ -1294,6 +1360,126 @@ ratbag_button_unref(struct ratbag_button *button)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_led *
|
||||
ratbag_led_unref(struct ratbag_led *led)
|
||||
{
|
||||
if (led == NULL)
|
||||
return NULL;
|
||||
|
||||
assert(led->refcount > 0);
|
||||
led->refcount--;
|
||||
|
||||
ratbag_profile_unref(led->profile);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_led_mode
|
||||
ratbag_led_get_mode(struct ratbag_led *led)
|
||||
{
|
||||
return led->mode;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_led_type
|
||||
ratbag_led_get_type(struct ratbag_led *led)
|
||||
{
|
||||
return led->type;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_color
|
||||
ratbag_led_get_color(struct ratbag_led *led)
|
||||
{
|
||||
return led->color;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT int
|
||||
ratbag_led_get_effect_rate(struct ratbag_led *led)
|
||||
{
|
||||
return led->hz;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT unsigned int
|
||||
ratbag_led_get_brightness(struct ratbag_led *led)
|
||||
{
|
||||
return led->brightness;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_led_set_mode(struct ratbag_led *led, enum ratbag_led_mode mode)
|
||||
{
|
||||
|
||||
if (!ratbag_device_has_capability(led->profile->device,
|
||||
RATBAG_DEVICE_CAP_LED))
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
led->mode = mode;
|
||||
led->dirty = true;
|
||||
led->profile->dirty = true;
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_led_set_color(struct ratbag_led *led, struct ratbag_color color)
|
||||
{
|
||||
if (!ratbag_device_has_capability(led->profile->device,
|
||||
RATBAG_DEVICE_CAP_LED))
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
led->color = color;
|
||||
led->dirty = true;
|
||||
led->profile->dirty = true;
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_led_set_effect_rate(struct ratbag_led *led, unsigned int hz)
|
||||
{
|
||||
if (!ratbag_device_has_capability(led->profile->device,
|
||||
RATBAG_DEVICE_CAP_LED))
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
led->hz = hz;
|
||||
led->dirty = true;
|
||||
led->profile->dirty = true;
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT enum ratbag_error_code
|
||||
ratbag_led_set_brightness(struct ratbag_led *led, unsigned int brightness)
|
||||
{
|
||||
if (!ratbag_device_has_capability(led->profile->device,
|
||||
RATBAG_DEVICE_CAP_LED))
|
||||
return RATBAG_ERROR_CAPABILITY;
|
||||
|
||||
led->brightness = brightness;
|
||||
led->dirty = true;
|
||||
led->profile->dirty = true;
|
||||
return RATBAG_SUCCESS;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT struct ratbag_led *
|
||||
ratbag_profile_get_led(struct ratbag_profile *profile,
|
||||
unsigned int index)
|
||||
{
|
||||
struct ratbag_device *device = profile->device;
|
||||
struct ratbag_led *led;
|
||||
|
||||
if (index >= ratbag_device_get_num_leds(device)) {
|
||||
log_bug_client(device->ratbag, "Requested invalid led %d\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_for_each(led, &profile->leds, link) {
|
||||
if (led->index == index)
|
||||
return ratbag_led_ref(led);
|
||||
}
|
||||
|
||||
log_bug_libratbag(device->ratbag, "Led %d, profile %d not found\n",
|
||||
index, profile->index);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBRATBAG_EXPORT void
|
||||
ratbag_set_user_data(struct ratbag *ratbag, void *userdata)
|
||||
{
|
||||
|
||||
205
src/libratbag.h
205
src/libratbag.h
@@ -55,6 +55,8 @@ extern "C" {
|
||||
*
|
||||
* @defgroup button Button configuration
|
||||
*
|
||||
* @defgroup led LED configuration
|
||||
*
|
||||
* @defgroup resolution Resolution and frequency mappings
|
||||
*
|
||||
* A device's sensor resolution and report rate can be configured per
|
||||
@@ -126,6 +128,28 @@ struct ratbag_button;
|
||||
*/
|
||||
struct ratbag_resolution;
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
* @struct ratbag_color
|
||||
*
|
||||
* Represents LED color in RGB format.
|
||||
* each color component is integer 0 - 255
|
||||
*/
|
||||
|
||||
struct ratbag_color {
|
||||
unsigned int red;
|
||||
unsigned int green;
|
||||
unsigned int blue;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
* @struct ratbag_led
|
||||
*
|
||||
* Represents a led on the device.
|
||||
*/
|
||||
struct ratbag_led;
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
* @struct ratbag_macro
|
||||
@@ -1317,6 +1341,23 @@ ratbag_button_set_button(struct ratbag_button *button,
|
||||
enum ratbag_button_action_special
|
||||
ratbag_button_get_special(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* RATBAG_LED_OFF - led is now off,
|
||||
* RATBAG_LED_ON - led is on with static color,
|
||||
* RATBAG_LED_CYCLE - led is cycling between all colors.
|
||||
* RATBAG_LED_BREATHING - led is pulsating with static color
|
||||
*
|
||||
* Each LED mode has different properties, e.g. the brightness and rate are only
|
||||
* available in modes @ref RATBAG_LED_CYCLE and @ref RATBAG_LED_BREATHING modes
|
||||
*/
|
||||
enum ratbag_led_mode {
|
||||
RATBAG_LED_OFF = 0,
|
||||
RATBAG_LED_ON,
|
||||
RATBAG_LED_CYCLE,
|
||||
RATBAG_LED_BREATHING,
|
||||
};
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
@@ -1327,6 +1368,145 @@ enum ratbag_led_type {
|
||||
RATBAG_LED_TYPE_LOGO = 0,
|
||||
RATBAG_LED_TYPE_SIDE
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* Return a reference to the LED given by the index. The order of the
|
||||
* LEDs is device-specific though.
|
||||
*
|
||||
* The LED is refcounted with an initial value of at least 1.
|
||||
* Use ratbag_led_unref() to release the LED.
|
||||
*
|
||||
* @param profile A previously initialized ratbag profile
|
||||
* @param index The index of the LED
|
||||
*
|
||||
* @return A LED context, or NULL if the LED does not exist.
|
||||
*
|
||||
* @see ratbag_device_get_profile
|
||||
*/
|
||||
struct ratbag_led *
|
||||
ratbag_profile_get_led(struct ratbag_profile *profile, unsigned int index);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the type for ratbag_led.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED type @ref enum ratbag_led_type
|
||||
*
|
||||
* @see ratbag_led_set_mode
|
||||
*/
|
||||
enum ratbag_led_type
|
||||
ratbag_led_get_type(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the mode for ratbag_led.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED mod @ref enum ratbag_led_mode
|
||||
*
|
||||
* @see ratbag_led_set_mode
|
||||
*/
|
||||
enum ratbag_led_mode
|
||||
ratbag_led_get_mode(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the led color.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED color in @ref enum ratbag_led_mode
|
||||
*
|
||||
* @see ratbag_led_set_color
|
||||
*/
|
||||
struct ratbag_color
|
||||
ratbag_led_get_color(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the LED effect rate.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED rate in Hz, can be 100 - 20000
|
||||
*
|
||||
* @see ratbag_led_set_effect_rate
|
||||
*/
|
||||
int
|
||||
ratbag_led_get_effect_rate(struct ratbag_led *led);
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* This function returns the LED brightness.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @return The LED brightness 0 - 255
|
||||
*
|
||||
* @see ratbag_led_get_brightness
|
||||
*/
|
||||
unsigned int
|
||||
ratbag_led_get_brightness(struct ratbag_led *led);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* this function sets the LED mode.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param mode LED mode @ref enum ratbag_led_mode.
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_mode
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_mode(struct ratbag_led *led, enum ratbag_led_mode mode);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* If the LED's mode is @ref RATBAG_LED_ON or @ref RATBAG_LED_BREATHING
|
||||
* then this function sets the LED color, otherwise it has no effect.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param color A LED color.
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_color
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_color(struct ratbag_led *led, struct ratbag_color color);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* If the LED's mode is @ref RATBAG_LED_CYCLE or @ref RATBAG_LED_BREATHING
|
||||
* then this function sets the LED rate in Hz
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param rate Effect rate in hz, 100 - 20000
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_effect_rate
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_effect_rate(struct ratbag_led *led, unsigned int rate);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* If the LED's mode is @ref RATBAG_LED_CYCLE or @ref RATBAG_LED_BREATHING
|
||||
* then this function sets the LED brightness, otherwise it has no effect.
|
||||
*
|
||||
* @param led A previously initialized ratbag LED
|
||||
* @param brightness Effect brightness 0 - 255
|
||||
* @return 0 on success or an error code otherwise.
|
||||
*
|
||||
* @see ratbag_led_get_brightness
|
||||
*/
|
||||
enum ratbag_error_code
|
||||
ratbag_led_set_brightness(struct ratbag_led *led, unsigned int brightness);
|
||||
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
@@ -1610,6 +1790,31 @@ ratbag_button_ref(struct ratbag_button *button);
|
||||
struct ratbag_button *
|
||||
ratbag_button_unref(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* Add a reference to the led. A led is destroyed whenever the
|
||||
* reference count reaches 0. See @ref ratbag_led_unref.
|
||||
*
|
||||
* @param led A previously initialized valid ratbag led
|
||||
* @return The passed ratbag led
|
||||
*/
|
||||
struct ratbag_led *
|
||||
ratbag_led_ref(struct ratbag_led *led);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* Dereference the ratbag led. 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 led A previously initialized ratbag led
|
||||
* @return Always NULL
|
||||
*/
|
||||
struct ratbag_led *
|
||||
ratbag_led_unref(struct ratbag_led *led);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -45,6 +45,18 @@ global:
|
||||
ratbag_log_get_priority;
|
||||
ratbag_log_set_handler;
|
||||
ratbag_log_set_priority;
|
||||
ratbag_profile_get_led;
|
||||
ratbag_led_get_mode;
|
||||
ratbag_led_get_type;
|
||||
ratbag_led_get_color;
|
||||
ratbag_led_get_effect_rate;
|
||||
ratbag_led_get_brightness;
|
||||
ratbag_led_ref;
|
||||
ratbag_led_set_mode;
|
||||
ratbag_led_set_color;
|
||||
ratbag_led_set_effect_rate;
|
||||
ratbag_led_set_brightness;
|
||||
ratbag_led_unref;
|
||||
ratbag_device_get_num_leds;
|
||||
ratbag_profile_get_button;
|
||||
ratbag_profile_get_num_resolutions;
|
||||
|
||||
@@ -79,6 +79,20 @@ const struct ratbag_test_device sane_device = {
|
||||
{ .xres = 2200, .yres = 2300, .hz = 3000 },
|
||||
{ .xres = 2300, .yres = 2400, .hz = 3000 },
|
||||
},
|
||||
.leds = {
|
||||
{
|
||||
.mode = RATBAG_LED_ON,
|
||||
.color = { .red = 255, .green = 0, .blue = 0 },
|
||||
.hz = 1,
|
||||
.brightness = 20
|
||||
},
|
||||
{
|
||||
.mode = RATBAG_LED_CYCLE,
|
||||
.color = { .red = 255, .green = 255, .blue = 0 },
|
||||
.hz = 3,
|
||||
.brightness = 40
|
||||
}
|
||||
},
|
||||
.active = false,
|
||||
.dflt = false,
|
||||
},
|
||||
@@ -754,6 +768,119 @@ START_TEST(device_buttons_set)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
assert_led_equals(struct ratbag_led *l, struct ratbag_test_led e_l)
|
||||
{
|
||||
enum ratbag_led_mode mode;
|
||||
struct ratbag_color color;
|
||||
int brightness, hz;
|
||||
|
||||
ck_assert(l != NULL);
|
||||
mode = ratbag_led_get_mode(l);
|
||||
color = ratbag_led_get_color(l);
|
||||
hz = ratbag_led_get_effect_rate(l);
|
||||
brightness = ratbag_led_get_brightness(l);
|
||||
ck_assert_int_eq(mode, e_l.mode);
|
||||
ck_assert_int_eq(color.red, e_l.color.red);
|
||||
ck_assert_int_eq(color.green, e_l.color.green);
|
||||
ck_assert_int_eq(color.blue, e_l.color.blue);
|
||||
ck_assert_int_eq(hz, e_l.hz);
|
||||
ck_assert_int_eq(brightness, e_l.brightness);
|
||||
}
|
||||
|
||||
START_TEST(device_leds)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_led *led_logo, *led_side;
|
||||
int nprofiles;
|
||||
int device_freed_count = 0;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
|
||||
td.destroyed_data = &device_freed_count;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
|
||||
nprofiles = ratbag_device_get_num_profiles(d);
|
||||
ck_assert_int_eq(nprofiles, 3);
|
||||
|
||||
p = ratbag_device_get_profile(d, 2);
|
||||
ck_assert(p != NULL);
|
||||
|
||||
led_logo = ratbag_profile_get_led(p, RATBAG_LED_TYPE_LOGO);
|
||||
assert_led_equals(led_logo, td.profiles[2].leds[RATBAG_LED_TYPE_LOGO]);
|
||||
led_side = ratbag_profile_get_led(p, RATBAG_LED_TYPE_SIDE);
|
||||
assert_led_equals(led_side, td.profiles[2].leds[RATBAG_LED_TYPE_SIDE]);
|
||||
|
||||
ratbag_led_unref(led_logo);
|
||||
ratbag_led_unref(led_side);
|
||||
ratbag_profile_unref(p);
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
ck_assert_int_eq(device_freed_count, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(device_leds_set)
|
||||
{
|
||||
struct ratbag *r;
|
||||
struct ratbag_device *d;
|
||||
struct ratbag_profile *p;
|
||||
struct ratbag_led *l;
|
||||
int nprofiles;
|
||||
int device_freed_count = 0;
|
||||
|
||||
struct ratbag_test_device td = sane_device;
|
||||
|
||||
struct ratbag_color c = {
|
||||
.red = 0,
|
||||
.green = 111,
|
||||
.blue = 222
|
||||
};
|
||||
|
||||
td.destroyed_data = &device_freed_count;
|
||||
|
||||
r = ratbag_create_context(&abort_iface, NULL);
|
||||
d = ratbag_device_new_test_device(r, &td);
|
||||
|
||||
nprofiles = ratbag_device_get_num_profiles(d);
|
||||
ck_assert_int_eq(nprofiles, 3);
|
||||
|
||||
p = ratbag_device_get_profile(d, 0);
|
||||
ck_assert(p != NULL);
|
||||
|
||||
l = ratbag_profile_get_led(p, RATBAG_LED_TYPE_LOGO);
|
||||
|
||||
ratbag_led_set_mode(l, RATBAG_LED_BREATHING);
|
||||
ratbag_led_set_color(l, c);
|
||||
ratbag_led_set_effect_rate(l, 11);
|
||||
ratbag_led_set_brightness(l, 22);
|
||||
|
||||
l = ratbag_profile_get_led(p, RATBAG_LED_TYPE_LOGO);
|
||||
struct ratbag_test_led e_l = {
|
||||
.mode = RATBAG_LED_BREATHING,
|
||||
.color = {
|
||||
.red = c.red,
|
||||
.green = c.green,
|
||||
.blue = c.blue
|
||||
},
|
||||
.hz = 11,
|
||||
.brightness = 22
|
||||
};
|
||||
assert_led_equals(l, e_l);
|
||||
|
||||
ratbag_led_unref(l);
|
||||
ratbag_led_unref(l);
|
||||
ratbag_profile_unref(p);
|
||||
ratbag_device_unref(d);
|
||||
ratbag_unref(r);
|
||||
ck_assert_int_eq(device_freed_count, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *
|
||||
test_context_suite(void)
|
||||
{
|
||||
@@ -792,6 +919,11 @@ test_context_suite(void)
|
||||
tcase_add_test(tc, device_buttons_set);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("led");
|
||||
tcase_add_test(tc, device_leds);
|
||||
tcase_add_test(tc, device_leds_set);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user