[Xfce4-commits] [xfce/xfce4-power-manager] 04/64: Initial work for a new battery indicator plugin

noreply at xfce.org noreply at xfce.org
Mon May 26 05:59:59 CEST 2014


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository xfce/xfce4-power-manager.

commit 1ec4ffb6ef741060b44696f67c435e9bce9b30ad
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Thu May 1 07:09:20 2014 +0300

    Initial work for a new battery indicator plugin
    
    This patch moves some code around, mostly putting shared stuff into
    power-common inside common/. It also creates a new plugin to monitor
    all the batteries in one icon on the panel rather than multiple icons
    inside the system tray. It also removes the power-info application
    as that will be moved inside the newly reworked settings dialog.
---
 Makefile.am                                        |    2 +-
 common/Makefile.am                                 |   76 +-
 {src => common}/xfpm-enum-glib.h                   |   12 +-
 {src => common}/xfpm-enum.h                        |    6 +-
 {src => common}/xfpm-power-common.c                |   79 +-
 {src => common}/xfpm-power-common.h                |    3 +
 configure.ac.in                                    |    1 +
 panel-plugins/Makefile.am                          |    3 +-
 panel-plugins/battery/Makefile.am                  |   69 ++
 panel-plugins/battery/battery-button.c             |  777 ++++++++++++++++
 panel-plugins/battery/battery-button.h             |   57 ++
 panel-plugins/battery/battery-plugin.c             |   93 ++
 .../battery/xfce4-battery-plugin.desktop.in.in     |    8 +
 src/Makefile.am                                    |   61 --
 src/xfpm-battery.c                                 |   72 --
 src/xfpm-power-info.c                              |  949 --------------------
 16 files changed, 1153 insertions(+), 1115 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index bb04112..993ecab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,7 +10,7 @@ SUBDIRS =        	\
 	common		\
 	src		\
 	settings	\
-	$(plugins_dir)	\
+	$(plugins_dir) \
 	po
 
 
diff --git a/common/Makefile.am b/common/Makefile.am
index f2d504f..2775818 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,24 +1,66 @@
-noinst_LTLIBRARIES =                    \
+noinst_LTLIBRARIES =        \
         libxfpmcommon.la
 
-libxfpmcommon_la_SOURCES =              \
-	xfpm-common.c			\
-	xfpm-common.h			\
-	xfpm-brightness.c		\
-	xfpm-brightness.h		\
-	xfpm-debug.c			\
-	xfpm-debug.h			\
-	xfpm-icons.h
-
-libxfpmcommon_la_CFLAGS =               \
-	-I$(top_srcdir) 	        \
-	-DSBINDIR=\"$(sbindir)\"		\
+libxfpmcommon_la_SOURCES =  \
+	$(BUILT_SOURCES)        \
+	xfpm-common.c           \
+	xfpm-common.h           \
+	xfpm-brightness.c       \
+	xfpm-brightness.h       \
+	xfpm-debug.c            \
+	xfpm-debug.h            \
+	xfpm-icons.h            \
+	xfpm-power-common.c     \
+	xfpm-power-common.h     \
+	xfpm-enum.h             \
+	xfpm-enum-glib.h
+
+libxfpmcommon_la_CFLAGS =           \
+	-I$(top_srcdir)                 \
+	-DSBINDIR=\"$(sbindir)\"        \
 	$(GTK_CFLAGS)                   \
 	$(GLIB_CFLAGS)                  \
-	$(LIBXFCE4UTIL_CFLAGS)
+	$(LIBXFCE4UTIL_CFLAGS)          \
+	$(DBUS_GLIB_CFLAGS)             \
+	$(UPOWER_CFLAGS)
 
-libxfpmcommon_la_LIBADD =               \
+libxfpmcommon_la_LIBADD =           \
 	$(GTK_LIBS)                     \
 	$(GLIB_LIBS)                    \
-	$(XRANDR_LIBS)                   \
-	$(X11_LIBS)
+	$(XRANDR_LIBS)                  \
+	$(X11_LIBS)                     \
+	$(DBUS_GLIB_LIBS)               \
+	$(UPOWER_LIBS)
+
+xfpm_glib_headers =                \
+        $(srcdir)/xfpm-enum-glib.h
+
+BUILT_SOURCES =       \
+	xfpm-enum-types.c \
+	xfpm-enum-types.h
+
+if MAINTAINER_MODE
+
+xfpm-enum-types.h: $(xfpm_glib_headers)
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#ifndef _XFPM_ENUM_TYPES_H\n#define _XFPM_ENUM_TYPES_H\n#include <glib-object.h>\nG_BEGIN_DECLS\n" \
+		--fprod "/* enumerations from \"@filename@\" */\n" \
+		--vhead "GType @enum_name at _get_type (void);\n#define XFPM_TYPE_ at ENUMSHORT@ (@enum_name at _get_type())\n" \
+		--ftail "G_END_DECLS\n\n#endif /* _XFPM_ENUM_TYPES_H__ */" \
+		$(xfpm_glib_headers) ) >> xgen \
+	&& (cmp -s xgen xfpm-enum-types.h || cp xgen xfpm-enum-types.h ) \
+	&& rm -f xgen xgen~
+
+xfpm-enum-types.c: xfpm-enum-types.h
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#include <xfpm-enum-types.h>\n" \
+		--fhead "#include \"xfpm-enum-glib.h\"\n\n" \
+		--fprod "\n/* enumerations from \"@filename@\" */\n" \
+		--vhead "GType\n at enum_name@_get_type (void)\n{\n\tstatic GType type = 0;\n\tif (type == 0) {\n\tstatic const G at Type@Value values[] = {"\
+		--vprod "\t{ @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+		--vtail "\t{ 0, NULL, NULL }\n\t};\n\ttype = g_ at type@_register_static (\"@EnumName@\", values);\n  }\n\treturn type;\n}\n" \
+		$(xfpm_glib_headers) ) > xgen \
+	&& cp xgen xfpm-enum-types.c  \
+	&& rm -f xgen xgen~
+
+endif
diff --git a/src/xfpm-enum-glib.h b/common/xfpm-enum-glib.h
similarity index 98%
rename from src/xfpm-enum-glib.h
rename to common/xfpm-enum-glib.h
index b29a611..a6964b0 100644
--- a/src/xfpm-enum-glib.h
+++ b/common/xfpm-enum-glib.h
@@ -36,7 +36,7 @@ typedef enum
     XFPM_BATTERY_CHARGE_CRITICAL,
     XFPM_BATTERY_CHARGE_LOW,
     XFPM_BATTERY_CHARGE_OK
-    
+
 } XfpmBatteryCharge;
 
 typedef enum
@@ -46,7 +46,7 @@ typedef enum
     XFPM_DO_HIBERNATE,
     XFPM_ASK,
     XFPM_DO_SHUTDOWN
-    
+
 } XfpmShutdownRequest;
 
 typedef enum
@@ -55,7 +55,7 @@ typedef enum
     LID_TRIGGER_SUSPEND,
     LID_TRIGGER_HIBERNATE,
     LID_TRIGGER_LOCK_SCREEN,
-    
+
 } XfpmLidTriggerAction;
 
 typedef enum
@@ -71,7 +71,7 @@ typedef enum
     BUTTON_KBD_BRIGHTNESS_UP,
     BUTTON_KBD_BRIGHTNESS_DOWN,
     NUMBER_OF_BUTTONS
-    
+
 } XfpmButtonKey;
 
 typedef enum
@@ -80,14 +80,14 @@ typedef enum
     SHOW_ICON_WHEN_BATTERY_PRESENT,
     SHOW_ICON_WHEN_BATTERY_CHARGING_DISCHARGING,
     NEVER_SHOW_ICON
-    
+
 } XfpmShowIcon;
 
 typedef enum
 {
     XFPM_POWER_MODE_NORMAL,
     XFPM_POWER_MODE_PRESENTATION
-    
+
 } XfpmPowerMode;
 
 G_END_DECLS
diff --git a/src/xfpm-enum.h b/common/xfpm-enum.h
similarity index 98%
rename from src/xfpm-enum.h
rename to common/xfpm-enum.h
index e254218..0146f6e 100644
--- a/src/xfpm-enum.h
+++ b/common/xfpm-enum.h
@@ -29,13 +29,13 @@
 
 G_BEGIN_DECLS
 
-typedef enum 
+typedef enum
 {
     SYSTEM_LAPTOP,
     SYSTEM_DESKTOP,
     SYSTEM_SERVER,
     SYSTEM_UNKNOWN
-    
+
 } SystemFormFactor;
 
 typedef enum
@@ -57,7 +57,7 @@ typedef enum
     CPU_POWERSAVE	= (1 << 1),
     CPU_ONDEMAND	= (1 << 2),
     CPU_PERFORMANCE	= (1 << 3)
-    
+
 } XfpmCpuGovernor;
 
 G_END_DECLS
diff --git a/src/xfpm-power-common.c b/common/xfpm-power-common.c
similarity index 67%
rename from src/xfpm-power-common.c
rename to common/xfpm-power-common.c
index 5da6928..30988ff 100644
--- a/src/xfpm-power-common.c
+++ b/common/xfpm-power-common.c
@@ -33,7 +33,7 @@
 
 /**
  * xfpm_power_translate_device_type:
- * 
+ *
  **/
 const gchar *
 xfpm_power_translate_device_type (guint type)
@@ -63,13 +63,13 @@ xfpm_power_translate_device_type (guint type)
 	case UP_DEVICE_KIND_UNKNOWN:
 	    return _("Unknown");
     }
-    
+
     return _("Battery");
 }
 
 /**
  * xfpm_power_translate_technology:
- * 
+ *
  **/
 const gchar *xfpm_power_translate_technology (guint value)
 {
@@ -90,7 +90,7 @@ const gchar *xfpm_power_translate_technology (guint value)
         case 6:
             return _("Nickel metal hybride");
     }
-    
+
     return _("Unknown");
 }
 
@@ -123,8 +123,77 @@ const gchar *xfpm_power_get_icon_name (guint device_type)
 	case UP_DEVICE_KIND_UNKNOWN:
 	    return XFPM_BATTERY_ICON;
     }
-    
+
     return XFPM_BATTERY_ICON;
 }
 
