don't track c implementation in c3 branch
This commit is contained in:
parent
04d32ab8a5
commit
b0a6551b06
1 changed files with 0 additions and 193 deletions
193
ambientd.c
193
ambientd.c
|
|
@ -1,193 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
|
||||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
|
||||||
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
|
||||||
#define MEDIAN_SAMPLES 4
|
|
||||||
|
|
||||||
const char *LUMINANCE_DEV = "/sys/bus/iio/devices/iio:device0/in_illuminance_raw";
|
|
||||||
const char *MAX_BRIGHTNESS_DEV = "/sys/class/backlight/intel_backlight/max_brightness";
|
|
||||||
const char *BRIGHTNESS_DEV = "/sys/class/backlight/intel_backlight/brightness";
|
|
||||||
const char *ACTUAL_BRIGHTNESS_DEV = "/sys/class/backlight/intel_backlight/actual_brightness";
|
|
||||||
|
|
||||||
char STR_BUFFER[128] = {0};
|
|
||||||
|
|
||||||
// file pointer to the luminance device
|
|
||||||
FILE *luminance_fp = NULL;
|
|
||||||
|
|
||||||
// max luminance that the display can output
|
|
||||||
int max_luminance = 700;
|
|
||||||
|
|
||||||
// minimum display brightness in percent
|
|
||||||
float min_brightness_percent = 0.05;
|
|
||||||
|
|
||||||
// returns the luminance value in percentage between 0 and 1
|
|
||||||
int get_luminance_raw (void)
|
|
||||||
{
|
|
||||||
freopen(NULL, "r", luminance_fp);
|
|
||||||
const char *x = fgets(STR_BUFFER, sizeof(STR_BUFFER), luminance_fp);
|
|
||||||
if (x == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int luminance = strtol(STR_BUFFER, NULL, 10);
|
|
||||||
|
|
||||||
return luminance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read a string from a file and convert it to int, should only be used for
|
|
||||||
// positive numbers since negative numbers mean an error
|
|
||||||
static int read_int(FILE *fp)
|
|
||||||
{
|
|
||||||
if (freopen(NULL, "r", fp) == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
const char *p = fgets(STR_BUFFER, sizeof(STR_BUFFER), fp);
|
|
||||||
if (p == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
long r = strtol(STR_BUFFER, NULL, 10);
|
|
||||||
if (r == LONG_MIN || r == LONG_MAX) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write an intger value to a file as a string
|
|
||||||
static int write_int(FILE* fp, int value)
|
|
||||||
{
|
|
||||||
if (freopen(NULL, "w", fp) == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int x = snprintf(STR_BUFFER, sizeof(STR_BUFFER), "%d", value);
|
|
||||||
if (x <= 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return fputs(STR_BUFFER, fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline float bezier(float t)
|
|
||||||
{
|
|
||||||
const float B = 0.66;
|
|
||||||
const float D = 0.28;
|
|
||||||
return 3*B*t+(3*D-6*B)*t*t+(1+3*B-3*D)*t*t*t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add some command line options like:
|
|
||||||
// -v: verbose/logging
|
|
||||||
// -c file; specify a config file
|
|
||||||
int main (void)
|
|
||||||
{
|
|
||||||
// open the luminance device
|
|
||||||
luminance_fp = fopen(LUMINANCE_DEV, "r");
|
|
||||||
if (luminance_fp == NULL) {
|
|
||||||
fprintf(stderr, "Could not open luminance device '%s': %s\n",
|
|
||||||
LUMINANCE_DEV, strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get max and min brightness
|
|
||||||
FILE *fp = fopen(MAX_BRIGHTNESS_DEV, "r");
|
|
||||||
if (fp == NULL) {
|
|
||||||
fprintf(stderr, "Could not open max_brightness file '%s': %s\n",
|
|
||||||
MAX_BRIGHTNESS_DEV, strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int max_brightness = read_int(fp);
|
|
||||||
if (max_brightness < 0) {
|
|
||||||
fprintf(stderr, "Could not read max brightness value: %s\n", strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
int min_brightness = max_brightness * min_brightness_percent;
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
|
|
||||||
// open brightness device
|
|
||||||
FILE *brightness_fp = fopen(BRIGHTNESS_DEV, "w");
|
|
||||||
if (brightness_fp == NULL) {
|
|
||||||
fprintf(stderr, "Could not open brightness device '%s': %s\n",
|
|
||||||
BRIGHTNESS_DEV, strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open actual brightness device
|
|
||||||
FILE *actual_brightness_fp = fopen(ACTUAL_BRIGHTNESS_DEV, "r");
|
|
||||||
if (brightness_fp == NULL) {
|
|
||||||
fprintf(stderr, "Could not open actual brightness device '%s': %s\n",
|
|
||||||
ACTUAL_BRIGHTNESS_DEV, strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = get_luminance_raw();
|
|
||||||
if (x < 0) {
|
|
||||||
fprintf(stderr, "Could not read luminance value: %s\n", strerror(errno));
|
|
||||||
}
|
|
||||||
int luminance_samples[MEDIAN_SAMPLES] = {x, x, x, x};
|
|
||||||
int idx = 0;
|
|
||||||
int user_offset = 0;
|
|
||||||
int brightness_target = min_brightness;
|
|
||||||
int brightness_old = min_brightness;
|
|
||||||
int brightness_adjusted = min_brightness;
|
|
||||||
int brightness_delta = 0;
|
|
||||||
while (1) {
|
|
||||||
static float luminance;
|
|
||||||
static float luminance_percent;
|
|
||||||
|
|
||||||
x = get_luminance_raw();
|
|
||||||
if (x >= 0) luminance_samples[idx] = x;
|
|
||||||
idx = (idx + 1) % MEDIAN_SAMPLES;
|
|
||||||
|
|
||||||
luminance = 0;
|
|
||||||
for (int i = 0; i < MEDIAN_SAMPLES; i++) {
|
|
||||||
luminance += luminance_samples[i] / MEDIAN_SAMPLES;
|
|
||||||
}
|
|
||||||
luminance_percent = bezier(MIN(luminance/max_luminance, 1.0));
|
|
||||||
|
|
||||||
brightness_old = brightness_target;
|
|
||||||
brightness_target = MAX((int)(luminance_percent * max_brightness), min_brightness);
|
|
||||||
brightness_delta = ABS((float)(brightness_target - brightness_old)/brightness_old);
|
|
||||||
|
|
||||||
// if the brightness changes by more than 10% reduce the user offset, scaling
|
|
||||||
// with the delta, this accounts for large changes in brightness no longer
|
|
||||||
// corresponding to the adjustments that the user made to the brightness
|
|
||||||
if (brightness_delta > 0.1) {
|
|
||||||
user_offset = user_offset * MAX(MIN(1-(brightness_delta*1.2), 1), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
brightness_adjusted = MIN(MAX(brightness_target + user_offset, min_brightness), max_brightness);
|
|
||||||
x = write_int(brightness_fp, brightness_adjusted);
|
|
||||||
if (x < 0) {
|
|
||||||
fprintf(stderr, "error writing brightness: %s\n", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep(3);
|
|
||||||
|
|
||||||
// read actual brightness to get the user offset
|
|
||||||
int actual_brightness = 0;
|
|
||||||
int off = 0;
|
|
||||||
actual_brightness = read_int(actual_brightness_fp);
|
|
||||||
if (actual_brightness < 0) {
|
|
||||||
fprintf(stderr, "error reading actual brightness: %s\n", strerror(errno));
|
|
||||||
actual_brightness = brightness_adjusted;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the actual brightness is zero, it means that the screen is turned
|
|
||||||
// off for some reason, usually DPMS. As such it should not count for user
|
|
||||||
// offset. Look at the TODO file.
|
|
||||||
if (actual_brightness != 0) {
|
|
||||||
off = actual_brightness - brightness_target;
|
|
||||||
if (brightness_target != max_brightness || off < 0){
|
|
||||||
user_offset = off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: option to turn off logging
|
|
||||||
printf("brightness target: %d; user offset: %d; brightness adjusted: %d\n", brightness_target, user_offset, brightness_adjusted);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue