Commit 090a6d4f authored by Ryan C. Gordon's avatar Ryan C. Gordon

Linux /proc/acpi: check for ac_adapter states, other cleanup.

Still not tested, though!

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403674
parent 0fef1278
...@@ -34,26 +34,28 @@ ...@@ -34,26 +34,28 @@
#include "SDL_power.h" #include "SDL_power.h"
static const char *proc_acpi_path = "/proc/acpi/battery"; static const char *proc_acpi_battery_path = "/proc/acpi/battery";
static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter";
static int open_acpi_file(const char *node, const char *key) static int open_acpi_file(const char *base, const char *node, const char *key)
{ {
const size_t pathlen = strlen(proc_acpi_path)+strlen(node)+strlen(key)+3; const size_t pathlen = strlen(base) + strlen(node) + strlen(key) + 3;
char *path = (char *) alloca(pathlen); char *path = (char *) alloca(pathlen);
if (path == NULL) { if (path == NULL) {
return -1; /* oh well. */ return -1; /* oh well. */
} }
snprintf(path, pathlen, "%s/%s/%s", proc_acpi_path, node, key); snprintf(path, pathlen, "%s/%s/%s", base, node, key);
return open(path, O_RDONLY); return open(path, O_RDONLY);
} }
static SDL_bool static SDL_bool
load_acpi_file(const char *node, const char *key, char *buf, size_t buflen) load_acpi_file(const char *base, const char *node, const char *key,
char *buf, size_t buflen)
{ {
ssize_t br = 0; ssize_t br = 0;
const int fd = open_acpi_file(node, key); const int fd = open_acpi_file(base, node, key);
if (fd == -1) { if (fd == -1) {
return SDL_FALSE; return SDL_FALSE;
} }
...@@ -66,8 +68,9 @@ load_acpi_file(const char *node, const char *key, char *buf, size_t buflen) ...@@ -66,8 +68,9 @@ load_acpi_file(const char *node, const char *key, char *buf, size_t buflen)
return SDL_TRUE; return SDL_TRUE;
} }
static SDL_bool static SDL_bool
make_acpi_key_val(char **_ptr, char **_key, char **_val) make_proc_acpi_key_val(char **_ptr, char **_key, char **_val)
{ {
char *ptr = *_ptr; char *ptr = *_ptr;
...@@ -114,13 +117,12 @@ make_acpi_key_val(char **_ptr, char **_key, char **_val) ...@@ -114,13 +117,12 @@ make_acpi_key_val(char **_ptr, char **_key, char **_val)
} }
static void static void
check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery, check_proc_acpi_battery(const char * node, SDL_bool * have_battery,
SDL_bool * charging, int *seconds, int *percent) SDL_bool * charging, int *seconds, int *percent)
{ {
int fd = -1; const char *base = proc_acpi_battery_path;
char info[1024]; char info[1024];
char state[1024]; char state[1024];
ssize_t br = 0;
char *ptr = NULL; char *ptr = NULL;
char *key = NULL; char *key = NULL;
char *val = NULL; char *val = NULL;
...@@ -132,14 +134,14 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery, ...@@ -132,14 +134,14 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery,
int secs = -1; int secs = -1;
int pct = -1; int pct = -1;
if (!load_acpi_file(fname, "state", state, sizeof (state))) { if (!load_acpi_file(base, node, "state", state, sizeof (state))) {
return; return;
} else if (!load_acpi_file(fname, "info", info, sizeof (info))) { } else if (!load_acpi_file(base, node, "info", info, sizeof (info))) {
return; return;
} }
ptr = &state[0]; ptr = &state[0];
while (make_acpi_key_val(&ptr, &key, &val)) { while (make_proc_acpi_key_val(&ptr, &key, &val)) {
if (strcmp(key, "present") == 0) { if (strcmp(key, "present") == 0) {
if (strcmp(val, "yes") == 0) { if (strcmp(val, "yes") == 0) {
*have_battery = SDL_TRUE; *have_battery = SDL_TRUE;
...@@ -147,15 +149,8 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery, ...@@ -147,15 +149,8 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery,
} else if (strcmp(key, "charging state") == 0) { } else if (strcmp(key, "charging state") == 0) {
/* !!! FIXME: what exactly _does_ charging/discharging mean? */ /* !!! FIXME: what exactly _does_ charging/discharging mean? */
if (strcmp(val, "charging/discharging") == 0) { if (strcmp(val, "charging/discharging") == 0) {
*have_ac = is_ac = SDL_TRUE;
charge = SDL_TRUE; charge = SDL_TRUE;
} else if (strcmp(val, "charging") == 0) { } else if (strcmp(val, "charging") == 0) {
*have_ac = is_ac = SDL_TRUE;
charge = SDL_TRUE;
} else if (strcmp(val, "charged") == 0) {
/* !!! FIXME: maybe another battery is discharging,
!!! FIXME: instead of AC connection. */
*have_ac = is_ac = SDL_TRUE;
charge = SDL_TRUE; charge = SDL_TRUE;
} }
} else if (strcmp(key, "remaining capacity") == 0) { } else if (strcmp(key, "remaining capacity") == 0) {
...@@ -166,9 +161,9 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery, ...@@ -166,9 +161,9 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery,
} }
} }
} }
ptr = &info[0]; ptr = &info[0];
while (make_acpi_key_val(&ptr, &key, &val)) { while (make_proc_acpi_key_val(&ptr, &key, &val)) {
if (strcmp(key, "design capacity") == 0) { if (strcmp(key, "design capacity") == 0) {
char *endptr = NULL; char *endptr = NULL;
const int cvt = (int) strtol(val, &endptr, 10); const int cvt = (int) strtol(val, &endptr, 10);
...@@ -209,31 +204,74 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery, ...@@ -209,31 +204,74 @@ check_acpi(const char * fname, SDL_bool * have_ac, SDL_bool * have_battery,
*percent = pct; *percent = pct;
*charging = charge; *charging = charge;
} }
}
static void
check_proc_acpi_ac_adapter(const char * node, SDL_bool * have_ac)
{
const char *base = proc_acpi_ac_adapter_path;
char state[256];
char *ptr = NULL;
char *key = NULL;
char *val = NULL;
SDL_bool charge = SDL_FALSE;
SDL_bool choose = SDL_FALSE;
SDL_bool is_ac = SDL_FALSE;
int maximum = -1;
int remaining = -1;
int secs = -1;
int pct = -1;
if (!load_acpi_file(base, node, "state", state, sizeof (state))) {
return;
}
ptr = &state[0];
while (make_proc_acpi_key_val(&ptr, &key, &val)) {
if (strcmp(key, "state") == 0) {
if (strcmp(val, "on-line") == 0) {
*have_ac = SDL_TRUE;
}
}
}
} }
SDL_bool SDL_bool
SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state, SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state,
int *seconds, int *percent) int *seconds, int *percent)
{ {
struct dirent *dent = NULL; struct dirent *dent = NULL;
DIR *dirp = NULL; DIR *dirp = NULL;
SDL_bool have_ac = SDL_FALSE;
SDL_bool have_battery = SDL_FALSE; SDL_bool have_battery = SDL_FALSE;
SDL_bool have_ac = SDL_FALSE;
SDL_bool charging = SDL_FALSE; SDL_bool charging = SDL_FALSE;
*seconds = -1; *seconds = -1;
*percent = -1; *percent = -1;
*state = SDL_POWERSTATE_UNKNOWN; *state = SDL_POWERSTATE_UNKNOWN;
dirp = opendir(proc_acpi_path); dirp = opendir(proc_acpi_battery_path);
if (dirp == NULL) { if (dirp == NULL) {
return SDL_FALSE; /* can't use this interface. */ return SDL_FALSE; /* can't use this interface. */
} else {
while ((dent = readdir(dirp)) != NULL) {
const char *node = dent->d_name;
check_proc_acpi_battery(node, &have_battery, &charging,
seconds, percent);
}
closedir(dirp);
} }
while ((dent = readdir(dirp)) != NULL) { dirp = opendir(proc_acpi_ac_adapter_path);
const char *name = dent->d_name; if (dirp == NULL) {
check_acpi(name, &have_ac, &have_battery, &charging, seconds, percent); return SDL_FALSE; /* can't use this interface. */
} else {
while ((dent = readdir(dirp)) != NULL) {
const char *node = dent->d_name;
check_proc_acpi_ac_adapter(node, &have_ac);
}
closedir(dirp);
} }
if (!have_battery) { if (!have_battery) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment