1 /* Not particularly good interface to hal, for programs that used to use
12 static DBusConnection
*dbus_ctx
= NULL
;
13 static LibHalContext
*hal_ctx
= NULL
;
15 int num_ac_adapters
= 0;
16 int num_batteries
= 0;
17 char **ac_adapters
= NULL
;
18 char **batteries
= NULL
;
20 int connect_hal (void) {
23 dbus_error_init(&error
);
24 dbus_ctx
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
);
25 if (dbus_ctx
== NULL
) {
26 fprintf(stderr
, "error: dbus_bus_get: %s: %s\n",
27 error
.name
, error
.message
);
28 LIBHAL_FREE_DBUS_ERROR(&error
);
31 if ((hal_ctx
= libhal_ctx_new()) == NULL
) {
32 fprintf(stderr
, "error: libhal_ctx_new\n");
33 LIBHAL_FREE_DBUS_ERROR(&error
);
36 if (!libhal_ctx_set_dbus_connection(hal_ctx
, dbus_ctx
)) {
37 fprintf(stderr
, "error: libhal_ctx_set_dbus_connection: %s: %s\n",
38 error
.name
, error
.message
);
39 LIBHAL_FREE_DBUS_ERROR(&error
);
42 if (!libhal_ctx_init(hal_ctx
, &error
)) {
43 if (dbus_error_is_set(&error
)) {
44 fprintf(stderr
, "error: libhal_ctx_init: %s: %s\n", error
.name
, error
.message
);
45 LIBHAL_FREE_DBUS_ERROR(&error
);
47 fprintf(stderr
, "Could not initialise connection to hald.\n"
48 "Normally this means the HAL daemon (hald) is not running or not ready.\n");
55 int hal_ready (void) {
56 if (hal_ctx
&& dbus_connection_get_is_connected(dbus_ctx
)) {
60 /* The messy business of reconnecting.
61 * dbus's design is crap when it comes to reconnecting.
62 * If dbus is down, can't actually close the connection to hal,
63 * since libhal wants to use dbus to do it. */
65 dbus_connection_close(dbus_ctx
);
66 dbus_connection_unref(dbus_ctx
);
75 signed int get_hal_int (const char *udi
, const char *key
, int optional
) {
83 dbus_error_init(&error
);
85 ret
= libhal_device_get_property_int (hal_ctx
, udi
, key
, &error
);
87 if (! dbus_error_is_set (&error
)) {
92 fprintf(stderr
, "error: libhal_device_get_property_int: %s: %s\n",
93 error
.name
, error
.message
);
95 dbus_error_free (&error
);
100 signed int get_hal_bool (const char *udi
, const char *key
, int optional
) {
108 dbus_error_init(&error
);
110 ret
= libhal_device_get_property_bool (hal_ctx
, udi
, key
, &error
);
112 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) {
128 dbus_error_init(&error
);
131 libhal_free_string_array(ac_adapters
);
132 ac_adapters
= libhal_find_device_by_capability(hal_ctx
, "ac_adapter",
133 &num_ac_adapters
, &error
);
134 if (dbus_error_is_set (&error
)) {
135 fprintf (stderr
, "error: %s: %s\n", error
.name
, error
.message
);
136 LIBHAL_FREE_DBUS_ERROR (&error
);
140 libhal_free_string_array(batteries
);
141 batteries
= libhal_find_device_by_capability(hal_ctx
, "battery",
142 &num_batteries
, &error
);
143 if (dbus_error_is_set (&error
)) {
144 fprintf (stderr
, "error: %s: %s\n", error
.name
, error
.message
);
145 LIBHAL_FREE_DBUS_ERROR (&error
);
149 int simplehal_supported (void) {
150 if (! connect_hal()) {
159 /* Fill the passed apm_info struct. */
160 int simplehal_read (int battery
, apm_info
*info
) {
164 /* Allow a battery that was not present before to appear. */
165 if (battery
> num_batteries
) {
169 info
->battery_flags
= 0;
170 info
->using_minutes
= 0;
172 info
->ac_line_status
=0;
173 for (i
= 0 ; i
< num_ac_adapters
&& ! info
->ac_line_status
; i
++) {
174 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
;
184 device
=batteries
[battery
-1];
187 if (get_hal_bool(device
, "battery.present", 0) != 1) {
188 info
->battery_percentage
= 0;
189 info
->battery_time
= 0;
190 info
->battery_status
= BATTERY_STATUS_ABSENT
;
194 /* remaining_time and charge_level.percentage are not a mandatory
195 * keys, so if not present, -1 will be returned */
196 info
->battery_time
= get_hal_int(device
, "battery.remaining_time", 1);
197 info
->battery_percentage
= get_hal_int(device
, "battery.charge_level.percentage", 1);
198 if (get_hal_bool(device
, "battery.rechargeable.is_discharging", 0) == 1) {
199 info
->battery_status
= BATTERY_STATUS_CHARGING
;
200 /* charge_level.warning and charge_level.low are not
201 * required to be available; this is good enough */
202 if (info
->battery_percentage
< 1) {
203 info
->battery_status
= BATTERY_STATUS_CRITICAL
;
205 else if (info
->battery_percentage
< 10) {
206 info
->battery_status
= BATTERY_STATUS_LOW
;
209 else if (info
->ac_line_status
&&
210 get_hal_bool(device
, "battery.rechargeable.is_charging", 0) == 1) {
211 info
->battery_status
= BATTERY_STATUS_CHARGING
;
212 info
->battery_flags
= info
->battery_flags
| BATTERY_FLAGS_CHARGING
;
214 else if (info
->ac_line_status
) {
215 /* Must be fully charged. */
216 info
->battery_status
= BATTERY_STATUS_HIGH
;
219 fprintf(stderr
, "unknown battery state\n");