diff options
author | Monsta <[email protected]> | 2014-12-30 15:56:43 +0300 |
---|---|---|
committer | infirit <[email protected]> | 2014-12-30 14:59:32 +0100 |
commit | 746aedb7c45aabe9aacf8b29bf4b393bcd83c7a4 (patch) | |
tree | 44f8b7ea74f646f655bf1fb9cda6be4732ec565d /battstat/battstat-hal.c | |
parent | 2dcb73c54833ae6af9fd724d40fdbfdbf16296f8 (diff) | |
download | mate-applets-746aedb7c45aabe9aacf8b29bf4b393bcd83c7a4.tar.bz2 mate-applets-746aedb7c45aabe9aacf8b29bf4b393bcd83c7a4.tar.xz |
battstat applet: remove HAL support
Diffstat (limited to 'battstat/battstat-hal.c')
-rw-r--r-- | battstat/battstat-hal.c | 608 |
1 files changed, 0 insertions, 608 deletions
diff --git a/battstat/battstat-hal.c b/battstat/battstat-hal.c deleted file mode 100644 index 28426f33..00000000 --- a/battstat/battstat-hal.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (C) 2005 by Ryan Lortie <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02110-1301, USA. - * - * $Id$ - */ - -#include <config.h> - -#ifdef HAVE_HAL - -#include <dbus/dbus-glib-lowlevel.h> -#include <libhal.h> -#include <string.h> -#include <math.h> - -#include "battstat-hal.h" - -static LibHalContext *battstat_hal_ctx; -static GSList *batteries; -static GSList *adaptors; -static void (*status_updated_callback) (void); - -struct battery_status -{ - int present; - int current_level, design_level, full_level; - int remaining_time; - int charging, discharging; - int rate; -}; - -struct battery_info -{ - char *udi; /* must be first member */ - struct battery_status status; -}; - -struct adaptor_info -{ - char *udi; /* must be first member */ - int present; -}; - -static gboolean -battery_update_property( LibHalContext *ctx, struct battery_info *battery, - const char *key ) -{ - DBusError error; - gboolean ret; - - ret = TRUE; - dbus_error_init( &error ); - - if( !strcmp( key, "battery.present" ) ) - battery->status.present = - libhal_device_get_property_bool( ctx, battery->udi, key, &error ); - - if( !strcmp( key, "battery.charge_level.current" ) ) - battery->status.current_level = - libhal_device_get_property_int( ctx, battery->udi, key, &error ); - - if( !strcmp( key, "battery.charge_level.rate" ) ) - battery->status.rate = - libhal_device_get_property_int( ctx, battery->udi, key, &error ); - - else if( !strcmp( key, "battery.charge_level.design" ) ) - battery->status.design_level = - libhal_device_get_property_int( ctx, battery->udi, key, &error ); - - else if( !strcmp( key, "battery.charge_level.last_full" ) ) - battery->status.full_level = - libhal_device_get_property_int( ctx, battery->udi, key, &error ); - - else if( !strcmp( key, "battery.remaining_time" ) ) - battery->status.remaining_time = - libhal_device_get_property_int( ctx, battery->udi, key, &error ); - - else if( !strcmp( key, "battery.rechargeable.is_charging" ) ) - battery->status.charging = - libhal_device_get_property_bool( ctx, battery->udi, key, &error ); - - else if( !strcmp( key, "battery.rechargeable.is_discharging" ) ) - battery->status.discharging = - libhal_device_get_property_bool( ctx, battery->udi, key, &error ); - - else - ret = FALSE; - - dbus_error_free( &error ); - - return ret; -} - -static gboolean -adaptor_update_property( LibHalContext *ctx, struct adaptor_info *adaptor, - const char *key ) -{ - DBusError error; - gboolean ret; - - ret = TRUE; - dbus_error_init( &error ); - - if( !strcmp( key, "ac_adapter.present" ) ) - adaptor->present = - libhal_device_get_property_bool( ctx, adaptor->udi, key, &error ); - else - ret = FALSE; - - dbus_error_free( &error ); - - return ret; -} - -static GSList * -find_link_by_udi( GSList *list, const char *udi ) -{ - GSList *link; - - for( link = list; link; link = g_slist_next( link ) ) - { - /* this might be an adaptor! this is OK as long as 'udi' is the first - * member of both structures. - */ - struct battery_info *battery = link->data; - - if( !strcmp( udi, battery->udi ) ) - return link; - } - - return NULL; -} - -static void * -find_device_by_udi( GSList *list, const char *udi ) -{ - GSList *link; - - link = find_link_by_udi( list, udi ); - - if( link ) - return link->data; - else - return NULL; -} - -static gboolean status_update_scheduled; - -static gboolean -update_status_idle (gpointer junk) -{ - if (status_updated_callback) - status_updated_callback (); - - return status_update_scheduled = FALSE; -} - -static void -schedule_status_callback (void) -{ - if (status_update_scheduled) - return; - - status_update_scheduled = TRUE; - g_idle_add (update_status_idle, NULL); -} - -static void -property_callback( LibHalContext *ctx, const char *udi, const char *key, - dbus_bool_t is_removed, dbus_bool_t is_added ) -{ - struct battery_info *battery; - struct adaptor_info *adaptor; - gboolean changed; - - /* It is safe to do nothing since the device will have been marked as - * not present and the old information will be ignored. - */ - if( is_removed ) - return; - - changed = FALSE; - - if( (battery = find_device_by_udi( batteries, udi )) ) - changed |= battery_update_property( ctx, battery, key ); - - if( (adaptor = find_device_by_udi( adaptors, udi )) ) - changed |= adaptor_update_property( ctx, adaptor, key ); - - if (changed && status_updated_callback) - schedule_status_callback (); -} - -static void -add_to_list( LibHalContext *ctx, GSList **list, const char *udi, int size ) -{ - struct battery_info *battery = g_malloc0( size ); - LibHalPropertySetIterator iter; - LibHalPropertySet *properties; - DBusError error; - - /* this might be an adaptor! this is OK as long as 'udi' is the first - * member of both structures. - */ - battery->udi = g_strdup( udi ); - *list = g_slist_append( *list, battery ); - - dbus_error_init( &error ); - - libhal_device_add_property_watch( ctx, udi, &error ); - - properties = libhal_device_get_all_properties( ctx, udi, &error ); - - for( libhal_psi_init( &iter, properties ); - libhal_psi_has_more( &iter ); - libhal_psi_next( &iter ) ) - { - const char *key = libhal_psi_get_key( &iter ); - property_callback( ctx, udi, key, FALSE, FALSE ); - } - - libhal_free_property_set( properties ); - dbus_error_free( &error ); -} - -static void -free_list_data( void *data ) -{ - /* this might be an adaptor! this is OK as long as 'udi' is the first - * member of both structures. - */ - struct battery_info *battery = data; - - g_free( battery->udi ); - g_free( battery ); -} - -static GSList * -remove_from_list( LibHalContext *ctx, GSList *list, const char *udi ) -{ - GSList *link = find_link_by_udi( list, udi ); - - if( link ) - { - DBusError error; - - dbus_error_init( &error ); - libhal_device_remove_property_watch( ctx, udi, &error ); - dbus_error_free( &error ); - - free_list_data( link->data ); - list = g_slist_delete_link( list, link ); - } - - return list; -} - -static GSList * -free_entire_list( GSList *list ) -{ - GSList *item; - - for( item = list; item; item = g_slist_next( item ) ) - free_list_data( item->data ); - - g_slist_free( list ); - - return NULL; -} - -static void -device_added_callback( LibHalContext *ctx, const char *udi ) -{ - if( libhal_device_property_exists( ctx, udi, "battery", NULL ) ) - { - char *type = libhal_device_get_property_string( ctx, udi, - "battery.type", - NULL ); - - if( type ) - { - /* We only track 'primary' batteries (ie: to avoid monitoring - * batteries in cordless mice or UPSes etc.) - */ - if( !strcmp( type, "primary" ) ) - add_to_list( ctx, &batteries, udi, sizeof (struct battery_info) ); - - libhal_free_string( type ); - } - } - - if( libhal_device_property_exists( ctx, udi, "ac_adapter", NULL ) ) - add_to_list( ctx, &adaptors, udi, sizeof (struct adaptor_info) ); -} - -static void -device_removed_callback( LibHalContext *ctx, const char *udi ) -{ - batteries = remove_from_list( ctx, batteries, udi ); - adaptors = remove_from_list( ctx, adaptors, udi ); -} - -/* ---- public functions ---- */ - -char * -battstat_hal_initialise (void (*callback) (void)) -{ - DBusConnection *connection; - LibHalContext *ctx; - DBusError error; - char *error_str; - char **devices; - int i, num; - - status_updated_callback = callback; - - if( battstat_hal_ctx != NULL ) - return g_strdup( "Already initialised!" ); - - dbus_error_init( &error ); - - if( (connection = dbus_bus_get( DBUS_BUS_SYSTEM, &error )) == NULL ) - goto error_out; - - dbus_connection_setup_with_g_main( connection, g_main_context_default() ); - - if( (ctx = libhal_ctx_new()) == NULL ) - { - dbus_set_error( &error, _("HAL error"), _("Could not create libhal_ctx") ); - goto error_out; - } - - libhal_ctx_set_device_property_modified( ctx, property_callback ); - libhal_ctx_set_device_added( ctx, device_added_callback ); - libhal_ctx_set_device_removed( ctx, device_removed_callback ); - libhal_ctx_set_dbus_connection( ctx, connection ); - - if( libhal_ctx_init( ctx, &error ) == 0 ) - goto error_freectx; - - devices = libhal_find_device_by_capability( ctx, "battery", &num, &error ); - - if( devices == NULL ) - goto error_shutdownctx; - - /* FIXME: for now, if 0 battery devices are present on first scan, then fail. - * This allows fallover to the legacy (ACPI, APM, etc) backends if the - * installed version of HAL doesn't know about batteries. This check should - * be removed at some point in the future (maybe circa MATE 2.13..). - */ - if( num == 0 ) - { - dbus_free_string_array( devices ); - dbus_set_error( &error, _("HAL error"), _("No batteries found") ); - goto error_shutdownctx; - } - - for( i = 0; i < num; i++ ) - { - char *type = libhal_device_get_property_string( ctx, devices[i], - "battery.type", - &error ); - - if( type ) - { - /* We only track 'primary' batteries (ie: to avoid monitoring - * batteries in cordless mice or UPSes etc.) - */ - if( !strcmp( type, "primary" ) ) - add_to_list( ctx, &batteries, devices[i], - sizeof (struct battery_info) ); - - libhal_free_string( type ); - } - } - dbus_free_string_array( devices ); - - devices = libhal_find_device_by_capability( ctx, "ac_adapter", &num, &error ); - - if( devices == NULL ) - { - batteries = free_entire_list( batteries ); - goto error_shutdownctx; - } - - for( i = 0; i < num; i++ ) - add_to_list( ctx, &adaptors, devices[i], sizeof (struct adaptor_info) ); - dbus_free_string_array( devices ); - - dbus_error_free( &error ); - - battstat_hal_ctx = ctx; - - return NULL; - -error_shutdownctx: - libhal_ctx_shutdown( ctx, NULL ); - -error_freectx: - libhal_ctx_free( ctx ); - -error_out: - error_str = g_strdup_printf( _("Unable to initialise HAL: %s: %s"), - error.name, error.message ); - dbus_error_free( &error ); - return error_str; -} - -void -battstat_hal_cleanup( void ) -{ - if( battstat_hal_ctx == NULL ) - return; - - libhal_ctx_free( battstat_hal_ctx ); - batteries = free_entire_list( batteries ); - adaptors = free_entire_list( adaptors ); -} - -#include "battstat.h" - -/* This function currently exists to allow the multiple batteries supported - * by the HAL backend to appear as a single composite battery device (since - * at the current time this is all that battstat supports). - * - * This entire function is filled with logic to make multiple batteries - * appear as one "composite" battery. Comments included as appropriate. - * - * For more information about some of the assumptions made in the following - * code please see the following mailing list post and the resulting thread: - * - * http://lists.freedesktop.org/archives/hal/2005-July/002841.html - */ -void -battstat_hal_get_battery_info( BatteryStatus *status ) -{ - /* The calculation to get overall percentage power remaining is as follows: - * - * Sum( Current charges ) / Sum( Full Capacities ) - * - * We can't just take an average of all of the percentages since this - * doesn't deal with the case that one battery might have a larger - * capacity than the other. - * - * In order to do this calculation, we need to keep a running total of - * current charge and full capacities. - */ - int current_charge_total = 0, full_capacity_total = 0; - - /* Record the time remaining as reported by HAL. This is used in the event - * that the system has exactly one battery (since, then, the HAL is capable - * of providing an accurate time remaining report and we should trust it.) - */ - int remaining_time = 0; - - /* The total (dis)charge rate of the system is the sum of the rates of - * the individual batteries. - */ - int rate_total = 0; - - /* We need to know if we should report the composite battery as present - * at all. The logic is that if at least one actual battery is installed - * then the composite battery will be reported to exist. - */ - int present = 0; - - /* We need to know if we are on AC power or not. Eventually, we can look - * at the AC adaptor HAL devices to determine that. For now, we assume that - * if any battery is discharging then we must not be on AC power. Else, by - * default, we must be on AC. - */ - int on_ac_power = 1; - - /* Finally, we consider the composite battery to be "charging" if at least - * one of the actual batteries in the system is charging. - */ - int charging = 0; - - /* A list iterator. */ - GSList *item; - - /* For each physical battery bay... */ - for( item = batteries; item; item = item->next ) - { - struct battery_info *battery = item->data; - - /* If no battery is installed here, don't count it toward the totals. */ - if( !battery->status.present ) - continue; - - /* This battery is present. */ - - /* At least one battery present -> composite battery is present. */ - present++; - - /* At least one battery charging -> composite battery is charging. */ - if( battery->status.charging ) - charging = 1; - - /* At least one battery is discharging -> we're not on AC. */ - if( battery->status.discharging ) - on_ac_power = 0; - - /* Sum the totals for current charge, design capacity, (dis)charge rate. */ - current_charge_total += battery->status.current_level; - full_capacity_total += battery->status.full_level; - rate_total += battery->status.rate; - - /* Record remaining time too, incase this is the only battery. */ - remaining_time = battery->status.remaining_time; - } - - if( !present || full_capacity_total <= 0 || (charging && !on_ac_power) ) - { - /* Either no battery is present or something has gone horribly wrong. - * In either case we must return that the composite battery is not - * present. - */ - status->present = FALSE; - status->percent = 0; - status->minutes = -1; - status->on_ac_power = TRUE; - status->charging = FALSE; - - return; - } - - /* Else, our composite battery is present. */ - status->present = TRUE; - - /* As per above, overall charge is: - * - * Sum( Current charges ) / Sum( Full Capacities ) - */ - status->percent = ( ((double) current_charge_total) / - ((double) full_capacity_total) ) * 100.0 + 0.5; - - if( present == 1 ) - { - /* In the case of exactly one battery, report the time remaining figure - * from HAL directly since it might have come from an authorative source - * (ie: the PMU or APM subsystem). - * - * HAL gives remaining time in seconds with a 0 to mean that the - * remaining time is unknown. Battstat uses minutes and -1 for - * unknown time remaining. - */ - - if( remaining_time == 0 ) - status->minutes = -1; - else - status->minutes = (remaining_time + 30) / 60; - } - /* Rest of cases to deal with multiple battery systems... */ - else if( !on_ac_power && rate_total != 0 ) - { - /* Then we're discharging. Calculate time remaining until at zero. */ - - double remaining; - - remaining = (double) current_charge_total; - remaining /= (double) rate_total; - status->minutes = (int) floor( remaining * 60.0 + 0.5 ); - } - else if( charging && rate_total != 0 ) - { - /* Calculate time remaining until charged. For systems with more than - * one battery, this code is very approximate. The assumption is that if - * one battery reaches full charge before the other that the other will - * start charging faster due to the increase in available power (similar - * to how a laptop will charge faster if you're not using it). - */ - - double remaining; - - remaining = (double) (full_capacity_total - current_charge_total); - if( remaining < 0 ) - remaining = 0; - remaining /= (double) rate_total; - - status->minutes = (int) floor( remaining * 60.0 + 0.5 ); - } - else - { - /* On AC power and not charging -or- rate is unknown. */ - status->minutes = -1; - } - - /* These are simple and well-explained above. */ - status->charging = charging; - status->on_ac_power = on_ac_power; -} - -#endif /* HAVE_HAL */ |