+const gchar * G_GNUC_CONST
+xfpm_battery_get_icon_index (UpDeviceKind type, guint percent)
+{
+    if (percent < 10)
+    {
+        return "000";
+    }
+    else if (percent < 30)
+    {
+        return ( (type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS) ? "020" : "030");
+    }
+    else if (percent < 50)
+    {
+        return ( (type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS ) ? "040" : "030");
+    }
+    else if (percent < 70)
+    {
+        return "060";
+    }
+    else if (percent < 90)
+    {
+        return ((type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS) ? "080" : "060");
+    }
 
+    return "100";
+}
+
+/*
+ * Taken from gpm
+ */
+gchar *
+xfpm_battery_get_time_string (guint seconds)
+{
+    char* timestring = NULL;
+    gint  hours;
+    gint  minutes;
+
+    /* Add 0.5 to do rounding */
+    minutes = (int) ( ( seconds / 60.0 ) + 0.5 );
+
+    if (minutes == 0)
+    {
+	timestring = g_strdup (_("Unknown time"));
+	return timestring;
+    }
+
+    if (minutes < 60)
+    {
+	timestring = g_strdup_printf (ngettext ("%i minute",
+			              "%i minutes",
+				      minutes), minutes);
+	return timestring;
+    }
+
+    hours = minutes / 60;
+    minutes = minutes % 60;
+
+    if (minutes == 0)
+	timestring = g_strdup_printf (ngettext (
+			    "%i hour",
+			    "%i hours",
+			    hours), hours);
+    else
+	/* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes"
+	 * Swap order with "%2$s %2$i %1$s %1$i if needed */
+	timestring = g_strdup_printf (_("%i %s %i %s"),
+			    hours, ngettext ("hour", "hours", hours),
+			    minutes, ngettext ("minute", "minutes", minutes));
+    return timestring;
+}
diff --git a/src/xfpm-power-common.h b/common/xfpm-power-common.h
similarity index 92%
rename from src/xfpm-power-common.h
rename to common/xfpm-power-common.h
index dbf6e16..708ddd5 100644
--- a/src/xfpm-power-common.h
+++ b/common/xfpm-power-common.h
@@ -47,5 +47,8 @@ const gchar	*xfpm_power_translate_technology	(guint value);
 
 const gchar	*xfpm_power_get_icon_name		(guint device_type);
 
+const gchar * G_GNUC_CONST xfpm_battery_get_icon_index (UpDeviceKind type, guint percent);
+
+gchar * xfpm_battery_get_time_string (guint seconds);
 
 #endif /* XFPM_UPOWER_COMMON */
diff --git a/configure.ac.in b/configure.ac.in
index 2891d07..67f0893 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -211,6 +211,7 @@ common/Makefile
 src/Makefile
 settings/Makefile
 panel-plugins/Makefile
+panel-plugins/battery/Makefile
 panel-plugins/brightness/Makefile
 data/Makefile
 data/icons/Makefile
diff --git a/panel-plugins/Makefile.am b/panel-plugins/Makefile.am
index c4ca8b6..6376cbf 100644
--- a/panel-plugins/Makefile.am
+++ b/panel-plugins/Makefile.am
@@ -1,2 +1,3 @@
-SUBDIRS = 		\
+SUBDIRS =       \
+	battery     \
 	brightness
