Rewrote status aread plugin for HAL usage
authorGregor Riepl <onitake@gmail.com>
Tue, 3 Aug 2010 12:29:48 +0000 (14:29 +0200)
committerGregor Riepl <onitake@gmail.com>
Tue, 3 Aug 2010 12:29:48 +0000 (14:29 +0200)
Added network icon

Makefile
mtetherd-net-icon.png [new file with mode: 0644]
mtetherd-plugin.desktop
status.c

index 6b0ea7b..d66ae7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,17 @@
 PREFIX = /usr
+HILDON_DESKTOP_DIR = $(shell pkg-config --variable=hildonstatusmenudesktopentrydir libhildondesktop-1)
+HILDON_PLUGIN_DIR = $(shell pkg-config --variable=hildondesktoplibdir libhildondesktop-1)
+BIN_DIR = $(PREFIX)/bin
+SBIN_DIR = $(PREFIX)/sbin
+DOC_DIR = $(PREFIX)/share/doc/mtetherd
+IMAGE_DIR = $(PREFIX)/share/pixmaps
+ETC_DIR = /etc
 CC = gcc
-CFLAGS = -Wall -O2 -g -D_GNU_SOURCE
-INCLUDES = $(shell pkg-config --cflags dbus-1 libhildondesktop-1)
+CFLAGS = -Wall -O2 -g -D_GNU_SOURCE -DIMAGE_DIR=\"$(IMAGE_DIR)\" -DSBIN_DIR=\"$(SBIN_DIR)\"
+INCLUDES = $(shell pkg-config --cflags dbus-1 libhildondesktop-1 hal)
 LDFLAGS =
 LIBS_DBUS = $(shell pkg-config --libs dbus-1)
-LIBS_HILDON = $(shell pkg-config --libs libhildondesktop-1)
-HILDON_DESKTOP = $(shell pkg-config --variable=hildonstatusmenudesktopentrydir libhildondesktop-1)
-HILDON_PLUGIN = $(shell pkg-config --variable=hildondesktoplibdir libhildondesktop-1)
+LIBS_HILDON = $(shell pkg-config --libs libhildondesktop-1 hal)
 
 all: mtetherd mtetherd-plugin.so
 
@@ -22,24 +27,26 @@ clean:
        rm -f *.o mtetherd mtetherd-plugin.so
 
 install: mtetherd mtetherd-plugin.so
-       install -m 755 -D mtetherd $(DESTDIR)/$(PREFIX)/sbin/mtetherd
-       install -m 644 -D event.d-mtetherd $(DESTDIR)/etc/event.d/mtetherd
-       install -m 644 -D README $(DESTDIR)/$(PREFIX)/share/doc/mtetherd/README
-       install -m 644 -D mtetherd-plugin.desktop $(DESTDIR)/$(HILDON_DESKTOP)/mtetherd-plugin.desktop
-       install -m 755 -D mtetherd-plugin.so $(DESTDIR)/$(HILDON_PLUGIN)/mtetherd-plugin.so
-       install -m 755 -D mtetherd-usbnet-enable.sh $(DESTDIR)/$(PREFIX)/sbin/mtetherd-usbnet-enable.sh
-       install -m 755 -D mtetherd-usbnet-disable.sh $(DESTDIR)/$(PREFIX)/sbin/mtetherd-usbnet-disable.sh
-       install -m 755 -D mtetherd.sudoers $(DESTDIR)/etc/sudoers.d/mtetherd.sudoers
+       install -m 755 -D mtetherd $(DESTDIR)/$(SBIN_DIR)/mtetherd
+       install -m 644 -D event.d-mtetherd $(DESTDIR)/$(ETC_DIR)/event.d/mtetherd
+       install -m 644 -D README $(DESTDIR)/$(DOC_DIR)/README
+       install -m 644 -D mtetherd-plugin.desktop $(DESTDIR)/$(HILDON_DESKTOP_DIR)/mtetherd-plugin.desktop
+       install -m 755 -D mtetherd-plugin.so $(DESTDIR)/$(HILDON_PLUGIN_DIR)/mtetherd-plugin.so
+       install -m 755 -D mtetherd-usbnet-enable.sh $(DESTDIR)/$(SBIN_DIR)/mtetherd-usbnet-enable.sh
+       install -m 755 -D mtetherd-usbnet-disable.sh $(DESTDIR)/$(SBIN_DIR)/mtetherd-usbnet-disable.sh
+       install -m 644 -D mtetherd.sudoers $(DESTDIR)/$(ETC_DIR)/sudoers.d/mtetherd.sudoers
+       install -m 644 -D mtetherd-net-icon.png $(DESTDIR)/$(IMAGE_DIR)/mtetherd-net-icon.png
 
 uninstall:
