2014-09-20 04:23:18 +00:00
|
|
|
/* Not particularly good interface to hal, for programs that used to use
|
|
|
|
* apm.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <upower.h>
|
|
|
|
#include "apm.h"
|
|
|
|
|
|
|
|
int num_batteries = 0;
|
|
|
|
|
|
|
|
struct context {
|
|
|
|
int current;
|
|
|
|
int needed;
|
|
|
|
guint state;
|
|
|
|
int percentage;
|
|
|
|
gboolean ac;
|
|
|
|
int time;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void get_devinfo(gpointer device, gpointer result)
|
|
|
|
{
|
|
|
|
gboolean online;
|
|
|
|
gdouble percentage;
|
|
|
|
guint state;
|
|
|
|
guint kind;
|
|
|
|
gint64 time_to_empty;
|
|
|
|
gint64 time_to_full;
|
2014-10-05 15:30:02 +00:00
|
|
|
struct context *ctx = result;
|
2014-09-20 04:23:18 +00:00
|
|
|
|
|
|
|
g_object_get(G_OBJECT(device), "percentage", &percentage,
|
|
|
|
"online", &online,
|
|
|
|
"state", &state,
|
|
|
|
"kind", &kind,
|
|
|
|
"time-to-empty", &time_to_empty,
|
|
|
|
"time-to-full", &time_to_full,
|
|
|
|
NULL);
|
|
|
|
if (kind == UP_DEVICE_KIND_BATTERY) {
|
|
|
|
if (ctx->current == ctx->needed) {
|
|
|
|
ctx->percentage = (int)percentage;
|
|
|
|
ctx->state = state;
|
2014-10-05 15:30:02 +00:00
|
|
|
if (time_to_empty)
|
2014-09-20 04:23:18 +00:00
|
|
|
ctx->time = time_to_empty;
|
2014-10-05 15:30:02 +00:00
|
|
|
else
|
2014-09-20 04:23:18 +00:00
|
|
|
ctx->time = time_to_full;
|
|
|
|
}
|
|
|
|
ctx->current++;
|
|
|
|
} else if (kind == UP_DEVICE_KIND_LINE_POWER) {
|
|
|
|
ctx->ac |= online;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-05 15:30:02 +00:00
|
|
|
int upower_supported(void)
|
|
|
|
{
|
|
|
|
UpClient *up;
|
2014-09-20 04:23:18 +00:00
|
|
|
up = up_client_new();
|
|
|
|
|
|
|
|
if (!up) {
|
|
|
|
return 0;
|
2014-10-05 15:30:02 +00:00
|
|
|
} else {
|
|
|
|
GPtrArray *devices = up_client_get_devices(up);
|
2014-09-20 04:23:18 +00:00
|
|
|
|
|
|
|
if (!devices) {
|
|
|
|
g_object_unref(up);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
g_ptr_array_unref(devices);
|
|
|
|
g_object_unref(up);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill the passed apm_info struct. */
|
2014-10-05 15:30:02 +00:00
|
|
|
int upower_read(int battery, apm_info *info)
|
|
|
|
{
|
|
|
|
UpClient *up;
|
|
|
|
GPtrArray *devices = NULL;
|
2014-09-20 04:23:18 +00:00
|
|
|
|
|
|
|
up = up_client_new();
|
|
|
|
|
2014-10-05 15:30:02 +00:00
|
|
|
if (!up)
|
2014-09-20 04:23:18 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
#if !UP_CHECK_VERSION(0, 9, 99)
|
|
|
|
/* Allow a battery that was not present before to appear. */
|
|
|
|
up_client_enumerate_devices_sync(up, NULL, NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
devices = up_client_get_devices(up);
|
|
|
|
|
2014-10-05 15:30:02 +00:00
|
|
|
if (!devices)
|
2014-09-20 04:23:18 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
info->battery_flags = 0;
|
|
|
|
info->using_minutes = 0;
|
|
|
|
|
|
|
|
struct context ctx = {
|
|
|
|
.current = 0,
|
|
|
|
.needed = battery - 1,
|
|
|
|
.state = UP_DEVICE_STATE_UNKNOWN,
|
|
|
|
.percentage = -1,
|
|
|
|
.ac = FALSE,
|
|
|
|
.time = -1
|
|
|
|
};
|
|
|
|
|
|
|
|
g_ptr_array_foreach(devices, &get_devinfo, &ctx);
|
|
|
|
|
|
|
|
info->ac_line_status = ctx.ac;
|
|
|
|
|
|
|
|
/* remaining_time and charge_level.percentage are not a mandatory
|
|
|
|
* keys, so if not present, -1 will be returned */
|
|
|
|
info->battery_time = ctx.time;
|
|
|
|
info->battery_percentage = ctx.percentage;
|
|
|
|
if (ctx.state == UP_DEVICE_STATE_DISCHARGING) {
|
|
|
|
info->battery_status = BATTERY_STATUS_CHARGING;
|
|
|
|
/* charge_level.warning and charge_level.low are not
|
|
|
|
* required to be available; this is good enough */
|
2014-10-05 15:30:02 +00:00
|
|
|
if (info->battery_percentage < 1)
|
2014-09-20 04:23:18 +00:00
|
|
|
info->battery_status = BATTERY_STATUS_CRITICAL;
|
2014-10-05 15:30:02 +00:00
|
|
|
else if (info->battery_percentage < 10)
|
2014-09-20 04:23:18 +00:00
|
|
|
info->battery_status = BATTERY_STATUS_LOW;
|
2014-10-05 15:30:02 +00:00
|
|
|
} else if (info->ac_line_status && ctx.state == UP_DEVICE_STATE_CHARGING) {
|
2014-09-20 04:23:18 +00:00
|
|
|
info->battery_status = BATTERY_STATUS_CHARGING;
|
|
|
|
info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING;
|
2014-10-05 15:30:02 +00:00
|
|
|
} else if (info->ac_line_status) {
|
2014-09-20 04:23:18 +00:00
|
|
|
/* Must be fully charged. */
|
|
|
|
info->battery_status = BATTERY_STATUS_HIGH;
|
2014-10-05 15:30:02 +00:00
|
|
|
} else {
|
2014-09-20 04:23:18 +00:00
|
|
|
fprintf(stderr, "unknown battery state\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx.percentage < 0) {
|
|
|
|
info->battery_percentage = 0;
|
|
|
|
info->battery_time = 0;
|
|
|
|
info->battery_status = BATTERY_STATUS_ABSENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_ptr_array_free(devices, TRUE);
|
|
|
|
g_object_unref(up);
|
|
|
|
return 0;
|
|
|
|
}
|