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 ==
' ') {
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;
459 }
else if (!read_power_file(
base,
name,
"type", str,
sizeof (str))) {
461 }
else if (
SDL_strcmp(str,
"Battery\n") != 0) {
469 if (read_power_file(
base,
name,
"scope", str,
sizeof (str))) {
476 if (read_power_file(
base,
name,
"present", str,
sizeof (str)) && (
SDL_strcmp(str,
"0\n") == 0)) {
478 }
else if (!read_power_file(
base,
name,
"status", str,
sizeof (str))) {
480 }
else if (
SDL_strcmp(str,
"Charging\n") == 0) {
482 }
else if (
SDL_strcmp(str,
"Discharging\n") == 0) {
490 if (!read_power_file(
base,
name,
"capacity", str,
sizeof (str))) {
494 pct = (pct > 100) ? 100 : pct;
497 if (read_power_file(
base,
name,
"time_to_empty_now", str,
sizeof (str))) {
499 secs = (secs <= 0) ? -1 : secs;
502 energy = (read_power_file(
base,
name,
"energy_now", str,
sizeof (str))) ?
SDL_atoi(str) : -1;
503 power = (read_power_file(
base,
name,
"power_now", str,
sizeof (str))) ?
SDL_atoi(str) : -1;
504 secs = (energy >= 0 && power > 0) ? (3600LL * energy) / power : -1;
513 if ((secs < 0) && (*seconds < 0)) {
514 if ((pct < 0) && (*percent < 0)) {
516 }
else if (pct > *percent) {
519 }
else if (secs > *seconds) {
537 #define UPOWER_DBUS_NODE "org.freedesktop.UPower"
538 #define UPOWER_DBUS_PATH "/org/freedesktop/UPower"
539 #define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower"
540 #define UPOWER_DEVICE_DBUS_INTERFACE "org.freedesktop.UPower.Device"
553 if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE,
path, UPOWER_DEVICE_DBUS_INTERFACE,
"Type", DBUS_TYPE_UINT32, &ui32)) {
555 }
else if (ui32 != 2) {
557 }
else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE,
path, UPOWER_DEVICE_DBUS_INTERFACE,
"PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) {
561 }
else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE,
path, UPOWER_DEVICE_DBUS_INTERFACE,
"IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) {
565 }
else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE,
path, UPOWER_DEVICE_DBUS_INTERFACE,
"State", DBUS_TYPE_UINT32, &ui32)) {
567 }
else if (ui32 == 1) {
569 }
else if ((ui32 == 2) || (ui32 == 3)) {
571 }
else if (ui32 == 4) {
577 if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE,
path, UPOWER_DEVICE_DBUS_INTERFACE,
"Percentage", DBUS_TYPE_DOUBLE, &
d)) {
581 pct = (pct > 100) ? 100 : pct;
584 if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE,
path, UPOWER_DEVICE_DBUS_INTERFACE,
"TimeToEmpty", DBUS_TYPE_INT64, &si64)) {
588 secs = (secs <= 0) ? -1 : secs;
595 if ((secs < 0) && (*seconds < 0)) {
596 if ((pct < 0) && (*percent < 0)) {
598 }
else if (pct > *percent) {
601 }
else if (secs > *seconds) {
619 SDL_DBusContext *dbus = SDL_DBus_GetContext();
623 if (!dbus || !SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE,
"EnumerateDevices",
625 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &
paths, &numpaths, DBUS_TYPE_INVALID)) {
634 for (
i = 0;
i < numpaths;
i++) {
635 check_upower_device(dbus->system_conn,
paths[
i],
state, seconds, percent);
639 dbus->free_string_array(
paths);
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
GLsizei const GLuint * paths
GLuint const GLchar * name
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei const GLchar *const * path
SDL_PowerState
The basic state for the system's power supply.
@ SDL_POWERSTATE_NO_BATTERY
@ SDL_POWERSTATE_CHARGING
@ SDL_POWERSTATE_ON_BATTERY
SDL_bool SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *, int *, int *)
SDL_bool SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *, int *, int *)
SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *)
SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *, int *, int *)
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)
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
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
typedef int(__stdcall *FARPROC)()