-       rm -f $(DESTDIR)/$(PREFIX)/sbin/mtetherd
-       rm -f $(DESTDIR)/etc/event.d/mtetherd
+       rm -f $(DESTDIR)/$(SBIN_DIR)/mtetherd
+       rm -f $(DESTDIR)/$(ETC_DIR)/event.d/mtetherd
        rm -rf $(DESTDIR)/$(PREFIX)/share/doc/mtetherd
-       rm -f $(DESTDIR)/$(HILDON_DESKTOP)/mtetherd-plugin.desktop
-       rm -f $(DESTDIR)/$(HILDON_PLUGIN)/mtetherd-plugin.so
-       rm -f $(DESTDIR)/$(PREFIX)/sbin/mtetherd-usbnet-enable.sh
-       rm -f $(DESTDIR)/$(PREFIX)/sbin/mtetherd-usbnet-disable.sh
-       rm -f $(DESTDIR)/etc/sudoers.d/mtetherd.sudoers
+       rm -f $(DESTDIR)/$(HILDON_DESKTOP_DIR)/mtetherd-plugin.desktop
+       rm -f $(DESTDIR)/$(HILDON_PLUGIN_DIR)/mtetherd-plugin.so
+       rm -f $(DESTDIR)/$(SBIN_DIR)/mtetherd-usbnet-enable.sh
+       rm -f $(DESTDIR)/$(SBIN_DIR)/mtetherd-usbnet-disable.sh
+       rm -f $(DESTDIR)/$(ETC_DIR)/sudoers.d/mtetherd.sudoers
+       rm -f $(DESTDIR)/$(IMAGE_DIR)/mtetherd-net-icon.png
 
 %.o: %.c
        $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $^
diff --git a/mtetherd-net-icon.png b/mtetherd-net-icon.png
new file mode 100644 (file)
index 0000000..653df6a
Binary files /dev/null and b/mtetherd-net-icon.png differ
index 3393567..004f84b 100644 (file)
@@ -1,6 +1,6 @@
 [Desktop Entry]
 Name=MTetherD USB Enabler
 Comment=Maemo Tethering Daemon USB networking enabler
-Category=permanent
+Category=conditional
 Type=default
 X-Path=mtetherd-plugin.so
index 7ca2364..4d7ec06 100644 (file)
--- a/status.c
+++ b/status.c
 #include <sys/types.h>
 #include <gtk/gtk.h>
 #include <hildon/hildon.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libhal.h>
 
 #include "status.h"
 
 #define MTETHERD_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, TYPE_MTETHERD_STATUS_PLUGIN, MTetherDStatusPluginPrivate))
 
 struct _MTetherDStatusPluginPrivate {
-       GtkWidget *button;
-       gboolean neton;
+       GtkWidget *enable_button;
+       gboolean usb_on;
+       gboolean net_on;
+       DBusGConnection *dbus_connection;
+       LibHalContext *hal_context;
 };
 
+static const char *USBDEV_PATH = "/org/freedesktop/Hal/devices/usb_device_1d6b_2_musb_hdrc";
+static const char *USBNET_MODULE = "g_ether";
+
+#ifndef IMAGE_DIR
+#define IMAGE_DIR "/usr/share/pixmaps"
+#endif
+#ifndef SBIN_DIR
+#define SBIN_DIR "/usr/sbin"
+#endif
+
 HD_DEFINE_PLUGIN_MODULE(MTetherDStatusPlugin, mtetherd_status_plugin, HD_TYPE_STATUS_MENU_ITEM);
 
 static void mtetherd_status_plugin_class_finalize(MTetherDStatusPluginClass *klass) { }
 
