aboutsummaryrefslogtreecommitdiff
path: root/src/indicator-power.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indicator-power.c')
-rw-r--r--src/indicator-power.c663
1 files changed, 0 insertions, 663 deletions
diff --git a/src/indicator-power.c b/src/indicator-power.c
deleted file mode 100644
index 729c7cf..0000000
--- a/src/indicator-power.c
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
-An indicator to power related information in the menubar.
-
-Copyright 2011 Canonical Ltd.
-
-Authors:
- Javier Jardon <javier.jardon@codethink.co.uk>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-/* GStuff */
-#include <glib-object.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
-
-#include "dbus-listener.h"
-#include "device.h"
-#include "indicator-power.h"
-
-#define ICON_POLICY_KEY "icon-policy"
-
-#define DEFAULT_ICON "gpm-battery-missing"
-
-enum {
- POWER_INDICATOR_ICON_POLICY_PRESENT,
- POWER_INDICATOR_ICON_POLICY_CHARGE,
- POWER_INDICATOR_ICON_POLICY_NEVER
-};
-
-struct _IndicatorPowerPrivate
-{
- GtkMenu *menu;
-
- GtkLabel *label;
- GtkImage *status_image;
- gchar *accessible_desc;
-
- IndicatorPowerDbusListener * dbus_listener;
-
- GSList * devices;
- IndicatorPowerDevice * device;
-
- GSettings *settings;
-};
-
-
-/* LCOV_EXCL_START */
-INDICATOR_SET_VERSION
-INDICATOR_SET_TYPE (INDICATOR_POWER_TYPE)
-/* LCOV_EXCL_STOP */
-
-/* Prototypes */
-static void indicator_power_dispose (GObject *object);
-static void indicator_power_finalize (GObject *object);
-
-static GtkLabel* get_label (IndicatorObject * io);
-static GtkImage* get_image (IndicatorObject * io);
-static GtkMenu* get_menu (IndicatorObject * io);
-static const gchar* get_accessible_desc (IndicatorObject * io);
-static const gchar* get_name_hint (IndicatorObject * io);
-
-static void update_visibility (IndicatorPower * self);
-static gboolean should_be_visible (IndicatorPower * self);
-
-static void on_entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data);
-
-/*
-static void gsd_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data);
-*/
-
-/* LCOV_EXCL_START */
-G_DEFINE_TYPE (IndicatorPower, indicator_power, INDICATOR_OBJECT_TYPE);
-/* LCOV_EXCL_STOP */
-
-static void
-indicator_power_class_init (IndicatorPowerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (IndicatorPowerPrivate));
-
- object_class->dispose = indicator_power_dispose;
- object_class->finalize = indicator_power_finalize;
-
- io_class->get_label = get_label;
- io_class->get_image = get_image;
- io_class->get_menu = get_menu;
- io_class->get_accessible_desc = get_accessible_desc;
- io_class->get_name_hint = get_name_hint;
-}
-
-static void
-indicator_power_init (IndicatorPower *self)
-{
- IndicatorPowerPrivate * priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_POWER_TYPE, IndicatorPowerPrivate);
-
- priv->menu = GTK_MENU(gtk_menu_new());
-
- priv->accessible_desc = NULL;
-
- priv->dbus_listener = g_object_new (INDICATOR_POWER_DBUS_LISTENER_TYPE, NULL);
- g_signal_connect_swapped (priv->dbus_listener, INDICATOR_POWER_DBUS_LISTENER_DEVICES_ENUMERATED,
- G_CALLBACK(indicator_power_set_devices), self);
-
- priv->settings = g_settings_new ("com.canonical.indicator.power");
- g_signal_connect_swapped (priv->settings, "changed::" ICON_POLICY_KEY,
- G_CALLBACK(update_visibility), self);
- g_object_set (G_OBJECT(self),
- INDICATOR_OBJECT_DEFAULT_VISIBILITY, FALSE,
- NULL);
-
- g_signal_connect (INDICATOR_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
- G_CALLBACK(on_entry_added), NULL);
-
- self->priv = priv;
-}
-
-static void
-dispose_devices (IndicatorPower * self)
-{
- IndicatorPowerPrivate * priv = self->priv;
-
- g_clear_object (&priv->device);
- g_slist_free_full (priv->devices, g_object_unref);
- priv->devices = NULL;
-}
-static void
-indicator_power_dispose (GObject *object)
-{
- IndicatorPower *self = INDICATOR_POWER(object);
- IndicatorPowerPrivate * priv = self->priv;
-
- dispose_devices (self);
-
- g_clear_object (&priv->label);
- g_clear_object (&priv->status_image);
- g_clear_object (&priv->dbus_listener);
- g_clear_object (&priv->settings);
-
- G_OBJECT_CLASS (indicator_power_parent_class)->dispose (object);
-}
-
-static void
-indicator_power_finalize (GObject *object)
-{
- IndicatorPower *self = INDICATOR_POWER(object);
- IndicatorPowerPrivate * priv = self->priv;
-
- g_free (priv->accessible_desc);
-
- G_OBJECT_CLASS (indicator_power_parent_class)->finalize (object);
-}
-
-/***
-****
-***/
-
-static void
-spawn_command_line_async (const char * command)
-{
- GError * err = NULL;
- if (!g_spawn_command_line_async (command, &err))
- g_warning ("Couldn't execute command \"%s\": %s", command, err->message);
- g_clear_error (&err);
-}
-
-static void
-option_toggled_cb (GtkCheckMenuItem *item, IndicatorPower * self)
-{
- gtk_widget_set_visible (GTK_WIDGET (self->priv->label),
- gtk_check_menu_item_get_active(item));
-}
-
-/* ensure that the entry is using self's accessible description */
-static void
-refresh_entry_accessible_desc (IndicatorPower * self, IndicatorObjectEntry * entry)
-{
- const char * newval = self->priv->accessible_desc;
-
- if (entry->accessible_desc != newval)
- {
- g_debug ("%s: setting entry %p accessible description to '%s'", G_STRFUNC, entry, newval);
- entry->accessible_desc = newval;
- g_signal_emit (self, INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, 0, entry);
- }
-}
-
-static void
-on_entry_added (IndicatorObject * io,
- IndicatorObjectEntry * entry,
- gpointer user_data G_GNUC_UNUSED)
-{
- refresh_entry_accessible_desc (INDICATOR_POWER(io), entry);
-}
-
-static void
-set_accessible_desc (IndicatorPower *self, const gchar *desc)
-{
- g_debug ("%s: setting accessible description to '%s'", G_STRFUNC, desc);
-
- if (desc && *desc)
- {
- /* update our copy of the string */
- char * oldval = self->priv->accessible_desc;
- self->priv->accessible_desc = g_strdup (desc);
-
- /* ensure that the entries are using self's accessible description */
- GList * l;
- GList * entries = indicator_object_get_entries(INDICATOR_OBJECT(self));
- for (l=entries; l!=NULL; l=l->next)
- refresh_entry_accessible_desc (self, l->data);
-
- /* cleanup */
- g_list_free (entries);
- g_free (oldval);
- }
-}
-
-static gboolean
-menu_add_device (GtkMenu * menu, const IndicatorPowerDevice * device)
-{
- gboolean added = FALSE;
- const UpDeviceKind kind = indicator_power_device_get_kind (device);
-
- if (kind != UP_DEVICE_KIND_LINE_POWER)
- {
- GtkWidget *icon;
- GtkWidget *item;
- GtkWidget *details_label;
- GtkWidget *grid;
- GIcon *device_gicon;
- gchar *short_details = NULL;
- gchar *details = NULL;
- gchar *accessible_name = NULL;
- AtkObject *atk_object;
-
- /* Process the data */
- device_gicon = indicator_power_device_get_gicon (device);
- icon = gtk_image_new_from_gicon (device_gicon, GTK_ICON_SIZE_SMALL_TOOLBAR);
- g_clear_object (&device_gicon);
-
- indicator_power_device_get_time_details (device, &short_details, &details, &accessible_name);
-
- /* Create menu item */
- item = gtk_image_menu_item_new ();
- atk_object = gtk_widget_get_accessible(item);
- if (atk_object != NULL)
- atk_object_set_name (atk_object, accessible_name);
-
- grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
- gtk_grid_attach (GTK_GRID (grid), icon, 0, 0, 1, 1);
- details_label = gtk_label_new (details);
- gtk_grid_attach_next_to (GTK_GRID (grid), details_label, icon, GTK_POS_RIGHT, 1, 1);
- gtk_container_add (GTK_CONTAINER (item), grid);
- gtk_widget_show (grid);
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- added = TRUE;
-
- g_signal_connect_swapped (G_OBJECT (item), "activate",
- G_CALLBACK (spawn_command_line_async), "gnome-power-statistics");
-
- g_free (short_details);
- g_free (details);
- g_free (accessible_name);
- }
-
- return added;
-}
-
-static gsize
-menu_add_devices (GtkMenu * menu, GSList * devices)
-{
- GSList * l;
- gsize n_added = 0;
-
- for (l=devices; l!=NULL; l=l->next)
- if (menu_add_device (menu, l->data))
- ++n_added;
-
- return n_added;
-}
-
-static gboolean
-get_greeter_mode (void)
-{
- const gchar *var;
- var = g_getenv("INDICATOR_GREETER_MODE");
- return (g_strcmp0(var, "1") == 0);
-}
-
-static void
-build_menu (IndicatorPower *self)
-{
- GtkWidget *item;
- GtkWidget *image;
- GList *children;
- gsize n_devices = 0;
- IndicatorPowerPrivate * priv = self->priv;
-
- /* remove the existing menuitems */
- children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
- g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL);
- g_list_free (children);
-
- /* devices */
- n_devices = menu_add_devices (priv->menu, priv->devices);
-
- if (!get_greeter_mode ()) {
- /* only do the separator if we have at least one device */
- if (n_devices != 0)
- {
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
- }
-
- /* options */
- item = gtk_check_menu_item_new_with_label (_("Show Time in Menu Bar"));
- g_signal_connect (item, "toggled", G_CALLBACK(option_toggled_cb), self);
- g_settings_bind (priv->settings, "show-time", item, "active", G_SETTINGS_BIND_DEFAULT);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
-
- /* preferences */
- item = gtk_image_menu_item_new_with_label (_("Power Settingsā€¦"));
- image = gtk_image_new_from_icon_name (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- g_signal_connect_swapped (G_OBJECT (item), "activate",
- G_CALLBACK (spawn_command_line_async), "gnome-control-center power");
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
- }
-
- /* show the menu */
- gtk_widget_show_all (GTK_WIDGET (priv->menu));
-}
-
-/* the higher the weight, the more interesting the device */
-static int
-get_device_kind_weight (const IndicatorPowerDevice * device)
-{
- UpDeviceKind kind;
- static gboolean initialized = FALSE;
- static int weights[UP_DEVICE_KIND_LAST];
-
- kind = indicator_power_device_get_kind (device);
- g_return_val_if_fail (0<=kind && kind<UP_DEVICE_KIND_LAST, 0);
-
- if (G_UNLIKELY(!initialized))
- {
- int i;
-
- initialized = TRUE;
-
- for (i=0; i<UP_DEVICE_KIND_LAST; i++)
- weights[i] = 1;
- weights[UP_DEVICE_KIND_BATTERY] = 2;
- weights[UP_DEVICE_KIND_LINE_POWER] = 0;
- }
-
- return weights[kind];
-}
-
-/* sort devices from most interesting to least interesting on this criteria:
- 1. discharging items from least time remaining until most time remaining
- 2. discharging items with an unknown time remaining
- 3. charging items from most time left to charge to least time left to charge
- 4. charging items with an unknown time remaining
- 5. batteries, then non-line power, then line-power */
-static gint
-device_compare_func (gconstpointer ga, gconstpointer gb)
-{
- int ret;
- int state;
- const IndicatorPowerDevice * a = INDICATOR_POWER_DEVICE(ga);
- const IndicatorPowerDevice * b = INDICATOR_POWER_DEVICE(gb);
- const int a_state = indicator_power_device_get_state (a);
- const int b_state = indicator_power_device_get_state (b);
- const gdouble a_percentage = indicator_power_device_get_percentage (a);
- const gdouble b_percentage = indicator_power_device_get_percentage (b);
- const time_t a_time = indicator_power_device_get_time (a);
- const time_t b_time = indicator_power_device_get_time (b);
-
- ret = 0;
-
- state = UP_DEVICE_STATE_DISCHARGING;
- if (!ret && ((a_state == state) || (b_state == state)))
- {
- if (a_state != state) /* b is discharging */
- {
- ret = 1;
- }
- else if (b_state != state) /* a is discharging */
- {
- ret = -1;
- }
- else /* both are discharging; least-time-left goes first */
- {
- if (!a_time || !b_time) /* known time always trumps unknown time */
- ret = a_time ? -1 : 1;
- else if (a_time != b_time)
- ret = a_time < b_time ? -1 : 1;
- else
- ret = a_percentage < b_percentage ? -1 : 1;
- }
- }
-
- state = UP_DEVICE_STATE_CHARGING;
- if (!ret && (((a_state == state) && a_time) || ((b_state == state) && b_time)))
- {
- if (a_state != state) /* b is charging */
- {
- ret = 1;
- }
- else if (b_state != state) /* a is charging */
- {
- ret = -1;
- }
- else /* both are discharging; most-time-to-charge goes first */
- {
- if (!a_time || !b_time) /* known time always trumps unknown time */
- ret = a_time ? -1 : 1;
- else if (a_time != b_time)
- ret = a_time > b_time ? -1 : 1;
- else
- ret = a_percentage < b_percentage ? -1 : 1;
- }
- }
-
- if (!ret) /* neither device is charging nor discharging... */
- {
- const int weight_a = get_device_kind_weight (a);
- const int weight_b = get_device_kind_weight (b);
-
- if (weight_a > weight_b)
- {
- ret = -1;
- }
- else if (weight_a < weight_b)
- {
- ret = 1;
- }
- }
-
- if (!ret)
- ret = a_state - b_state;
-
- return ret;
-}
-
-IndicatorPowerDevice *
-indicator_power_choose_primary_device (GSList * devices)
-{
- IndicatorPowerDevice * primary = NULL;
-
- if (devices != NULL)
- {
- GSList * tmp;
-
- tmp = g_slist_copy (devices);
- tmp = g_slist_sort (tmp, device_compare_func);
- primary = g_object_ref (tmp->data);
-
- g_slist_free (tmp);
- }
-
- return primary;
-}
-
-static void
-put_primary_device (IndicatorPower *self, IndicatorPowerDevice *device)
-{
- IndicatorPowerPrivate * priv = self->priv;
-
- /* set icon */
- GIcon * device_gicon = indicator_power_device_get_gicon (device);
- gtk_image_set_from_gicon (priv->status_image, device_gicon, GTK_ICON_SIZE_LARGE_TOOLBAR);
- g_clear_object (&device_gicon);
- gtk_widget_show (GTK_WIDGET (priv->status_image));
-
- /* get the description */
- gchar * short_details;
- gchar * details;
- gchar * accessible_name;
- indicator_power_device_get_time_details (device, &short_details, &details, &accessible_name);
- gtk_label_set_label (GTK_LABEL (priv->label), short_details);
- set_accessible_desc (self, accessible_name);
- g_free (accessible_name);
- g_free (details);
- g_free (short_details);
-}
-
-void
-indicator_power_set_devices (IndicatorPower * self, GSList * devices)
-{
- /* LCOV_EXCL_START */
- g_return_if_fail (IS_INDICATOR_POWER(self));
- /* LCOV_EXCL_STOP */
-
- IndicatorPowerPrivate * priv = self->priv;
-
- /* update our devices & primary device */
- g_slist_foreach (devices, (GFunc)g_object_ref, NULL);
- dispose_devices (self);
- priv->devices = g_slist_copy (devices);
- priv->device = indicator_power_choose_primary_device (devices);
-
- /* and our menus/visibility from the new device list */
- if (priv->device != NULL)
- put_primary_device (self, priv->device);
- else
- g_message ("Couldn't find primary device");
- build_menu (self);
- update_visibility (self);
-}
-
-static void
-update_visibility (IndicatorPower * self)
-{
- indicator_object_set_visible (INDICATOR_OBJECT (self),
- should_be_visible (self));
-}
-
-
-/* Grabs the label. Creates it if it doesn't
- exist already */
-static GtkLabel *
-get_label (IndicatorObject *io)
-{
- IndicatorPower *self = INDICATOR_POWER (io);
- IndicatorPowerPrivate * priv = self->priv;
-
- if (priv->label == NULL)
- {
- /* Create the label if it doesn't exist already */
- priv->label = GTK_LABEL (gtk_label_new (""));
- g_object_ref_sink (priv->label);
- gtk_widget_set_visible (GTK_WIDGET (priv->label), FALSE);
- }
-
- return priv->label;
-}
-
-static GtkImage *
-get_image (IndicatorObject *io)
-{
- GIcon *gicon;
- IndicatorPower *self = INDICATOR_POWER (io);
- IndicatorPowerPrivate * priv = self->priv;
-
- if (priv->status_image == NULL)
- {
- /* Will create the status icon if it doesn't exist already */
- gicon = g_themed_icon_new (DEFAULT_ICON);
- priv->status_image = GTK_IMAGE (gtk_image_new_from_gicon (gicon,
- GTK_ICON_SIZE_LARGE_TOOLBAR));
- g_object_ref_sink (priv->status_image);
- g_object_unref (gicon);
- }
-
- return priv->status_image;
-}
-
-static GtkMenu *
-get_menu (IndicatorObject *io)
-{
- IndicatorPower *self = INDICATOR_POWER (io);
-
- build_menu (self);
-
- return GTK_MENU (self->priv->menu);
-}
-
-static const gchar *
-get_accessible_desc (IndicatorObject *io)
-{
- IndicatorPower *self = INDICATOR_POWER (io);
-
- return self->priv->accessible_desc;
-}
-
-static const gchar *
-get_name_hint (IndicatorObject *io)
-{
- return PACKAGE_NAME;
-}
-
-/***
-****
-***/
-
-static void
-count_batteries (GSList * devices, int *total, int *inuse)
-{
- GSList * l;
-
- for (l=devices; l!=NULL; l=l->next)
- {
- const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data);
-
- if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY ||
- indicator_power_device_get_kind(device) == UP_DEVICE_KIND_UPS)
- {
- ++*total;
-
- const UpDeviceState state = indicator_power_device_get_state (device);
- if ((state == UP_DEVICE_STATE_CHARGING) || (state == UP_DEVICE_STATE_DISCHARGING))
- ++*inuse;
- }
- }
-
- g_debug("count_batteries found %d batteries (%d are charging/discharging)", *total, *inuse);
-}
-
-static gboolean
-should_be_visible (IndicatorPower * self)
-{
- gboolean visible = TRUE;
- IndicatorPowerPrivate * priv = self->priv;
-
- const int icon_policy = g_settings_get_enum (priv->settings, ICON_POLICY_KEY);
-
- g_debug ("icon_policy is: %d (present==0, charge==1, never==2)", icon_policy);
-
- if (icon_policy == POWER_INDICATOR_ICON_POLICY_NEVER)
- {
- visible = FALSE;
- }
- else
- {
- int batteries=0, inuse=0;
- count_batteries (priv->devices, &batteries, &inuse);
-
- if (icon_policy == POWER_INDICATOR_ICON_POLICY_PRESENT)
- {
- visible = batteries > 0;
- }
- else if (icon_policy == POWER_INDICATOR_ICON_POLICY_CHARGE)
- {
- visible = inuse > 0;
- }
- }
-
- g_debug ("should_be_visible: %s", visible?"yes":"no");
- return visible;
-}