[netspeed/unstable] Create a new class NetworkDevice, which implements polling the info from glibtop



commit aadf6a5edc386e6b295fb02e6964e13351683855
Author: Jörgen Scheibengruber <mfcn gmx de>
Date:   Fri Jul 2 03:25:47 2010 +0300

    Create a new class NetworkDevice, which implements polling the info from glibtop

 src/Makefile.am      |    2 +
 src/backend.c        |    5 +-
 src/backend.h        |   17 +--
 src/info-dialog.c    |  244 +++++++++++++++++---------
 src/info-dialog.h    |    5 +-
 src/netspeed.c       |  230 +++++++++++++------------
 src/network-device.c |  476 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/network-device.h |   80 +++++++++
 8 files changed, 845 insertions(+), 214 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index fc29b4e..97e3a79 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,8 @@ libexec_PROGRAMS = netspeed_applet2
 netspeed_applet2_SOURCES = \
 	backend.h \
 	backend.c \
+	network-device.h \
+	network-device.c \
 	utils.h \
 	utils.c \
 	settings.h \
diff --git a/src/backend.c b/src/backend.c
index aa9b1bb..9c079c3 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -125,7 +125,7 @@ free_devices_list(GList *list)
 	g_list_free(list);
 }
 
-
+#if 0
 /* Frees a DevInfo struct and all the stuff it contains
  */
 void
@@ -188,8 +188,6 @@ get_ptp_info(DevInfo *devinfo)
 }
 
 
-
-
 void
 get_device_info(const char *device, DevInfo *devinfo)
 {
@@ -325,4 +323,5 @@ out:
 	if (fd != -1)
 		close (fd);
 }
+#endif
 #endif /* HAVE_IW */
diff --git a/src/backend.h b/src/backend.h
index b60c615..d70317e 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -38,18 +38,7 @@
 #define SIOCGIWNAME     0x8B01          /* get name == wireless protocol */
 #define SIOCGIWENCODE	0x8B2B		    /* get encoding token & mode */
 
-/* Different types of interfaces */
-typedef enum
-{
-	DEV_LO,
-	DEV_ETHERNET,
-	DEV_WIRELESS,
-	DEV_PPP,
-	DEV_PLIP,
-	DEV_SLIP,
-	DEV_UNKNOWN	// this has to be the last one
-} DevType;	
-
+#if 0
 /* Some information about the selected network device
  */
 typedef struct
@@ -69,6 +58,7 @@ typedef struct
 	char *rx_rate;
 	char *sum_rate;
 } DevInfo;
+#endif
 
 GList*
 get_available_devices(void);
@@ -82,6 +72,7 @@ is_dummy_device(const char* device);
 void
 free_devices_list(GList *list);
 
+#if 0
 void
 free_device_info(DevInfo *devinfo);
 
@@ -93,4 +84,6 @@ compare_device_info(const DevInfo *a, const DevInfo *b);
 
 void 
 get_wireless_info (DevInfo *devinfo);
+#endif
+
 #endif /* _BACKEND_H */
diff --git a/src/info-dialog.c b/src/info-dialog.c
index 411fdde..82fae38 100644
--- a/src/info-dialog.c
+++ b/src/info-dialog.c
@@ -24,7 +24,6 @@
 
 #include <glib/gi18n.h>
 #include "info-dialog.h"
-#include "backend.h"
 #include "utils.h"
 
 #define GRAPH_VALUES 180
@@ -34,7 +33,7 @@ enum
 {
 	PROP_0,
 	PROP_SETTINGS,
-	PROP_DEV_INFO
+	PROP_DEVICE
 };
 
 struct _InfoDialogPrivate
@@ -43,8 +42,12 @@ struct _InfoDialogPrivate
 	GtkWidget *signalbar;
 	GtkWidget *inbytes_text;
 	GtkWidget *outbytes_text;
+	GtkWidget *ip_text;
+	GtkWidget *netmask_text;
+	GtkWidget *hwaddr_text;
+	GtkWidget *ptpip_text;
 	
-	DevInfo devinfo;
+	NetworkDevice *device;
 
 	double max_graph, in_graph[GRAPH_VALUES], out_graph[GRAPH_VALUES];
 	int index_graph;