+static void mtetherd_status_plugin_finalize(GObject *object) {
+       g_message("Destroying mtetherd status plugin");
+
+       MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(object);
+
+       if (plugin && plugin->priv) {
+               if (plugin->priv->hal_context) {
+                       libhal_ctx_shutdown(plugin->priv->hal_context, NULL);
+                       libhal_ctx_free(plugin->priv->hal_context);
+               }
+               if (plugin->priv->dbus_connection) {
+                       dbus_g_connection_unref(plugin->priv->dbus_connection);
+               }
+       }
+}
+
 static void mtetherd_status_plugin_class_init(MTetherDStatusPluginClass *klass) {
+       GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+       gobject_class->finalize = mtetherd_status_plugin_finalize;
        g_type_class_add_private(klass, sizeof(MTetherDStatusPluginPrivate));
 }
 
 static gboolean get_usbnet_enabled(MTetherDStatusPlugin *plugin) {
+       g_message("Scanning /proc/modules");
+       //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Scanning /proc/modules");
+
        FILE *fp = fopen("/proc/modules", "r");
        if (!fp) {
-               // fallback (useless?)
-               return plugin->priv->neton;
+               return FALSE;
        }
        gboolean found = FALSE;
        char *line = NULL;
        while (!found && getline(&line, NULL, fp) != -1) {
-               if (strncmp(line, "g_ether", 7) == 0) {
+               g_message("Checking if '%s' contains g_ether...", line);
+               if (strncmp(line, USBNET_MODULE, sizeof(USBNET_MODULE) - 1) == 0) {
+                       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Found g_ether");
                        found = TRUE;
                }
                free(line);
@@ -63,21 +101,14 @@ static gboolean get_usbnet_enabled(MTetherDStatusPlugin *plugin) {
        return found;
 }
 
-static void set_button_text(GtkWidget *button, gboolean enabled) {
-       if (enabled) {
-               gtk_button_set_label(GTK_BUTTON(button), "Disable USB Networking");
-       } else {
-               gtk_button_set_label(GTK_BUTTON(button), "Enable USB Networking");
-       }
-}
-
 static gboolean launch_usbnet_script(gboolean enable) {
        const char *arg;
        if (enable) {
-               arg = "/usr/sbin/mtetherd-usbnet-enable.sh";
+               arg = SBIN_DIR "mtetherd-usbnet-enable.sh";
        } else {
-               arg = "/usr/sbin/mtetherd-usbnet-disable.sh";
+               arg = SBIN_DIR "mtetherd-usbnet-disable.sh";
        }
+       g_debug("Launching %s", arg);
        const char *command[] = { "/usr/bin/sudo", arg, NULL };
        pid_t pid = fork();
        if (pid == 0) {
@@ -92,20 +123,91 @@ static gboolean launch_usbnet_script(gboolean enable) {
        return TRUE;
 }
 
-static void enable_usb_net_clicked(GtkWidget *button, gpointer user) {
-       MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(user);
+static void enable_button_set_text(GtkWidget *button, gboolean enabled) {
+       if (enabled) {
+               hildon_button_set_text(HILDON_BUTTON(button), "Toggle USB Networking", "Enabled");
+       } else {
+               hildon_button_set_text(HILDON_BUTTON(button), "Toggle USB Networking", "Disabled");
+       }
+}
 
-       if (button == plugin->priv->button) {
-               gboolean enabled = get_usbnet_enabled(plugin);
-               set_button_text(plugin->priv->button, enabled);
-               if (enabled) {
-                       if (launch_usbnet_script(FALSE)) {
-                               // launch ok
-                               plugin->priv->neton = FALSE;
+static void enable_button_clicked(GtkWidget *button, gpointer data) {
+       MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(data);
+
+       if (plugin && plugin->priv && button == plugin->priv->enable_button) {
+               if (plugin->priv->net_on) {
+                       if (!launch_usbnet_script(FALSE)) {
+                               g_error("Error starting USB networking");
                        }
                } else {
-                       if (launch_usbnet_script(TRUE)) {
-                               plugin->priv->neton = TRUE;
+                       if (!launch_usbnet_script(TRUE)) {
+                               g_error("Error starting USB networking");
+                       }
+               }
+       }
+}
+
+static void mtetherd_status_plugin_usb_plugged_show(MTetherDStatusPlugin *plugin) {
+       if (plugin) {
+               if (plugin->priv && plugin->priv->hal_context) {
+                       DBusError derr;
+                       dbus_error_init(&derr);
+                       dbus_bool_t plugged = libhal_device_get_property_bool(plugin->priv->hal_context, USBDEV_PATH, "button.state.value", &derr);
+                       if (dbus_error_is_set(&derr)) {
+                               g_warning("Error getting USB plugged status (%s): %s", derr.name, derr.message);
+                               hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Error getting USB plugged status (%s): %s", derr.name, derr.message);
+                               dbus_error_free(&derr);
+                       } else {
+                               plugin->priv->usb_on = plugged;
+                               if (plugin->priv->usb_on) {
+                                       gtk_widget_show(GTK_WIDGET(plugin));
+                               } else {
+                                       gtk_widget_hide(GTK_WIDGET(plugin));
+                               }
+                       }
+               } else {
+                       // DEBUG
+                       //gtk_widget_show(GTK_WIDGET(plugin));
+               }
+       }
+}
+
+static void mtetherd_status_plugin_mapped(GtkWidget *widget, gpointer data) {
+       hildon_banner_show_informationf(widget, NULL, "Plugin mapped");
+       MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(widget);
+       
+       if (plugin && plugin->priv) {
+               plugin->priv->net_on = get_usbnet_enabled(plugin);
+               if (plugin->priv->enable_button) {
+                       enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
+               }
+       }
+}
+
+static gboolean mtetherd_status_plugin_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
+       g_message("Got event %d", event->type);
+       return FALSE;
+}
+
+static void mtetherd_status_plugin_device_condition(LibHalContext *ctx, const char *udi, const char *condition, const char *detail) {
+       MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(libhal_ctx_get_user_data(ctx));
+       
+       if (plugin) {
+               g_message("Got HAL condition %s on %s: %s", condition, udi, detail);
+               //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Got HAL condition %s on %s: %s", condition, udi, detail);
+               if (strcmp(USBDEV_CONDITION, "ButtonPressed") == 0) {
+                       if (strcmp(USBDEV_PATH, udi) == 0) {
+                               mtetherd_status_plugin_usb_plugged_show(plugin);
+                       }
+               } else if (strcmp("DeviceAdded", condition) == 0) {
+                       if (strcmp(USBDEV_PATH, detail) == 0) {
+                               plugin->priv->net_on = TRUE;
+                               enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
+                       }
+               } else if (strcmp("DeviceRemoved", condition) == 0) {
+                       if (strcmp(USBDEV_PATH, detail) == 0) {
+                               plugin->priv->net_on = FALSE;
+                               enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
                        }
                }
        }
@@ -114,12 +216,82 @@ static void enable_usb_net_clicked(GtkWidget *button, gpointer user) {
 static void mtetherd_status_plugin_init(MTetherDStatusPlugin *plugin) {
        plugin->priv = MTETHERD_STATUS_PLUGIN_GET_PRIVATE(plugin);
 
-       plugin->priv->neton = FALSE;
-       plugin->priv->button = gtk_button_new();
-       set_button_text(plugin->priv->button, plugin->priv->neton);
-       g_signal_connect(plugin->priv->button, "clicked", G_CALLBACK(enable_usb_net_clicked), plugin);
-       gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->button);
-       gtk_widget_show_all(plugin->priv->button);
-       gtk_widget_show(GTK_WIDGET(plugin));
+       plugin->priv->usb_on = FALSE;
+       plugin->priv->net_on = FALSE;
+       
+       plugin->priv->enable_button = hildon_button_new(HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
+       if (plugin->priv->enable_button) {
+               GError *err = NULL;
+               GdkPixbuf *icon = gdk_pixbuf_new_from_file(IMAGE_DIR "/mtetherd-net-icon.png", &err);
+               if (err) {
+                       g_warning("Can't load mtetherd icon: %s", err->message);
+                       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Can't load mtetherd icon: %s", err->message);
+                       g_error_free(err);
+                       err = NULL;
+               }
+               if (icon) {
+                       GtkWidget *image = gtk_image_new_from_pixbuf(icon);
+                       hildon_button_set_image(HILDON_BUTTON(plugin->priv->enable_button), image);
+                       hildon_button_set_image_position(HILDON_BUTTON(plugin->priv->enable_button), GTK_POS_LEFT);
+                       g_object_unref(icon);
+               }
+               gboolean enabled = get_usbnet_enabled(plugin);
+               enable_button_set_text(plugin->priv->enable_button, enabled);
+               g_signal_connect(plugin->priv->enable_button, "clicked", G_CALLBACK(enable_button_clicked), plugin);
+               gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->enable_button);
+               gtk_widget_show_all(plugin->priv->enable_button);
+       }
+       //g_signal_connect(plugin, "expose-event", G_CALLBACK(mtetherd_status_plugin_event), NULL);
+
+       //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
+       GError *err = NULL;
+       plugin->priv->dbus_connection = hd_status_plugin_item_get_dbus_g_connection(HD_STATUS_PLUGIN_ITEM(plugin), DBUS_BUS_SYSTEM, &err);
+       if (err) {
+               g_warning("Can't open DBUS connection: %s", err->message);
+               hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Error opening DBUS connection: %s", err->message);
+               g_error_free(err);
+               err = NULL;
+       } else {
+               g_message("Got DBUS Glib connection: %p", plugin->priv->dbus_connection);
+       }
+       if (plugin->priv->dbus_connection) {
+               plugin->priv->hal_context = libhal_ctx_new();
+               if (plugin->priv->hal_context) {
+                       if (libhal_ctx_set_dbus_connection(plugin->priv->hal_context, dbus_g_connection_get_connection(plugin->priv->dbus_connection))) {
+                               if (!libhal_ctx_set_user_data(plugin->priv->hal_context, plugin)) {
+                                       g_warning("Can't set user data of HAL context");
+                                       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Can't set user data of HAL context");
+                               }
+                               if (!libhal_ctx_set_device_condition(plugin->priv->hal_context, mtetherd_status_plugin_device_condition)) {
+                                       g_warning("Error assigning device condition callback");
+                                       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Error assigning device condition callback");
+                               }
+                               DBusError derr;
+                               dbus_error_init(&derr);
+                               if (!libhal_ctx_init(plugin->priv->hal_context, &derr)) {
+                                       if (dbus_error_is_set(&derr)) {
+                                               g_warning("Error initializing HAL context (%s): %s", derr.name, derr.message);
+                                               hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Error initializing HAL context (%s): %s", derr.name, derr.message);
+                                               dbus_error_free(&derr);
+                                       } else {
+                                               g_warning("Error initializing HAL context: unknown error");
+                                               //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Error initializing HAL context: unknown error");
+                                       }
+                                       libhal_ctx_free(plugin->priv->hal_context);
+                                       plugin->priv->hal_context = NULL;
+                               }
+                       } else {
+                               g_warning("Can't set DBUS connection of HAL context");
+                               hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Can't set DBUS connection of HAL context");
+                               libhal_ctx_free(plugin->priv->hal_context);
+                               plugin->priv->hal_context = NULL;
+                       }
+               } else {
+                       g_warning("Can't allocate HAL context");
+                       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Can't allocate HAL context");
+               }
+       }
+
+       mtetherd_status_plugin_usb_plugged_show(plugin);
 }