diff --git a/panel-plugins/battery/Makefile.am b/panel-plugins/battery/Makefile.am
new file mode 100644
index 0000000..dcbff72
--- /dev/null
+++ b/panel-plugins/battery/Makefile.am
@@ -0,0 +1,69 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir) \
+	-DG_LOG_DOMAIN=\"xfce4-battery-plugin\" \
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+	$(PLATFORM_CPPFLAGS)
+
+#
+# xfce4 battery plugin
+#
+plugin_LTLIBRARIES = \
+	libxfce4battery.la
+
+plugindir = \
+	$(libdir)/xfce4/panel/plugins
+
+libxfce4battery_la_SOURCES = \
+	battery-plugin.c     \
+	battery-button.c     \
+	battery-button.h
+
+libxfce4battery_la_CFLAGS =             \
+	-I$(top_srcdir)	                \
+	-I$(top_srcdir)/src             \
+	-DLOCALEDIR=\"$(localedir)\"    \
+	$(LIBXFCE4PANEL_CFLAGS)         \
+	$(LIBXFCE4UTIL_CFLAGS)          \
+	$(LIBXFCE4UI_CFLAGS)            \
+	$(GTK_CFLAGS)                   \
+	$(GLIB_CFLAGS)                  \
+	$(PLATFORM_CPPFLAGS)            \
+	$(PLATFORM_CFLAGS)              \
+	$(DBUS_GLIB_CFLAGS)             \
+	$(UPOWER_CFLAGS)
+
+libxfce4battery_la_LDFLAGS = \
+       -avoid-version \
+       -module \
+       -no-undefined \
+       -export-symbols-regex '^xfce_panel_module_(preinit|init|construct)' \
+       $(PLATFORM_LDFLAGS)
+
+libxfce4battery_la_LIBADD =                     \
+	$(top_builddir)/common/libxfpmcommon.la \
+	$(LIBXFCE4PANEL_LIBS)                   \
+	$(LIBXFCE4UI_LIBS)                      \
+	$(LIBXFCE4UTIL_LIBS)                    \
+	$(GTK_LIBS)                             \
+	$(GLIB_LIBS)                            \
+	$(DBUS_GLIB_LIBS)                       \
+	$(UPOWER_LIBS)
+
+#
+# Desktop file
+#
+desktopdir = $(datadir)/xfce4/panel-plugins
+desktop_in_in_files = xfce4-battery-plugin.desktop.in.in
+desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST =                                                            \
+        $(desktop_in_in_files)
+
+CLEANFILES =                                                            \
+        $(desktop_in_files)                                             \
+        $(desktop_DATA)
+
+%.desktop.in: %.desktop.in.in
+	sed -e "s,\@libdir\@,$(libdir),g" < $< > $@
diff --git a/panel-plugins/battery/battery-button.c b/panel-plugins/battery/battery-button.c
new file mode 100644
index 0000000..731b740
--- /dev/null
+++ b/panel-plugins/battery/battery-button.c
@@ -0,0 +1,777 @@
+/*
+ * * Copyright (C) 2009-2011 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+#include <dbus/dbus-glib.h>
+#include <upower.h>
+
+#include "common/xfpm-common.h"
+#include "common/xfpm-icons.h"
+#include "common/xfpm-power-common.h"
+
+#include "battery-button.h"
+
+static void battery_button_finalize   (GObject *object);
+
+#define BATTERY_BUTTON_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), BATTERY_TYPE_BUTTON, BatteryButtonPrivate))
+
+struct BatteryButtonPrivate
+{
+    XfcePanelPlugin *plugin;
+
+    UpClient        *upower;
+
+    GtkWidget       *popup;
+    GtkWidget       *image;
+    GtkWidget       *treeview;
+    gboolean         popup_open;
+};
+
+enum
+{
+    PROP_0,
+    PROP_PLUGIN
+};
+
+enum
+{
+    DEVICE_INFO_NAME,
+    DEVICE_INFO_VALUE,
+    DEVICE_INFO_LAST
+};
+
+enum
+{
+    COL_ICON,
+    COL_NAME,
+    NCOLS
+};
+
+G_DEFINE_TYPE (BatteryButton, battery_button, GTK_TYPE_BUTTON)
+
+static void
+battery_button_set_property (GObject *object,
+				guint prop_id,
+				const GValue *value,
+				GParamSpec   *pspec)
+{
+    BatteryButton *button = BATTERY_BUTTON (object);
+    switch (prop_id)
+    {
+	case PROP_PLUGIN:
+	    button->priv->plugin = XFCE_PANEL_PLUGIN (g_object_ref (g_value_get_object (value)));
+	    break;
+	default:
+	    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+/*
+ * The Code for handling grab/ungrab events are taken from GtkScaleButton.
+ * GTK - The GIMP Toolkit
+ * Copyright (C) 2005 Ronald S. Bultje
+ * Copyright (C) 2006, 2007 Christian Persch
+ * Copyright (C) 2006 Jan Arne Petersen
+ * Copyright (C) 2005-2007 Red Hat, Inc.
+ */
+static void
+battery_button_grab_notify (BatteryButton *button, gboolean was_grabbed)
+{
+    GdkDisplay *display;
+    if (was_grabbed != FALSE)
+	return;
+
+    if (!gtk_widget_has_grab (button->priv->popup))
+	return;
+
+    if (gtk_widget_is_ancestor (gtk_grab_get_current (), button->priv->popup))
+	return;
+
+    display = gtk_widget_get_display (button->priv->popup);
+    gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
+    gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
+    gtk_grab_remove (button->priv->popup);
+    gtk_widget_hide (button->priv->popup);
+    button->priv->popup_open = FALSE;
+}
+
+static void
+battery_button_popup_grab_notify (GtkWidget *widget, gboolean was_grabbed, BatteryButton *button)
+{
+    battery_button_grab_notify (button, was_grabbed);
+}
+
+static gboolean
+battery_button_popup_broken_event (GtkWidget *widget, gboolean was_grabbed, BatteryButton *button)
+{
+    battery_button_grab_notify (button, FALSE);
+    return FALSE;
+}
+
+static void
+battery_button_release_grab (BatteryButton *button, GdkEventButton *event)
+{
+    GdkEventButton *e;
+    GdkDisplay *display;
+
+    display = gtk_widget_get_display (GTK_WIDGET (button));
+    gdk_display_keyboard_ungrab (display, event->time);
+    gdk_display_pointer_ungrab (display, event->time);
+    gtk_grab_remove (button->priv->popup);
+
+    gtk_widget_hide (button->priv->popup);
+
+    e = (GdkEventButton *) gdk_event_copy ((GdkEvent *) event);
+    e->window = gtk_widget_get_window (GTK_WIDGET (button));
+    e->type = GDK_BUTTON_RELEASE;
+    gtk_widget_event (GTK_WIDGET (button), (GdkEvent *) e);
+    e->window = event->window;
+    gdk_event_free ((GdkEvent *) e);
+    button->priv->popup_open = FALSE;
+}
+
+static gboolean
+battery_button_popup_button_press_event (GtkWidget *widget, GdkEventButton *ev, BatteryButton *button)
+{
+    if ( ev->type == GDK_BUTTON_PRESS )
+    {
+	battery_button_release_grab (button, ev);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean
+battery_button_popup_key_release_event (GtkWidget *widget, GdkEventKey *ev, gpointer data)
+{
+
+    return FALSE;
+}
+
+static void
+battery_button_set_tooltip (BatteryButton *button)
+{
+    gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("Display battery levels for attached devices"));
+}
+
+static gboolean
+battery_button_popup_win (GtkWidget *widget, GdkEvent *ev, guint32 ev_time)
+{
+    gint x, y;
+    GdkDisplay *display;
+    GdkScreen *screen;
+    BatteryButton *button;
+    XfceScreenPosition pos;
+    GtkAllocation widget_allocation, popup_allocation;
+
+    button = BATTERY_BUTTON (widget);
+
+    display = gtk_widget_get_display (widget);
+    screen = gtk_widget_get_screen (widget);
+
+    gtk_window_set_screen (GTK_WINDOW (button->priv->popup), screen);
+
+    gtk_widget_show_all (button->priv->popup);
+
+    gtk_grab_add (button->priv->popup);
+
+    if (gdk_pointer_grab (gtk_widget_get_window (button->priv->popup), TRUE,
+			GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+			GDK_POINTER_MOTION_MASK, NULL, NULL, ev_time)
+	  != GDK_GRAB_SUCCESS)
+    {
+	gtk_grab_remove (button->priv->popup);
+	gtk_widget_hide (button->priv->popup);
+	return FALSE;
+    }
+
+    if (gdk_keyboard_grab (gtk_widget_get_window (button->priv->popup), TRUE, ev_time) != GDK_GRAB_SUCCESS)
+    {
+	gdk_display_pointer_ungrab (display, ev_time);
+	gtk_grab_remove (button->priv->popup);
+	gtk_widget_hide (button->priv->popup);
+	return FALSE;
+    }
+
+    gtk_widget_grab_focus (button->priv->popup);
+
+    /* Position */
+    gdk_window_get_origin (gtk_widget_get_window (widget), &x, &y);
+
+    pos = xfce_panel_plugin_get_screen_position (button->priv->plugin);
+
+    gtk_widget_get_allocation (widget, &widget_allocation);
+    gtk_widget_get_allocation (button->priv->popup, &popup_allocation);
+
+
+    if ( pos == XFCE_SCREEN_POSITION_N )
+    {
+	x += widget_allocation.x + widget_allocation.width/2;
+	y += widget_allocation.height;
+	x -= popup_allocation.width/2;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_NE_H )
+    {
+	x += widget_allocation.x + widget_allocation.width;
+	y += widget_allocation.height;
+	x -= popup_allocation.width;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_NW_H )
+    {
+	x += widget_allocation.x + widget_allocation.width/2;
+	y += widget_allocation.height;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_NW_V ||
+	      pos == XFCE_SCREEN_POSITION_W )
+    {
+	y += widget_allocation.y + widget_allocation.height/2;
+	x += widget_allocation.width;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_SW_V )
+    {
+	y += widget_allocation.y + widget_allocation.height/2;
+	x += widget_allocation.width;
+	y -= popup_allocation.height;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_NE_V )
+    {
+	x += widget_allocation.x + widget_allocation.width;
+	y += widget_allocation.height;
+	x -= popup_allocation.width;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_E    ||
+	      pos == XFCE_SCREEN_POSITION_SE_V )
+    {
+	y += widget_allocation.y
+		+ widget_allocation.height/2;
+	x -= popup_allocation.width;
+	y -= popup_allocation.height/2;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_SW_H )
+    {
+	x += widget_allocation.x + widget_allocation.width/2;
+	y -= popup_allocation.height;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_SE_H )
+    {
+	x += widget_allocation.x + widget_allocation.width;
+	y -= popup_allocation.height;
+	x -= popup_allocation.width;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_S )
+    {
+	x += widget_allocation.x + widget_allocation.width/2;
+	y -= popup_allocation.height;
+	x -= popup_allocation.width/2;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_FLOATING_H )
+    {
+	x += widget_allocation.x + widget_allocation.width/2;
+	x -= popup_allocation.width/2;
+	if ( y > popup_allocation.height )
+	    y -= popup_allocation.height;
+	else
+	     y += widget_allocation.height;
+    }
+    else if ( pos == XFCE_SCREEN_POSITION_FLOATING_V )
+    {
+	y -= popup_allocation.height/2;
+	y += widget_allocation.y + widget_allocation.height/2;
+	if ( x < popup_allocation.width )
+	    x += widget_allocation.width;
+	else
+	    x -= popup_allocation.width;
+    }
+    else
+    {
+	battery_button_release_grab (button, (GdkEventButton *)ev);
+	g_return_val_if_reached (FALSE);
+    }
+
+    gtk_window_move (GTK_WINDOW(button->priv->popup), x, y);
+    TRACE("Displaying window on x=%d y=%d", x, y);
+
+    button->priv->popup_open = TRUE;
+    return TRUE;
+}
+
+static gboolean
+battery_button_press_event (GtkWidget *widget, GdkEventButton *ev)
+{
+    return battery_button_popup_win (widget, (GdkEvent *) ev, ev->time);
+}
+
+static void
+device_changed_cb (BatteryButton *button)
+{
+    TRACE ("entering");
+}
+
+static gchar*
+get_device_description (UpClient *upower, UpDevice *device)
+{
+    gchar *tip = NULL;
+    gchar *est_time_str = NULL;
+    gchar *power_status = NULL;
+    guint type = 0, state = 0;
+    gchar *model = NULL, *vendor = NULL;
+    gboolean on_battery;
+    gboolean present;
+    gdouble percentage;
+    guint64 time_to_empty, time_to_full;
+
+    /* hack, this depends on XFPM_DEVICE_TYPE_* being in sync with UP_DEVICE_KIND_* */
+    g_object_get (device,
+		  "kind", &type,
+		  "vendor", &vendor,
+		  "model", &model,
+		  "state", &state,
+		  "is-present", &present,
+		  "percentage", &percentage,
+		  "time-to-empty", &time_to_empty,
+		  "time-to-full", &time_to_full,
+		   NULL);
+
+    g_object_get (upower,
+                  "on-battery", &on_battery,
+		  NULL);
+
+    if (type == UP_DEVICE_KIND_LINE_POWER)
+    {
+	if (on_battery)
+	{
+	    tip = g_strdup_printf(_("<b>On Battery</b>\t"));
+	}
+	else
+	{
+	    tip = g_strdup_printf(_("<b>Plugged In</b>\t"));
+	}
+
+	return tip;
+    }
+
+    if ( state == UP_DEVICE_STATE_FULLY_CHARGED )
+    {
+	if ( time_to_empty > 0 )
+	{
+	    est_time_str = xfpm_battery_get_time_string (time_to_empty);
+	    tip = g_strdup_printf (_("<b>%s %s</b>\t\nFully charged (%0.0f%%).\t\nProvides %s runtime\t"),
+				   vendor, model,
+				   percentage,
+				   est_time_str);
+	    g_free (est_time_str);
+	}
+	else
+	{
+	    tip = g_strdup_printf (_("<b>%s %s</b>\t\nFully charged (%0.0f%%).\t"),
+				   vendor, model,
+				   percentage);
+	}
+    }
+    else if ( state == UP_DEVICE_STATE_CHARGING )
+    {
+	if ( time_to_full != 0 )
+	{
+	    est_time_str = xfpm_battery_get_time_string (time_to_full);
+	    tip = g_strdup_printf (_("<b>%s %s</b>\t\nCharging (%0.0f%%).\t\n%s until is fully charged.\t"),
+				   vendor, model,
+				   percentage,
+				   est_time_str);
+	    g_free (est_time_str);
+	}
+	else
+	{
+	    tip = g_strdup_printf (_("<b>%s %s</b>\t\nCharging (%0.0f%%).\t"),
+				   vendor, model,
+				   percentage);
+	}
+    }
+    else if ( state == UP_DEVICE_STATE_DISCHARGING )
+    {
+	if ( time_to_empty != 0 )
+	{
+	    est_time_str = xfpm_battery_get_time_string (time_to_empty);
+	    tip = g_strdup_printf (_("<b>%s %s</b>\t\nDischarging (%0.0f%%).\t\nEstimated time left is %s.\t"),
+				   vendor, model,
+				   percentage,
+				   est_time_str);
+	    g_free (est_time_str);
+	}
+	else
+	{
+	    tip = g_strdup_printf (_("<b>%s %s</b>\t\nDischarging (%0.0f%%).\t"),
+				   vendor, model,
+				   percentage);
+	}
+
+    }
+    else if ( state == UP_DEVICE_STATE_PENDING_CHARGE )
+    {
+	tip = g_strdup_printf (_("<b>%s %s</b>\t\nWaiting to discharge (%0.0f%%).\t"),
+			       vendor, model,
+			       percentage);
+    }
+    else if ( state == UP_DEVICE_STATE_PENDING_DISCHARGE )
+    {
+	tip = g_strdup_printf (_("<b>%s %s</b>\t\nWaiting to charge (%0.0f%%).\t"),
+	                       vendor, model,
+			       percentage);
+    }
+    else if ( state == UP_DEVICE_STATE_EMPTY )
+    {
+	tip = g_strdup_printf (_("<b>%s %s</b>\t\nis empty\t"),
+	                       vendor, model);
+    }
+    else
+    {
+	/* unknown device state, just display the percentage */
+	tip = g_strdup_printf (_("<b>%s %s</b>\t\nis at (%0.0f%%).\t"),
+			       vendor, model,
+			       percentage);
+    }
+
+    g_free (power_status);
+    return tip;
+}
+
+static void
+battery_button_add_device (UpDevice *device, BatteryButton *button)
+{
+    GtkListStore *list_store;
+    GtkTreeIter iter;
+    GdkPixbuf *pix;
+    guint type = 0;
+    gchar *details;
+
+    /* hack, this depends on XFPM_DEVICE_TYPE_* being in sync with UP_DEVICE_KIND_* */
+    g_object_get (device,
+		  "kind", &type,
+		   NULL);
+
+    list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (button->priv->treeview)));
+
+    pix = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+				    xfpm_power_get_icon_name (type),
+				    48,
+				    GTK_ICON_LOOKUP_USE_BUILTIN,
+				    NULL);
+
+    details = get_device_description(button->priv->upower, device);
+
+    DBG("device %s : %s", xfpm_power_get_icon_name (type), details);
+
+    gtk_list_store_append (list_store, &iter);
+    gtk_list_store_set (list_store, &iter,
+			COL_ICON, pix,
+			COL_NAME, details,
+			-1);
+
+    if ( pix )
+	g_object_unref (pix);
+}
+
+
+static void
+battery_button_remove_device (BatteryButton *button, const gchar *object_path)
+{
+}
+
+static void
+device_added_cb (UpClient *upower, UpDevice *device, BatteryButton *button)
+{
+    battery_button_add_device (device, button);
+}
+
+#if UP_CHECK_VERSION(0, 99, 0)
+static void
+device_removed_cb (UpClient *upower, const gchar *object_path, BatteryButton *button)
+{
+    battery_button_remove_device (button, object_path);
+}
+#else
+static void
+device_removed_cb (UpClient *upower, UpDevice *device, BatteryButton *button)
+{
+    const gchar *object_path = up_device_get_object_path(device);
+    battery_button_remove_device (button, object_path);
+}
+#endif
+
+
+static void
+battery_button_add_all_devices (BatteryButton *button)
+{
+#if !UP_CHECK_VERSION(0, 99, 0)
+    /* the device-add callback is called for each device */
+    up_client_enumerate_devices_sync(button->priv->upower, NULL, NULL);
+#else
+    GPtrArray *array = NULL;
+    guint i;
+
+    array = up_client_get_devices(button->priv->upower);
+
+    if ( array )
+    {
+	for ( i = 0; i < array->len; i++)
+	{
+	    UpDevice *device = g_ptr_array_index (array, i);
+	    const gchar *object_path = up_device_get_object_path(device);
+
+	    battery_button_add_device (device, button);
+	}
+	g_ptr_array_free (array, TRUE);
+    }
+#endif
+}
+
+static void
+battery_button_create_popup (BatteryButton *button)
+{
+    GtkOrientation orientation;
+    GtkWidget *box;
+    GtkListStore *list_store;
+    GtkTreeViewColumn *col;
+    GtkCellRenderer *renderer;
+
+    button->priv->popup = gtk_window_new (GTK_WINDOW_POPUP);
+    gtk_window_set_decorated (GTK_WINDOW(button->priv->popup), FALSE);
+
+    g_signal_connect (button->priv->popup, "grab-notify",
+		      G_CALLBACK (battery_button_popup_grab_notify), button);
+    g_signal_connect (button->priv->popup, "grab-broken-event",
+		      G_CALLBACK (battery_button_popup_broken_event), button);
+    g_signal_connect (button->priv->popup, "key_release_event",
+		      G_CALLBACK (battery_button_popup_key_release_event), button);
+    g_signal_connect (button->priv->popup , "button_press_event",
+		      G_CALLBACK (battery_button_popup_button_press_event), button);
+
+    orientation = xfce_panel_plugin_get_orientation (button->priv->plugin);
+
+    if ( orientation == GTK_ORIENTATION_VERTICAL)
+	box = gtk_hbox_new (FALSE, 1);
+    else
+	box = gtk_vbox_new (FALSE, 1);
+
+    gtk_container_add (GTK_CONTAINER (button->priv->popup), box);
+
+    button->priv->treeview = gtk_tree_view_new ();
+    list_store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
+
+    gtk_tree_view_set_model (GTK_TREE_VIEW (button->priv->treeview), GTK_TREE_MODEL (list_store));
+
+    /* turn off alternating row colors, themes will probably override this */
+    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (button->priv->treeview), FALSE);
+    col = gtk_tree_view_column_new ();
+
+    renderer = gtk_cell_renderer_pixbuf_new ();
+
+    gtk_tree_view_column_pack_start (col, renderer, FALSE);
+    gtk_tree_view_column_set_attributes (col, renderer, "pixbuf", 0, NULL);
+
+    renderer = gtk_cell_renderer_text_new ();
+    gtk_tree_view_column_pack_start (col, renderer, FALSE);
+    gtk_tree_view_column_set_attributes (col, renderer, "markup", 1, NULL);
+
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (button->priv->treeview), TRUE);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (button->priv->treeview), col);
+
+    gtk_box_pack_start (GTK_BOX (box), button->priv->treeview, TRUE, TRUE, 0);
+
+    gtk_window_set_type_hint (GTK_WINDOW(button->priv->popup), GDK_WINDOW_TYPE_HINT_UTILITY );
+
+    battery_button_add_all_devices (button);
+
+    gtk_widget_show_all (box);
+}
+
+static void
+battery_button_class_init (BatteryButtonClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+    object_class->finalize = battery_button_finalize;
+    object_class->set_property = battery_button_set_property;
+
+    widget_class->button_press_event = battery_button_press_event;
+
+    g_object_class_install_property (object_class,
+				     PROP_PLUGIN,
+				     g_param_spec_object ("plugin",
+							  NULL,
+							  NULL,
+							  XFCE_TYPE_PANEL_PLUGIN,
+							  G_PARAM_CONSTRUCT_ONLY |
+							  G_PARAM_WRITABLE));
+
+    g_type_class_add_private (klass, sizeof (BatteryButtonPrivate));
+}
+
+static void
+battery_button_init (BatteryButton *button)
+{
+    button->priv = BATTERY_BUTTON_GET_PRIVATE (button);
+
+    gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+
+    button->priv->upower  = up_client_new ();
+
+    g_signal_connect (button->priv->upower, "device-added", G_CALLBACK (device_added_cb), button);
+    g_signal_connect (button->priv->upower, "device-removed", G_CALLBACK (device_removed_cb), button);
+#if UP_CHECK_VERSION(0, 99, 0)
+    g_signal_connect (button->priv->upower, "notify", G_CALLBACK (device_changed_cb), button);
+#else
+    g_signal_connect (button->priv->upower, "changed", G_CALLBACK (device_changed_cb), button);
+#endif
+}
+
+static void
+battery_button_finalize (GObject *object)
+{
+    BatteryButton *button;
+
+    button = BATTERY_BUTTON (object);
+
+    g_object_unref (button->priv->plugin);
+
+    G_OBJECT_CLASS (battery_button_parent_class)->finalize (object);
+}
+
+GtkWidget *
+battery_button_new (XfcePanelPlugin *plugin)
+{
+    BatteryButton *button = NULL;
+    button = g_object_new (BATTERY_TYPE_BUTTON, "plugin", plugin, NULL);
+    return GTK_WIDGET (button);
+}
+
+static void
+destroy_popup (BatteryButton *button)
+{
+    if ( GTK_IS_WIDGET (button->priv->popup) )
+	gtk_widget_destroy (button->priv->popup);
+}
+
+static gboolean
+battery_button_set_icon (BatteryButton *button, gint width)
+{
+    GdkPixbuf *pixbuf;
+    const gchar *icon_name;
+
+    icon_name = XFPM_AC_ADAPTER_ICON;
+
+    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                       icon_name,
+                                       width,
+                                       GTK_ICON_LOOKUP_FORCE_SIZE,
+                                       NULL);
+
+    if ( pixbuf )
+    {
+        gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->image), pixbuf);
+        g_object_unref (pixbuf);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean
+battery_button_size_changed_cb (XfcePanelPlugin *plugin, gint size, BatteryButton *button)
+{
+    gint width = size -2 - 2* MAX(gtk_widget_get_style(GTK_WIDGET(button))->xthickness,
+				  gtk_widget_get_style(GTK_WIDGET(button))->xthickness);
+
+    gtk_widget_set_size_request (GTK_WIDGET(plugin), size, size);
+    return battery_button_set_icon (button, width);
+}
+
+static void
+battery_button_free_data_cb (XfcePanelPlugin *plugin, BatteryButton *button)
+{
+    destroy_popup (button);
+    gtk_widget_destroy (GTK_WIDGET (button));
+}
+
+static void
+battery_button_orientation_changed_cb (XfcePanelPlugin *plugin, GtkOrientation or, BatteryButton *button)
+{
+
+}
+
+static void
+help_cb (GtkMenuItem *menuitem, gpointer user_data)
+{
+    BatteryButton *button = BATTERY_BUTTON (user_data);
+    xfce_dialog_show_help (GTK_WINDOW (button->priv->popup), "xfce4-power-manager", "start", NULL);
+}
+
+void battery_button_show (BatteryButton *button)
+{
+    GtkWidget *mi;
+
+    g_return_if_fail (BATTERY_IS_BUTTON (button));
+
+    xfce_panel_plugin_add_action_widget (button->priv->plugin, GTK_WIDGET (button));
+
+    button->priv->image = gtk_image_new ();
+    gtk_container_add (GTK_CONTAINER (button), button->priv->image);
+
+    /* help dialog */
+    mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_HELP, NULL);
+    gtk_widget_set_sensitive (mi, TRUE);
+    gtk_widget_show (mi);
+    g_signal_connect (mi, "activate", G_CALLBACK (help_cb), button);
+
+    xfce_panel_plugin_menu_insert_item (button->priv->plugin, GTK_MENU_ITEM (mi));
+
+    /* preferences dialog */
+    mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_PREFERENCES, NULL);
+    gtk_widget_set_sensitive (mi, TRUE);
+    gtk_widget_show (mi);
+    g_signal_connect (mi, "activate",G_CALLBACK (xfpm_preferences), NULL);
+
+    xfce_panel_plugin_menu_insert_item (button->priv->plugin, GTK_MENU_ITEM (mi));
+
+
+    g_signal_connect (button->priv->plugin, "size-changed",
+		      G_CALLBACK (battery_button_size_changed_cb), button);
+
+    g_signal_connect (button->priv->plugin, "orientation_changed",
+		      G_CALLBACK (battery_button_orientation_changed_cb), button);
+
+    g_signal_connect (button->priv->plugin, "free-data",
+		      G_CALLBACK (battery_button_free_data_cb), button);
+
+    gtk_widget_show_all (GTK_WIDGET(button));
+    battery_button_create_popup (button);
+    battery_button_set_tooltip (button);
+}
diff --git a/panel-plugins/battery/battery-button.h b/panel-plugins/battery/battery-button.h
new file mode 100644
index 0000000..ca0edce
--- /dev/null
+++ b/panel-plugins/battery/battery-button.h
@@ -0,0 +1,57 @@
+/*
+ * * Copyright (C) 2009-2011 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __BATTERY_BUTTON_H
+#define __BATTERY_BUTTON_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+
+G_BEGIN_DECLS
+
+#define BATTERY_TYPE_BUTTON        (battery_button_get_type () )
+#define BATTERY_BUTTON(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), BATTERY_TYPE_BUTTON, BatteryButton))
+#define BATTERY_IS_BUTTON(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), BATTERY_TYPE_BUTTON))
+
+typedef struct BatteryButtonPrivate BatteryButtonPrivate;
+
+typedef struct
+{
+    GtkButton         		 parent;
+    BatteryButtonPrivate     *priv;
+
+} BatteryButton;
+
+typedef struct
+{
+    GtkButtonClass 		 parent_class;
+
+} BatteryButtonClass;
+
+GType        			 battery_button_get_type        (void) G_GNUC_CONST;
+
+GtkWidget       		*battery_button_new             (XfcePanelPlugin *plugin);
+
+void                             battery_button_show            (BatteryButton *button);
+
+G_END_DECLS
+
+#endif /* __BATTERY_BUTTON_H */
diff --git a/panel-plugins/battery/battery-plugin.c b/panel-plugins/battery/battery-plugin.c
new file mode 100644
index 0000000..db446d5
--- /dev/null
+++ b/panel-plugins/battery/battery-plugin.c
@@ -0,0 +1,93 @@
+/*
+ * * Copyright (C) 2009-2011 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include <libxfce4panel/libxfce4panel.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+
+#include "battery-button.h"
+
+/* plugin structure */
+typedef struct
+{
+    XfcePanelPlugin *plugin;
+
+    /* panel widgets */
+    GtkWidget       *ebox;
+    GtkWidget       *battery_button;
+}
+BatteryPlugin;
+
+/* prototypes */
+static void battery_plugin_construct (XfcePanelPlugin *plugin);
+
+
+/* register the plugin */
+XFCE_PANEL_PLUGIN_REGISTER (battery_plugin_construct);
+
+
+static BatteryPlugin *
+battery_plugin_new (XfcePanelPlugin *plugin)
+{
+    BatteryPlugin *battery_plugin;
+
+    /* allocate memory for the plugin structure */
+    battery_plugin = panel_slice_new0 (BatteryPlugin);
+
+    /* pointer to plugin */
+    battery_plugin->plugin = plugin;
+
+    /* pointer to plugin */
+    battery_plugin->plugin = plugin;
+
+    /* create some panel ebox */
+    battery_plugin->ebox = gtk_event_box_new ();
+    gtk_widget_show (battery_plugin->ebox);
+    gtk_event_box_set_visible_window (GTK_EVENT_BOX(battery_plugin->ebox), FALSE);
+
+    battery_plugin->battery_button = battery_button_new (plugin);
+    battery_button_show(BATTERY_BUTTON(battery_plugin->battery_button));
+    gtk_container_add (GTK_CONTAINER (battery_plugin->ebox), battery_plugin->battery_button);
+
+    return battery_plugin;
+}
+
+
+static void
+battery_plugin_construct (XfcePanelPlugin *plugin)
+{
+    BatteryPlugin *battery_plugin;
+
+    /* create the plugin */
+    battery_plugin = battery_plugin_new (plugin);
+
+    /* add the ebox to the panel */
+    gtk_container_add (GTK_CONTAINER (plugin), battery_plugin->ebox);
+}
diff --git a/panel-plugins/battery/xfce4-battery-plugin.desktop.in.in b/panel-plugins/battery/xfce4-battery-plugin.desktop.in.in
new file mode 100644
index 0000000..48b7ba2
--- /dev/null
+++ b/panel-plugins/battery/xfce4-battery-plugin.desktop.in.in
@@ -0,0 +1,8 @@
+[Xfce Panel]
+Type=X-XFCE-PanelPlugin
+_Name=Battery indicator plugin
+_Comment=Display the battery levels of your devices
+Icon=xfpm-primary-100-charging
+X-XFCE-Module=xfce4battery
+X-XFCE-Unique=TRUE
+X-XFCE-Internal=false
diff --git a/src/Makefile.am b/src/Makefile.am
index 1704c4d..68ce9a2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,18 +1,13 @@
 bin_PROGRAMS = xfce4-power-manager		\
