forked from enlightenment/enlightenment
Add support for the new sysfs acpi power interface. With 2.6.24 kernels, the procfs inteface has been marked deprecated. Few people have tested without issues.
SVN revision: 33644
This commit is contained in:
parent
6de51f5ec4
commit
e6acbda91b
|
@ -62,6 +62,7 @@ static void _menu_cb_post(void *data, E_Menu *m);
|
|||
static Status *_battery_linux_acpi_check(void);
|
||||
static Status *_battery_linux_apm_check(void);
|
||||
static Status *_battery_linux_powerbook_check(void);
|
||||
static Status *_battery_linux_sys_acpi_check(void);
|
||||
#ifdef __FreeBSD__
|
||||
static Status *_battery_bsd_acpi_check(void);
|
||||
static Status *_battery_bsd_apm_check(void);
|
||||
|
@ -250,8 +251,10 @@ _battery_cb_check(void *data)
|
|||
#else
|
||||
if (battery_config->battery_check_mode == 0)
|
||||
{
|
||||
if (ecore_file_is_dir("/proc/acpi"))
|
||||
if (ecore_file_is_dir("/proc/acpi")) /* <= 2.6.24 */
|
||||
battery_config->battery_check_mode = CHECK_ACPI;
|
||||
else if (ecore_file_is_dir("/sys/class/power_supply")) /* >= 2.6.24 */
|
||||
battery_config->battery_check_mode = CHECK_SYS_ACPI;
|
||||
else if (ecore_file_exists("/proc/apm"))
|
||||
battery_config->battery_check_mode = CHECK_APM;
|
||||
else if (ecore_file_is_dir("/proc/pmu"))
|
||||
|
@ -268,6 +271,9 @@ _battery_cb_check(void *data)
|
|||
case CHECK_PMU:
|
||||
ret = _battery_linux_powerbook_check();
|
||||
break;
|
||||
case CHECK_SYS_ACPI:
|
||||
ret = _battery_linux_sys_acpi_check();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -368,6 +374,257 @@ _battery_cb_check(void *data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static Status *
|
||||
_battery_linux_sys_acpi_check(void)
|
||||
{
|
||||
Ecore_List *bats;
|
||||
char buf[4096], buf2[4096];
|
||||
char *name;
|
||||
int bat_max = 0;
|
||||
int bat_filled = 0;
|
||||
int bat_level = 0;
|
||||
int bat_drain = 1;
|
||||
int bat_val = 0;
|
||||
int discharging = 0;
|
||||
int charging = 0;
|
||||
int battery = 0;
|
||||
int design_cap_unknown = 0;
|
||||
int last_full_unknown = 0;
|
||||
int rate_unknown = 0;
|
||||
int level_unknown = 0;
|
||||
int hours, minutes;
|
||||
Status *stat;
|
||||
static double last_poll_time = 0.0;
|
||||
double poll_time, t;
|
||||
|
||||
stat = E_NEW(Status, 1);
|
||||
if (!stat) return NULL;
|
||||
|
||||
t = ecore_time_get();
|
||||
poll_time = t - last_poll_time;
|
||||
last_poll_time = t;
|
||||
|
||||
/* Read some information on first run. */
|
||||
bats = ecore_file_ls("/sys/class/power_supply/");
|
||||
if (bats)
|
||||
{
|
||||
while ((name = ecore_list_next(bats)))
|
||||
{
|
||||
FILE *f;
|
||||
int design_cap = 0;
|
||||
int last_full = 0;
|
||||
int present = 0;
|
||||
char *charging_state = NULL;
|
||||
int rate = 1;
|
||||
int level = 0;
|
||||
|
||||
if (name && strncmp("BAT",name,3)) continue;
|
||||
|
||||
/* present */
|
||||
snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/present", name);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
fgets(buf2, sizeof(buf2), f);
|
||||
present = atoi(buf2);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* design capacity */
|
||||
snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/charge_full_design", name);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
fgets(buf2, sizeof(buf2), f);
|
||||
design_cap = atoi(buf2);
|
||||
|
||||
if(!design_cap) design_cap_unknown++;
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* last full capacity */
|
||||
snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/charge_full", name);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
fgets(buf2, sizeof(buf2), f);
|
||||
last_full = atoi(buf2);
|
||||
|
||||
if(!last_full) last_full_unknown++;
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* charging state */
|
||||
snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/status", name);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
fgets(buf2, sizeof(buf2), f);
|
||||
charging_state = strdup(buf2);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* present rate */
|
||||
snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/current_now", name);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
fgets(buf2, sizeof(buf2), f);
|
||||
rate = atoi(buf2);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/* remaining capacity */
|
||||
snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/charge_now", name);
|
||||
f = fopen(buf, "r");
|
||||
if (f)
|
||||
{
|
||||
fgets(buf2, sizeof(buf2), f);
|
||||
level = atoi(buf2);
|
||||
|
||||
if(!level) level_unknown++;
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (present) battery++;
|
||||
|
||||
if (charging_state)
|
||||
{
|
||||
if (!strncmp(charging_state, "Discharging", strlen("Discharging")))
|
||||
{
|
||||
discharging++;
|
||||
if ((rate == 0) && (rate_unknown == 0)) rate_unknown++;
|
||||
}
|
||||
else if (!strncmp(charging_state, "Charging", strlen("Charging")))
|
||||
{
|
||||
charging++;
|
||||
if ((rate == 0) && (rate_unknown == 0)) rate_unknown++;
|
||||
}
|
||||
else if (!strncmp(charging_state, "Full", strlen("Full")))
|
||||
{
|
||||
rate_unknown--;
|
||||
}
|
||||
free(charging_state);
|
||||
}
|
||||
|
||||
bat_drain += rate;
|
||||
bat_level += level;
|
||||
bat_max += design_cap;
|
||||
bat_filled += last_full;
|
||||
}
|
||||
ecore_list_destroy(bats);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((rate_unknown) && (bat_level != battery_config->battery_prev_level) &&
|
||||
(battery_config->battery_prev_level >= 0) && (poll_time > 0.0))
|
||||
{
|
||||
bat_drain =
|
||||
((bat_level - battery_config->battery_prev_level) * 60 * 60) /
|
||||
poll_time;
|
||||
if (bat_drain < 0) bat_drain = -bat_drain;
|
||||
if (bat_drain == 0) bat_drain = 1;
|
||||
rate_unknown = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (battery_config->battery_prev_drain < 1)
|
||||
battery_config->battery_prev_drain = 1;
|
||||
if (bat_drain < 1)
|
||||
bat_drain = battery_config->battery_prev_drain;
|
||||
battery_config->battery_prev_drain = bat_drain;
|
||||
}
|
||||
|
||||
if (bat_filled > 0) bat_val = (100 * bat_level) / bat_filled;
|
||||
else bat_val = 100;
|
||||
|
||||
battery_config->battery_prev_level = bat_level;
|
||||
|
||||
if (discharging) minutes = (60 * bat_level) / bat_drain;
|
||||
else
|
||||
{
|
||||
/* FIXME: Batteries charge in paralell! */
|
||||
if (bat_filled > 0)
|
||||
minutes = (60 * (bat_filled - bat_level)) / bat_drain;
|
||||
else
|
||||
minutes = 0;
|
||||
}
|
||||
hours = minutes / 60;
|
||||
minutes -= (hours * 60);
|
||||
|
||||
if (hours < 0) hours = 0;
|
||||
if (minutes < 0) minutes = 0;
|
||||
|
||||
if (!battery)
|
||||
{
|
||||
stat->has_battery = 0;
|
||||
stat->state = BATTERY_STATE_NONE;
|
||||
stat->reading = strdup(_("N/A"));
|
||||
stat->time = strdup("--:--");
|
||||
stat->level = 1.0;
|
||||
}
|
||||
else if ((charging) || (discharging))
|
||||
{
|
||||
battery_config->battery_prev_battery = 1;
|
||||
stat->has_battery = 1;
|
||||
if (charging)
|
||||
{
|
||||
stat->state = BATTERY_STATE_CHARGING;
|
||||
battery_config->alarm_triggered = 0;
|
||||
}
|
||||
else if (discharging)
|
||||
{
|
||||
stat->state = BATTERY_STATE_DISCHARGING;
|
||||
if (stat->level < 0.1)
|
||||
{
|
||||
if (((hours * 60) + minutes) <= battery_config->alarm)
|
||||
stat->alarm = 1;
|
||||
if (bat_val <= battery_config->alarm_p)
|
||||
stat->alarm = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (level_unknown)
|
||||
{
|
||||
stat->reading = strdup(_("BAD DRIVER"));
|
||||
stat->time = strdup("--:--");
|
||||
stat->level = 0.0;
|
||||
}
|
||||
else if (rate_unknown)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%i%%", bat_val);
|
||||
stat->reading = strdup(buf);
|
||||
stat->time = strdup("--:--");
|
||||
stat->level = (double)bat_val / 100.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%i%%", bat_val);
|
||||
stat->reading = strdup(buf);
|
||||
snprintf(buf, sizeof(buf), "%i:%02i", hours, minutes);
|
||||
stat->time = strdup(buf);
|
||||
stat->level = (double)bat_val / 100.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stat->has_battery = 1;
|
||||
stat->state = BATTERY_STATE_NONE;
|
||||
stat->reading = strdup(_("FULL"));
|
||||
stat->time = strdup("--:--");
|
||||
stat->level = 1.0;
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
static Status *
|
||||
_battery_linux_acpi_check(void)
|
||||
{
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
typedef struct _Config Config;
|
||||
typedef struct _Status Status;
|
||||
|
||||
#define CHECK_NONE 0
|
||||
#define CHECK_ACPI 1
|
||||
#define CHECK_APM 2
|
||||
#define CHECK_PMU 3
|
||||
#define CHECK_NONE 0
|
||||
#define CHECK_ACPI 1
|
||||
#define CHECK_APM 2
|
||||
#define CHECK_PMU 3
|
||||
#define CHECK_SYS_ACPI 4
|
||||
|
||||
struct _Config
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue