Skip to content

Commit

Permalink
Get defaults from udev for Screen FB plugin and Gamma,Dpms DRM plugin…
Browse files Browse the repository at this point in the history
…. Moreover, emit Dpms,Gamma.Changed signals overriding displayId if empty (in drm case); ie: avoid emitting a Gamma.Changed signal on empty id.
  • Loading branch information
FedeDP committed Dec 18, 2020
1 parent 567767c commit 50e2220
Show file tree
Hide file tree
Showing 16 changed files with 106 additions and 50 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

[![Packaging status](https://repology.org/badge/vertical-allrepos/clightd.svg)](https://repology.org/project/clightd/versions)

Clightd is a bus interface that lets you easily set screen brightness, gamma temperature and get ambient brightness through webcam frames capture or ALS devices.
Clightd is a bus interface that lets you easily set/get screen brightness, gamma temperature and display dpms state.
Moreover, it enables getting ambient brightness through webcam frames capture or ALS devices.

It works on both X, Wayland and tty.
On wayland specific protocols need to be implemented by your compositor; have a look at {Gamma, Dpms, Screen} wiki pages.

Clightd is used as a backend by [Clight](https://github.com/FedeDP/Clight) but it can be used without it too.

**For a guide on how to build, features and lots of other infos, refer to [Clightd Wiki Pages](https://github.com/FedeDP/Clightd/wiki).**
**Note that Wiki pages will always refer to master branch.**
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
- [x] Add new deps to wiki (libwayland-dev on ubuntu, wayland on arch and wayland-devel on fedora) + libdrm + libjpeg-turbo + libusb
- [x] Fix: second call to get an open wl_display does not need XDG_RUNTIME_DIR properly set
- [x] Moved to LIBEXECDIR intead of LIBDIR (#52 PR #53)
- [x] For DRM and FB plugins -> override empty display variable with one got through libudev, this way Changed signal is emitted on proper device -> eg:

## 4.X
- [ ] Keep it up to date with possible ddcutil/libmodule api changes
Expand Down
2 changes: 1 addition & 1 deletion src/commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define _ctor_ __attribute__((constructor (101))) // Used for Sensors registering
#define _dtor_ __attribute__((destructor (101))) // Used for libusb dtor

/* Used by dpms, gamm and screen*/
/* Used by dpms, gamma and screen*/
#define UNSUPPORTED INT_MIN
#define WRONG_PLUGIN INT_MIN + 1
#define COMPOSITOR_NO_PROTOCOL INT_MIN + 2
Expand Down
34 changes: 24 additions & 10 deletions src/modules/dpms.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,22 @@ static int method_getdpms(sd_bus_message *m, void *userdata, sd_bus_error *ret_e
return r;
}

/*
* Note: this is freed by drm plugin if it is an empty string
* to get a default drm device.
*/
const char *dpy = strdup(display);
dpms_plugin *plugin = userdata;
int dpms_state = WRONG_PLUGIN;
if (!plugin) {
for (int i = 0; i < DPMS_NUM && dpms_state == WRONG_PLUGIN; i++) {
dpms_state = plugins[i]->get(display, env);
dpms_state = plugins[i]->get(&dpy, env);
}
} else {
dpms_state = plugin->get(display, env);
dpms_state = plugin->get(&dpy, env);
}
free((char *)dpy);

if (dpms_state < 0) {
switch (dpms_state) {
case COMPOSITOR_NO_PROTOCOL:
Expand Down Expand Up @@ -141,15 +148,20 @@ static int method_setdpms(sd_bus_message *m, void *userdata, sd_bus_error *ret_e
return -EINVAL;
}

/*
* Note: this is freed by drm plugin if it is an empty string
* to get a default drm device.
*/
const char *dpy = strdup(display);
dpms_plugin *plugin = userdata;
int err = WRONG_PLUGIN;
if (!plugin) {
for (int i = 0; i < DPMS_NUM && err == WRONG_PLUGIN; i++) {
plugin = plugins[i];
err = plugin->set(display, env, level);
err = plugin->set(&dpy, env, level);
}
} else {
err = plugin->set(display, env, level);
err = plugin->set(&dpy, env, level);
}
if (err) {
switch (err) {
Expand All @@ -163,13 +175,15 @@ static int method_setdpms(sd_bus_message *m, void *userdata, sd_bus_error *ret_e
sd_bus_error_set_const(ret_error, SD_BUS_ERROR_FAILED, "Failed to set dpms level.");
break;
}
return -EACCES;
err = -EACCES;
} else {
m_log("New dpms state: %d.\n", level);
sd_bus_emit_signal(bus, object_path, bus_interface, "Changed", "si", dpy, level);
sd_bus_emit_signal(bus, plugin->obj_path, bus_interface, "Changed", "si", dpy, level);
err = sd_bus_reply_method_return(m, "b", true);
}

m_log("New dpms state: %d.\n", level);
sd_bus_emit_signal(bus, object_path, bus_interface, "Changed", "si", display, level);
sd_bus_emit_signal(bus, plugin->obj_path, bus_interface, "Changed", "si", display, level);
return sd_bus_reply_method_return(m, "b", true);
free((char *)dpy);
return err;
}

#endif
12 changes: 8 additions & 4 deletions src/modules/dpms.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ enum dpms_plugins {
DPMS_NUM
};

/*
* set() and get() take double pointer as
* drm plugin may override id.
*/
typedef struct {
const char *name;
int (*set)(const char *id, const char *env, int level);
int (*get)(const char *id, const char *env);
int (*set)(const char **id, const char *env, int level);
int (*get)(const char **id, const char *env);
char obj_path[100];
} dpms_plugin;

#define DPMS(name) \
static int get(const char *id, const char *env); \
static int set(const char *id, const char *env, int level); \
static int get(const char **id, const char *env); \
static int set(const char **id, const char *env, int level); \
static void _ctor_ register_gamma_plugin(void) { \
static dpms_plugin self = { name, set, get }; \
dpms_register_new(&self); \
Expand Down
6 changes: 4 additions & 2 deletions src/modules/dpms_plugins/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ DPMS("Drm");
*
* Clightd returns -1 if dpms is disabled
*/
static int get(const char *card, const char *env) {
static int get(const char **card, const char *env) {
int state = -1;
drmModeConnectorPtr connector;

Expand All @@ -43,12 +43,14 @@ static int get(const char *card, const char *env) {
}
}
drmModeFreeResources(res);
} else {
perror("dpms drmModeGetResources");
}
close(fd);
return state;
}

static int set(const char *card, const char *env, int level) {
static int set(const char **card, const char *env, int level) {
int err = 0;
drmModeConnectorPtr connector;
drmModePropertyPtr prop;
Expand Down
8 changes: 4 additions & 4 deletions src/modules/dpms_plugins/wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ static void destroy_node(struct output *output) {
free(output);
}

static int get(const char *display, const char *env) {
int ret = wl_init(display, env);
static int get(const char **display, const char *env) {
int ret = wl_init(*display, env);
if (ret == 0) {
struct output *output;
wl_list_for_each(output, &outputs, link) {
Expand All @@ -167,8 +167,8 @@ static int get(const char *display, const char *env) {
return ret;
}

static int set(const char *display, const char *env, int level) {
int ret = wl_init(display, env);
static int set(const char **display, const char *env, int level) {
int ret = wl_init(*display, env);
if (ret == 0) {
struct output *output;
wl_list_for_each(output, &outputs, link) {
Expand Down
8 changes: 4 additions & 4 deletions src/modules/dpms_plugins/xorg.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ DPMS("Xorg");
* 2 DPMSModeSuspend Blanked, lower power
* 3 DPMSModeOff Shut off, awaiting activity
*/
static int get(const char *display, const char *xauthority) {
static int get(const char **display, const char *xauthority) {
BOOL onoff;
CARD16 s;
int ret = WRONG_PLUGIN;

setenv("XAUTHORITY", xauthority, 1);

Display *dpy = XOpenDisplay(display);
Display *dpy = XOpenDisplay(*display);
if (dpy) {
if (DPMSCapable(dpy)) {
DPMSInfo(dpy, &s, &onoff);
Expand All @@ -34,13 +34,13 @@ static int get(const char *display, const char *xauthority) {
return ret;
}

static int set(const char *display, const char *xauthority, int dpms_level) {
static int set(const char **display, const char *xauthority, int dpms_level) {
int ret = WRONG_PLUGIN;

/* set xauthority cookie */
setenv("XAUTHORITY", xauthority, 1);

Display *dpy = XOpenDisplay(display);
Display *dpy = XOpenDisplay(*display);
if (dpy) {
if (DPMSCapable(dpy)) {
DPMSEnable(dpy);
Expand Down
8 changes: 4 additions & 4 deletions src/modules/gamma.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ static void client_dtor(void *c) {
cl->plugin->dtor(cl->priv);
}
free(cl->priv);
free(cl->display);
free(cl->env);
free((char *)cl->display);
free((char *)cl->env);
free(cl);
}

Expand Down Expand Up @@ -352,10 +352,10 @@ static gamma_client *fetch_client(gamma_plugin *plugin, const char *display, con
*err = WRONG_PLUGIN;
for (int i = 0; i < GAMMA_NUM && *err == WRONG_PLUGIN; i++) {
plugin = plugins[i];
*err = plugin->validate(cl->display, cl->env, &cl->priv);
*err = plugin->validate(&cl->display, cl->env, &cl->priv);
}
} else {
*err = plugin->validate(cl->display, cl->env, &cl->priv);
*err = plugin->validate(&cl->display, cl->env, &cl->priv);
}
if (*err != 0) {
client_dtor(cl);
Expand Down
12 changes: 8 additions & 4 deletions src/modules/gamma.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,28 @@ typedef struct _gamma_cl {
unsigned int smooth_step;
unsigned int smooth_wait;
unsigned int current_temp;
char *display;
char *env;
const char *display;
const char *env;
int fd;
struct _gamma_plugin *plugin;
void *priv;
} gamma_client;

/*
* validate() takes double pointer as
* drm plugin may override id.
*/
typedef struct _gamma_plugin {
const char *name;
int (*validate)(const char *id, const char *env, void **priv_data);
int (*validate)(const char **id, const char *env, void **priv_data);
int (*set)(void *priv_data, const int temp);
int (*get)(void *priv_data);
int (*dtor)(void *priv_data);
char obj_path[100];
} gamma_plugin;

#define GAMMA(name) \
static int validate(const char *id, const char *env, void **priv_data); \
static int validate(const char **id, const char *env, void **priv_data); \
static int set(void *priv_data, const int temp); \
static int get(void *priv_data); \
static int dtor(void *priv_data); \
Expand Down
3 changes: 2 additions & 1 deletion src/modules/gamma_plugins/drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ typedef struct {

GAMMA("Drm");

static int validate(const char *id, const char *env, void **priv_data) {
static int validate(const char **id, const char *env, void **priv_data) {
int ret = WRONG_PLUGIN;
int fd = drm_open_card(id);
if (fd < 0) {
Expand All @@ -28,6 +28,7 @@ static int validate(const char *id, const char *env, void **priv_data) {
ret = -ENOMEM;
}
} else {
perror("gamma drmModeGetResources");
ret = UNSUPPORTED;
}

Expand Down
4 changes: 2 additions & 2 deletions src/modules/gamma_plugins/wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ static const struct wl_registry_listener registry_listener = {

GAMMA("Wl");

static int validate(const char *id, const char *env, void **priv_data) {
struct wl_display *display = fetch_wl_display(id, env);
static int validate(const char **id, const char *env, void **priv_data) {
struct wl_display *display = fetch_wl_display(*id, env);
if (display == NULL) {
return WRONG_PLUGIN;
}
Expand Down
4 changes: 2 additions & 2 deletions src/modules/gamma_plugins/xorg.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ typedef struct {

GAMMA("Xorg");

static int validate(const char *id, const char *env, void **priv_data) {
static int validate(const char **id, const char *env, void **priv_data) {
int ret = WRONG_PLUGIN;

setenv("XAUTHORITY", env, 1);

Display *dpy = XOpenDisplay(id);
Display *dpy = XOpenDisplay(*id);
if (dpy) {
int screen = DefaultScreen(dpy);
Window root = RootWindow(dpy, screen);
Expand Down
21 changes: 16 additions & 5 deletions src/modules/screen_plugins/fb.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include "screen.h"
#include <linux/fb.h> /* to handle framebuffer ioctls */
#include <sys/ioctl.h>
#include "udev.h"

#define DEFAULT_FB "/dev/fb0"
#define FB_SUBSYSTEM "graphics"

static int get_framebufferdata(int fd, struct fb_var_screeninfo *fb_varinfo_p, struct fb_fix_screeninfo *fb_fixedinfo);
static int read_framebuffer(int fd, size_t bytes, unsigned char *buf_p, int skip_bytes);
Expand All @@ -11,16 +12,23 @@ SCREEN("Fb")

/* Many thanks to fbgrab utility: https://github.com/GunnarMonell/fbgrab/blob/master/fbgrab.c */
static int get_frame_brightness(const char *id, const char *env) {
if (!id || !strlen(id)) {
id = DEFAULT_FB;
int ret = WRONG_PLUGIN;

struct udev_device *dev = NULL;
if (!id || !strlen(id)) {
/* Fetch first matching device from udev */
get_udev_device(NULL, FB_SUBSYSTEM, NULL, NULL, &dev);
if (!dev) {
return ret;
}
id = udev_device_get_devnode(dev);
}

int ret = WRONG_PLUGIN;
unsigned char *buf_p = NULL;
int fd = open(id, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "Error: Couldn't open %s.\n", id);
return ret;
goto err;
}

ret = UNSUPPORTED;
Expand Down Expand Up @@ -62,6 +70,9 @@ static int get_frame_brightness(const char *id, const char *env) {
if (fd != -1) {
close(fd);
}
if (dev) {
udev_device_unref(dev);
}
return ret;
}

Expand Down
23 changes: 18 additions & 5 deletions src/utils/drm_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@

#include "drm_utils.h"
#include "commons.h"
#include "udev.h"

#define DEFAULT_DRM "/dev/dri/card0"
#define DRM_SUBSYSTEM "drm"

int drm_open_card(const char *card) {
if (!card || !strlen(card)) {
card = DEFAULT_DRM;
int drm_open_card(const char **card) {
if (!*card || !strlen(*card)) {
/* Fetch first matching device from udev */
struct udev_device *dev = NULL;
get_udev_device(NULL, DRM_SUBSYSTEM, NULL, NULL, &dev);
if (!dev) {
return -ENOENT;
}

/* Free old value */
free((char *)*card);

/* Store new value */
*card = strdup(udev_device_get_devnode(dev));
udev_device_unref(dev);
}
int fd = open(card, O_RDWR | O_CLOEXEC);
int fd = open(*card, O_RDWR | O_CLOEXEC);
if (fd < 0) {
perror("open");
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/drm_utils.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <xf86drm.h>
#include <xf86drmMode.h>

int drm_open_card(const char *card_num);
int drm_open_card(const char **card_num);

0 comments on commit 50e2220

Please sign in to comment.