-	       xfce4-power-information      \
 	       xfce4-pm-helper
 
 xfce4_power_manager_SOURCES =                   \
 	$(BUILT_SOURCES)			\
-	xfpm-enum.h				\
-	xfpm-enum-glib.h			\
 	xfpm-main.c				\
 	xfpm-manager.c				\
 	xfpm-manager.h				\
 	xfpm-power.c				\
 	xfpm-power.h				\
-	xfpm-power-common.c			\
-	xfpm-power-common.h			\
 	xfpm-battery.c				\
 	xfpm-battery.h				\
 	xfpm-xfconf.c				\
@@ -83,35 +78,6 @@ xfce4_power_manager_LDADD =                     \
 	$(XRANDR_LIBS)				\
 	$(DPMS_LIBS)
 
-xfce4_power_information_SOURCES =		\
-	xfpm-power-info.c			\
-	xfpm-power-common.c			\
-	xfpm-power-common.h
-
-xfce4_power_information_CFLAGS =		\
-	-I$(top_srcdir)                         \
-	-I$(top_srcdir)/common                  \
-	-I$(top_srcdir)/libdbus                 \
-	-DLOCALEDIR=\"$(localedir)\"            \
-	-DG_LOG_DOMAIN=\"xfce4-power-information\"\
-	$(GOBJECT_CFLAGS)                       \
-	$(DBUS_GLIB_CFLAGS)                     \
-	$(UPOWER_CFLAGS)                        \
-	$(LIBXFCE4UI_CFLAGS)			\
-	$(PLATFORM_CPPFLAGS)			\
-	$(PLATFORM_CFLAGS)
-
-xfce4_power_information_LDFLAGS =		\
-	-no-undefined				\
-	$(PLATFORM_LDFLAGS)
-
-xfce4_power_information_LDADD =			\
-	$(GOBJECT_LIBS)                         \
-	$(DBUS_GLIB_LIBS)                       \
-	$(UPOWER_LIBS)                          \
-	$(LIBXFCE4UI_LIBS)			\
-	$(top_builddir)/libdbus/libxfpmdbus.la
-
 xfce4_pm_helper_SOURCES =  \
 	xfpm-pm-helper.c
 
