make backlight code a bit more generic with a list of sysfs files to

look at to get backlight working.



SVN revision: 64503
This commit is contained in:
Carsten Haitzler 2011-10-29 04:36:32 +00:00
parent 732845eb7c
commit 5ed77cf412
2 changed files with 196 additions and 111 deletions

View File

@ -13,10 +13,12 @@ static double bl_animval = 1.0;
static E_Backlight_Mode bl_mode = E_BACKLIGHT_MODE_NORMAL;
static int sysmode = MODE_NONE;
static Ecore_Animator *bl_anim = NULL;
static const char *bl_sysvalmax = NULL;
static const char *bl_sysval = NULL;
static Ecore_Event_Handler *bl_sys_exit_handler = NULL;
static Ecore_Exe *bl_sys_set_exe = NULL;
static Eina_Bool bl_sys_pending_set = EINA_FALSE;
static Eina_Bool bl_sys_set_exe_ready = EINA_TRUE;
static void _e_backlight_update(E_Zone *zone);
static void _e_backlight_set(E_Zone *zone, double val);
@ -42,6 +44,8 @@ e_backlight_shutdown(void)
{
if (bl_anim) ecore_animator_del(bl_anim);
bl_anim = NULL;
if (bl_sysval) eina_stringshare_del(bl_sysvalmax);
bl_sysvalmax = NULL;
if (bl_sysval) eina_stringshare_del(bl_sysval);
bl_sysval = NULL;
if (bl_sys_exit_handler) ecore_event_handler_del(bl_sys_exit_handler);
@ -252,84 +256,125 @@ _bl_sys_num_get(const char *file)
return maxval;
}
typedef struct _Bl_Entry
{
char type;
const char *base;
const char *max;
const char *set;
} Bl_Entry;
static const Bl_Entry search[] =
{
{ 'F', "/sys/devices/virtual/backlight/acpi_video0", "max_brightness", "brightness" },
{ 'D', "/sys/devices/virtual/backlight", "max_brightness", "brightness" },
{ 'F', "/sys/class/leds/lcd-backlight", "max_brightness", "brightness" },
{ 'F', "/sys/class/backlight/acpi_video0", "max_brightness", "brightness" },
{ 'D', "/sys/class/backlight", "max_brightness", "brightness" }
};
static void
_bl_sys_find(void)
{
int maxval = 0;
const char *tryfile;
if (bl_sysval) return;
tryfile = "/sys/devices/virtual/backlight/acpi_video0/max_brightness";
maxval = _bl_sys_num_get(tryfile);
if (maxval > 0)
int i, curlevel = 0;
char *valstr;
char file[4096] = "";
for (i = 0; i < (int)(sizeof(search) / sizeof(Bl_Entry)); i++)
{
bl_sysval = eina_stringshare_add(tryfile);
return;
}
else
{
Eina_List *files;
const char *dir = "/sys/devices/virtual/backlight";
char buf[4096];
const Bl_Entry *b = &(search[i]);
files = ecore_file_ls(dir);
if (files)
if (b->type == 'F')
{
char *file;
EINA_LIST_FREE(files, file)
snprintf(buf, sizeof(buf), "%s/%s", b->base, b->set);
valstr = _bl_read_file(buf);
if (valstr)
{
if (!bl_sysval)
curlevel = atoi(valstr);
if (curlevel < 0)
{
char buf[PATH_MAX];
snprintf(buf, sizeof(buf),
"%s/%s/max_brightness", dir, file);
maxval = _bl_sys_num_get(buf);
if (maxval > 0)
bl_sysval = eina_stringshare_add(buf);
free(valstr);
valstr = NULL;
}
else
{
bl_sysval = eina_stringshare_add(buf);
snprintf(file, sizeof(file), "%s/%s", b->base, b->max);
bl_sysvalmax = eina_stringshare_add(file);
free(valstr);
valstr = NULL;
}
free(file);
}
}
if (maxval <= 0)
else if (b->type == 'D')
{
struct stat st;
DIR *dirp = opendir(b->base);
struct dirent *dp;
tryfile = "/sys/class/leds/lcd-backlight/brightness";
if (stat(tryfile, &st) == 0)
if (dirp)
{
tryfile = "/sys/class/leds/lcd-backlight/max_brightness";
bl_sysval = eina_stringshare_add(tryfile);
maxval = _bl_sys_num_get(tryfile);
if (maxval <= 0) maxval = 255;
return;
while ((dp = readdir(dirp)))
{
if ((strcmp(dp->d_name, ".")) &&
(strcmp(dp->d_name, "..")))
{
snprintf(buf, sizeof(buf), "%s/%s/%s",
b->base, dp->d_name, b->set);
valstr = _bl_read_file(buf);
if (valstr)
{
curlevel = atoi(valstr);
if (curlevel < 0)
{
free(valstr);
valstr = NULL;
}
else
{
bl_sysval = eina_stringshare_add(buf);
snprintf(file, sizeof(file), "%s/%s/%s",
b->base, dp->d_name, b->max);
bl_sysvalmax = eina_stringshare_add(file);
free(valstr);
valstr = NULL;
break;
}
}
}
}
closedir(dirp);
}
}
if (file[0]) break;
}
}
static void
_bl_sys_level_get(void)
{
const char *maxfile = bl_sysval;
char *valfile, *p;
int maxval, val;
if (!bl_sysval) return;
valfile = strdup(maxfile);
p = strrchr(valfile, '/');
if (p)
{
p[1] = 0;
strcat(p, "brightness");
}
maxval = _bl_sys_num_get(maxfile);
if (maxval < 0) maxval = 255;
val = _bl_sys_num_get(valfile);
maxval = _bl_sys_num_get(bl_sysvalmax);
if (maxval <= 0) maxval = 255;
val = _bl_sys_num_get(bl_sysval);
if ((val >= 0) && (val <= maxval))
bl_val = (double)val / (double)maxval;
// printf("GET: %i/%i (%1.3f)\n", val, maxval, bl_val);
free(valfile);
printf("%s, %s\n", bl_sysvalmax, bl_sysval);
printf("GET: %i/%i (%1.3f)\n", val, maxval, bl_val);
}
static Eina_Bool
_e_bl_cb_ext_delay(void *data __UNUSED__)
{
bl_sys_set_exe_ready = EINA_TRUE;
if (bl_sys_pending_set)
{
bl_sys_pending_set = EINA_FALSE;
_bl_sys_level_set(bl_val);
}
return EINA_FALSE;
}
static Eina_Bool
@ -340,12 +385,9 @@ _e_bl_cb_exit(void *data __UNUSED__, int type __UNUSED__, void *event)
ev = event;
if (ev->exe == bl_sys_set_exe)
{
bl_sys_set_exe_ready = EINA_FALSE;
bl_sys_set_exe = NULL;
if (bl_sys_pending_set)
{
bl_sys_pending_set = EINA_FALSE;
_bl_sys_level_set(bl_val);
}
ecore_timer_add(0.1, _e_bl_cb_ext_delay, NULL);
}
return ECORE_CALLBACK_RENEW;
}
@ -358,7 +400,7 @@ _bl_sys_level_set(double val)
if (!bl_sys_exit_handler)
bl_sys_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
_e_bl_cb_exit, NULL);
if (bl_sys_set_exe)
if ((bl_sys_set_exe) || (!bl_sys_set_exe_ready))
{
bl_sys_pending_set = EINA_TRUE;
return;

View File

@ -11,7 +11,7 @@
/* local subsystem functions */
static char *
read_file(const char *file)
_bl_read_file(const char *file)
{
FILE *f = fopen(file, "r");
size_t len;
@ -33,7 +33,7 @@ read_file(const char *file)
}
static int
write_file(const char *file, int val)
_bl_write_file(const char *file, int val)
{
char buf[256];
int fd = open(file, O_WRONLY);
@ -54,6 +54,22 @@ write_file(const char *file, int val)
}
/* local subsystem globals */
typedef struct _Bl_Entry
{
char type;
const char *base;
const char *max;
const char *set;
} Bl_Entry;
static const Bl_Entry search[] =
{
{ 'F', "/sys/devices/virtual/backlight/acpi_video0", "max_brightness", "brightness" },
{ 'D', "/sys/devices/virtual/backlight", "max_brightness", "brightness" },
{ 'F', "/sys/class/leds/lcd-backlight", "max_brightness", "brightness" },
{ 'F', "/sys/class/backlight/acpi_video0", "max_brightness", "brightness" },
{ 'D', "/sys/class/backlight", "max_brightness", "brightness" }
};
/* externally accessible functions */
int
@ -61,9 +77,10 @@ main(int argc, char **argv)
{
int i;
int level;
char *maxstr;
int maxlevel = 0, curlevel;
char *valstr;
int maxlevel = 0, curlevel = -1;
char file[4096] = "";
char buf[4096] = "";
for (i = 1; i < argc; i++)
{
@ -91,66 +108,92 @@ main(int argc, char **argv)
printf("ERROR: UNABLE TO ASSUME ROOT GROUP PRIVILEGES\n");
exit(7);
}
maxstr = read_file("/sys/devices/virtual/backlight/acpi_video0/max_brightness_max");
if (maxstr)
{
maxlevel = atoi(maxstr);
if (maxlevel <= 0)
{
free(maxstr);
maxstr = NULL;
}
else
{
snprintf(file, sizeof(file),
"/sys/devices/virtual/backlight/acpi_video0/brightness");
free(maxstr);
maxstr = NULL;
}
}
if (maxlevel <= 0)
{
DIR *dirp = opendir("/sys/devices/virtual/backlight");
struct dirent *dp;
if (!dirp) return 1;
while ((dp = readdir(dirp)))
{
if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
{
char buf[4096];
snprintf(buf, sizeof(buf),
"/sys/devices/virtual/backlight/%s/max_brightness",
dp->d_name);
maxstr = read_file(buf);
if (maxstr)
for (i = 0; i < (int)(sizeof(search) / sizeof(Bl_Entry)); i++)
{
const Bl_Entry *b = &(search[i]);
if (b->type == 'F')
{
snprintf(buf, sizeof(buf), "%s/%s", b->base, b->set);
valstr = _bl_read_file(buf);
if (valstr)
{
curlevel = atoi(valstr);
if (curlevel < 0)
{
maxlevel = atoi(maxstr);
if (maxlevel <= 0)
free(valstr);
valstr = NULL;
}
else
{
snprintf(file, sizeof(file), "%s/%s", b->base, b->max);
free(valstr);
valstr = _bl_read_file(file);
if (valstr)
{
free(maxstr);
maxstr = NULL;
}
else
{
snprintf(file, sizeof(file),
"/sys/devices/virtual/backlight/%s/brightness",
dp->d_name);
free(maxstr);
maxstr = NULL;
break;
maxlevel = atoi(valstr);
free(valstr);
valstr = NULL;
}
}
}
}
closedir(dirp);
else if (b->type == 'D')
{
DIR *dirp = opendir(b->base);
struct dirent *dp;
if (dirp)
{
while ((dp = readdir(dirp)))
{
if ((strcmp(dp->d_name, ".")) &&
(strcmp(dp->d_name, "..")))
{
snprintf(buf, sizeof(buf), "%s/%s/%s",
b->base, dp->d_name, b->set);
valstr = _bl_read_file(buf);
if (valstr)
{
curlevel = atoi(valstr);
if (curlevel < 0)
{
free(valstr);
valstr = NULL;
}
else
{
snprintf(file, sizeof(file), "%s/%s/%s",
b->base, dp->d_name, b->max);
free(valstr);
valstr = _bl_read_file(file);
if (valstr)
{
maxlevel = atoi(valstr);
free(valstr);
valstr = NULL;
}
break;
}
}
}
}
closedir(dirp);
}
}
if (file[0]) break;
}
if (maxlevel > 0)
if (maxlevel <= 0) maxlevel = 255;
printf("curlevel = %i\n", curlevel);
printf("maxlevel = %i\n", maxlevel);
printf("file = %s\n", file);
printf("buf = %s\n", buf);
if (curlevel >= 0)
{
curlevel = ((maxlevel * level) + (500 / maxlevel)) / 1000;
return write_file(file, curlevel);
printf("SET: %i, %i/%i\n", level, curlevel, maxlevel);
return _bl_write_file(buf, curlevel);
}
return -1;
}