mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
Add an API for LEDs
This commit is contained in:
committed by
Peter Hutterer
parent
c0c4ba156a
commit
5dcdc3c652
16
README.md
16
README.md
@@ -23,6 +23,7 @@ Interfaces:
|
||||
- org.freedesktop.ratbag1.Profile
|
||||
- org.freedesktop.ratbag1.Resolution
|
||||
- org.freedesktop.ratbag1.Button
|
||||
- org.freedesktop.ratbag1.Led
|
||||
|
||||
The **org.freedesktop.ratbag1.Manager** interface provides:
|
||||
- Properties:
|
||||
@@ -48,6 +49,7 @@ The **org.freedesktop.ratbag1.Profile** interface provides:
|
||||
- Index -> index of the profile
|
||||
- Resolutions -> array of object paths with interface Resolution
|
||||
- Buttons -> array of object paths with interface Button
|
||||
- Leds -> array of object paths with interface Led
|
||||
- ActiveResolution -> index of the currently active resolution in Resolutions
|
||||
- DefaultResolution -> index of the default resolution in Resolutions
|
||||
- Methods:
|
||||
@@ -86,6 +88,20 @@ The **org.freedesktop.ratbag1.Button** interface provides:
|
||||
- SetKeyMapping(uint[]) -> set the key mapping, first entry is the keycode, other entries, if any, are modifier keycodes
|
||||
- Disable(void) -> disable this button
|
||||
|
||||
The **org.freedesktop.ratbag1.Led** interface provides:
|
||||
- Properties:
|
||||
- Index -> index of the LED
|
||||
- Mode -> uint mapping to the mode enum from libratbag
|
||||
- Type -> string describing the LED type
|
||||
- Color -> uint triplet (RGB) of the LED's color
|
||||
- EffectRate -> the effect rate in Hz, possible values are in the range 100 - 20000
|
||||
- Brightness -> the brightness of the LED, possible values are in the range 0 - 255
|
||||
- Methods:
|
||||
- SetMode(uint) -> set the mode to the given mode enum value from libratbag
|
||||
- SetColor((uuu)) -> set the color to the given uint triplet (RGB)
|
||||
- SetEffectRate(uint) -> set the effect rate in Hz, possible values are in the range 100 - 20000
|
||||
- SetBrightness(int) -> set the brightness, possible values are in the range 0 - 255
|
||||
|
||||
For easier debugging, objects paths are constructed from the device. e.g.
|
||||
`/org/freedesktop/ratbag/button/event5/p0/b10` is the button interface for
|
||||
button 10 on profile 0 on event5. The naming is subject to change. Do not
|
||||
|
||||
@@ -78,6 +78,7 @@ dep_libshared = declare_dependency(link_with: lib_libshared)
|
||||
src_ratbagd = [
|
||||
'src/ratbagd.h',
|
||||
'src/ratbagd.c',
|
||||
'src/ratbagd-led.c',
|
||||
'src/ratbagd-button.c',
|
||||
'src/ratbagd-device.c',
|
||||
'src/ratbagd-profile.c',
|
||||
|
||||
@@ -427,6 +427,12 @@ unsigned int ratbagd_device_get_num_buttons(struct ratbagd_device *device)
|
||||
return ratbag_device_get_num_buttons(device->lib_device);
|
||||
}
|
||||
|
||||
unsigned int ratbagd_device_get_num_leds(struct ratbagd_device *device)
|
||||
{
|
||||
assert(device);
|
||||
return ratbag_device_get_num_leds(device->lib_device);
|
||||
}
|
||||
|
||||
bool ratbagd_device_linked(struct ratbagd_device *device)
|
||||
{
|
||||
return device && rbnode_linked(&device->node);
|
||||
@@ -502,6 +508,18 @@ void ratbagd_device_link(struct ratbagd_device *device)
|
||||
r = ratbagd_profile_register_buttons(device->ctx->bus,
|
||||
device,
|
||||
device->profiles[i]);
|
||||
if (r < 0) {
|
||||
log_error("Cannot register buttons for '%s': %m\n",
|
||||
device->name);
|
||||
}
|
||||
|
||||
r = ratbagd_profile_register_leds(device->ctx->bus,
|
||||
device,
|
||||
device->profiles[i]);
|
||||
if (r < 0) {
|
||||
log_error("Cannot register leds for '%s': %m\n",
|
||||
device->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
271
src/ratbagd-led.c
Normal file
271
src/ratbagd-led.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/***
|
||||
This file is part of ratbagd.
|
||||
|
||||
Copyright 2017 Jente Hidskes <hjdskes@gmail.com>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
***/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <libratbag.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
#include "ratbagd.h"
|
||||
#include "shared-macro.h"
|
||||
|
||||
struct ratbagd_led {
|
||||
struct ratbag_led *lib_led;
|
||||
unsigned int index;
|
||||
char *path;
|
||||
};
|
||||
|
||||
static int ratbagd_led_get_mode(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
enum ratbag_led_mode mode;
|
||||
|
||||
mode = ratbag_led_get_mode(led->lib_led);
|
||||
return sd_bus_message_append(reply, "u", mode);
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_mode(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
enum ratbag_led_mode mode;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &mode);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ratbag_led_set_mode(led->lib_led, mode);
|
||||
return sd_bus_reply_method_return(m, "u", r);
|
||||
}
|
||||
|
||||
static int ratbagd_led_get_type(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
const char *type = NULL;
|
||||
enum ratbag_led_type t;
|
||||
|
||||
t = ratbag_led_get_type(led->lib_led);
|
||||
|
||||
switch(t) {
|
||||
default:
|
||||
log_error("Unknown led type %d\n", t);
|
||||
/* fallthrough */
|
||||
case RATBAG_LED_TYPE_UNKNOWN:
|
||||
type = "unknown";
|
||||
break;
|
||||
case RATBAG_LED_TYPE_LOGO:
|
||||
type = "logo";
|
||||
break;
|
||||
case RATBAG_LED_TYPE_SIDE:
|
||||
type = "side";
|
||||
break;
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "s", type);
|
||||
}
|
||||
|
||||
static int ratbagd_led_get_color(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
struct ratbag_color c;
|
||||
|
||||
c = ratbag_led_get_color(led->lib_led);
|
||||
return sd_bus_message_append(reply, "(uuu)", c.red, c.green, c.blue);
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_color(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
struct ratbag_color c;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "(uuu)", &c.red, &c.green, &c.blue);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ratbag_led_set_color(led->lib_led, c);
|
||||
return sd_bus_reply_method_return(m, "u", r);
|
||||
}
|
||||
|
||||
static int ratbagd_led_get_effect_rate(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
int rate;
|
||||
|
||||
rate = ratbag_led_get_effect_rate(led->lib_led);
|
||||
return sd_bus_message_append(reply, "i", rate);
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_effect_rate(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
unsigned int rate;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &rate);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (rate < 100 || rate > 20000)
|
||||
return 0;
|
||||
|
||||
r = ratbag_led_set_effect_rate(led->lib_led, rate);
|
||||
return sd_bus_reply_method_return(m, "u", r);
|
||||
}
|
||||
|
||||
static int ratbagd_led_get_brightness(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
unsigned int brightness;
|
||||
|
||||
brightness = ratbag_led_get_brightness(led->lib_led);
|
||||
return sd_bus_message_append(reply, "u", brightness);
|
||||
}
|
||||
|
||||
static int ratbagd_led_set_brightness(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_led *led = userdata;
|
||||
unsigned int brightness;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(m, "u", &brightness);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (brightness > 255)
|
||||
return 0;
|
||||
|
||||
r = ratbag_led_set_brightness(led->lib_led, brightness);
|
||||
return sd_bus_reply_method_return(m, "u", r);
|
||||
}
|
||||
|
||||
const sd_bus_vtable ratbagd_led_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Index", "u", NULL, offsetof(struct ratbagd_led, index), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Mode", "u", ratbagd_led_get_mode, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Type", "s", ratbagd_led_get_type, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Color", "(uuu)", ratbagd_led_get_color, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("EffectRate", "i", ratbagd_led_get_effect_rate, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Brightness", "u", ratbagd_led_get_brightness, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
SD_BUS_METHOD("SetMode", "u", "u", ratbagd_led_set_mode, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetColor", "(uuu)", "u", ratbagd_led_set_color, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetEffectRate", "u", "u", ratbagd_led_set_effect_rate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetBrightness", "u", "u", ratbagd_led_set_brightness, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_VTABLE_END,
|
||||
};
|
||||
|
||||
int ratbagd_led_new(struct ratbagd_led **out,
|
||||
struct ratbagd_device *device,
|
||||
struct ratbagd_profile *profile,
|
||||
struct ratbag_led *lib_led,
|
||||
unsigned int index)
|
||||
{
|
||||
_cleanup_(ratbagd_led_freep) struct ratbagd_led *led = NULL;
|
||||
char profile_buffer[DECIMAL_TOKEN_MAX(unsigned int) + 1],
|
||||
led_buffer[DECIMAL_TOKEN_MAX(unsigned int) + 1];
|
||||
int r;
|
||||
|
||||
assert(out);
|
||||
assert(lib_led);
|
||||
|
||||
led = calloc(1, sizeof(*led));
|
||||
if (!led)
|
||||
return -ENOMEM;
|
||||
|
||||
led->lib_led = lib_led;
|
||||
led->index = index;
|
||||
|
||||
sprintf(profile_buffer, "p%u", ratbagd_profile_get_index(profile));
|
||||
sprintf(led_buffer, "b%u", index);
|
||||
r = sd_bus_path_encode_many(&led->path,
|
||||
"/org/freedesktop/ratbag1/led/%/%/%",
|
||||
ratbagd_device_get_name(device),
|
||||
profile_buffer,
|
||||
led_buffer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*out = led;
|
||||
led = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *ratbagd_led_get_path(struct ratbagd_led *led)
|
||||
{
|
||||
assert(led);
|
||||
return led->path;
|
||||
}
|
||||
|
||||
struct ratbagd_led *ratbagd_led_free(struct ratbagd_led *led)
|
||||
{
|
||||
if (!led)
|
||||
return NULL;
|
||||
|
||||
led->path = mfree(led->path);
|
||||
led->lib_led = ratbag_led_unref(led->lib_led);
|
||||
|
||||
return mfree(led);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,11 @@ struct ratbagd_profile {
|
||||
sd_bus_slot *button_enum_slot;
|
||||
unsigned int n_buttons;
|
||||
struct ratbagd_button **buttons;
|
||||
|
||||
sd_bus_slot *led_vtable_slot;
|
||||
sd_bus_slot *led_enum_slot;
|
||||
unsigned int n_leds;
|
||||
struct ratbagd_led **leds;
|
||||
};
|
||||
|
||||
static int ratbagd_profile_find_resolution(sd_bus *bus,
|
||||
@@ -148,6 +153,37 @@ static int ratbagd_profile_get_buttons(sd_bus *bus,
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int ratbagd_profile_get_leds(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
struct ratbagd_led *led;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "o");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (i = 0; i < profile->n_leds; ++i) {
|
||||
led = profile->leds[i];
|
||||
if (!led)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append(reply,
|
||||
"o",
|
||||
ratbagd_led_get_path(led));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int ratbagd_profile_get_active_resolution(sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -234,6 +270,37 @@ static int ratbagd_profile_find_button(sd_bus *bus,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_find_led(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
void *userdata,
|
||||
void **found,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
_cleanup_(freep) char *name = NULL;
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
unsigned int index;
|
||||
int r;
|
||||
|
||||
r = sd_bus_path_decode_many(path,
|
||||
"/org/freedesktop/ratbag1/led/%/p%/b%",
|
||||
NULL,
|
||||
NULL,
|
||||
&name);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = safe_atou(name, &index);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
if (index >= profile->n_leds || !profile->leds[index])
|
||||
return 0;
|
||||
|
||||
*found = profile->leds[index];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_set_active(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *error)
|
||||
@@ -282,6 +349,7 @@ const sd_bus_vtable ratbagd_profile_vtable[] = {
|
||||
SD_BUS_PROPERTY("Index", "u", NULL, offsetof(struct ratbagd_profile, index), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Resolutions", "ao", ratbagd_profile_get_resolutions, 0, 0),
|
||||
SD_BUS_PROPERTY("Buttons", "ao", ratbagd_profile_get_buttons, 0, 0),
|
||||
SD_BUS_PROPERTY("Leds", "ao", ratbagd_profile_get_leds, 0, 0),
|
||||
SD_BUS_PROPERTY("ActiveResolution", "u", ratbagd_profile_get_active_resolution, 0, 0),
|
||||
SD_BUS_PROPERTY("DefaultResolution", "u", ratbagd_profile_get_default_resolution, 0, 0),
|
||||
SD_BUS_METHOD("SetActive", "", "u", ratbagd_profile_set_active, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
@@ -298,6 +366,7 @@ int ratbagd_profile_new(struct ratbagd_profile **out,
|
||||
_cleanup_(ratbagd_profile_freep) struct ratbagd_profile *profile = NULL;
|
||||
struct ratbag_resolution *resolution;
|
||||
struct ratbag_button *button;
|
||||
struct ratbag_led *led;
|
||||
char index_buffer[DECIMAL_TOKEN_MAX(unsigned int) + 1];
|
||||
unsigned int i;
|
||||
int r;
|
||||
@@ -331,6 +400,11 @@ int ratbagd_profile_new(struct ratbagd_profile **out,
|
||||
if (!profile->buttons)
|
||||
return -ENOMEM;
|
||||
|
||||
profile->n_leds = ratbagd_device_get_num_leds(device);
|
||||
profile->leds = calloc(profile->n_leds, sizeof(*profile->leds));
|
||||
if (!profile->leds)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < profile->n_resolutions; ++i) {
|
||||
resolution = ratbag_profile_get_resolution(profile->lib_profile, i);
|
||||
if (!resolution)
|
||||
@@ -365,6 +439,23 @@ int ratbagd_profile_new(struct ratbagd_profile **out,
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < profile->n_leds; ++i) {
|
||||
led = ratbag_profile_get_led(profile->lib_profile, i);
|
||||
if (!led)
|
||||
continue;
|
||||
|
||||
r = ratbagd_led_new(&profile->leds[i],
|
||||
device,
|
||||
profile,
|
||||
led,
|
||||
i);
|
||||
if (r < 0) {
|
||||
errno = -r;
|
||||
log_error("Cannot allocate led for '%s': %m\n",
|
||||
ratbagd_device_get_name(device));
|
||||
}
|
||||
}
|
||||
|
||||
*out = profile;
|
||||
profile = NULL;
|
||||
return 0;
|
||||
@@ -381,12 +472,17 @@ struct ratbagd_profile *ratbagd_profile_free(struct ratbagd_profile *profile)
|
||||
profile->resolution_enum_slot = sd_bus_slot_unref(profile->resolution_enum_slot);
|
||||
profile->button_vtable_slot = sd_bus_slot_unref(profile->button_vtable_slot);
|
||||
profile->button_enum_slot = sd_bus_slot_unref(profile->button_enum_slot);
|
||||
profile->led_vtable_slot = sd_bus_slot_unref(profile->led_vtable_slot);
|
||||
profile->led_enum_slot = sd_bus_slot_unref(profile->led_enum_slot);
|
||||
|
||||
for (i = 0; i< profile->n_leds; ++i)
|
||||
ratbagd_led_free(profile->leds[i]);
|
||||
for (i = 0; i< profile->n_buttons; ++i)
|
||||
ratbagd_button_free(profile->buttons[i]);
|
||||
for (i = 0; i< profile->n_resolutions; ++i)
|
||||
ratbagd_resolution_free(profile->resolutions[i]);
|
||||
|
||||
mfree(profile->leds);
|
||||
mfree(profile->buttons);
|
||||
mfree(profile->resolutions);
|
||||
|
||||
@@ -467,7 +563,6 @@ int ratbagd_profile_register_resolutions(struct sd_bus *bus,
|
||||
ratbagd_device_get_name(device),
|
||||
index_buffer);
|
||||
|
||||
|
||||
if (r >= 0) {
|
||||
r = sd_bus_add_fallback_vtable(bus,
|
||||
&profile->resolution_vtable_slot,
|
||||
@@ -544,7 +639,6 @@ int ratbagd_profile_register_buttons(struct sd_bus *bus,
|
||||
ratbagd_device_get_name(device),
|
||||
index_buffer);
|
||||
|
||||
|
||||
if (r >= 0) {
|
||||
r = sd_bus_add_fallback_vtable(bus,
|
||||
&profile->button_vtable_slot,
|
||||
@@ -568,3 +662,79 @@ int ratbagd_profile_register_buttons(struct sd_bus *bus,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ratbagd_profile_list_leds(sd_bus *bus,
|
||||
const char *path,
|
||||
void *userdata,
|
||||
char ***paths,
|
||||
sd_bus_error *error)
|
||||
{
|
||||
struct ratbagd_profile *profile = userdata;
|
||||
struct ratbagd_led *led;
|
||||
char **leds;
|
||||
unsigned int i;
|
||||
|
||||
leds = calloc(profile->n_leds + 1, sizeof(char *));
|
||||
if (!leds)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < profile->n_leds; ++i) {
|
||||
led = profile->leds[i];
|
||||
if (!led)
|
||||
continue;
|
||||
|
||||
leds[i] = strdup(ratbagd_led_get_path(led));
|
||||
if (!leds[i])
|
||||
goto error;
|
||||
}
|
||||
|
||||
leds[i] = NULL;
|
||||
*paths = leds;
|
||||
return 1;
|
||||
|
||||
error:
|
||||
for (i = 0; leds[i]; ++i)
|
||||
free(leds[i]);
|
||||
free(leds);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int ratbagd_profile_register_leds(struct sd_bus *bus,
|
||||
struct ratbagd_device *device,
|
||||
struct ratbagd_profile *profile)
|
||||
{
|
||||
_cleanup_(freep) char *prefix = NULL;
|
||||
char index_buffer[DECIMAL_TOKEN_MAX(unsigned int) + 1];
|
||||
int r;
|
||||
|
||||
sprintf(index_buffer, "p%u", profile->index);
|
||||
|
||||
/* register led interfaces */
|
||||
r = sd_bus_path_encode_many(&prefix,
|
||||
"/org/freedesktop/ratbag1/led/%/%",
|
||||
ratbagd_device_get_name(device),
|
||||
index_buffer);
|
||||
|
||||
if (r >= 0) {
|
||||
r = sd_bus_add_fallback_vtable(bus,
|
||||
&profile->led_vtable_slot,
|
||||
prefix,
|
||||
"org.freedesktop.ratbag1.Led",
|
||||
ratbagd_led_vtable,
|
||||
ratbagd_profile_find_led,
|
||||
profile);
|
||||
if (r >= 0)
|
||||
r = sd_bus_add_node_enumerator(bus,
|
||||
&profile->led_enum_slot,
|
||||
prefix,
|
||||
ratbagd_profile_list_leds,
|
||||
profile);
|
||||
}
|
||||
if (r < 0) {
|
||||
errno = -r;
|
||||
log_error("Cannot register leds for '%s': %m\n",
|
||||
ratbagd_device_get_name(device));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ struct ratbagd_device;
|
||||
struct ratbagd_profile;
|
||||
struct ratbagd_resolution;
|
||||
struct ratbagd_button;
|
||||
struct ratbagd_led;
|
||||
|
||||
void log_verbose(const char *fmt, ...) _printf_(1, 2);
|
||||
void log_error(const char *fmt, ...) _printf_(1, 2);
|
||||
@@ -68,6 +69,9 @@ int ratbagd_profile_register_resolutions(struct sd_bus *bus,
|
||||
int ratbagd_profile_register_buttons(struct sd_bus *bus,
|
||||
struct ratbagd_device *device,
|
||||
struct ratbagd_profile *profile);
|
||||
int ratbagd_profile_register_leds(struct sd_bus *bus,
|
||||
struct ratbagd_device *device,
|
||||
struct ratbagd_profile *profile);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_profile *, ratbagd_profile_free);
|
||||
|
||||
@@ -103,6 +107,21 @@ const char *ratbagd_button_get_path(struct ratbagd_button *button);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_button *, ratbagd_button_free);
|
||||
|
||||
/*
|
||||
* Leds
|
||||
*/
|
||||
extern const sd_bus_vtable ratbagd_led_vtable[];
|
||||
|
||||
int ratbagd_led_new(struct ratbagd_led **out,
|
||||
struct ratbagd_device *device,
|
||||
struct ratbagd_profile *profile,
|
||||
struct ratbag_led *lib_led,
|
||||
unsigned int index);
|
||||
struct ratbagd_led *ratbagd_led_free(struct ratbagd_led *led);
|
||||
const char *ratbagd_led_get_path(struct ratbagd_led *led);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_led *, ratbagd_led_free);
|
||||
|
||||
/*
|
||||
* Devices
|
||||
*/
|
||||
@@ -117,6 +136,7 @@ struct ratbagd_device *ratbagd_device_free(struct ratbagd_device *device);
|
||||
const char *ratbagd_device_get_name(struct ratbagd_device *device);
|
||||
const char *ratbagd_device_get_path(struct ratbagd_device *device);
|
||||
unsigned int ratbagd_device_get_num_buttons(struct ratbagd_device *device);
|
||||
unsigned int ratbagd_device_get_num_leds(struct ratbagd_device *device);
|
||||
|
||||
bool ratbagd_device_linked(struct ratbagd_device *device);
|
||||
void ratbagd_device_link(struct ratbagd_device *device);
|
||||
|
||||
Reference in New Issue
Block a user