From: Gregor Riepl Date: Tue, 3 Aug 2010 12:29:48 +0000 (+0200) Subject: Rewrote status aread plugin for HAL usage X-Git-Url: http://vcs.maemo.org/git/?p=mtetherd;a=commitdiff_plain;h=1416438da8af731b20b15a20e41fd45c9fdfe632 Rewrote status aread plugin for HAL usage Added network icon --- diff --git a/Makefile b/Makefile index 6b0ea7b..d66ae7e 100644 --- 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 index 0000000..653df6a Binary files /dev/null and b/mtetherd-net-icon.png differ diff --git a/mtetherd-plugin.desktop b/mtetherd-plugin.desktop index 3393567..004f84b 100644 --- a/mtetherd-plugin.desktop +++ b/mtetherd-plugin.desktop @@ -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 diff --git a/status.c b/status.c index 7ca2364..4d7ec06 100644 --- a/status.c +++ b/status.c @@ -26,34 +26,72 @@ #include #include #include +#include +#include #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); }