1 /* Not particularly good interface to hal, for programs that used to use
12 static DBusConnection
*dbus_ctx
;
13 static LibHalContext
*hal_ctx
;
15 int num_ac_adapters
= 0;
16 int num_batteries
= 0;
17 char **ac_adapters
= NULL
;
18 char **batteries
= NULL
;
24 dbus_error_init(&error
);
25 dbus_ctx
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
);
26 if (dbus_ctx
== NULL
) {
27 fprintf(stderr
, "error: dbus_bus_get: %s: %s\n",
28 error
.name
, error
.message
);
29 LIBHAL_FREE_DBUS_ERROR(&error
);
32 hal_ctx
= libhal_ctx_new();
33 if (hal_ctx
== NULL
) {
34 fprintf(stderr
, "error: libhal_ctx_new\n");
35 LIBHAL_FREE_DBUS_ERROR(&error
);
38 if (!libhal_ctx_set_dbus_connection(hal_ctx
, dbus_ctx
)) {
39 fprintf(stderr
, "error: libhal_ctx_set_dbus_connection: %s: %s\n",
40 error
.name
, error
.message
);
41 LIBHAL_FREE_DBUS_ERROR(&error
);
44 if (!libhal_ctx_init(hal_ctx
, &error
)) {
45 if (dbus_error_is_set(&error
)) {
46 fprintf(stderr
, "error: libhal_ctx_init: %s: %s\n", error
.name
, error
.message
);
47 LIBHAL_FREE_DBUS_ERROR(&error
);
49 fprintf(stderr
, "Could not initialise connection to hald.\n"
50 "Normally this means the HAL daemon (hald) is not running or not ready.\n");
59 if (hal_ctx
&& dbus_connection_get_is_connected(dbus_ctx
)) {
62 /* The messy business of reconnecting.
63 * dbus's design is crap when it comes to reconnecting.
64 * If dbus is down, can't actually close the connection to hal,
65 * since libhal wants to use dbus to do it. */
67 dbus_connection_close(dbus_ctx
);
68 dbus_connection_unref(dbus_ctx
);
77 signed int get_hal_int(const char *udi
, const char *key
, int optional
)
85 dbus_error_init(&error
);
87 ret
= libhal_device_get_property_int (hal_ctx
, udi
, key
, &error
);
89 if (!dbus_error_is_set(&error
)) {
93 fprintf(stderr
, "error: libhal_device_get_property_int: %s: %s\n",
94 error
.name
, error
.message
);
96 dbus_error_free(&error
);
101 signed int get_hal_bool(const char *udi
, const char *key
, int optional
)
109 dbus_error_init(&error
);
111 ret
= libhal_device_get_property_bool(hal_ctx
, udi
, key
, &error
);
113 if (!dbus_error_is_set(&error
)) {
117 fprintf(stderr
, "error: libhal_device_get_property_bool: %s: %s\n",
118 error
.name
, error
.message
);
120 dbus_error_free(&error
);
125 void find_devices(void)
129 dbus_error_init(&error
);
132 libhal_free_string_array(ac_adapters
);
133 ac_adapters
= libhal_find_device_by_capability(hal_ctx
, "ac_adapter",
134 &num_ac_adapters
, &error
);
135 if (dbus_error_is_set(&error
)) {
136 fprintf(stderr
, "error: %s: %s\n", error
.name
, error
.message
);
137 LIBHAL_FREE_DBUS_ERROR(&error
);
141 libhal_free_string_array(batteries
);
142 batteries
= libhal_find_device_by_capability(hal_ctx
, "battery",
143 &num_batteries
, &error
);
144 if (dbus_error_is_set(&error
)) {
145 fprintf(stderr
, "error: %s: %s\n", error
.name
, error
.message
);
146 LIBHAL_FREE_DBUS_ERROR(&error
);
150 int simplehal_supported(void)
152 if (!connect_hal()) {
160 /* Fill the passed apm_info struct. */
161 int simplehal_read(int battery
, apm_info
*info
)
166 /* Allow a battery that was not present before to appear. */
167 if (battery
> num_batteries
)
170 info
->battery_flags
= 0;
171 info
->using_minutes
= 0;
173 info
->ac_line_status
= 0;
174 for (i
= 0 ; i
< num_ac_adapters
&& !info
->ac_line_status
; i
++)
175 info
->ac_line_status
= (get_hal_bool(ac_adapters
[i
], "ac_adapter.present", 0) == 1);
177 if (battery
> num_batteries
) {
178 info
->battery_percentage
= 0;
179 info
->battery_time
= 0;
180 info
->battery_status
= BATTERY_STATUS_ABSENT
;
183 device
= batteries
[battery
-1];
186 if (get_hal_bool(device
, "battery.present", 0) != 1) {
187 info
->battery_percentage
= 0;
188 info
->battery_time
= 0;
189 info
->battery_status
= BATTERY_STATUS_ABSENT
;
193 /* remaining_time and charge_level.percentage are not a mandatory
194 * keys, so if not present, -1 will be returned */
195 info
->battery_time
= get_hal_int(device
, "battery.remaining_time", 1);
196 info
->battery_percentage
= get_hal_int(device
, "battery.charge_level.percentage", 1);
197 if (get_hal_bool(device
, "battery.rechargeable.is_discharging", 0) == 1) {
198 info
->battery_status
= BATTERY_STATUS_CHARGING
;
199 /* charge_level.warning and charge_level.low are not
200 * required to be available; this is good enough */
201 if (info
->battery_percentage
< 1)
202 info
->battery_status
= BATTERY_STATUS_CRITICAL
;
203 else if (info
->battery_percentage
< 10)
204 info
->battery_status
= BATTERY_STATUS_LOW
;
205 } else if (info
->ac_line_status
&&
206 get_hal_bool(device
, "battery.rechargeable.is_charging", 0) == 1) {
207 info
->battery_status
= BATTERY_STATUS_CHARGING
;
208 info
->battery_flags
= info
->battery_flags
| BATTERY_FLAGS_CHARGING
;
209 } else if (info
->ac_line_status
) {
210 /* Must be fully charged. */
211 info
->battery_status
= BATTERY_STATUS_HIGH
;
213 fprintf(stderr
, "unknown battery state\n");