@@ -155,14 +121,9 @@ manpagedir = $(mandir)/man1
 
 manpage_DATA = xfce4-power-manager.1
 
-xfpm_glib_headers =                             \
-        $(srcdir)/xfpm-enum-glib.h
-
 BUILT_SOURCES =					\
 	xfce-power-manager-dbus-server.h	\
 	xfce-power-manager-dbus-client.h	\
-	xfpm-enum-types.c                       \
-	xfpm-enum-types.h			\
 	xfpm-marshal.c                          \
         xfpm-marshal.h				\
 	org.freedesktop.PowerManagement.h       \
@@ -170,28 +131,6 @@ BUILT_SOURCES =					\
 
 if MAINTAINER_MODE
 
-xfpm-enum-types.h: $(xfpm_glib_headers)
-	( cd $(srcdir) && glib-mkenums \
-		--fhead "#ifndef _XFPM_ENUM_TYPES_H\n#define _XFPM_ENUM_TYPES_H\n#include <glib-object.h>\nG_BEGIN_DECLS\n" \
-		--fprod "/* enumerations from \"@filename@\" */\n" \
-		--vhead "GType @enum_name at _get_type (void);\n#define XFPM_TYPE_ at ENUMSHORT@ (@enum_name at _get_type())\n" \
-		--ftail "G_END_DECLS\n\n#endif /* _XFPM_ENUM_TYPES_H__ */" \
-		$(xfpm_glib_headers) ) >> xgen \
-	&& (cmp -s xgen xfpm-enum-types.h || cp xgen xfpm-enum-types.h ) \
-	&& rm -f xgen xgen~
-
-xfpm-enum-types.c: xfpm-enum-types.h
-	( cd $(srcdir) && glib-mkenums \
-		--fhead "#include <xfpm-enum-types.h>\n" \
-		--fhead "#include \"xfpm-enum-glib.h\"\n\n" \
-		--fprod "\n/* enumerations from \"@filename@\" */\n" \
-		--vhead "GType\n at enum_name@_get_type (void)\n{\n\tstatic GType type = 0;\n\tif (type == 0) {\n\tstatic const G at Type@Value values[] = {"\
-		--vprod "\t{ @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
-		--vtail "\t{ 0, NULL, NULL }\n\t};\n\ttype = g_ at type@_register_static (\"@EnumName@\", values);\n  }\n\treturn type;\n}\n" \
-		$(xfpm_glib_headers) ) > xgen \
-	&& cp xgen xfpm-enum-types.c  \
-	&& rm -f xgen xgen~
-
 xfpm-marshal.c: xfpm-marshal.list
 	echo "#include \"xfpm-marshal.h\"" > $@ && \
 	glib-genmarshal $< --prefix=_xfpm_marshal --body >> $@
diff --git a/src/xfpm-battery.c b/src/xfpm-battery.c
index 3a246ad..1a3c322 100644
--- a/src/xfpm-battery.c
+++ b/src/xfpm-battery.c
@@ -95,33 +95,6 @@ static guint signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (XfpmBattery, xfpm_battery, GTK_TYPE_STATUS_ICON)
 
-static const gchar * G_GNUC_CONST
-xfpm_battery_get_icon_index (UpDeviceKind type, guint percent)
-{
-    if (percent < 10)
-    {
-        return "000";
-    }
-    else if (percent < 30)
-    {
-        return ( (type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS) ? "020" : "030");
-    }
-    else if (percent < 50)
-    {
-        return ( (type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS ) ? "040" : "030");
-    }
-    else if (percent < 70)
-    {
-        return "060";
-    }
-    else if (percent < 90)
-    {
-        return ((type == UP_DEVICE_KIND_BATTERY || type == UP_DEVICE_KIND_UPS) ? "080" : "060");
-    }
-
-    return "100";
-}
-
 static void
 xfpm_battery_refresh_visible (XfpmBattery *battery)
 {
@@ -154,51 +127,6 @@ xfpm_battery_refresh_visible (XfpmBattery *battery)
     gtk_status_icon_set_visible (GTK_STATUS_ICON (battery), visible);
 }
 
