21 #include "../../SDL_internal.h" 23 #ifndef SDL_POWER_DISABLED 29 #include <sys/types.h> 35 #include "../SDL_syspower.h" 37 #include "../../core/linux/SDL_dbus.h" 39 static const char *proc_apm_path =
"/proc/apm";
40 static const char *proc_acpi_battery_path =
"/proc/acpi/battery";
41 static const char *proc_acpi_ac_adapter_path =
"/proc/acpi/ac_adapter";
42 static const char *sys_class_power_supply_path =
"/sys/class/power_supply";
45 open_power_file(
const char *
base,
const char *node,
const char *
key)
47 const size_t pathlen = strlen(base) + strlen(node) + strlen(key) + 3;
48 char *
path = (
char *) alloca(pathlen);
53 snprintf(path, pathlen,
"%s/%s/%s", base, node, key);
54 return open(path, O_RDONLY);
59 read_power_file(
const char *base,
const char *node,
const char *key,
60 char *
buf,
size_t buflen)
63 const int fd = open_power_file(base, node, key);
67 br = read(fd, buf, buflen-1);
78 make_proc_acpi_key_val(
char **_ptr,
char **_key,
char **_val)
92 while ((*ptr !=
':') && (*ptr !=
'\0')) {
102 while ((*ptr ==
' ') && (*ptr !=
'\0')) {
112 while ((*ptr !=
'\n') && (*ptr !=
'\0')) {
125 check_proc_acpi_battery(
const char * node,
SDL_bool * have_battery,
126 SDL_bool * charging,
int *seconds,
int *percent)
128 const char *base = proc_acpi_battery_path;
141 if (!read_power_file(base, node,
"state", state,
sizeof (state))) {
143 }
else if (!read_power_file(base, node,
"info", info,
sizeof (info))) {
148 while (make_proc_acpi_key_val(&ptr, &key, &val)) {
149 if (strcmp(key,
"present") == 0) {
150 if (strcmp(val,
"yes") == 0) {
153 }
else if (strcmp(key,
"charging state") == 0) {
155 if (strcmp(val,
"charging/discharging") == 0) {
157 }
else if (strcmp(val,
"charging") == 0) {
160 }
else if (strcmp(key,
"remaining capacity") == 0) {
162 const int cvt = (int) strtol(val, &endptr, 10);
163 if (*endptr ==
' ') {
170 while (make_proc_acpi_key_val(&ptr, &key, &val)) {
171 if (strcmp(key,
"design capacity") == 0) {
173 const int cvt = (int) strtol(val, &endptr, 10);
174 if (*endptr ==
' ') {
180 if ((maximum >= 0) && (remaining >= 0)) {
181 pct = (int) ((((
float) remaining) / ((
float) maximum)) * 100.0f);
184 }
else if (pct > 100) {
195 if ((secs < 0) && (*seconds < 0)) {
196 if ((pct < 0) && (*percent < 0)) {
199 if (pct > *percent) {
202 }
else if (secs > *seconds) {
214 check_proc_acpi_ac_adapter(
const char * node,
SDL_bool * have_ac)
216 const char *base = proc_acpi_ac_adapter_path;
222 if (!read_power_file(base, node,
"state", state,
sizeof (state))) {
227 while (make_proc_acpi_key_val(&ptr, &key, &val)) {
228 if (strcmp(key,
"state") == 0) {
229 if (strcmp(val,
"on-line") == 0) {
239 int *seconds,
int *percent)
241 struct dirent *dent =
NULL;
251 dirp = opendir(proc_acpi_battery_path);
255 while ((dent = readdir(dirp)) !=
NULL) {
256 const char *node = dent->d_name;
257 check_proc_acpi_battery(node, &have_battery, &charging,
263 dirp = opendir(proc_acpi_ac_adapter_path);
267 while ((dent = readdir(dirp)) !=
NULL) {
268 const char *node = dent->d_name;
269 check_proc_acpi_ac_adapter(node, &have_ac);
276 }
else if (charging) {
278 }
else if (have_ac) {
289 next_string(
char **_ptr,
char **_str)
294 while (*ptr ==
' ') {
303 while ((*ptr !=
' ') && (*ptr !=
'\n') && (*ptr !=
'\0'))
315 int_string(
char *str,
int *val)
318 *val = (int) strtol(str, &endptr, 0);
319 return ((*str !=
'\0') && (*endptr ==
'\0'));
325 int *seconds,
int *percent)
329 int battery_status = 0;
330 int battery_flag = 0;
331 int battery_percent = 0;
332 int battery_time = 0;
333 const int fd = open(proc_apm_path, O_RDONLY);
343 br = read(fd, buf,
sizeof (buf) - 1);
351 if (!next_string(&ptr, &str)) {
354 if (!next_string(&ptr, &str)) {
357 if (!next_string(&ptr, &str)) {
361 if (!next_string(&ptr, &str)) {
363 }
else if (!int_string(str, &ac_status)) {
367 if (!next_string(&ptr, &str)) {
369 }
else if (!int_string(str, &battery_status)) {
372 if (!next_string(&ptr, &str)) {
374 }
else if (!int_string(str, &battery_flag)) {
377 if (!next_string(&ptr, &str)) {
380 if (str[strlen(str) - 1] ==
'%') {
381 str[strlen(str) - 1] =
'\0';
383 if (!int_string(str, &battery_percent)) {
387 if (!next_string(&ptr, &str)) {
389 }
else if (!int_string(str, &battery_time)) {
393 if (!next_string(&ptr, &str)) {
395 }
else if (strcmp(str,
"min") == 0) {
399 if (battery_flag == 0xFF) {
401 }
else if (battery_flag & (1 << 7)) {
403 }
else if (battery_flag & (1 << 3)) {
406 }
else if (ac_status == 1) {
417 const int pct = battery_percent;
418 const int secs = battery_time;
421 *percent = (pct > 100) ? 100 : pct;
434 const char *base = sys_class_power_supply_path;
438 dirp = opendir(base);
447 while ((dent = readdir(dirp)) !=
NULL) {
448 const char *
name = dent->d_name;
457 }
else if (!read_power_file(base, name,
"type", str,
sizeof (str))) {
459 }
else if (
SDL_strcmp(str,
"Battery\n") != 0) {
467 if (read_power_file(base, name,
"scope", str,
sizeof (str))) {
474 if (read_power_file(base, name,
"present", str,
sizeof (str)) && (
SDL_strcmp(str,
"0\n") == 0)) {
476 }
else if (!read_power_file(base, name,
"status", str,
sizeof (str))) {
478 }
else if (
SDL_strcmp(str,
"Charging\n") == 0) {
480 }
else if (
SDL_strcmp(str,
"Discharging\n") == 0) {
488 if (!read_power_file(base, name,
"capacity", str,
sizeof (str))) {
492 pct = (pct > 100) ? 100 : pct;
495 if (!read_power_file(base, name,
"time_to_empty_now", str,
sizeof (str))) {
499 secs = (secs <= 0) ? -1 : secs;
506 if ((secs < 0) && (*seconds < 0)) {
507 if ((pct < 0) && (*percent < 0)) {
509 }
else if (pct > *percent) {
512 }
else if (secs > *seconds) {
530 #define UPOWER_DBUS_NODE "org.freedesktop.UPower" 531 #define UPOWER_DBUS_PATH "/org/freedesktop/UPower" 532 #define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower" 533 #define UPOWER_DEVICE_DBUS_INTERFACE "org.freedesktop.UPower.Device" 536 check_upower_device(DBusConnection *conn,
const char *path,
SDL_PowerState *state,
int *seconds,
int *percent)
546 if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE,
"Type", DBUS_TYPE_UINT32, &ui32)) {
548 }
else if (ui32 != 2) {
550 }
else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE,
"PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) {
554 }
else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE,
"IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) {
558 }
else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE,
"State", DBUS_TYPE_UINT32, &ui32)) {
560 }
else if (ui32 == 1) {
562 }
else if ((ui32 == 2) || (ui32 == 3)) {
564 }
else if (ui32 == 4) {
570 if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE,
"Percentage", DBUS_TYPE_DOUBLE, &d)) {
574 pct = (pct > 100) ? 100 : pct;
577 if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE,
"TimeToEmpty", DBUS_TYPE_INT64, &si64)) {
581 secs = (secs <= 0) ? -1 : secs;
588 if ((secs < 0) && (*seconds < 0)) {
589 if ((pct < 0) && (*percent < 0)) {
591 }
else if (pct > *percent) {
594 }
else if (secs > *seconds) {
612 SDL_DBusContext *dbus = SDL_DBus_GetContext();
616 if (!dbus || !SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE,
"EnumerateDevices",
618 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) {
627 for (i = 0; i < numpaths; i++) {
628 check_upower_device(dbus->system_conn, paths[i], state, seconds, percent);
632 dbus->free_string_array(paths);
SDL_bool SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *, int *, int *)
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst st
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
SDL_bool SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *, int *, int *)
GLuint const GLchar * name
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst base
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
GLenum GLuint GLenum GLsizei const GLchar * buf
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
SDL_PowerState
The basic state for the system's power supply.
SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *)
GLsizei const GLchar *const * path
GLsizei const GLuint * paths
SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *, int *, int *)