21 #include "../../SDL_internal.h" 23 #ifndef SDL_POWER_DISABLED 29 #include <sys/types.h> 36 static const char *proc_apm_path =
"/proc/apm";
37 static const char *proc_acpi_battery_path =
"/proc/acpi/battery";
38 static const char *proc_acpi_ac_adapter_path =
"/proc/acpi/ac_adapter";
39 static const char *sys_class_power_supply_path =
"/sys/class/power_supply";
42 open_power_file(
const char *base,
const char *node,
const char *key)
44 const size_t pathlen = strlen(base) + strlen(node) + strlen(key) + 3;
45 char *
path = (
char *) alloca(pathlen);
50 snprintf(path, pathlen,
"%s/%s/%s", base, node, key);
51 return open(path, O_RDONLY);
56 read_power_file(
const char *base,
const char *node,
const char *key,
57 char *
buf,
size_t buflen)
60 const int fd = open_power_file(base, node, key);
64 br = read(fd, buf, buflen-1);
75 make_proc_acpi_key_val(
char **_ptr,
char **_key,
char **_val)
89 while ((*ptr !=
':') && (*ptr !=
'\0')) {
99 while ((*ptr ==
' ') && (*ptr !=
'\0')) {
109 while ((*ptr !=
'\n') && (*ptr !=
'\0')) {
122 check_proc_acpi_battery(
const char * node,
SDL_bool * have_battery,
123 SDL_bool * charging,
int *seconds,
int *percent)
125 const char *base = proc_acpi_battery_path;
138 if (!read_power_file(base, node,
"state", state,
sizeof (state))) {
140 }
else if (!read_power_file(base, node,
"info", info,
sizeof (info))) {
145 while (make_proc_acpi_key_val(&ptr, &key, &val)) {
146 if (strcmp(key,
"present") == 0) {
147 if (strcmp(val,
"yes") == 0) {
150 }
else if (strcmp(key,
"charging state") == 0) {
152 if (strcmp(val,
"charging/discharging") == 0) {
154 }
else if (strcmp(val,
"charging") == 0) {
157 }
else if (strcmp(key,
"remaining capacity") == 0) {
159 const int cvt = (int) strtol(val, &endptr, 10);
160 if (*endptr ==
' ') {
167 while (make_proc_acpi_key_val(&ptr, &key, &val)) {
168 if (strcmp(key,
"design capacity") == 0) {
170 const int cvt = (int) strtol(val, &endptr, 10);
171 if (*endptr ==
' ') {
177 if ((maximum >= 0) && (remaining >= 0)) {
178 pct = (int) ((((
float) remaining) / ((
float) maximum)) * 100.0f);
181 }
else if (pct > 100) {
192 if ((secs < 0) && (*seconds < 0)) {
193 if ((pct < 0) && (*percent < 0)) {
196 if (pct > *percent) {
199 }
else if (secs > *seconds) {
211 check_proc_acpi_ac_adapter(
const char * node,
SDL_bool * have_ac)
213 const char *base = proc_acpi_ac_adapter_path;
219 if (!read_power_file(base, node,
"state", state,
sizeof (state))) {
224 while (make_proc_acpi_key_val(&ptr, &key, &val)) {
225 if (strcmp(key,
"state") == 0) {
226 if (strcmp(val,
"on-line") == 0) {
236 int *seconds,
int *percent)
238 struct dirent *dent =
NULL;
248 dirp = opendir(proc_acpi_battery_path);
252 while ((dent = readdir(dirp)) !=
NULL) {
253 const char *node = dent->d_name;
254 check_proc_acpi_battery(node, &have_battery, &charging,
260 dirp = opendir(proc_acpi_ac_adapter_path);
264 while ((dent = readdir(dirp)) !=
NULL) {
265 const char *node = dent->d_name;
266 check_proc_acpi_ac_adapter(node, &have_ac);
273 }
else if (charging) {
275 }
else if (have_ac) {
286 next_string(
char **_ptr,
char **_str)
291 while (*ptr ==
' ') {
300 while ((*ptr !=
' ') && (*ptr !=
'\n') && (*ptr !=
'\0'))
312 int_string(
char *str,
int *val)
315 *val = (int) strtol(str, &endptr, 0);
316 return ((*str !=
'\0') && (*endptr ==
'\0'));
322 int *seconds,
int *percent)
326 int battery_status = 0;
327 int battery_flag = 0;
328 int battery_percent = 0;
329 int battery_time = 0;
330 const int fd = open(proc_apm_path, O_RDONLY);
340 br = read(fd, buf,
sizeof (buf) - 1);
348 if (!next_string(&ptr, &str)) {
351 if (!next_string(&ptr, &str)) {
354 if (!next_string(&ptr, &str)) {
358 if (!next_string(&ptr, &str)) {
360 }
else if (!int_string(str, &ac_status)) {
364 if (!next_string(&ptr, &str)) {
366 }
else if (!int_string(str, &battery_status)) {
369 if (!next_string(&ptr, &str)) {
371 }
else if (!int_string(str, &battery_flag)) {
374 if (!next_string(&ptr, &str)) {
377 if (str[strlen(str) - 1] ==
'%') {
378 str[strlen(str) - 1] =
'\0';
380 if (!int_string(str, &battery_percent)) {
384 if (!next_string(&ptr, &str)) {
386 }
else if (!int_string(str, &battery_time)) {
390 if (!next_string(&ptr, &str)) {
392 }
else if (strcmp(str,
"min") == 0) {
396 if (battery_flag == 0xFF) {
398 }
else if (battery_flag & (1 << 7)) {
400 }
else if (battery_flag & (1 << 3)) {
403 }
else if (ac_status == 1) {
414 const int pct = battery_percent;
415 const int secs = battery_time;
418 *percent = (pct > 100) ? 100 : pct;
433 const char *base = sys_class_power_supply_path;
437 dirp = opendir(base);
446 while ((dent = readdir(dirp)) !=
NULL) {
447 const char *
name = dent->d_name;
456 }
else if (!read_power_file(base, name,
"type", str,
sizeof (str))) {
458 }
else if (
SDL_strcmp(str,
"Battery\n") != 0) {
463 if (read_power_file(base, name,
"present", str,
sizeof (str)) && (
SDL_strcmp(str,
"0\n") == 0)) {
465 }
else if (!read_power_file(base, name,
"status", str,
sizeof (str))) {
467 }
else if (
SDL_strcmp(str,
"Charging\n") == 0) {
469 }
else if (
SDL_strcmp(str,
"Discharging\n") == 0) {
477 if (!read_power_file(base, name,
"capacity", str,
sizeof (str))) {
481 pct = (pct > 100) ? 100 : pct;
484 if (!read_power_file(base, name,
"time_to_empty_now", str,
sizeof (str))) {
488 secs = (secs <= 0) ? -1 : secs;
495 if ((secs < 0) && (*seconds < 0)) {
496 if ((pct < 0) && (*percent < 0)) {
498 }
else if (pct > *percent) {
501 }
else if (secs > *seconds) {
SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *)
SDL_bool SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *, int *, int *)
GLuint const GLchar * name
GLenum GLuint GLenum GLsizei const GLchar * buf
SDL_PowerState
The basic state for the system's power supply.
GLsizei const GLchar *const * path
SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *, int *, int *)