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