wmbattery: Add to repository.
[dockapps.git] / wmbattery / upower.c
blob0890908d873aca0ed99bf6480b45736b2286826a
1 /* Not particularly good interface to hal, for programs that used to use
2 * apm.
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <upower.h>
10 #include "apm.h"
12 int num_batteries = 0;
14 struct context {
15 int current;
16 int needed;
17 guint state;
18 int percentage;
19 gboolean ac;
20 int time;
23 static void get_devinfo(gpointer device, gpointer result)
25 gboolean online;
26 gdouble percentage;
27 guint state;
28 guint kind;
29 gint64 time_to_empty;
30 gint64 time_to_full;
31 struct context * ctx = result;
33 g_object_get(G_OBJECT(device), "percentage", &percentage,
34 "online", &online,
35 "state", &state,
36 "kind", &kind,
37 "time-to-empty", &time_to_empty,
38 "time-to-full", &time_to_full,
39 NULL);
40 if (kind == UP_DEVICE_KIND_BATTERY) {
41 if (ctx->current == ctx->needed) {
42 ctx->percentage = (int)percentage;
43 ctx->state = state;
44 if (time_to_empty) {
45 ctx->time = time_to_empty;
46 } else {
47 ctx->time = time_to_full;
50 ctx->current++;
51 } else if (kind == UP_DEVICE_KIND_LINE_POWER) {
52 ctx->ac |= online;
56 int upower_supported (void) {
57 UpClient * up;
58 up = up_client_new();
60 if (!up) {
61 return 0;
63 else {
64 GPtrArray * devices = up_client_get_devices(up);
66 if (!devices) {
67 g_object_unref(up);
68 return 0;
69 } else {
70 g_ptr_array_unref(devices);
71 g_object_unref(up);
72 return 1;
77 /* Fill the passed apm_info struct. */
78 int upower_read(int battery, apm_info *info) {
79 UpClient * up;
80 GPtrArray * devices = NULL;
82 up = up_client_new();
84 if (!up) {
85 return -1;
88 #if !UP_CHECK_VERSION(0, 9, 99)
89 /* Allow a battery that was not present before to appear. */
90 up_client_enumerate_devices_sync(up, NULL, NULL);
91 #endif
93 devices = up_client_get_devices(up);
95 if (!devices) {
96 return -1;
99 info->battery_flags = 0;
100 info->using_minutes = 0;
102 struct context ctx = {
103 .current = 0,
104 .needed = battery - 1,
105 .state = UP_DEVICE_STATE_UNKNOWN,
106 .percentage = -1,
107 .ac = FALSE,
108 .time = -1
111 g_ptr_array_foreach(devices, &get_devinfo, &ctx);
113 info->ac_line_status = ctx.ac;
115 /* remaining_time and charge_level.percentage are not a mandatory
116 * keys, so if not present, -1 will be returned */
117 info->battery_time = ctx.time;
118 info->battery_percentage = ctx.percentage;
119 if (ctx.state == UP_DEVICE_STATE_DISCHARGING) {
120 info->battery_status = BATTERY_STATUS_CHARGING;
121 /* charge_level.warning and charge_level.low are not
122 * required to be available; this is good enough */
123 if (info->battery_percentage < 1) {
124 info->battery_status = BATTERY_STATUS_CRITICAL;
126 else if (info->battery_percentage < 10) {
127 info->battery_status = BATTERY_STATUS_LOW;
130 else if (info->ac_line_status && ctx.state == UP_DEVICE_STATE_CHARGING) {
131 info->battery_status = BATTERY_STATUS_CHARGING;
132 info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING;
134 else if (info->ac_line_status) {
135 /* Must be fully charged. */
136 info->battery_status = BATTERY_STATUS_HIGH;
138 else {
139 fprintf(stderr, "unknown battery state\n");
142 if (ctx.percentage < 0) {
143 info->battery_percentage = 0;
144 info->battery_time = 0;
145 info->battery_status = BATTERY_STATUS_ABSENT;
148 g_ptr_array_free(devices, TRUE);
149 g_object_unref(up);
150 return 0;