wmclock: Bump to version 1.0.15.
[dockapps.git] / wmbattery / upower.c
blob857c7f4d762cc4c960f8739b17e2a04a78420b38
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;
49 ctx->current++;
50 } else if (kind == UP_DEVICE_KIND_LINE_POWER) {
51 ctx->ac |= online;
55 int upower_supported(void)
57 UpClient *up;
58 up = up_client_new();
60 if (!up) {
61 return 0;
62 } else {
63 GPtrArray *devices = up_client_get_devices(up);
65 if (!devices) {
66 g_object_unref(up);
67 return 0;
68 } else {
69 g_ptr_array_unref(devices);
70 g_object_unref(up);
71 return 1;
76 /* Fill the passed apm_info struct. */
77 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;
87 #if !UP_CHECK_VERSION(0, 9, 99)
88 /* Allow a battery that was not present before to appear. */
89 up_client_enumerate_devices_sync(up, NULL, NULL);
90 #endif
92 devices = up_client_get_devices(up);
94 if (!devices)
95 return -1;
97 info->battery_flags = 0;
98 info->using_minutes = 0;
100 struct context ctx = {
101 .current = 0,
102 .needed = battery - 1,
103 .state = UP_DEVICE_STATE_UNKNOWN,
104 .percentage = -1,
105 .ac = FALSE,
106 .time = -1
109 g_ptr_array_foreach(devices, &get_devinfo, &ctx);
111 info->ac_line_status = ctx.ac;
113 /* remaining_time and charge_level.percentage are not a mandatory
114 * keys, so if not present, -1 will be returned */
115 info->battery_time = ctx.time;
116 info->battery_percentage = ctx.percentage;
117 if (ctx.state == UP_DEVICE_STATE_DISCHARGING) {
118 info->battery_status = BATTERY_STATUS_CHARGING;
119 /* charge_level.warning and charge_level.low are not
120 * required to be available; this is good enough */
121 if (info->battery_percentage < 1)
122 info->battery_status = BATTERY_STATUS_CRITICAL;
123 else if (info->battery_percentage < 10)
124 info->battery_status = BATTERY_STATUS_LOW;
125 } else if (info->ac_line_status && ctx.state == UP_DEVICE_STATE_CHARGING) {
126 info->battery_status = BATTERY_STATUS_CHARGING;
127 info->battery_flags = info->battery_flags | BATTERY_FLAGS_CHARGING;
128 } else if (info->ac_line_status) {
129 /* Must be fully charged. */
130 info->battery_status = BATTERY_STATUS_HIGH;
131 } else {
132 fprintf(stderr, "unknown battery state\n");
135 if (ctx.percentage < 0) {
136 info->battery_percentage = 0;
137 info->battery_time = 0;
138 info->battery_status = BATTERY_STATUS_ABSENT;
141 g_ptr_array_free(devices, TRUE);
142 g_object_unref(up);
143 return 0;