diff options
author | Christian Persch <chpe@cvs.gnome.org> | 2006-01-26 05:52:27 +0800 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2006-01-26 05:52:27 +0800 |
commit | dd06e70a33a386b716fedd68393885f45a343b68 (patch) | |
tree | 97e77dd243f3d714f0571a62b4db7c53cb17d2aa | |
parent | 48828a1977fc21c6fc6d03fa6003a081bf14b017 (diff) | |
download | gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.tar gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.tar.gz gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.tar.bz2 gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.tar.lz gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.tar.xz gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.tar.zst gsoc2013-epiphany-dd06e70a33a386b716fedd68393885f45a343b68.zip |
libnm-glib be-gone! Use NetworkManager directly via DBUS, by importing the
2006-01-25 Christian Persch <chpe@cvs.gnome.org>
* configure.ac:
* data/epiphany.schemas.in:
* embed/mozilla/Makefile.am:
* embed/mozilla/mozilla-embed-single.cpp:
* lib/ephy-prefs.h:
* src/Makefile.am:
* src/ephy-net-monitor.c:
* src/ephy-net-monitor.h:
* src/ephy-shell.c: (ephy_shell_sync_network_status),
(impl_get_embed_single), (ephy_shell_dispose),
(ephy_shell_get_net_monitor), (_ephy_shell_create_instance),
(_ephy_shell_startup):
* src/ephy-shell.h:
libnm-glib be-gone! Use NetworkManager directly via DBUS, by
importing the excellent net-monitor extension directly into
Epiphany. Code by Jean-François Rameau.
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | configure.ac | 16 | ||||
-rw-r--r-- | data/epiphany.schemas.in | 32 | ||||
-rw-r--r-- | embed/mozilla/Makefile.am | 5 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed-single.cpp | 84 | ||||
-rw-r--r-- | lib/ephy-prefs.h | 1 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/ephy-net-monitor.c | 584 | ||||
-rw-r--r-- | src/ephy-net-monitor.h | 63 | ||||
-rw-r--r-- | src/ephy-shell.c | 77 | ||||
-rw-r--r-- | src/ephy-shell.h | 7 |
11 files changed, 767 insertions, 128 deletions
@@ -1,3 +1,23 @@ +2006-01-25 Christian Persch <chpe@cvs.gnome.org> + + * configure.ac: + * data/epiphany.schemas.in: + * embed/mozilla/Makefile.am: + * embed/mozilla/mozilla-embed-single.cpp: + * lib/ephy-prefs.h: + * src/Makefile.am: + * src/ephy-net-monitor.c: + * src/ephy-net-monitor.h: + * src/ephy-shell.c: (ephy_shell_sync_network_status), + (impl_get_embed_single), (ephy_shell_dispose), + (ephy_shell_get_net_monitor), (_ephy_shell_create_instance), + (_ephy_shell_startup): + * src/ephy-shell.h: + + libnm-glib be-gone! Use NetworkManager directly via DBUS, by + importing the excellent net-monitor extension directly into + Epiphany. Code by Jean-François Rameau. + 2006-01-22 Peter Harvey <peter.a.harvey@gmail.com> * src/bookmarks/ephy-bookmarks-ui.c diff --git a/configure.ac b/configure.ac index c923616c9..1e1ce8494 100644 --- a/configure.ac +++ b/configure.ac @@ -561,17 +561,19 @@ AM_CONDITIONAL([ENABLE_CERTIFICATE_MANAGER],[test "$enable_certificate_manager" AC_MSG_CHECKING([whether to enable NetworkManager support]) AC_ARG_ENABLE([network-manager], - AS_HELP_STRING([--enable-network-manager],[Whether to enable automatic network status with NetworkManager (default: disabled]), + AS_HELP_STRING([--enable-network-manager],[Whether to enable automatic network status with NetworkManager (default: disabled)]), [],[enable_network_manager=no]) AC_MSG_RESULT([$enable_network_manager]) -if test "x$enable_network_manager" != "xno"; then - NETWORKMANAGER_REQUIRED=0.5.0 +if test "$enable_network_manager" != "no"; then + AC_CHECK_HEADERS([NetworkManager/NetworkManager.h], + [have_network_manager=yes],[have_network_manager=no]) - PKG_CHECK_MODULES([NETWORK_MANAGER],[libnm_glib >= $NETWORKMANAGER_REQUIRED], - [enable_network_manager=yes],[enable_network_manager=no]) - AC_SUBST([NETWORK_MANAGER_CFLAGS]) - AC_SUBST([NETWORK_MANAGER_LIBS]) + if test "$enable_network_manager" = "yes" -a "$have_network_manager" = "no"; then + AC_MSG_ERROR([NetworkManager support requested but NetworkManager headers not found]) + elif test "$have_network_manager" = "no"; then + AC_MSG_WARN([NetworkManager headers not found; disabling NetworkManager support]) + fi fi if test "x$enable_network_manager" = "xyes"; then diff --git a/data/epiphany.schemas.in b/data/epiphany.schemas.in index 05ab80ff9..e90c8abcb 100644 --- a/data/epiphany.schemas.in +++ b/data/epiphany.schemas.in @@ -24,28 +24,6 @@ </long> </locale> </schema> - <schema> - <key>/schemas/apps/epiphany/dialogs/find_match_case</key> - <applyto>/apps/epiphany/dialogs/find_match_case</applyto> - <owner>epiphany</owner> - <type>bool</type> - <default>false</default> - <locale name="C"> - <short>Match case for find in page</short> - </locale> - </schema> - <schema> - <key>/schemas/apps/epiphany/dialogs/find_autowrap</key> - <applyto>/apps/epiphany/dialogs/find_autowrap</applyto> - <owner>epiphany</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Autowrap for find in page</short> - <long>For find in page, whether to start again at the beginning after - reaching the end of the page.</long> - </locale> - </schema> <schema> <key>/schemas/apps/epiphany/dialogs/bookmarks_view_details</key> <applyto>/apps/epiphany/dialogs/bookmarks_view_details</applyto> @@ -457,5 +435,15 @@ <short>Browse with caret</short> </locale> </schema> + <schema> + <key>/schemas/apps/epiphany/general/managed_network</key> + <applyto>/apps/epiphany/general/managed_network</applyto> + <owner>epiphany</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Automatically manage offline status with NetworkManager</short> + </locale> + </schema> </schemalist> </gconfschemafile> diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am index 291cbd069..f5504128b 100644 --- a/embed/mozilla/Makefile.am +++ b/embed/mozilla/Makefile.am @@ -148,8 +148,3 @@ libephymozillaembed_la_CXXFLAGS = \ $(GECKO_CFLAGS) \ $(DEPENDENCIES_CFLAGS) \ $(AM_CXXFLAGS) - -if ENABLE_NETWORK_MANAGER -libephymozillaembed_la_CXXFLAGS += \ - $(NETWORK_MANAGER_CFLAGS) -endif diff --git a/embed/mozilla/mozilla-embed-single.cpp b/embed/mozilla/mozilla-embed-single.cpp index 62809590a..4165ff11e 100644 --- a/embed/mozilla/mozilla-embed-single.cpp +++ b/embed/mozilla/mozilla-embed-single.cpp @@ -105,10 +105,6 @@ #include <stdlib.h> -#ifdef ENABLE_NETWORK_MANAGER -#include <libnm_glib.h> -#endif - #ifdef HAVE_GECKO_1_8 #include <nsIURI.h> #include <nsIStyleSheetService.h> @@ -136,11 +132,6 @@ struct MozillaEmbedSinglePrivate GtkWidget *theme_window; #endif -#ifdef ENABLE_NETWORK_MANAGER - libnm_glib_ctx *nm_context; - guint nm_callback_id; -#endif - #ifdef HAVE_GECKO_1_8 char *user_css_file; guint user_css_enabled_notifier_id; @@ -552,62 +543,6 @@ mozilla_init_observer (MozillaEmbedSingle *single) } } -#ifdef ENABLE_NETWORK_MANAGER - -static void -network_state_cb (libnm_glib_ctx *context, - gpointer data) -{ - EphyEmbedSingle *single = EPHY_EMBED_SINGLE (data); - libnm_glib_state state; - - state = libnm_glib_get_network_state (context); - - LOG ("Network state: %d\n", state); - - switch (state) - { - case LIBNM_NO_DBUS: - case LIBNM_NO_NETWORKMANAGER: - case LIBNM_INVALID_CONTEXT: - /* do nothing */ - break; - case LIBNM_NO_NETWORK_CONNECTION: - ephy_embed_single_set_network_status (single, FALSE); - break; - case LIBNM_ACTIVE_NETWORK_CONNECTION: - ephy_embed_single_set_network_status (single, TRUE); - break; - } -} - -static void -mozilla_init_network_manager (MozillaEmbedSingle *single) -{ - MozillaEmbedSinglePrivate *priv = single->priv; - - priv->nm_context = libnm_glib_init (); - if (priv->nm_context == NULL) - { - g_warning ("Could not initialise NetworkManager, connection status will not be managed!\n"); - return; - } - - priv->nm_callback_id = libnm_glib_register_callback (priv->nm_context, - network_state_cb, - single, NULL); - if (priv->nm_callback_id == 0) - { - libnm_glib_shutdown (priv->nm_context); - priv->nm_context = NULL; - - g_warning ("Could not connect to NetworkManager, connection status will not be managed!\n"); - return; - } -} - -#endif /* ENABLE_NETWORK_MANAGER */ - #ifdef HAVE_GECKO_1_8 static void @@ -837,10 +772,6 @@ impl_init (EphyEmbedSingle *esingle) mozilla_init_observer (single); -#ifdef ENABLE_NETWORK_MANAGER - mozilla_init_network_manager (single); -#endif - #ifdef HAVE_GECKO_1_8 mozilla_stylesheet_init (single); #endif @@ -896,21 +827,6 @@ mozilla_embed_single_dispose (GObject *object) priv->mSingleObserver = nsnull; } -#ifdef ENABLE_NETWORK_MANAGER - if (priv->nm_context != NULL) - { - if (priv->nm_callback_id != 0) - { - libnm_glib_unregister_callback (priv->nm_context, - priv->nm_callback_id); - priv->nm_callback_id = 0; - } - - libnm_glib_shutdown (priv->nm_context); - priv->nm_context = NULL; - } -#endif - parent_class->dispose (object); } diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h index cba9bb996..a1ee22117 100644 --- a/lib/ephy-prefs.h +++ b/lib/ephy-prefs.h @@ -36,6 +36,7 @@ G_BEGIN_DECLS #define CONF_INTERFACE_TOOLBAR_STYLE "/apps/epiphany/general/toolbar_style" #define CONF_AUTO_DOWNLOADS "/apps/epiphany/general/automatic_downloads" #define CONF_DESKTOP_IS_HOME_DIR "/apps/nautilus/preferences/desktop_is_home_dir" +#define CONF_NETWORK_MANAGED "/apps/epiphany/general/managed_network" /* Directories */ #define CONF_STATE_SAVE_DIR "/apps/epiphany/directories/save" diff --git a/src/Makefile.am b/src/Makefile.am index 2ab63564f..15b4ee5e6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -122,6 +122,12 @@ libephymain_la_CFLAGS = \ $(DBUS_CFLAGS) \ $(AM_CFLAGS) +if ENABLE_NETWORK_MANAGER +libephymain_la_SOURCES += \ + ephy-net-monitor.c \ + ephy-net-monitor.h +endif + if ENABLE_PYTHON NOINST_H_FILES += \ ephy-python.h \ diff --git a/src/ephy-net-monitor.c b/src/ephy-net-monitor.c new file mode 100644 index 000000000..0b0dd901c --- /dev/null +++ b/src/ephy-net-monitor.c @@ -0,0 +1,584 @@ +/* + * Copyright (C) 2005, 2006 Jean-François Rameau + * + * 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include "config.h" + +#include "ephy-net-monitor.h" + +#include "ephy-dbus.h" +#include "ephy-shell.h" +#include "ephy-session.h" +#include "ephy-embed-single.h" +#include "eel-gconf-extensions.h" +#include "ephy-prefs.h" +#include "ephy-debug.h" + +#include <NetworkManager/NetworkManager.h> + +#include <gmodule.h> + +typedef enum +{ + NETWORK_UP, + NETWORK_DOWN +} NetworkStatus; + +#define EPHY_NET_MONITOR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_NET_MONITOR, EphyNetMonitorPrivate)) + +struct _EphyNetMonitorPrivate +{ + DBusConnection *bus; + guint notify_id; + guint active : 1; + NetworkStatus status; +}; + +enum +{ + PROP_0, + PROP_NETWORK_STATUS +}; + +static GObjectClass *parent_class; + +static void +ephy_net_monitor_set_net_status (EphyNetMonitor *monitor, + NetworkStatus status) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + + LOG ("EphyNetMonitor turning Epiphany to %s mode", + status != NETWORK_DOWN ? "online" : "offline"); + + priv->status = priv->active ? status : NETWORK_UP; + + g_object_notify (G_OBJECT (monitor), "network-status"); +} + +static NetworkStatus +ephy_net_monitor_check_for_active_device (EphyNetMonitor *monitor, + char *all_path[], + int num) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + int i; + DBusMessage * message = NULL; + DBusMessage * reply = NULL; + const char * iface = NULL; + char * op = NULL; + dbus_uint32_t type = 0; + const char * udi = NULL; + dbus_bool_t active = FALSE; + const char * ip4_address = NULL; + const char * broadcast = NULL; + const char * subnetmask = NULL; + const char * hw_addr = NULL; + const char * route = NULL; + const char * primary_dns = NULL; + const char * secondary_dns = NULL; + dbus_uint32_t mode = 0; + dbus_int32_t strength = -1; + char * active_network_path = NULL; + dbus_bool_t link_active = FALSE; + dbus_uint32_t caps = NM_DEVICE_CAP_NONE; + char ** networks = NULL; + int num_networks = 0; + NMActStage act_stage = NM_ACT_STAGE_UNKNOWN; + NetworkStatus status = NETWORK_DOWN; + + for (i = 0; i < num; i++) + { + const char *path = all_path [i]; + DBusError error; + + message = dbus_message_new_method_call (NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_DEVICES, + "getProperties"); + if (message == NULL) + { + g_warning ("EphyNetMonitor: couldn't allocate the dbus message"); + status = NETWORK_UP; + break; + } + + reply = dbus_connection_send_with_reply_and_block (priv->bus, message, -1, NULL); + dbus_message_unref (message); + + if (reply == NULL) + { + g_warning ("EphyNetMonitor: " + "didn't get a reply from NetworkManager for device %s.\n", path); + status = NETWORK_UP; + break; + } + + dbus_error_init (&error); + if (dbus_message_get_args (reply, &error, DBUS_TYPE_OBJECT_PATH, &op, + DBUS_TYPE_STRING, &iface, + DBUS_TYPE_UINT32, &type, + DBUS_TYPE_STRING, &udi, + DBUS_TYPE_BOOLEAN,&active, + DBUS_TYPE_UINT32, &act_stage, + DBUS_TYPE_STRING, &ip4_address, + DBUS_TYPE_STRING, &subnetmask, + DBUS_TYPE_STRING, &broadcast, + DBUS_TYPE_STRING, &hw_addr, + DBUS_TYPE_STRING, &route, + DBUS_TYPE_STRING, &primary_dns, + DBUS_TYPE_STRING, &secondary_dns, + DBUS_TYPE_UINT32, &mode, + DBUS_TYPE_INT32, &strength, + DBUS_TYPE_BOOLEAN,&link_active, + DBUS_TYPE_UINT32, &caps, + DBUS_TYPE_STRING, &active_network_path, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &networks, &num_networks, + DBUS_TYPE_INVALID)) + { + dbus_message_unref (reply); + + /* found one active device */ + if (active) + { + status = NETWORK_UP; + break; + } + } + else + { + g_warning ("EphyNetMonitor: " + "unexpected reply from NetworkManager for device %s.\n", path); + if (dbus_error_is_set(&error)) + { + g_warning ("EphyNetMonitor: %s: %s", error.name, error.message); + dbus_error_free(&error); + } + + status = NETWORK_UP; + + break; + } + } + + return active; +} + +/* This is the heart of Net Monitor monitor */ +/* ATM, if there is an active device, we say that network is up: that's all ! */ +static gboolean +ephy_net_monitor_network_status (EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + DBusMessage *message, *reply; + DBusError error; + NetworkStatus net_status; + + /* ask to Network Manager if there is at least one active device */ + message = dbus_message_new_method_call (NM_DBUS_SERVICE, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "getDevices"); + + if (message == NULL) + { + g_warning ("Couldn't allocate the dbus message"); + /* fallbak: let's Epiphany roll */ + return NETWORK_UP; + } + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (priv->bus, + message, + -1, + &error); + if (dbus_error_is_set (&error)) + { + if (dbus_error_has_name (&error, NM_DBUS_NO_DEVICES_ERROR)) + { + LOG ("EphyNetMonitor: Network Manager says - no available network devices -"); + + net_status = NETWORK_DOWN; + } + else + { + LOG ("EphyNetMonitor can't talk to Network Manager: %s: %s", + error.name, error.message); + + /* fallback */ + net_status = NETWORK_UP; + } + + dbus_error_free(&error); + } + else + { + if (reply == NULL) + { + g_warning("EphyNetMonitor got NULL reply"); + + /* fallback */ + net_status = NETWORK_UP; + } + else + { + /* check if we have at least one active device */ + char **paths = NULL; + int num = -1; + + if (!dbus_message_get_args (reply, + NULL, + DBUS_TYPE_ARRAY, + DBUS_TYPE_OBJECT_PATH, + &paths, + &num, + DBUS_TYPE_INVALID)) + { + g_warning ("EphyNetMonitor: unexpected reply from NetworkManager"); + dbus_message_unref (reply); + net_status = NETWORK_UP; + } + else + { + net_status = ephy_net_monitor_check_for_active_device + (monitor, paths, num); + } + } + } + + if (reply) + { + dbus_message_unref (reply); + } + + if (message) + { + dbus_message_unref (message); + } + + return net_status; +} + +static void +ephy_net_monitor_check_network (EphyNetMonitor *monitor) +{ + NetworkStatus net_status; + + net_status = ephy_net_monitor_network_status (monitor); + + LOG ("EphyNetMonitor guesses the network is %s", + net_status != NETWORK_DOWN ? "up" : "down"); + + ephy_net_monitor_set_net_status (monitor, net_status); +} + +/* Filters all the messages from Network Manager */ +static DBusHandlerResult +filter_func (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + EphyNetMonitor *monitor; + + g_return_val_if_fail (user_data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + + monitor = EPHY_NET_MONITOR (user_data); + + if (dbus_message_is_signal (message, + NM_DBUS_INTERFACE, + "DeviceNoLongerActive")) + { + LOG ("EphyNetMonitor catches DeviceNoLongerActive signal"); + + ephy_net_monitor_check_network (monitor); + + return DBUS_HANDLER_RESULT_HANDLED; + } + if (dbus_message_is_signal (message, + NM_DBUS_INTERFACE, + "DeviceNowActive")) + { + LOG ("EphyNetMonitor catches DeviceNowActive signal"); + + ephy_net_monitor_set_net_status (monitor, NETWORK_UP); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void +ephy_net_monitor_attach_to_dbus (EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + DBusError error; + EphyDbus *dbus; + DBusGConnection *g_connection; + + LOG ("EphyNetMonitor is trying to attach to SYSTEM bus"); + + dbus = ephy_dbus_get_default (); + + g_connection = ephy_dbus_get_bus (dbus, EPHY_DBUS_SYSTEM); + g_return_if_fail (g_connection != NULL); + + priv->bus = dbus_g_connection_get_connection (g_connection); + + if (priv->bus != NULL) + { + dbus_connection_add_filter (priv->bus, + filter_func, + monitor, + NULL); + dbus_error_init (&error); + dbus_bus_add_match (priv->bus, + "type='signal',interface='" NM_DBUS_INTERFACE "'", + &error); + if (dbus_error_is_set(&error)) + { + g_warning("EphyNetMonitor cannot register signal handler: %s: %s", + error.name, error.message); + dbus_error_free(&error); + } + LOG ("EphyNetMonitor attached to SYSTEM bus"); + } +} + +static void +connect_to_system_bus_cb (EphyDbus *dbus, + EphyDbusBus kind, + EphyNetMonitor *monitor) +{ + if (kind == EPHY_DBUS_SYSTEM) + { + LOG ("EphyNetMonitor connecting to SYSTEM bus"); + + ephy_net_monitor_attach_to_dbus (monitor); + } +} + +static void +disconnect_from_system_bus_cb (EphyDbus *dbus, + EphyDbusBus kind, + EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + + if (kind == EPHY_DBUS_SYSTEM) + { + LOG ("EphyNetMonitor disconnected from SYSTEM bus"); + + /* no bus anymore */ + priv->bus = NULL; + } +} + +static void +ephy_net_monitor_startup (EphyNetMonitor *monitor) +{ + EphyDbus *dbus; + + dbus = ephy_dbus_get_default (); + + LOG ("EphyNetMonitor starting up"); + + ephy_net_monitor_attach_to_dbus (monitor); + + /* DBUS may disconnect us at any time. So listen carefully to it */ + g_signal_connect (dbus, "connected", + G_CALLBACK (connect_to_system_bus_cb), monitor); + g_signal_connect (dbus, "disconnected", + G_CALLBACK (disconnect_from_system_bus_cb), monitor); + + /* FIXME what if the system bus isn't available right now? */ + ephy_net_monitor_check_network (monitor); +} + +static void +ephy_net_monitor_shutdown (EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + EphyDbus *dbus; + + dbus = ephy_dbus_get_default (); + + g_signal_handlers_disconnect_by_func + (dbus, G_CALLBACK (connect_to_system_bus_cb), monitor); + g_signal_handlers_disconnect_by_func + (dbus,G_CALLBACK (disconnect_from_system_bus_cb), monitor); + + priv->bus = NULL; + + LOG ("EphyNetMonitor shutdown"); +} + +static void +notify_network_managed_cb (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv = monitor->priv; + GConfValue *value; + gboolean active = FALSE; + + LOG (CONF_NETWORK_MANAGED " key changed"); + + g_assert (entry != NULL); + + value = gconf_entry_get_value (entry); + if (value != NULL && value->type == GCONF_VALUE_BOOL) + { + active = gconf_value_get_bool (value); + } + + priv->active = active; + + g_object_notify (G_OBJECT (monitor), "network-status"); +} + +static void +ephy_net_monitor_init (EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv; + + priv = monitor->priv = EPHY_NET_MONITOR_GET_PRIVATE (monitor); + + LOG ("EphyNetMonitor initialising"); + + priv->status = NETWORK_UP; + + priv->notify_id = eel_gconf_notification_add + (CONF_NETWORK_MANAGED, + (GConfClientNotifyFunc) notify_network_managed_cb, + monitor); + eel_gconf_notify (CONF_NETWORK_MANAGED); + + ephy_net_monitor_startup (monitor); +} + +static void +ephy_net_monitor_dispose (GObject *object) +{ + EphyNetMonitor *monitor = EPHY_NET_MONITOR (object); + EphyNetMonitorPrivate *priv = monitor->priv; + + LOG ("EphyNetMonitor finalising"); + + ephy_net_monitor_shutdown (monitor); + + if (priv->notify_id != 0) + { + eel_gconf_notification_remove (priv->notify_id); + priv->notify_id = 0; + } + + parent_class->dispose (object); +} + +static void +ephy_net_monitor_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyNetMonitor *monitor = EPHY_NET_MONITOR (object); + + switch (prop_id) + { + case PROP_NETWORK_STATUS: + g_value_set_boolean (value, ephy_net_monitor_get_net_status (monitor)); + break; + } +} + +static void +ephy_net_monitor_class_init (EphyNetMonitorClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->dispose = ephy_net_monitor_dispose; + object_class->get_property = ephy_net_monitor_get_property; + +/** + * EphyNetMonitor::network-status: + * + * Whether the network is on-line. + */ + g_object_class_install_property + (object_class, + PROP_NETWORK_STATUS, + g_param_spec_boolean ("network-status", + "network-status", + "network-status", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (object_class, sizeof (EphyNetMonitorPrivate)); +} + +/* public API */ + +GType +ephy_net_monitor_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GTypeInfo our_info = + { + sizeof (EphyShellClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_net_monitor_class_init, + NULL, + NULL, /* class_data */ + sizeof (EphyNetMonitor), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_net_monitor_init + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "EphyNetMonitor", + &our_info, 0); + } + + return type; +} + +EphyNetMonitor * +ephy_net_monitor_new (void) +{ + return g_object_new (EPHY_TYPE_NET_MONITOR, NULL); +} + +gboolean +ephy_net_monitor_get_net_status (EphyNetMonitor *monitor) +{ + EphyNetMonitorPrivate *priv; + + g_return_val_if_fail (EPHY_IS_NET_MONITOR (monitor), FALSE); + + priv = monitor->priv; + + return !priv->active || priv->status != NETWORK_DOWN; +} diff --git a/src/ephy-net-monitor.h b/src/ephy-net-monitor.h new file mode 100644 index 000000000..34c6bb550 --- /dev/null +++ b/src/ephy-net-monitor.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch + * Copyright (C) 2005, 2006 Jean-François Rameau + * + * 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifndef EPHY_NET_MONITOR_H +#define EPHY_NET_MONITOR_H + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_NET_MONITOR (ephy_net_monitor_get_type ()) +#define EPHY_NET_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_NET_MONITOR, EphyNetMonitor)) +#define EPHY_NET_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_NET_MONITOR, EphyNetMonitorClass)) +#define EPHY_IS_NET_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_NET_MONITOR)) +#define EPHY_IS_NET_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_NET_MONITOR)) +#define EPHY_NET_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_NET_MONITOR, EphyNetMonitorClass)) + +typedef struct _EphyNetMonitor EphyNetMonitor; +typedef struct _EphyNetMonitorClass EphyNetMonitorClass; +typedef struct _EphyNetMonitorPrivate EphyNetMonitorPrivate; + +struct _EphyNetMonitorClass +{ + GObjectClass parent_class; +}; + +struct _EphyNetMonitor +{ + GObject parent_instance; + + /*< private >*/ + EphyNetMonitorPrivate *priv; +}; + +GType ephy_net_monitor_get_type (void); + +EphyNetMonitor *ephy_net_monitor_new (void); + +gboolean ephy_net_monitor_get_net_status (EphyNetMonitor *monitor); + +G_END_DECLS + +#endif diff --git a/src/ephy-shell.c b/src/ephy-shell.c index 62b2788d6..810f3ca8b 100644 --- a/src/ephy-shell.c +++ b/src/ephy-shell.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2004 Marco Pesenti Gritti - * Copyright (C) 2003, 2004 Christian Persch + * Copyright (C) 2003, 2004, 2006 Christian Persch * * 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 @@ -54,7 +54,9 @@ #include <dirent.h> #include <unistd.h> -#define AUTOMATION_IID "OAFIID:GNOME_Epiphany_Automation" +#ifdef ENABLE_NETWORK_MANAGER +#include "ephy-net-monitor.h" +#endif #define EPHY_SHELL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SHELL, EphyShellPrivate)) @@ -66,13 +68,17 @@ struct _EphyShellPrivate EggToolbarsModel *toolbars_model; EggToolbarsModel *fs_toolbars_model; EphyExtensionsManager *extensions_manager; +#ifdef ENABLE_NETWORK_MANAGER + EphyNetMonitor *net_monitor; +#endif GtkWidget *bme; GtkWidget *history_window; GObject *pdm_dialog; GObject *prefs_dialog; GObject *print_setup_dialog; GList *del_on_exit; - gboolean embed_single_connected; + + guint embed_single_connected : 1; }; EphyShell *ephy_shell = NULL; @@ -83,7 +89,7 @@ static void ephy_shell_dispose (GObject *object); static void ephy_shell_finalize (GObject *object); static GObject *impl_get_embed_single (EphyEmbedShell *embed_shell); -static GObjectClass *parent_class = NULL; +static GObjectClass *parent_class; GType ephy_shell_get_type (void) @@ -209,15 +215,38 @@ ephy_shell_add_sidebar_cb (EphyEmbedSingle *embed_single, return TRUE; } +#ifdef ENABLE_NETWORK_MANAGER + +static void +ephy_shell_sync_network_status (EphyNetMonitor *net_monitor, + GParamSpec *pspec, + EphyShell *shell) +{ + EphyShellPrivate *priv = shell->priv; + EphyEmbedSingle *single; + gboolean net_status; + + if (!priv->embed_single_connected) return; + + single = EPHY_EMBED_SINGLE (ephy_embed_shell_get_embed_single (EPHY_EMBED_SHELL (shell))); + + net_status = ephy_net_monitor_get_net_status (net_monitor); + ephy_embed_single_set_network_status (single, net_status); +} + +#endif /* ENABLE_NETWORK_MANAGER */ + static GObject* impl_get_embed_single (EphyEmbedShell *embed_shell) { EphyShell *shell = EPHY_SHELL (embed_shell); + EphyShellPrivate *priv = shell->priv; GObject *embed_single; embed_single = EPHY_EMBED_SHELL_CLASS (parent_class)->get_embed_single (embed_shell); - if (embed_single != NULL && shell->priv->embed_single_connected == FALSE) + if (embed_single != NULL && + priv->embed_single_connected == FALSE) { g_signal_connect_object (embed_single, "new-window", G_CALLBACK (ephy_shell_new_window_cb), @@ -227,7 +256,13 @@ impl_get_embed_single (EphyEmbedShell *embed_shell) G_CALLBACK (ephy_shell_add_sidebar_cb), shell, G_CONNECT_AFTER); - shell->priv->embed_single_connected = TRUE; +#ifdef ENABLE_NETWORK_MANAGER + /* Now we need the net monitor */ + ephy_shell_get_net_monitor (shell); + ephy_shell_sync_network_status (priv->net_monitor, NULL, shell); +#endif + + priv->embed_single_connected = TRUE; } return embed_single; @@ -333,6 +368,17 @@ ephy_shell_dispose (GObject *object) priv->bookmarks = NULL; } +#ifdef ENABLE_NETWORK_MANAGER + if (priv->net_monitor != NULL) + { + LOG ("Unref net monitor"); + g_signal_handlers_disconnect_by_func + (priv->net_monitor, G_CALLBACK (ephy_shell_sync_network_status), shell); + g_object_unref (priv->net_monitor); + priv->net_monitor = NULL; + } +#endif /* ENABLE_NETWORK_MANAGER */ + G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -673,6 +719,25 @@ ephy_shell_get_extensions_manager (EphyShell *es) return G_OBJECT (es->priv->extensions_manager); } +GObject * +ephy_shell_get_net_monitor (EphyShell *shell) +{ +#ifdef ENABLE_NETWORK_MANAGER + EphyShellPrivate *priv = shell->priv; + + if (priv->net_monitor == NULL) + { + priv->net_monitor = ephy_net_monitor_new (); + g_signal_connect (priv->net_monitor, "notify::network-status", + G_CALLBACK (ephy_shell_sync_network_status), shell); + } + + return G_OBJECT (priv->net_monitor); +#else + return NULL; +#endif /* ENABLE_NETWORK_MANAGER */ +} + static void toolwindow_show_cb (GtkWidget *widget, EphyShell *es) { diff --git a/src/ephy-shell.h b/src/ephy-shell.h index 2581e48bb..76e661c0f 100644 --- a/src/ephy-shell.h +++ b/src/ephy-shell.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2000-2004 Marco Pesenti Gritti - * Copyright (C) 2003, 2004 Christian Persch + * Copyright (C) 2003, 2004, 2006 Christian Persch * * 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 @@ -100,6 +100,8 @@ EphyTab *ephy_shell_new_tab_full (EphyShell *shell, GObject *ephy_shell_get_session (EphyShell *shell); +GObject *ephy_shell_get_net_monitor (EphyShell *shell); + EphyBookmarks *ephy_shell_get_bookmarks (EphyShell *shell); GObject *ephy_shell_get_toolbars_model (EphyShell *shell, @@ -117,10 +119,7 @@ GObject *ephy_shell_get_prefs_dialog (EphyShell *shell); GObject *ephy_shell_get_print_setup_dialog (EphyShell *shell); -GObject *ephy_shell_get_dbus_service (EphyShell *shell); - /* private API */ - void _ephy_shell_create_instance (void); G_END_DECLS |