-
-/*
- * Taken from gpm
- */
-static gchar *
-xfpm_battery_get_time_string (guint seconds)
-{
-    char* timestring = NULL;
-    gint  hours;
-    gint  minutes;
-
-    /* Add 0.5 to do rounding */
-    minutes = (int) ( ( seconds / 60.0 ) + 0.5 );
-
-    if (minutes == 0)
-    {
-	timestring = g_strdup (_("Unknown time"));
-	return timestring;
-    }
-
-    if (minutes < 60)
-    {
-	timestring = g_strdup_printf (ngettext ("%i minute",
-			              "%i minutes",
-				      minutes), minutes);
-	return timestring;
-    }
-
-    hours = minutes / 60;
-    minutes = minutes % 60;
-
-    if (minutes == 0)
-	timestring = g_strdup_printf (ngettext (
-			    "%i hour",
-			    "%i hours",
-			    hours), hours);
-    else
-	/* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes"
-	 * Swap order with "%2$s %2$i %1$s %1$i if needed */
-	timestring = g_strdup_printf (_("%i %s %i %s"),
-			    hours, ngettext ("hour", "hours", hours),
-			    minutes, ngettext ("minute", "minutes", minutes));
-    return timestring;
-}
-
 static gchar *
 xfpm_battery_get_message_from_battery_state (XfpmBattery *battery)
 {
diff --git a/src/xfpm-power-info.c b/src/xfpm-power-info.c
deleted file mode 100644
index 2ffaa83..0000000
--- a/src/xfpm-power-info.c
+++ /dev/null
@@ -1,949 +0,0 @@
-/*
- * * Copyright (C) 2008-2011 Ali <aliov at xfce.org>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <signal.h>
-
-#include <gtk/gtk.h>
-#include <glib.h>
-
-#include <libxfce4util/libxfce4util.h>
-#include <libxfce4ui/libxfce4ui.h>
-
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <upower.h>
-
-#include "xfpm-icons.h"
-#include "xfpm-power-common.h"
-#include "xfpm-enum-glib.h"
-
-#include "xfpm-unique.h"
-
-typedef struct 
-{
-    DBusGConnection *bus;
-    
-    DBusGProxy 	    *power_proxy;
-    DBusGProxy      *wakeups_proxy;
-    
-    GtkWidget 	    *dialog;
-    GtkWidget       *notebook;
-    GtkWidget	    *sideview; /*Sidebar tree view*/
-    
-    GtkWidget	    *wakeups; /* Tree view processor wakeups*/
-    
-    UpClient        *upower;
-
-} XfpmInfo;
-
-enum
-{
-    XFPM_DEVICE_INFO_NAME,
-    XFPM_DEVICE_INFO_VALUE,
-    XFPM_DEVICE_INFO_LAST
-};
-    
-enum
-{
-    COL_SIDEBAR_ICON,
-    COL_SIDEBAR_NAME,
-    COL_SIDEBAR_INT,
-    NCOLS_SIDEBAR
-    
-};
-  
-enum
-{
-    COL_WAKEUPS_TYPE,
-    COL_WAKEUPS_PID,
-    COL_WAKEUPS_CMD,
-    COL_WAKEUPS_VALUE,
-    COL_WAKEUPS_DETAILS,
-    NCOLS_WAKEUPS
-};
-
-static void G_GNUC_NORETURN
-show_version (void)
-{
-    g_print (_("\n"
-             "Xfce Power Manager %s\n\n"
-             "Part of the Xfce Goodies Project\n"
-             "http://goodies.xfce.org\n\n"
-             "Licensed under the GNU GPL.\n\n"), VERSION);
-
-    exit (EXIT_SUCCESS);
-}
-
-
-/**
- * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
- * gpm_stats_format_cmdline:
- **/
-static gchar *
-gpm_stats_format_cmdline (const gchar *command, gboolean is_userspace)
-{
-	gchar *found;
-	gchar *temp = NULL;
-	gchar *cmdline;
-	const gchar *temp_ptr;
-
-	/* nothing */
-	if (command == NULL) {
-		/* TRANSLATORS: the command line was not provided */
-		temp_ptr = _("No data");
-		goto out;
-	}
-
-	/* common kernel cmd names */
-	if (g_strcmp0 (command, "insmod") == 0) {
-		/* TRANSLATORS: kernel module, usually a device driver */
-		temp_ptr = _("Kernel module");
-		goto out;
-	}
-	if (g_strcmp0 (command, "modprobe") == 0) {
-		/* TRANSLATORS: kernel module, usually a device driver */
-		temp_ptr = _("Kernel module");
-		goto out;
-	}
-	if (g_strcmp0 (command, "swapper") == 0) {
-		/* TRANSLATORS: kernel housekeeping */
-		temp_ptr = _("Kernel core");
-		goto out;
-	}
-	if (g_strcmp0 (command, "kernel-ipi") == 0) {
-		/* TRANSLATORS: interrupt between processors */
-		temp_ptr = _("Interprocessor interrupt");
-		goto out;
-	}
-	if (g_strcmp0 (command, "interrupt") == 0) {
-		/* TRANSLATORS: unknown interrupt */
-		temp_ptr = _("Interrupt");
-		goto out;
-	}
-
-	/* truncate at first space or ':' */
-	temp = g_strdup (command);
-	found = strstr (temp, ":");
-	if (found != NULL)
-		*found = '\0';
-	found = strstr (temp, " ");
-	if (found != NULL)
-		*found = '\0';
-
-	/* remove path */
-	found = g_strrstr (temp, "/");
-	if (found != NULL && strncmp (temp, "event", 5) != 0)
-		temp_ptr = found + 1;
-	else
-		temp_ptr = temp;
-
-out:
-	/* format command line */
-	if (is_userspace)
-		cmdline = g_markup_escape_text (temp_ptr, -1);
-	else
-		cmdline = g_markup_printf_escaped ("<i>%s</i>", temp_ptr);
-	g_free (temp);
-
-	/* return */
-	return cmdline;
-}
-
-/**
- * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
- * gpm_stats_format_details:
- **/
-static gchar *
-gpm_stats_format_details (const gchar *command_details)
-{
-	gchar *details;
-
-	/* replace common driver names */
-	if (g_strcmp0 (command_details, "i8042") == 0) {
-		/* TRANSLATORS: the keyboard and mouse device event */
-		details = g_strdup (_("PS/2 keyboard/mouse/touchpad"));
-	} else if (g_strcmp0 (command_details, "acpi") == 0) {
-		/* TRANSLATORS: ACPI, the Intel power standard on laptops and desktops */
-		details = g_strdup (_("ACPI"));
-	} else if (g_strcmp0 (command_details, "ata_piix") == 0) {
-		/* TRANSLATORS: serial ATA is a new style of hard disk interface */
-		details = g_strdup (_("Serial ATA"));
-	} else if (g_strcmp0 (command_details, "libata") == 0) {
-		/* TRANSLATORS: this is the old-style ATA interface */
-		details = g_strdup (_("ATA host controller"));
-	} else if (g_strcmp0 (command_details, "iwl3945") == 0 || g_strcmp0 (command_details, "iwlagn") == 0) {
-		/* TRANSLATORS: 802.11 wireless adaptor */
-		details = g_strdup (_("Intel wireless adaptor"));
-
-	/* try to make the wakeup type nicer */
-	} else if (g_str_has_prefix (command_details, "__mod_timer")) {
-		/* TRANSLATORS: a timer is something that fires periodically */
-		details = g_strdup_printf (_("Timer %s"), command_details+12);
-	} else if (g_str_has_prefix (command_details, "mod_timer")) {
-		/* TRANSLATORS: a timer is something that fires periodically */
-		details = g_strdup_printf (_("Timer %s"), command_details+10);
-	} else if (g_str_has_prefix (command_details, "hrtimer_start_expires")) {
-		/* TRANSLATORS: a timer is something that fires periodically */
-		details = g_strdup_printf (_("Timer %s"), command_details+22);
-	} else if (g_str_has_prefix (command_details, "hrtimer_start")) {
-		/* TRANSLATORS: a timer is something that fires periodically */
-		details = g_strdup_printf (_("Timer %s"), command_details+14);
-	} else if (g_str_has_prefix (command_details, "do_setitimer")) {
-		/* TRANSLATORS: a timer is something that fires periodically */
-		details = g_strdup_printf (_("Timer %s"), command_details+10);
-	} else if (g_str_has_prefix (command_details, "do_nanosleep")) {
-		/* TRANSLATORS: this is a task that's woken up from sleeping */
-		details = g_strdup_printf (_("Sleep %s"), command_details+13);
-	} else if (g_str_has_prefix (command_details, "enqueue_task_rt")) {
-		/* TRANSLATORS: this is a new realtime task */
-		details = g_strdup_printf (_("New task %s"), command_details+16);
-	} else if (g_str_has_prefix (command_details, "futex_wait")) {
-		/* TRANSLATORS: this is a task thats woken to check state */
-		details = g_strdup_printf (_("Wait %s"), command_details+11);
-	} else if (g_str_has_prefix (command_details, "queue_delayed_work_on")) {
-		/* TRANSLATORS: a work queue is a list of work that has to be done */
-		details = g_strdup_printf (_("Work queue %s"), command_details+22);
-	} else if (g_str_has_prefix (command_details, "queue_delayed_work")) {
-		/* TRANSLATORS: a work queue is a list of work that has to be done */
-		details = g_strdup_printf (_("Work queue %s"), command_details+19);
-	} else if (g_str_has_prefix (command_details, "dst_run_gc")) {
-		/* TRANSLATORS: this is when the networking subsystem clears out old entries */
-		details = g_strdup_printf (_("Network route flush %s"), command_details+11);
-	} else if (g_str_has_prefix (command_details, "usb_hcd_poll_rh_status")) {
-		/* TRANSLATORS: activity on the USB bus */
-		details = g_strdup_printf (_("USB activity %s"), command_details+23);
-	} else if (g_str_has_prefix (command_details, "schedule_hrtimeout_range")) {
-		/* TRANSLATORS: we've timed out of an aligned timer */
-		details = g_strdup_printf (_("Wakeup %s"), command_details+25);
-	} else if (g_str_has_prefix (command_details, "Local timer interrupts")) {
-		/* TRANSLATORS: interupts on the system required for basic operation */
-		details = g_strdup (_("Local interrupts"));
-	} else if (g_str_has_prefix (command_details, "Rescheduling interrupts")) {
-		/* TRANSLATORS: interrupts when a task gets moved from one core to another */
-		details = g_strdup (_("Rescheduling interrupts"));
-	} else
-		details = g_markup_escape_text (command_details, -1);
-
-	return details;
-}
-
-static gchar *
-xfpm_info_get_energy_property (gdouble energy, const gchar *unit)
-{
-    gchar *val = NULL;
-    
-    val = g_strdup_printf ("%.1f %s", energy, unit);
-    
-    return val;
-}
-
-static void
-xfpm_info_add_sidebar_icon (XfpmInfo *info, const gchar *name, const gchar *icon_name)
-{
-    GtkListStore *list_store;
-    GtkTreeIter iter;
-    GdkPixbuf *pix;
-    guint nt;
-
-    list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (info->sideview)));
-    
-    nt = gtk_notebook_get_n_pages (GTK_NOTEBOOK (info->notebook));
-    
-    pix = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-				    icon_name,
-				    48,
-				    GTK_ICON_LOOKUP_USE_BUILTIN,
-				    NULL);
-    
-    gtk_list_store_append (list_store, &iter);
-    gtk_list_store_set (list_store, &iter, 
-			COL_SIDEBAR_ICON, pix,
-			COL_SIDEBAR_NAME, name,
-			COL_SIDEBAR_INT, nt,
-			-1);
-			
-    if ( pix )
-	g_object_unref (pix);
-}
-
-static void
-xfpm_info_add_device_view (XfpmInfo *info, UpDevice *device, const gchar *object_path)
-{
-    GtkWidget *view;
-
-    GtkListStore *list_store;
-    GtkTreeIter iter;
-    GtkTreeViewColumn *col;
-    GtkCellRenderer *renderer;
-    gchar *str;
-    gint i = 0;
-    guint type = 0, tech = 0;
-    gdouble energy_full_design = -1.0, energy_full = -1.0, energy_empty = -1.0, voltage = -1.0, percent = -1.0;
-    gboolean p_supply = FALSE;
-    gchar *model = NULL, *vendor = NULL, *serial = NULL;
-    const gchar *battery_type = NULL;
-    
-    view = gtk_tree_view_new ();
-    
-    list_store = gtk_list_store_new (XFPM_DEVICE_INFO_LAST, G_TYPE_STRING, G_TYPE_STRING);
-
-    gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (list_store));
-    
-    renderer = gtk_cell_renderer_text_new ();
-    
-    /*Device Attribute*/
-    col = gtk_tree_view_column_new();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "text", XFPM_DEVICE_INFO_NAME, NULL);
-    gtk_tree_view_column_set_title (col, _("Attribute"));
-    gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
-    
-    /*Device Attribute Value*/
-    col = gtk_tree_view_column_new();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "text", XFPM_DEVICE_INFO_VALUE, NULL);
-    gtk_tree_view_column_set_title (col, _("Value"));
-    
-    gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
-    
-    /**
-     * Add Device information:
-     **/
-    /*Device*/
-    gtk_list_store_append (list_store, &iter);
-    gtk_list_store_set (list_store, &iter, 
-			XFPM_DEVICE_INFO_NAME, _("Device"), 
-			XFPM_DEVICE_INFO_VALUE, g_str_has_prefix (object_path, UPOWER_PATH_DEVICE) ? object_path + strlen (UPOWER_PATH_DEVICE) : object_path,
-			-1);
-    i++;
-    
-    
-    /*Type*/
-    /* hack, this depends on XFPM_DEVICE_TYPE_* being in sync with UP_DEVICE_KIND_* */
-    g_object_get (device,
-		  "kind", &type,
-		  "power-supply", &p_supply,
-		  "model", &model,
-		  "vendor", &vendor,
-		  "serial", &serial,
-		  "technology", &tech,
-		  "energy-full-design", &energy_full_design,
-		  "energy-full", &energy_full,
-		  "energy-empty", &energy_empty,
-		  "voltage", &voltage,
-		  "percentage", &percent,
-		  NULL);
-
-    if (type != UP_DEVICE_KIND_UNKNOWN)
-    {
-	battery_type = xfpm_power_translate_device_type (type);
-	gtk_list_store_append (list_store, &iter);
-	gtk_list_store_set (list_store, &iter, 
-			    XFPM_DEVICE_INFO_NAME, _("Type"), 
-			    XFPM_DEVICE_INFO_VALUE, battery_type,
-			    -1);
-	i++;
-    }
-    
-    gtk_list_store_append (list_store, &iter);
-    gtk_list_store_set (list_store, &iter,
-			XFPM_DEVICE_INFO_NAME, _("PowerSupply"),
-			XFPM_DEVICE_INFO_VALUE, p_supply == TRUE ? _("True") : _("False"),
-			-1);
-    i++;
-    
-    if ( type != UP_DEVICE_KIND_LINE_POWER )
-    {
-	/*Model*/
-	if (model && strlen (model) > 0)
-	{
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter,
-				XFPM_DEVICE_INFO_NAME, _("Model"),
-				XFPM_DEVICE_INFO_VALUE, model,
-				-1);
-	    i++;
-	}
-	
-	gtk_list_store_append (list_store, &iter);
-	gtk_list_store_set (list_store, &iter,
-			    XFPM_DEVICE_INFO_NAME, _("Technology"),
-			    XFPM_DEVICE_INFO_VALUE, xfpm_power_translate_technology (tech),
-			    -1);
-	i++;
-
-	/*Percentage*/
-	if (percent >= 0)
-	{
-	    str = g_strdup_printf("%d", (guint) percent);
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter,
-				XFPM_DEVICE_INFO_NAME, _("Energy percent"),
-				XFPM_DEVICE_INFO_VALUE, str,
-				-1);
-	    i++;
-	    g_free(str);
-	}
-
-	if (energy_full_design > 0)
-	{
-	    /* TRANSLATORS: Unit here is Watt hour*/
-	    str = xfpm_info_get_energy_property (energy_full_design, _("Wh"));
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter, 
-				XFPM_DEVICE_INFO_NAME, _("Energy full design"), 
-				XFPM_DEVICE_INFO_VALUE, str,
-				-1);
-	    i++;
-	    g_free (str);
-	}
-	
-	if (energy_full > 0)
-	{
-	    /* TRANSLATORS: Unit here is Watt hour*/
-	    str = xfpm_info_get_energy_property (energy_full, _("Wh"));
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter, 
-				XFPM_DEVICE_INFO_NAME, _("Energy full"), 
-				XFPM_DEVICE_INFO_VALUE, str,
-				-1);
-	    i++;
-	    g_free (str);
-	}
-	
-	if (energy_empty > 0)
-	{
-	    /* TRANSLATORS: Unit here is Watt hour*/
-	    str = xfpm_info_get_energy_property (energy_empty, _("Wh"));
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter, 
-				XFPM_DEVICE_INFO_NAME, _("Energy empty"), 
-				XFPM_DEVICE_INFO_VALUE, str,
-				-1);
-	    i++;
-	    g_free (str);
-	}
-	
-	if (voltage > 0)
-	{
-	    /* TRANSLATORS: Unit here is Volt*/
-	    str = xfpm_info_get_energy_property (voltage, _("V"));
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter, 
-				XFPM_DEVICE_INFO_NAME, _("Voltage"), 
-				XFPM_DEVICE_INFO_VALUE, str,
-				-1);
-	    i++;
-	    g_free (str);
-	}
-
-	if (vendor && strlen (vendor) > 0)
-	{
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter,
-				XFPM_DEVICE_INFO_NAME, _("Vendor"),
-				XFPM_DEVICE_INFO_VALUE, vendor,
-				-1);
-	    i++;
-	}
-
-	if (serial && strlen (serial) > 0)
-	{
-	    gtk_list_store_append (list_store, &iter);
-	    gtk_list_store_set (list_store, &iter,
-				XFPM_DEVICE_INFO_NAME, _("Serial"),
-				XFPM_DEVICE_INFO_VALUE, serial,
-				-1);
-	    i++;
-	}
-    }
-    
-    xfpm_info_add_sidebar_icon (info, battery_type, xfpm_power_get_icon_name (type));
-    
-    gtk_notebook_append_page (GTK_NOTEBOOK (info->notebook), view, NULL);
-    gtk_widget_show (view);
-}
-
-static void
-xfpm_info_add_device (XfpmInfo *info, UpDevice *device)
-{
-    const gchar *object_path = up_device_get_object_path(device);
-    xfpm_info_add_device_view (info, device, object_path);
-}
-
-static void
-xfpm_info_power_devices (XfpmInfo *info)
-{
-    GPtrArray *array = NULL;
-    guint i;
-#if !UP_CHECK_VERSION(0, 99, 0)
-    up_client_enumerate_devices_sync(info->upower, NULL, NULL);
-#endif
-    /*Check for upower/devkit power here*/
-    array = up_client_get_devices(info->upower);
-    
-    if ( array )
-    {
-	for ( i = 0; i < array->len; i++)
-	{
-	    UpDevice *device = g_ptr_array_index (array, i);
-	    xfpm_info_add_device (info, device);
-	}
-	g_ptr_array_free (array, TRUE);
-    }
-}
-
-
-/**
- * 
- * Method GetData on /org/freedesktop/DeviceKit/Power/Wakeups
- * 
- * <method name="GetData">
- *     <arg name="data" type="a(budss)" direction="out"/> (1)
- * </method>
- *  (1): array | boolean	Wheter the proceess on userspace
- * 	       | uint           PID
- *             | double		Wakeups value            
- *             | string         command line
- *             | string         details
- **/
-static void
-xfpm_info_update_wakeups (XfpmInfo *info)
-{
-    GtkListStore *store;
-    
-    GError *error = NULL;
-    
-    static GType collection_type = G_TYPE_INVALID;
-    static GType struct_type = G_TYPE_INVALID;
-
-    GPtrArray *array = NULL;
-    
-    gboolean ret;
-    guint i;
-    
-    if ( G_UNLIKELY (collection_type == G_TYPE_INVALID ) )
-    {
-	struct_type = dbus_g_type_get_struct ("GValueArray",
-					      G_TYPE_BOOLEAN,
-					      G_TYPE_UINT,
-					      G_TYPE_DOUBLE,
-					      G_TYPE_STRING,
-					      G_TYPE_STRING,
-					      G_TYPE_INVALID);
-    
-	collection_type = dbus_g_type_get_collection ("GPtrArray", struct_type);
-    }
-    
-    ret = dbus_g_proxy_call (info->wakeups_proxy, "GetData", &error,
-			     G_TYPE_INVALID,
-			     collection_type, &array,
-			     NULL);
-		       
-    if ( !ret )
-    {
-	g_warning ("GetData Failed on %s : %s", UPOWER_PATH_WAKEUPS, error->message);
-	g_error_free (error);
-	return;
-    }
-		    
-    store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (info->wakeups)));
-    
-    gtk_list_store_clear (GTK_LIST_STORE (store));
-    
-    for ( i = 0; i < array->len; i++ )
-    {
-	GValue elem = { 0 };
-	GtkTreeIter iter;
-	
-	gboolean userspace;
-	guint pid;
-	gdouble value;
-	gchar *cmd;
-	gchar *formatted_cmd;
-	gchar *details;
-	gchar *formatted_details;
-	gchar *pid_str;
-	gchar *value_str;
-	const gchar *icon;
-	
-	g_value_init (&elem, struct_type);
-	g_value_set_static_boxed (&elem, g_ptr_array_index (array, i));
-	
-	dbus_g_type_struct_get (&elem,
-				0, &userspace,
-				1, &pid,
-				2, &value,
-				3, &cmd,
-				4, &details,
-				G_MAXUINT);
-	
-	if ( userspace )
-	{
-	    pid_str = g_strdup_printf ("%i", pid);
-	}
-	else
-	{
-	    if ( pid < 0xff0 )
-	    {
-		pid_str = g_strdup_printf ("IRQ%i", pid);
-	    }
-	    else
-	    {
-		pid_str = g_strdup("IRQx");
-	    }
-	}
-	value_str = g_strdup_printf ("%.1f", value);
-	
-	icon = userspace ? "application-x-executable" : "applications-system";
-	
-	formatted_cmd = gpm_stats_format_cmdline (cmd, userspace);
-	formatted_details = gpm_stats_format_details (details);
-	
-	gtk_list_store_append (store, &iter);
-	gtk_list_store_set (store, &iter, 
-			    COL_WAKEUPS_TYPE, icon,
-			    COL_WAKEUPS_PID, pid_str,
-			    COL_WAKEUPS_VALUE, value_str,
-			    COL_WAKEUPS_CMD, formatted_cmd,
-			    COL_WAKEUPS_DETAILS, formatted_details,
-			    -1);
-	
-	g_free (cmd);
-	g_free (details);
-	g_free (formatted_cmd);
-	g_free (formatted_details);
-	
-	g_value_unset (&elem);
-    }
-	
-    g_ptr_array_free (array, TRUE);
-    
-}
-
-static gboolean
-xfpm_info_update_wakeups_idle (gpointer data)
-{
-    XfpmInfo *info;
-    
-    info = (XfpmInfo*)data;
-    
-    if ( gtk_widget_get_visible (info->wakeups) )
-        xfpm_info_update_wakeups (info);
-    
-    return TRUE;
-}
-
-static void
-xfpm_info_cpu_wakeups (XfpmInfo *info)
-{
-    GtkWidget *vbox;
-    GtkWidget *scrolled;
-    GtkListStore *list_store;
-    GtkTreeViewColumn *col;
-    GtkCellRenderer *renderer;
-    
-    info->wakeups_proxy = dbus_g_proxy_new_for_name (info->bus,
-						     UPOWER_NAME,
-						     UPOWER_PATH_WAKEUPS,
-						     UPOWER_IFACE_WAKEUPS);
-							  
-    if ( !info->wakeups_proxy )
-    {
-	g_warning ("Unable to create proxy for %s", UPOWER_PATH_WAKEUPS);
-	return;
-    }
-    
-    list_store = gtk_list_store_new (NCOLS_WAKEUPS, 
-				     G_TYPE_STRING, /*type*/
-				     G_TYPE_STRING, /*pid*/
-				     G_TYPE_STRING, /*value*/
-				     G_TYPE_STRING, /*command*/
-				     G_TYPE_STRING); /*details*/
-				     
-    info->wakeups = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
-    
-    xfpm_info_add_sidebar_icon (info, _("Processor"), XFPM_PROCESSOR_ICON);
-    
-    col = gtk_tree_view_column_new ();
-    renderer = gtk_cell_renderer_pixbuf_new ();
-    g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "icon-name", COL_WAKEUPS_TYPE, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (info->wakeups), col);
-    gtk_tree_view_column_set_title (col, _("Type"));
-    
-    renderer = gtk_cell_renderer_text_new ();
-    
-    col = gtk_tree_view_column_new ();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "text", COL_WAKEUPS_PID, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (info->wakeups), col);
-    /* TANSLATORS: PID, is the process id, e.g what ps x gives*/
-    gtk_tree_view_column_set_title (col, _("PID"));
-    
-    col = gtk_tree_view_column_new ();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "markup", COL_WAKEUPS_VALUE, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (info->wakeups), col);
-    gtk_tree_view_column_set_title (col, _("Wakeups"));
-    
-    col = gtk_tree_view_column_new ();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "markup", COL_WAKEUPS_CMD, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (info->wakeups), col);
-    gtk_tree_view_column_set_title (col, _("Command"));
-    
-    col = gtk_tree_view_column_new ();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "markup", COL_WAKEUPS_DETAILS, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (info->wakeups), col);
-    gtk_tree_view_column_set_title (col, _("Details"));
-    
-    vbox = gtk_vbox_new (FALSE, 4);
-    scrolled = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
-				    GTK_POLICY_NEVER,
-				    GTK_POLICY_AUTOMATIC);
-    gtk_container_add (GTK_CONTAINER (scrolled), info->wakeups);
-    
-    gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
-    gtk_notebook_append_page (GTK_NOTEBOOK (info->notebook), vbox, NULL);
-    
-    xfpm_info_update_wakeups (info);
-    
-    xfpm_info_update_wakeups (info);
-    g_timeout_add_seconds (4, (GSourceFunc) xfpm_info_update_wakeups_idle, info);
-    
-    gtk_widget_show (vbox);
-}
-
-static void
-view_cursor_changed_cb (GtkTreeView *view, XfpmInfo *info)
-{
-    GtkTreeSelection *sel;
-    GtkTreeModel     *model;
-    GtkTreeIter       selected_row;
-    gint int_data = 0;
-
-    sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
-
-    if ( !gtk_tree_selection_get_selected (sel, &model, &selected_row))
-	return;
-
-    gtk_tree_model_get(model,
-                       &selected_row,
-                       COL_SIDEBAR_INT,
-                       &int_data,
-                       -1);
-
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (info->notebook), int_data);
-}
-
-static void
-xfpm_info_create (XfpmInfo *info)
-{
-    GtkWidget *content_area;
-    GtkWidget *hbox;
-    GtkWidget *viewport;
-    GtkListStore *list_store;
-    GtkTreeViewColumn *col;
-    GtkCellRenderer *renderer;
-    
-    info->dialog = xfce_titled_dialog_new_with_buttons (_("Power Information"),
-							NULL,
-							GTK_DIALOG_DESTROY_WITH_PARENT,
-							GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-							NULL);
-    gtk_window_set_position (GTK_WINDOW (info->dialog), GTK_WIN_POS_CENTER_ALWAYS);
-    gtk_window_set_default_size (GTK_WINDOW (info->dialog), -1, 400);
-				 
-    gtk_window_set_icon_name (GTK_WINDOW (info->dialog), GTK_STOCK_INFO);
-			      
-    content_area = gtk_dialog_get_content_area (GTK_DIALOG (info->dialog));
-    
-    hbox = gtk_hbox_new (FALSE, 4);
-    
-    gtk_container_add (GTK_CONTAINER (content_area), hbox);
-    
-    viewport = gtk_viewport_new (NULL, NULL);
-    info->sideview = gtk_tree_view_new ();
-    list_store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);
-
-    gtk_tree_view_set_model (GTK_TREE_VIEW (info->sideview), GTK_TREE_MODEL (list_store));
-    
-    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (info->sideview),TRUE);
-    col = gtk_tree_view_column_new ();
-
-    renderer = gtk_cell_renderer_pixbuf_new ();
-    
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "pixbuf", 0, NULL);
-
-    renderer = gtk_cell_renderer_text_new ();
-    gtk_tree_view_column_pack_start (col, renderer, FALSE);
-    gtk_tree_view_column_set_attributes (col, renderer, "markup", 1, NULL);
-    
-    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (info->sideview), FALSE);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (info->sideview), col);
-    
-    g_signal_connect (info->sideview, "cursor-changed",
-		      G_CALLBACK (view_cursor_changed_cb), info);
-    
-    gtk_container_add (GTK_CONTAINER (viewport), info->sideview);
-    
-    gtk_box_pack_start (GTK_BOX (hbox), viewport, FALSE, FALSE, 0);
-    
-    info->notebook = gtk_notebook_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), info->notebook, TRUE, TRUE, 0);
-    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (info->notebook), FALSE);
-    
-    /*Show power devices information, AC adapter, batteries*/
-    xfpm_info_power_devices (info);
-    
-    /*Sow CPU wakeups*/
-    xfpm_info_cpu_wakeups (info);
-    
-    g_object_set (G_OBJECT (hbox),
-		  "border-width", 4,
-		  NULL);
-    
-    gtk_widget_show_all (hbox);
-}
-
-static void
-xfpm_info_connect (XfpmInfo *info)
-{
-    GError *error = NULL;
-    
-    info->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-    
-    if ( error )
-    {
-	g_error ("Cannot connect to system bus : %s", error->message);
-	g_error_free (error);
-    }
-}
-
-static XfpmInfo *
-xfpm_info_new (void)
-{
-    XfpmInfo *info;
-    
-    info = g_new0 (XfpmInfo, 1);
-    
-    info->bus           = NULL;
-    info->power_proxy   = NULL;
-    info->wakeups_proxy = NULL;
-    info->dialog        = NULL;
-    info->upower        = up_client_new ();
-    
-    return info;
-}
-
-static void
-xfpm_info_free (XfpmInfo *info)
-{
-    if ( info->bus ) 
-	dbus_g_connection_unref (info->bus);
-	
-    if ( info->power_proxy )
-	g_object_unref (info->power_proxy);
-	
-    if ( info->wakeups_proxy )
-	g_object_unref (info->wakeups_proxy);
-	
-    g_free (info);
-}
-
-int main (int argc, char **argv)
-{
-    XfpmInfo *info;
-    XfpmUnique *unique;
-    
-    GError *error = NULL;
-    gboolean version = FALSE;
-    
-    GOptionEntry option_entries[] = 
-    {
-	{ "version", 'V', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &version, N_("Version information"), NULL },
-	{ NULL, },
-    };
-
-    xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
-    
-    g_set_application_name (PACKAGE_NAME);
-    
-    if (!gtk_init_with_args (&argc, &argv, (gchar *)"", option_entries, (gchar *)PACKAGE, &error)) 
-    {
-        if (G_LIKELY (error)) 
-        {
-            g_printerr ("%s: %s.\n", G_LOG_DOMAIN, error->message);
-            g_printerr (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
-            g_printerr ("\n");
-            g_error_free (error);
-        }
-        else
-        {
-            g_error ("Unable to open display.");
-	}
-
-        return EXIT_FAILURE;
-    }
-    
-    if ( version )    
-    {
-	show_version ();
-    }
-    
-    
-    unique = xfpm_unique_new ("org.Xfce.PowerManager.Info");
-    
-    if ( !xfpm_unique_app_is_running (unique ) )
-    {
-	info = xfpm_info_new ();
-	xfpm_info_connect (info);
-	xfpm_info_create (info);
-	
-	g_signal_connect_swapped (unique, "ping-received",
-				  G_CALLBACK (gtk_window_present), info->dialog);
-	
-	gtk_dialog_run (GTK_DIALOG (info->dialog));
-	
-	gtk_widget_destroy (info->dialog);
-	
-	xfpm_info_free (info);
-    }
-    
-    g_object_unref (unique);
-    
-    return EXIT_SUCCESS;
-}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list