@@ -67,6 +70,124 @@ static void info_dialog_get_property (GObject *object, guint property_id, GValue
 
 G_DEFINE_TYPE (InfoDialog, info_dialog, GTK_TYPE_DIALOG);
 
+GtkWidget*
+info_dialog_new (Settings *settings, NetworkDevice *device)
+{
+	return g_object_new (INFO_DIALOG_TYPE,
+						"settings", settings,
+						"device", device,
+						"has-separator", FALSE,
+						NULL);
+}
+
+static void
+network_device_changed_cb (NetworkDevice *device, gpointer user_data)
+{
+	InfoDialogPrivate *priv = INFO_DIALOG (user_data)->priv;
+	
+	char *inbytes, *outbytes;
+	gboolean show_bits;
+	int wifi_quality;
+	guint64 rx, tx;
+
+	g_object_get (priv->device,
+				"wifi-quality", &wifi_quality,
+				"rx", &rx, "tx", &tx,
+				NULL);
+
+	if (priv->signalbar) {
+		float quality;
+		char *text;
+
+		quality = wifi_quality / 100.0f;
+		if (quality > 1.0)
+			quality = 1.0;
+
+		text = g_strdup_printf ("%d %%", wifi_quality);
+		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->signalbar), quality);
+		gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->signalbar), text);
+		g_free(text);
+	}
+
+	g_object_get (priv->settings,
+			"display-bits", &show_bits,
+			NULL);
+	/* Refresh the values of the Infodialog */
+	if (priv->inbytes_text) {
+		inbytes = bytes_to_string((double)rx, FALSE, show_bits);
+		gtk_label_set_text(GTK_LABEL(priv->inbytes_text), inbytes);
+		g_free(inbytes);
+	}	
+	if (priv->outbytes_text) {
+		outbytes = bytes_to_string((double)tx, FALSE, show_bits);
+		gtk_label_set_text(GTK_LABEL(priv->outbytes_text), outbytes);
+		g_free(outbytes);
+	}
+#if 0
+	/* Redraw the graph of the Infodialog */
+	if (priv->drawingarea)
+		redraw_graph(priv);
+#endif
+}
+
+void
+info_dialog_set_device (InfoDialog *info_dialog, NetworkDevice *device)
+{
+	InfoDialogPrivate *priv;
+	char *title;
+	char *ipv4_addr;
+	char *netmask;
+	char *hw_addr;
+	char *ptp_addr;
+
+	g_return_if_fail (IS_NETWORK_DEVICE (device));
+	g_return_if_fail (IS_INFO_DIALOG (info_dialog));
+
+	priv = info_dialog->priv;
+
+	if (priv->device) {
+		g_object_unref (device);
+	}
+	priv->device = g_object_ref (device);
+
+	title = g_strdup_printf(_("Device Details for %s"),
+					network_device_name (priv->device));
+	gtk_window_set_title (GTK_WINDOW (info_dialog), title);
+	g_free(title);
+
+	g_object_get (priv->device,
+			"ipv4-addr", &ipv4_addr,
+			"netmask", &netmask,
+			"hw-addr", &hw_addr,
+			"ptp-addr", &ptp_addr,
+			NULL);
+
+	gtk_label_set_text (GTK_LABEL(priv->ip_text), ipv4_addr ? ipv4_addr : _("none"));
+	gtk_label_set_text (GTK_LABEL(priv->netmask_text), netmask ? netmask : _("none"));
+	gtk_label_set_text (GTK_LABEL(priv->hwaddr_text), hw_addr ? hw_addr : _("none"));
+	gtk_label_set_text (GTK_LABEL(priv->ptpip_text), ptp_addr ? ptp_addr : _("none"));
+
+	g_free (ipv4_addr);
+	g_free (netmask);
+	g_free (hw_addr);
+	g_free (ptp_addr);
+#if 0
+		for (i = 0; i < GRAPH_VALUES; i++)
+		{
+			priv->in_graph[i] = -1;
+			priv->out_graph[i] = -1;
+		}
+		priv->max_graph = 0;
+		priv->index_graph = 0;
+#endif
+
+	g_signal_connect (G_OBJECT (priv->device),
+					"changed",
+					G_CALLBACK (network_device_changed_cb),
+					info_dialog);
+}
+
+
 #if 0
 /* Redraws the graph drawingarea
  * Some really black magic is going on in here ;-)
@@ -219,7 +340,13 @@ info_dialog_class_init (InfoDialogClass *klass)
 							 "Settings",
 							 "The netspeed settings.",
 							 SETTINGS_TYPE,
-							 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+							 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
+	g_object_class_install_property (object_class, PROP_DEVICE,
+		g_param_spec_object ("device",
+							 "Device",
+							 "The network device.",
+							 NETWORK_DEVICE_TYPE,
+							 G_PARAM_CONSTRUCT | G_PARAM_WRITABLE));
 }
 
 static void
@@ -235,15 +362,10 @@ info_dialog_init (InfoDialog *self)
 	GtkWidget *inbytes_label, *outbytes_label;
 	GtkWidget *incolor_sel, *incolor_label;
 	GtkWidget *outcolor_sel, *outcolor_label;
-	char *title;
 
 	priv = INFO_DIALOG_GET_PRIVATE (self);
 	self->priv = priv;
 
-	title = g_strdup_printf(_("Device Details for %s"), priv->devinfo.name);
-	gtk_window_set_title (GTK_WINDOW (self), title);
-	g_free(title);
-
 	gtk_dialog_add_buttons (GTK_DIALOG (self),
 							GTK_STOCK_HELP, GTK_RESPONSE_HELP,
 							GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
@@ -289,10 +411,10 @@ info_dialog_init (InfoDialog *self)
 	inbytes_label = gtk_label_new(_("Bytes in:"));
 	outbytes_label = gtk_label_new(_("Bytes out:"));
 	
-	ip_text = gtk_label_new(priv->devinfo.ip ? priv->devinfo.ip : _("none"));
-	netmask_text = gtk_label_new(priv->devinfo.netmask ? priv->devinfo.netmask : _("none"));
-	hwaddr_text = gtk_label_new(priv->devinfo.hwaddr ? priv->devinfo.hwaddr : _("none"));
-	ptpip_text = gtk_label_new(priv->devinfo.ptpip ? priv->devinfo.ptpip : _("none"));
+	priv->ip_text = gtk_label_new(NULL);
+	priv->netmask_text = gtk_label_new(NULL);
+	priv->hwaddr_text = gtk_label_new(NULL);
+	priv->ptpip_text = gtk_label_new(NULL);
 	priv->inbytes_text = gtk_label_new("0 byte");
 	priv->outbytes_text = gtk_label_new("0 byte");
 
@@ -326,7 +448,8 @@ info_dialog_init (InfoDialog *self)
 	gtk_table_attach_defaults(GTK_TABLE(table), priv->inbytes_text, 1, 2, 2, 3);
 	gtk_table_attach_defaults(GTK_TABLE(table), outbytes_label, 2, 3, 2, 3);
 	gtk_table_attach_defaults(GTK_TABLE(table), priv->outbytes_text, 3, 4, 2, 3);
-	
+
+#if 0	
 	/* check if we got an ipv6 address */
 	if (priv->devinfo.ipv6 && (strlen (priv->devinfo.ipv6) > 2)) {
 		GtkWidget *ipv6_label, *ipv6_text;
@@ -378,6 +501,7 @@ info_dialog_init (InfoDialog *self)
 		gtk_table_attach_defaults (GTK_TABLE (table), essid_label, 0, 3, 4, 5);
 		gtk_table_attach_defaults (GTK_TABLE (table), essid_text, 1, 4, 4, 5);
 	}
+#endif
 
 #if 0
 	g_signal_connect(G_OBJECT(applet->drawingarea), "expose_event",
@@ -422,6 +546,7 @@ info_dialog_constructed (GObject *object)
 	}
 }
 
+
 static void
 info_dialog_set_property (GObject    *object,
 						guint         property_id,
@@ -434,6 +559,9 @@ info_dialog_set_property (GObject    *object,
 		case PROP_SETTINGS:
 			priv->settings = g_value_dup_object (value);
 			break;
+		case PROP_DEVICE:
+			info_dialog_set_device (INFO_DIALOG (object), g_value_get_object (value));
+			break;
 	}
 }
 
@@ -443,18 +571,26 @@ info_dialog_get_property (GObject    *object,
 						GValue       *value,
 						GParamSpec   *pspec)
 {
-	InfoDialogPrivate *priv = INFO_DIALOG (object)->priv;
-
-	switch (property_id) {
-		case PROP_SETTINGS:
-			g_value_set_object (value, priv->settings);
-			break;
-	}
+	/* No readable props */
 }
 
 static void
 info_dialog_dispose (GObject *object)
 {
+	InfoDialogPrivate *priv = INFO_DIALOG (object)->priv;
+
+	if (priv->settings) {
+		g_object_unref (priv->settings);
+		priv->settings = NULL;
+	}
+	if (priv->device) {
+		g_object_disconnect(G_OBJECT(priv->device), "any_signal::changed",
+						G_CALLBACK(network_device_changed_cb), object,
+						NULL);
+		g_object_unref (priv->device);
+		priv->device = NULL;
+	}
+
 	G_OBJECT_CLASS (info_dialog_parent_class)->dispose (object);
 }
 
