|
|
|
@ -34,6 +34,8 @@
|
|
|
|
|
#include "SDL_power.h"
|
|
|
|
|
#include "../SDL_syspower.h"
|
|
|
|
|
|
|
|
|
|
#include "../../core/linux/SDL_dbus.h"
|
|
|
|
|
|
|
|
|
|
static const char *proc_apm_path = "/proc/apm";
|
|
|
|
|
static const char *proc_acpi_battery_path = "/proc/acpi/battery";
|
|
|
|
|
static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter";
|
|
|
|
@ -426,8 +428,6 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state,
|
|
|
|
|
return SDL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* !!! FIXME: implement d-bus queries to org.freedesktop.UPower. */
|
|
|
|
|
|
|
|
|
|
SDL_bool
|
|
|
|
|
SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *seconds, int *percent)
|
|
|
|
|
{
|
|
|
|
@ -514,6 +514,118 @@ SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *second
|
|
|
|
|
return SDL_TRUE; /* don't look any further. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* d-bus queries to org.freedesktop.UPower. */
|
|
|
|
|
#if SDL_USE_LIBDBUS
|
|
|
|
|
#define UPOWER_DBUS_NODE "org.freedesktop.UPower"
|
|
|
|
|
#define UPOWER_DBUS_PATH "/org/freedesktop/UPower"
|
|
|
|
|
#define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower"
|
|
|
|
|
#define UPOWER_DEVICE_DBUS_INTERFACE "org.freedesktop.UPower.Device"
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *state, int *seconds, int *percent)
|
|
|
|
|
{
|
|
|
|
|
SDL_bool choose = SDL_FALSE;
|
|
|
|
|
SDL_PowerState st;
|
|
|
|
|
int secs;
|
|
|
|
|
int pct;
|
|
|
|
|
Uint32 ui32 = 0;
|
|
|
|
|
Sint64 si64 = 0;
|
|
|
|
|
double d = 0.0;
|
|
|
|
|
|
|
|
|
|
if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Type", DBUS_TYPE_UINT32, &ui32)) {
|
|
|
|
|
return; /* Don't know _what_ we're looking at. Give up on it. */
|
|
|
|
|
} else if (ui32 != 2) { /* 2==Battery*/
|
|
|
|
|
return; /* we don't care about UPS and such. */
|
|
|
|
|
} else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) {
|
|
|
|
|
return;
|
|
|
|
|
} else if (!ui32) {
|
|
|
|
|
return; /* we don't care about random devices with batteries, like wireless controllers, etc */
|
|
|
|
|
} else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) {
|
|
|
|
|
return;
|
|
|
|
|
} else if (!ui32) {
|
|
|
|
|
st = SDL_POWERSTATE_NO_BATTERY;
|
|
|
|
|
} else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) {
|
|
|
|
|
st = SDL_POWERSTATE_UNKNOWN; /* uh oh */
|
|
|
|
|
} else if (ui32 == 1) { /* 1 == charging */
|
|
|
|
|
st = SDL_POWERSTATE_CHARGING;
|
|
|
|
|
} else if ((ui32 == 2) || (ui32 == 3)) { /* 2 == discharging, 3 == empty. */
|
|
|
|
|
st = SDL_POWERSTATE_ON_BATTERY;
|
|
|
|
|
} else if (ui32 == 4) { /* 4 == full */
|
|
|
|
|
st = SDL_POWERSTATE_CHARGED;
|
|
|
|
|
} else {
|
|
|
|
|
st = SDL_POWERSTATE_UNKNOWN; /* uh oh */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Percentage", DBUS_TYPE_DOUBLE, &d)) {
|
|
|
|
|
pct = -1; /* some old/cheap batteries don't set this property. */
|
|
|
|
|
} else {
|
|
|
|
|
pct = (int) d;
|
|
|
|
|
pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "TimeToEmpty", DBUS_TYPE_INT64, &si64)) {
|
|
|
|
|
secs = -1;
|
|
|
|
|
} else {
|
|
|
|
|
secs = (int) si64;
|
|
|
|
|
secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* We pick the battery that claims to have the most minutes left.
|
|
|
|
|
* (failing a report of minutes, we'll take the highest percent.)
|
|
|
|
|
*/
|
|
|
|
|
if ((secs < 0) && (*seconds < 0)) {
|
|
|
|
|
if ((pct < 0) && (*percent < 0)) {
|
|
|
|
|
choose = SDL_TRUE; /* at least we know there's a battery. */
|
|
|
|
|
} else if (pct > *percent) {
|
|
|
|
|
choose = SDL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
} else if (secs > *seconds) {
|
|
|
|
|
choose = SDL_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (choose) {
|
|
|
|
|
*seconds = secs;
|
|
|
|
|
*percent = pct;
|
|
|
|
|
*state = st;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
SDL_bool
|
|
|
|
|
SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *seconds, int *percent)
|
|
|
|
|
{
|
|
|
|
|
SDL_bool retval = SDL_FALSE;
|
|
|
|
|
|
|
|
|
|
#if SDL_USE_LIBDBUS
|
|
|
|
|
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
|
|
|
|
char **paths = NULL;
|
|
|
|
|
int i, numpaths = 0;
|
|
|
|
|
|
|
|
|
|
if (!SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "EnumerateDevices",
|
|
|
|
|
DBUS_TYPE_INVALID,
|
|
|
|
|
DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) {
|
|
|
|
|
return SDL_FALSE; /* try a different approach than UPower. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
retval = SDL_TRUE; /* Clearly we can use this interface. */
|
|
|
|
|
*state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */
|
|
|
|
|
*seconds = -1;
|
|
|
|
|
*percent = -1;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < numpaths; i++) {
|
|
|
|
|
check_upower_device(dbus->system_conn, paths[i], state, seconds, percent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dbus) {
|
|
|
|
|
dbus->free_string_array(paths);
|
|
|
|
|
}
|
|
|
|
|
#endif /* SDL_USE_LIBDBUS */
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* SDL_POWER_LINUX */
|
|
|
|
|
#endif /* SDL_POWER_DISABLED */
|
|
|
|
|
|
|
|
|
|