@@ -464,69 +600,3 @@ info_dialog_finalize (GObject *object)
 	G_OBJECT_CLASS (info_dialog_parent_class)->finalize (object);
 }
 
-GtkWidget*
-info_dialog_new (Settings *settings)
-{
-	return g_object_new (INFO_DIALOG_TYPE,
-						"settings", settings,
-						"has-separator", FALSE,
-						NULL);
-}
-
-void
-info_dialog_device_changed (InfoDialog *info_dialog)
-{
-#if 0
-		for (i = 0; i < GRAPH_VALUES; i++)
-		{
-			priv->in_graph[i] = -1;
-			priv->out_graph[i] = -1;
-		}
-		priv->max_graph = 0;
-		priv->index_graph = 0;
-#endif
-
-}
-
-void
-info_dialog_update (InfoDialog *info_dialog)
-{
-	InfoDialogPrivate *priv = INFO_DIALOG (info_dialog)->priv;
-	char *inbytes, *outbytes;
-	gboolean show_bits;
-
-	if (priv->signalbar) {
-		float quality;
-		char *text;
-
-		quality = priv->devinfo.qual / 100.0f;
-		if (quality > 1.0)
-			quality = 1.0;
-
-		text = g_strdup_printf ("%d %%", priv->devinfo.qual);
-		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->signalbar), quality);
-		gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->signalbar), text);
-		g_free(text);
-	}
-
-	g_object_get (priv->settings,
-			"display-bits", &show_bits,
-			NULL);
-	/* Refresh the values of the Infodialog */
-	if (priv->inbytes_text) {
-		inbytes = bytes_to_string((double)priv->devinfo.rx, FALSE, show_bits);
-		gtk_label_set_text(GTK_LABEL(priv->inbytes_text), inbytes);
-		g_free(inbytes);
-	}	
-	if (priv->outbytes_text) {
-		outbytes = bytes_to_string((double)priv->devinfo.tx, FALSE, show_bits);
-		gtk_label_set_text(GTK_LABEL(priv->outbytes_text), outbytes);
-		g_free(outbytes);
-	}
-#if 0
-	/* Redraw the graph of the Infodialog */
-	if (priv->drawingarea)
-		redraw_graph(priv);
-#endif
-}
-
diff --git a/src/info-dialog.h b/src/info-dialog.h
index 58bf760..0c09026 100644
--- a/src/info-dialog.h
+++ b/src/info-dialog.h
@@ -23,6 +23,7 @@
 
 #include <gtk/gtk.h>
 #include "settings.h"
+#include "network-device.h"
 
 G_BEGIN_DECLS
 
@@ -50,7 +51,9 @@ struct _InfoDialog
 
 GType info_dialog_get_type (void);
 
-GtkWidget* info_dialog_new (Settings*);
+GtkWidget* info_dialog_new (Settings *settings, NetworkDevice *device);
+
+void info_dialog_set_device (InfoDialog *info_dialog, NetworkDevice *device);
 
 void info_dialog_update (InfoDialog *info_dialog);
 
diff --git a/src/netspeed.c b/src/netspeed.c
index 5558173..b2ca414 100644
--- a/src/netspeed.c
+++ b/src/netspeed.c
@@ -30,11 +30,11 @@
 #include "settings.h"
 #include "settings-dialog.h"
 #include "info-dialog.h"
-#include "backend.h"
+#include "network-device.h"
 #include "utils.h"
 
 /* Icons for the interfaces */
-static const char* const dev_type_icon[DEV_UNKNOWN + 1] = {
+static const char* const dev_type_icon[NETWORK_DEVICE_TYPE_UNKNOWN + 1] = {
 	"netspeed-loopback",         /* DEV_LO */
 	"network-wired",             /* DEV_ETHERNET */
 	"network-wireless",          /* DEV_WIRELESS */
@@ -63,14 +63,11 @@ static const char LOGO_ICON[] = "netspeed-applet";
  */
 #define OLD_VALUES 5
 
-typedef struct _NetspeedApplet NetspeedApplet;
-
 struct _NetspeedPrivate
 {
-	NetspeedApplet *stuff;
-
 	Settings *settings;
-	guint timeout_id;
+
+	NetworkDevice *device;
 
 	GtkWidget *settings_dialog;
 	GtkWidget *info_dialog;
@@ -118,23 +115,10 @@ static void netspeed_menu_show_about (BonoboUIComponent *uic, gpointer data, con
 static void netspeed_menu_show_settings_dialog (BonoboUIComponent *uic, gpointer data, const gchar *verbname);
 static void netspeed_menu_show_info_dialog (BonoboUIComponent *uic, gpointer data, const gchar *verbname);
 static void netspeed_display_help_section (GtkWidget *parent, const gchar *section);
+static void netspeed_set_network_device (Netspeed *netspeed, NetworkDevice *device);
 
 G_DEFINE_TYPE (Netspeed, netspeed, PANEL_TYPE_APPLET);
 
-/* A struct containing all the "global" data of the 
- * applet
- * FIXME: This is old stuff and should be moved into NetspeedPrivate
- */
-struct _NetspeedApplet
-{
-	PanelApplet *applet;
-	
-	int refresh_time;
-	
-	DevInfo devinfo;
-	gboolean device_has_changed;
-};
-
 static void
 update_tooltip(Netspeed* applet);
 
@@ -148,26 +132,28 @@ change_icons(Netspeed *applet)
 	GdkPixbuf *in_arrow, *out_arrow;
 	GtkIconTheme *icon_theme;
 	gboolean change_icon;
+	NetworkDeviceType type;
+	NetworkDeviceState state;
 
 	icon_theme = gtk_icon_theme_get_default();
 	/* If the user wants a different icon then the eth0, we load it */
 	g_object_get (priv->settings, "display-specific-icon", &change_icon, NULL);
+	g_object_get (priv->device, "type", &type, "state", &state, NULL);
 	if (change_icon) {
-		dev = gtk_icon_theme_load_icon(icon_theme, 
-                        dev_type_icon[priv->stuff->devinfo.type], 16, 0, NULL);
+		dev = gtk_icon_theme_load_icon(icon_theme,
+                        dev_type_icon[type], 16, 0, NULL);
 	} else {
         	dev = gtk_icon_theme_load_icon(icon_theme, 
-					       dev_type_icon[DEV_UNKNOWN], 
+					       dev_type_icon[NETWORK_DEVICE_TYPE_UNKNOWN], 
 					       16, 0, NULL);
 	}
     
-    	/* We need a fallback */
-    	if (dev == NULL) 
-		dev = gtk_icon_theme_load_icon(icon_theme, 
-					       dev_type_icon[DEV_UNKNOWN],
-					       16, 0, NULL);
-        
-    
+	/* We need a fallback */
+	if (dev == NULL)
+	dev = gtk_icon_theme_load_icon(icon_theme, 
+					   dev_type_icon[NETWORK_DEVICE_TYPE_UNKNOWN],
+					   16, 0, NULL);
+	
 	in_arrow = gtk_icon_theme_load_icon(icon_theme, IN_ICON, 16, 0, NULL);
 	out_arrow = gtk_icon_theme_load_icon(icon_theme, OUT_ICON, 16, 0, NULL);
 
@@ -179,7 +165,7 @@ change_icons(Netspeed *applet)
 	gdk_pixbuf_unref(in_arrow);
 	gdk_pixbuf_unref(out_arrow);
 	
-	if (priv->stuff->devinfo.running) {
+	if (state & NETWORK_DEVICE_STATE_RUNNING) {
 		gtk_widget_show(priv->in_box);
 		gtk_widget_show(priv->out_box);
 	} else {
@@ -193,9 +179,9 @@ change_icons(Netspeed *applet)
         	down = gtk_icon_theme_load_icon(icon_theme, ERROR_ICON, 16, 0, NULL);	
 		gdk_pixbuf_composite(down, copy, 8, 8, 8, 8, 8, 8, 0.5, 0.5, GDK_INTERP_BILINEAR, 0xFF);
 		g_object_unref(down);
-	      	g_object_unref(dev);
+		g_object_unref(dev);
 		dev = copy;
-	}		
+	}
 
 	gtk_image_set_from_pixbuf(GTK_IMAGE(priv->dev_pix), dev);
 	g_object_unref(dev);
@@ -206,9 +192,10 @@ update_quality_icon(Netspeed *applet)
 {
 	NetspeedPrivate *priv = applet->priv;
 	unsigned int q;
-	
-	q = (priv->stuff->devinfo.qual);
-	q /= 25;
+	int wifi_quality;
+
+	g_object_get (priv->device, "wifi-quality", &wifi_quality, NULL);
+	q = wifi_quality / 25;
 	q = CLAMP(q, 0, 3); /* q out of range would crash when accessing qual_pixbufs[q] */
 	gtk_image_set_from_pixbuf (GTK_IMAGE(priv->qual_pix), priv->qual_pixbufs[q]);
 }
@@ -237,14 +224,32 @@ icon_theme_changed_cb(GtkIconTheme *icon_theme, gpointer user_data)
 {
 	Netspeed *applet = NETSPEED (user_data);
 	NetspeedPrivate *priv = applet->priv;
+	NetworkDeviceType type;
+	NetworkDeviceState state;
 
 	init_quality_pixbufs (applet);
-	if (priv->stuff->devinfo.type == DEV_WIRELESS && priv->stuff->devinfo.up) {
+	g_object_get (priv->device, "type", &type, "state", &state, NULL);
+	if (type == NETWORK_DEVICE_TYPE_WIRELESS &&
+		(state & NETWORK_DEVICE_STATE_UP)) {
 		update_quality_icon (applet);
 	}
 	change_icons (applet);
 }
 
+
+static void
+netspeed_set_network_device (Netspeed *applet, NetworkDevice *device)
+{
+	NetspeedPrivate *priv = applet->priv;
+	g_return_if_fail (IS_NETWORK_DEVICE (device));
+
+	if (priv->device) {
+		g_object_unref (priv->device);
+	}
+	priv->device = g_object_ref (device);
+}
+
+#if 0
 static gboolean
 set_applet_devinfo(NetspeedApplet* applet, const char* iface)
 {
@@ -287,11 +292,13 @@ search_for_up_if(NetspeedApplet *applet)
 	}
 	free_devices_list(devices);
 }
+#endif
 
 /* Here happens the really interesting stuff */
 static void
 update_applet(Netspeed *applet)
 {
+#if 0
 	NetspeedPrivate *priv = NETSPEED (applet)->priv;
 	guint64 indiff, outdiff;
 	double inrate, outrate;
@@ -419,15 +426,7 @@ update_applet(Netspeed *applet)
 			search_for_up_if(priv->stuff);
 		}
 	}
-}
-
-static gboolean
-timeout_function(gpointer user_data)
-{
-	Netspeed *applet = NETSPEED (user_data);
-	
-	update_applet (applet);
-	return TRUE;
+#endif
 }
 
 /* Block the size_request signal emit by the label if the
@@ -454,23 +453,38 @@ update_tooltip(Netspeed* applet)
 	NetspeedPrivate *priv = NETSPEED (applet)->priv;
 	GString* tooltip;
 	gboolean show_sum;
+	char *ipv4_addr;
+	char *netmask;
+	char *hw_addr;
+	char *ptp_addr;
+	char *name;
+	NetworkDeviceState state;
+	NetworkDeviceType type;
 
 	if (!priv->show_tooltip) {
 		return;
 	}
 
 	g_object_get (priv->settings, "display-sum", &show_sum, NULL);
+	g_object_get (priv->device,
+			"state", &state,
+			"name", &name,
+			"ipv4-addr", &ipv4_addr,
+			"netmask", &netmask,
+			"hw-addr", &hw_addr,
+			"ptp-addr", &ptp_addr,
+			NULL);
 
 	tooltip = g_string_new("");
+#if 0
+	if (state & NETWORK_DEVICE_STATE_RUNNING) {
 	if (!priv->stuff->devinfo.running) {
-		g_string_printf(tooltip, _("%s is down"), priv->stuff->devinfo.name);
-	} else {
 		if (show_sum) {
 			g_string_printf(
 				  tooltip,
 				  _("%s: %s\nin: %s out: %s"),
-				  priv->stuff->devinfo.name,
-				  priv->stuff->devinfo.ip ? priv->stuff->devinfo.ip : _("has no ip"),
+				  name,
+				  ipv4_addr ? ipv4_addr : _("has no ip"),
 				  priv->stuff->devinfo.rx_rate,
 				  priv->stuff->devinfo.tx_rate
 				  );
@@ -478,12 +492,12 @@ update_tooltip(Netspeed* applet)
 			g_string_printf(
 				  tooltip,
 				  _("%s: %s\nsum: %s"),
-				  priv->stuff->devinfo.name,
-				  priv->stuff->devinfo.ip ? priv->stuff->devinfo.ip : _("has no ip"),
+				  name,
+				  ipv4_addr ? ipv4_addr : _("has no ip"),
 				  priv->stuff->devinfo.sum_rate
 				  );
 		}
-		if (priv->stuff->devinfo.type == DEV_WIRELESS) {
+		if (type == NETWORK_DEVICE_TYPE_WIRELESS) {
 			g_string_append_printf(
 					 tooltip,
 					 _("\nESSID: %s\nStrength: %d %%"),
@@ -491,13 +505,28 @@ update_tooltip(Netspeed* applet)
 					 priv->stuff->devinfo.qual
 					 );
 		}
+	} else {
+		g_string_printf(tooltip, _("%s is down"), priv->stuff->devinfo.name);
 	}
+#endif
+	g_free (name);
+	g_free (ipv4_addr);
+	g_free (netmask);
+	g_free (hw_addr);
+	g_free (ptp_addr);
 
 	gtk_widget_set_tooltip_text(GTK_WIDGET(applet), tooltip->str);
 	gtk_widget_trigger_tooltip_query(GTK_WIDGET(applet));
 	g_string_free(tooltip, TRUE);
 }
 
+static void
+network_device_changed_cb(NetworkDevice *device, gpointer user_data)
+{
+	Netspeed *applet = NETSPEED (user_data);
+	
+	update_applet (applet);
+}
 
 static void
 settings_display_sum_changed_cb (GObject *object,
@@ -527,10 +556,11 @@ settings_device_changed_cb (GObject *object,
 	NetspeedPrivate *priv = applet->priv;
 	char *device;
 
+#if 0
 	g_object_get (object, "device", &device, NULL);
 	get_device_info (device, &priv->stuff->devinfo);
 	priv->stuff->device_has_changed = TRUE;
-	update_applet (applet);
+#endif
 }
 
 static void
@@ -559,25 +589,17 @@ static void
 netspeed_init (Netspeed *self)
 {
 	NetspeedPrivate *priv = NETSPEED_GET_PRIVATE (self);
-	NetspeedApplet *applet;
 	int i;
 	GtkIconTheme *icon_theme;
 	GtkWidget *spacer, *spacer_box;
 	
 	/* Install shortcut */
 	self->priv = priv;
-
 	gtk_widget_set_name (GTK_WIDGET(self), "PanelApplet");
-	
-	/* Alloc the applet. The "NULL-setting" is really redudant
- 	 * but aren't we paranoid?
-	 */
-	applet = g_malloc0(sizeof(NetspeedApplet));
-	applet->applet = PANEL_APPLET(self);
-	priv->stuff = applet;
-	memset(&applet->devinfo, 0, sizeof(DevInfo));
-	applet->refresh_time = 1000.0;
 
+	panel_applet_set_flags (PANEL_APPLET (self),
+			PANEL_APPLET_EXPAND_MINOR);
+	
 #if 0
 	for (i = 0; i < GRAPH_VALUES; i++)
 	{
@@ -585,9 +607,9 @@ netspeed_init (Netspeed *self)
 		applet->out_graph[i] = -1;
 	}	
 #endif
-	priv->in_label = gtk_label_new("");
-	priv->out_label = gtk_label_new("");
-	priv->sum_label = gtk_label_new("");
+	priv->in_label = gtk_label_new("test");
+	priv->out_label = gtk_label_new("test");
+	priv->sum_label = gtk_label_new("test");
 	
 	priv->in_pix = gtk_image_new();
 	priv->out_pix = gtk_image_new();
@@ -653,10 +675,6 @@ netspeed_factory (PanelApplet *applet, const gchar *iid, gpointer data)
 	priv->settings = settings_new_with_gconf_path (gconf_path);
 	g_free (gconf_path);
 
-	g_object_get (priv->settings, "device", &device, NULL);
-	get_device_info(device, &priv->stuff->devinfo);
-	g_free (device);
-
 	g_signal_connect (G_OBJECT (priv->settings),
 					"notify::display-sum",
 					G_CALLBACK (settings_display_sum_changed_cb),
@@ -670,34 +688,20 @@ netspeed_factory (PanelApplet *applet, const gchar *iid, gpointer data)
 					G_CALLBACK (settings_device_changed_cb),
 					applet);
 
-	if (!priv->stuff->devinfo.name) {
-		GList *ptr, *devices = get_available_devices();
-		ptr = devices;
-		while (ptr) { 
-			if (!g_str_equal(ptr->data, "lo")) {
-				get_device_info(ptr->data, &priv->stuff->devinfo);
-				break;
-			}
-			ptr = g_list_next(ptr);
-		}
-		free_devices_list(devices);		
-	}
-	if (!priv->stuff->devinfo.name)
-		get_device_info("lo", &priv->stuff->devinfo);	
-	priv->stuff->device_has_changed = TRUE;	
-	
-	init_quality_pixbufs (NETSPEED (applet));
+	g_object_get (priv->settings, "device", &device, NULL);
+	priv->device = network_device_new (device);
+	g_free (device);
 
-	netspeed_relayout (NETSPEED (applet));
-	update_applet(NETSPEED (applet));
+	g_signal_connect (G_OBJECT (priv->device),
+					"changed",
+					G_CALLBACK (network_device_changed_cb),
+					applet);
 
-	panel_applet_set_flags(applet, PANEL_APPLET_EXPAND_MINOR);
+	init_quality_pixbufs (NETSPEED (applet));
+	netspeed_relayout (NETSPEED (applet));
 
 	gtk_widget_show_all(GTK_WIDGET(applet));
 
-	priv->timeout_id = g_timeout_add (priv->stuff->refresh_time,
-									timeout_function,
-									applet);
 
 	return TRUE;
 }
@@ -803,11 +807,11 @@ static gboolean
 netspeed_button_press_event (GtkWidget *widget, GdkEventButton *event)
 {
 	NetspeedPrivate *priv = NETSPEED (widget)->priv;
-	char *up_cmd, *down_cmd;
 
 	if (event->button == 1)
 	{
 		GError *error = NULL;
+		char *up_cmd, *down_cmd;
 		
 		if (priv->connect_dialog)
 		{	
@@ -823,8 +827,14 @@ netspeed_button_press_event (GtkWidget *widget, GdkEventButton *event)
 		{
 			const char *question;
 			int response;
+			NetworkDeviceState state;
+			char *name;
 			
-			if (priv->stuff->devinfo.up)
+			g_object_get (priv->device,
+					"state", &state,
+					"name", &name,
+					NULL);
+			if (state & NETWORK_DEVICE_STATE_UP)
 			{
 				question = _("Do you want to disconnect %s now?");
 			} 
@@ -837,19 +847,20 @@ netspeed_button_press_event (GtkWidget *widget, GdkEventButton *event)
 					GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
 					GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
 					question,
-					priv->stuff->devinfo.name);
+					name);
 			response = gtk_dialog_run(GTK_DIALOG(priv->connect_dialog));
 			gtk_widget_destroy (priv->connect_dialog);
 			priv->connect_dialog = NULL;
-			
+			g_free (name);
+
 			if (response == GTK_RESPONSE_YES)
 			{
 				GtkWidget *dialog;
 				char *command;
 				
 				command = g_strdup_printf("%s %s", 
-					priv->stuff->devinfo.up ? down_cmd : up_cmd,
-					priv->stuff->devinfo.name);
+					state & NETWORK_DEVICE_STATE_UP ? down_cmd : up_cmd,
+					network_device_name (priv->device));
 
 				if (!g_spawn_command_line_async(command, &error))
 				{
@@ -1011,7 +1022,7 @@ netspeed_menu_show_info_dialog (BonoboUIComponent *uic, gpointer data, const gch
 		return;
 	}
 	
-	priv->info_dialog = info_dialog_new (priv->settings);
+	priv->info_dialog = info_dialog_new (priv->settings, priv->device);
 	g_signal_connect (G_OBJECT (priv->info_dialog), "response",
 			 G_CALLBACK (info_dialog_response_cb), applet);
 
@@ -1134,7 +1145,6 @@ netspeed_display_help_section (GtkWidget *parent, const gchar *section)
 	}
 }
 
-
 static void
 netspeed_dispose (GObject *object)
 {
@@ -1146,6 +1156,11 @@ netspeed_dispose (GObject *object)
 		priv->settings = NULL;
 	}
 
+	if (priv->device) {
+		g_object_unref (priv->device);
+		priv->device = NULL;
+	}
+
 	G_OBJECT_CLASS (netspeed_parent_class)->dispose (object);
 }
 
@@ -1153,22 +1168,15 @@ static void
 netspeed_finalize (GObject *object)
 {
 	NetspeedPrivate *priv;
-	NetspeedApplet *applet;
 	GtkIconTheme *icon_theme;
 
 	priv = NETSPEED (object)->priv;
-	applet = priv->stuff;
 
 	icon_theme = gtk_icon_theme_get_default();
 	g_object_disconnect(G_OBJECT(icon_theme), "any_signal::changed",
 						G_CALLBACK(icon_theme_changed_cb), object,
 						NULL);
 
-	g_source_remove(priv->timeout_id);
-
-	free_device_info(&applet->devinfo);
-	g_free(applet);
-
 	G_OBJECT_CLASS (netspeed_parent_class)->finalize (object);
 }
 
diff --git a/src/network-device.c b/src/network-device.c
new file mode 100644
index 0000000..63185b6
--- /dev/null
+++ b/src/network-device.c
@@ -0,0 +1,476 @@
+/*  network-device.c
+ *  vim:ts=4:sw=4:noexpandtab:cindent
+ *
+ *  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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  Netspeed Applet was writen by Jörgen Scheibengruber <mfcn gmx de>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(sun) && defined(__SVR4)
+
+#include <sys/sockio.h>
+#endif
+
+#include <glibtop/netlist.h>
+#include <glibtop/netload.h>
+
+#ifdef HAVE_IW
+ #include <iwlib.h>
+#endif /* HAVE_IW */
+
+#include "network-device.h"
+
+enum
+{
+	PROP_0, /* dummy */
+	PROP_TYPE,
+	PROP_NAME,
+	PROP_IPV4_ADDR,
+	PROP_IPV6_ADDR,
+	PROP_NETMASK,
+	PROP_PTP_ADDR,
+	PROP_HW_ADDR,
+	PROP_WIFI_ESSID,
+	PROP_WIFI_QUALITY,
+	PROP_STATE,
+	PROP_TX,
+	PROP_RX
+};
+
+enum
+{
+	CHANGED,
+	LAST
+};
+
+struct _NetworkDevicePrivate
+{
+	NetworkDeviceType type;
+	char *name;
+	char *ipv4_addr;
+	char *ipv6_addr;
+	char *netmask;
+	char *ptp_addr;
+	char *hw_addr;
+	struct {
+		char *essid;
+		int	quality;
+	} wifi;
+	guint state;
+	guint64 tx, rx;
+
+	guint timeout_id;
+};
+
+#define NETWORK_DEVICE_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), NETWORK_DEVICE_TYPE, NetworkDevicePrivate))
+
+static guint signals[LAST] = {0};
+
+static void network_device_class_init (NetworkDeviceClass *klass);
+static void network_device_init       (NetworkDevice *self);
+static void network_device_finalize   (GObject *object);
+static void network_device_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void network_device_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void network_device_reset (NetworkDevice *device);
+static void network_device_poll_info (NetworkDevice *device);
+static gboolean timeout_function (gpointer user_data);
+
+G_DEFINE_TYPE (NetworkDevice, network_device, G_TYPE_OBJECT);
+
+NetworkDevice*
+network_device_new (const char *name)
+{
+	return g_object_new (NETWORK_DEVICE_TYPE,
+						"name", name,
+						NULL);
+}
+
+const char*
+network_device_name (NetworkDevice* device)
+{
+	g_return_val_if_fail (IS_NETWORK_DEVICE (device), NULL);
+
+	return device->priv->name;
+}
+
+static void
+network_device_class_init (NetworkDeviceClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (NetworkDevicePrivate));
+
+	object_class->finalize = network_device_finalize;
+	object_class->get_property = network_device_get_property;
+	object_class->set_property = network_device_set_property;
+
+	signals[CHANGED] = g_signal_new ("changed",
+		G_TYPE_FROM_CLASS (object_class),
+		G_SIGNAL_RUN_FIRST,
+		G_STRUCT_OFFSET (NetworkDeviceClass, changed),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__VOID,
+		G_TYPE_NONE, 0);
+
+	g_object_class_install_property (object_class, PROP_TYPE,
+		g_param_spec_uint ("type",
+							"Type",
+							"The type of the device.",
+							0, G_MAXUINT, 0,
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_NAME,
+		g_param_spec_string ("name",
+							"Name",
+							"The name of the device that is monitored.",
+							"lo",
+							G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (object_class, PROP_IPV4_ADDR,
+		g_param_spec_string ("ipv4-addr",
+							"IPv4-address",
+							"The IPv4 address of the device.",
+							"0.0.0.0",
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_IPV6_ADDR,
+		g_param_spec_string ("ipv6-addr",
+							"IPv6-address",
+							"The IPv6 address of the device.",
+							"0000:0000:0000:000:0000:0000",
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_NETMASK,
+		g_param_spec_string ("netmask",
+							"Netmask",
+							"The IP network mask of the device.",
+							"255.255.255.255",
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_PTP_ADDR,
+		g_param_spec_string ("ptp-addr",
+							"PTP-address",
+							"The IPv4 peer address of the device.",
+							"0.0.0.0",
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_HW_ADDR,
+		g_param_spec_string ("hw-addr",
+							"Hardware-address",
+							"The hardware (Mac) address of the device.",
+							"00:00:00:00:00:00",
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_WIFI_ESSID,
+		g_param_spec_string ("wifi-essid",
+							"WIFI Essid",
+							"The currently configured wlan essid.",
+							NULL,
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_WIFI_QUALITY,
+		g_param_spec_int ("wifi-quality",
+							"WIFI Quality",
+							"The current wlan receptionquality.",
+							0, 100, 0,
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_STATE,
+		g_param_spec_uint ("state",
+							"State",
+							"A bit mask describing the current device-state.",
+							0, G_MAXUINT, 0,
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_RX,
+		g_param_spec_uint64 ("rx",
+							"rx",
+							"The amount of received octets.",
+							0, G_MAXUINT64, 0,
+							G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_TX,
+		g_param_spec_uint64 ("tx",
+							"tx",
+							"The amount of transmitted octets.",
+							0, G_MAXUINT64, 0,
+							G_PARAM_READABLE));
+}
+
+static void
+network_device_init (NetworkDevice *self)
+{
+	NetworkDevicePrivate *priv = NETWORK_DEVICE_GET_PRIVATE (self);
+	self->priv = priv;
+
+	priv->timeout_id = g_timeout_add (1000,
+									timeout_function,
+									self);
+}
+
+static void
+network_device_get_property (GObject *object,
+	guint property_id,
+	GValue *value,
+	GParamSpec *pspec)
+{
+	NetworkDevicePrivate *priv = NETWORK_DEVICE (object)->priv;
+
+	switch (property_id) {
+		case PROP_TYPE:
+			g_value_set_uint (value, priv->type);
+			break;
+		case PROP_NAME:
+			g_value_set_string (value, priv->name);
+			break;
+		case PROP_IPV4_ADDR:
+			g_value_set_string (value, priv->ipv4_addr);
+			break;
+		case PROP_IPV6_ADDR:
+			g_value_set_string (value, priv->ipv6_addr);
+			break;
+		case PROP_NETMASK:
+			g_value_set_string (value, priv->netmask);
+			break;
+		case PROP_PTP_ADDR:
+			g_value_set_string (value, priv->ptp_addr);
+			break;
+		case PROP_HW_ADDR:
+			g_value_set_string (value, priv->hw_addr);
+			break;
+		case PROP_WIFI_ESSID:
+			g_value_set_string (value, priv->wifi.essid);
+			break;
+		case PROP_WIFI_QUALITY:
+			g_value_set_int (value, priv->wifi.quality);
+			break;
+		case PROP_STATE:
+			g_value_set_uint (value, priv->state);
+			break;
+		case PROP_TX:
+			g_value_set_uint64 (value, priv->tx);
+			break;
+		case PROP_RX:
+			g_value_set_uint64 (value, priv->rx);
+			break;
+	}
+}
+
+static void
+network_device_set_property (GObject *object,
+	guint property_id,
+	const GValue *value,
+	GParamSpec *pspec)
+{
+	NetworkDevicePrivate *priv = NETWORK_DEVICE (object)->priv;
+
+	switch (property_id) {
+		case PROP_NAME:
+			g_free (priv->name);
+			priv->name = g_value_dup_string (value);
+			break;
+	}
+}
+
+static void
+network_device_reset (NetworkDevice *device)
+{
+	NetworkDevicePrivate *priv = NETWORK_DEVICE (device)->priv;
+	g_free (priv->ipv4_addr);
+	g_free (priv->ipv6_addr);
+	g_free (priv->netmask);
+	g_free (priv->ptp_addr);
+	g_free (priv->hw_addr);
+	g_free (priv->wifi.essid);
+}
+
+static void
+network_device_finalize (GObject *object)
+{
+	NetworkDevicePrivate *priv = NETWORK_DEVICE (object)->priv;
+
+	g_source_remove (priv->timeout_id);
+	network_device_reset (NETWORK_DEVICE (object));
+	g_free (priv->name);
+
+	G_OBJECT_CLASS (network_device_parent_class)->finalize (object);
+}
+
+static gboolean
+timeout_function (gpointer user_data)
+{
+	NetworkDevice *device = NETWORK_DEVICE (user_data);
+	
+	network_device_poll_info (device);
+
+	return TRUE;
+}
+
+static char*
+format_ipv4(guint32 ip)
+{
+	char *str = g_malloc(INET_ADDRSTRLEN);
+	inet_ntop(AF_INET, &ip, str, INET_ADDRSTRLEN);
+	return str;
+}
+
+static char*
+format_ipv6(const guint8 ip[16])
+{
+	char *str = g_malloc(INET6_ADDRSTRLEN);
+	inet_ntop(AF_INET6, ip, str, INET6_ADDRSTRLEN);
+	return str;
+}
+
+/* TODO:
+   these stuff are not portable because of ioctl
+*/
+static void
+network_device_get_ptp_info (NetworkDevice *device)
+{
+	NetworkDevicePrivate *priv = device->priv;
+	int fd = -1;
+	struct ifreq request = {};
+
+	g_strlcpy(request.ifr_name, priv->name, sizeof request.ifr_name);
+
+	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+		return;
+
+	if (ioctl(fd, SIOCGIFDSTADDR, &request) >= 0) {
+		struct sockaddr_in* addr;
+		addr = (struct sockaddr_in*)&request.ifr_dstaddr;
+		priv->ptp_addr = format_ipv4(addr->sin_addr.s_addr);
+	}
+
+	close(fd);
+}
+
+#ifdef HAVE_IW
+static void
+network_device_get_wireless_info (NetworkDevice *device)
+{
+	NetworkDevicePrivate *priv = device->priv;
+	int fd;
+	int newqual;
+	wireless_info info = {0};
+
+	fd = iw_sockets_open ();
+
+	if (fd < 0)
+		return;
+
+	if (iw_get_basic_config (fd, priv->name, &info.b) < 0) 
+		goto out;
+	
+	if (info.b.has_essid) {
+		if ((!priv->wifi.essid) || (strcmp (priv->wifi.essid, info.b.essid) != 0)) {
+			priv->wifi.essid = g_strdup (info.b.essid);
+		}
+	} else {
+		priv->wifi.essid = NULL;
+	}
+
+	if (iw_get_stats (fd, priv->name, &info.stats, &info.range, info.has_range) >= 0)
+		info.has_stats = 1;
+
+	if (info.has_stats) {
+		if ((iw_get_range_info(fd, priv->name, &info.range) >= 0) && (info.range.max_qual.qual > 0)) {
+			newqual = 0.5f + (100.0f * info.stats.qual.qual) / (1.0f * info.range.max_qual.qual);
+		} else {
+			newqual = info.stats.qual.qual;
+		}
+		
+		newqual = CLAMP(newqual, 0, 100);
+		if (priv->wifi.quality != newqual)
+			priv->wifi.quality = newqual;
+	} else {
+		priv->wifi.quality = 0;
+	}
+
+	goto out;
+out:
+	if (fd != -1)
+		close (fd);
+}
+#endif /* HAVE_IW */
+
+static void
+network_device_poll_info (NetworkDevice *device)
+{
+	NetworkDevicePrivate *priv = device->priv;
+	glibtop_netload netload;
+	guint8 *hw;
+
+	g_return_if_fail (priv->name && priv->name[0]);
+
+	priv->type = NETWORK_DEVICE_TYPE_UNKNOWN;
+
+	network_device_reset (device);
+	glibtop_get_netload(&netload, priv->name);
+	priv->tx = netload.bytes_out;
+	priv->rx = netload.bytes_in;
+
+	priv->state = 0;
+	priv->state |= (netload.if_flags & (1L << GLIBTOP_IF_FLAGS_UP) ? NETWORK_DEVICE_STATE_UP : 0);
+	priv->state |= (netload.if_flags & (1L << GLIBTOP_IF_FLAGS_RUNNING) ? NETWORK_DEVICE_STATE_UP : 0);
+
+	priv->ipv4_addr = format_ipv4(netload.address);
+	priv->netmask = format_ipv4(netload.subnet);
+	priv->ipv6_addr = format_ipv6(netload.address6);
+	priv->wifi.quality = 0;
+	priv->wifi.essid = NULL;
+
+	hw = netload.hwaddress;
+	if (hw[6] || hw[7]) {
+		priv->hw_addr = g_strdup_printf(
+			"%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
+			hw[0], hw[1], hw[2], hw[3],
+			hw[4], hw[5], hw[6], hw[7]);
+	} else {
+		priv->hw_addr = g_strdup_printf(
+			"%02X:%02X:%02X:%02X:%02X:%02X",
+			hw[0], hw[1], hw[2],
+			hw[3], hw[4], hw[5]);
+	}
+	/* stolen from gnome-applets/multiload/linux-proc.c */
+
+	if(netload.if_flags & (1L << GLIBTOP_IF_FLAGS_LOOPBACK)) {
+		priv->type = NETWORK_DEVICE_TYPE_LO;
+	}
+
+#ifdef HAVE_IW
+
+	else if (netload.if_flags & (1L << GLIBTOP_IF_FLAGS_WIRELESS)) {
+		priv->type = NETWORK_DEVICE_TYPE_WIRELESS;
+		network_device_get_wireless_info (device);
+	}
+
+#endif /* HAVE_IW */
+
+	else if(netload.if_flags & (1L << GLIBTOP_IF_FLAGS_POINTOPOINT)) {
+		if (g_str_has_prefix(priv->name, "plip")) {
+			priv->type = NETWORK_DEVICE_TYPE_PLIP;
+		}
+		else if (g_str_has_prefix(priv->name, "sl")) {
+			priv->type = NETWORK_DEVICE_TYPE_SLIP;
+		}
+		else {
+			priv->type = NETWORK_DEVICE_TYPE_PPP;
+		}
+
+		network_device_get_ptp_info (device);
+	}
+	else {
+		priv->type = NETWORK_DEVICE_TYPE_ETHERNET;
+	}
+
+	g_signal_emit (device, signals[CHANGED], 0);
+}
+
diff --git a/src/network-device.h b/src/network-device.h
new file mode 100644
index 0000000..c1f113f
--- /dev/null
+++ b/src/network-device.h
@@ -0,0 +1,80 @@
+/*  network-device.h
+ *  vim:ts=4:sw=4:noexpandtab:cindent
+ *
+ *  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 Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  Netspeed Applet was writen by Jörgen Scheibengruber <mfcn gmx de>
+ */
+
+#ifndef __NETWORK_DEVICE_H__
+#define __NETWORK_DEVICE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "backend.h"
+
+G_BEGIN_DECLS
+
+#define NETWORK_DEVICE_TYPE            (network_device_get_type ())
+#define NETWORK_DEVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NETWORK_DEVICE_TYPE, NetworkDevice))
+#define NETWORK_DEVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NETWORK_DEVICE_TYPE, NetworkDeviceClass))
+#define IS_NETWORK_DEVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NETWORK_DEVICE_TYPE))
+#define IS_NETWORK_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NETWORK_DEVICE_TYPE))
+#define NETWORK_DEVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NETWORK_DEVICE_TYPE, NetworkDeviceClass))
+
+typedef struct _NetworkDevice        NetworkDevice;
+typedef struct _NetworkDeviceClass   NetworkDeviceClass;
+typedef struct _NetworkDevicePrivate NetworkDevicePrivate;
+
+/* Different types of interfaces */
+typedef enum
+{
+	NETWORK_DEVICE_TYPE_LO,
+	NETWORK_DEVICE_TYPE_ETHERNET,
+	NETWORK_DEVICE_TYPE_WIRELESS,
+	NETWORK_DEVICE_TYPE_PPP,
+	NETWORK_DEVICE_TYPE_PLIP,
+	NETWORK_DEVICE_TYPE_SLIP,
+	NETWORK_DEVICE_TYPE_UNKNOWN
+} NetworkDeviceType;
+
+typedef enum
+{
+	NETWORK_DEVICE_STATE_UP = 1 << 0,
+	NETWORK_DEVICE_STATE_RUNNING = 1 << 1
+} NetworkDeviceState;
+
+struct _NetworkDeviceClass
+{
+	GObjectClass parent_class;
+
+	void (*changed)(void);
+};
+
+struct _NetworkDevice
+{
+	GObject parent;
+	NetworkDevicePrivate *priv;
+};
+
+GType network_device_get_type (void);
+
+NetworkDevice* network_device_new (const char *name);
+const char* network_device_name (NetworkDevice* device);
+
+G_END_DECLS
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]