pidgin: fe68f3ce: A patch from QuLogic to replace the libn...
rlaager at pidgin.im
rlaager at pidgin.im
Fri May 9 23:45:59 EDT 2008
-----------------------------------------------------------------
Revision: fe68f3cef0f055a97a7b4425baae5c7711cfb4e7
Ancestor: 7728b8a9608a90aafa262e4af373af38d8fa7055
Author: rlaager at pidgin.im
Date: 2008-05-10T03:29:15
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/fe68f3cef0f055a97a7b4425baae5c7711cfb4e7
Modified files:
libpurple/network.c
ChangeLog:
A patch from QuLogic to replace the libnm_glib calls with straight DBus
calls. This removes a library dependence and should be more stable, we hope.
Comments:
Fixes #179
-------------- next part --------------
============================================================
--- libpurple/network.c b9a475b32bee6b8a12d23d704e3f2e247a230824
+++ libpurple/network.c 5c015178cc377e1fe622bbb2a1bdfd10f327b9d8
@@ -60,10 +60,12 @@
#endif
#ifdef HAVE_LIBNM
-#include <libnm_glib.h>
+#include <dbus/dbus-glib.h>
+#include <NetworkManager.h>
-static libnm_glib_ctx *nm_context = NULL;
-static guint nm_callback_idx = 0;
+static DBusGConnection *nm_conn = NULL;
+static DBusGProxy *nm_proxy = NULL;
+static DBusGProxy *dbus_proxy = NULL;
#elif defined _WIN32
static int current_network_count;
@@ -80,7 +82,7 @@ struct _PurpleNetworkListenData {
};
#ifdef HAVE_LIBNM
-static void nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data);
+static NMState nm_get_network_state(void);
#endif
const unsigned char *
@@ -593,17 +595,12 @@ purple_network_is_available(void)
{
#ifdef HAVE_LIBNM
/* Try NetworkManager first, maybe we'll get lucky */
- int libnm_retval = -1;
-
- if (nm_context)
+ if (nm_get_network_state() != NM_STATE_CONNECTED)
{
- if ((libnm_retval = libnm_glib_get_network_state(nm_context)) == LIBNM_NO_NETWORK_CONNECTION)
- {
- purple_debug_warning("network", "NetworkManager not active or reports no connection (retval = %i)\n", libnm_retval);
- return FALSE;
- }
- if (libnm_retval == LIBNM_ACTIVE_NETWORK_CONNECTION) return TRUE;
- }
+ purple_debug_warning("network", "NetworkManager not active or reports no connection\n");
+ return FALSE;
+ } else
+ return TRUE;
#elif defined _WIN32
return (current_network_count > 0);
#endif
@@ -612,40 +609,79 @@ static void
#ifdef HAVE_LIBNM
static void
-nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data)
+nm_update_state(NMState state)
{
- static libnm_glib_state prev = LIBNM_NO_DBUS;
- libnm_glib_state current;
+ static NMState prev = NM_STATE_UNKNOWN;
PurpleConnectionUiOps *ui_ops = purple_connections_get_ui_ops();
- current = libnm_glib_get_network_state(ctx);
- purple_debug_info("network","Entering nm_callback_func!\n");
-
purple_signal_emit(purple_network_get_handle(), "network-configuration-changed", NULL);
- switch(current)
+ switch(state)
{
- case LIBNM_ACTIVE_NETWORK_CONNECTION:
- /* Call res_init in case DNS servers have changed */
- res_init();
- if (ui_ops != NULL && ui_ops->network_connected != NULL)
- ui_ops->network_connected();
- prev = current;
- break;
- case LIBNM_NO_NETWORK_CONNECTION:
- if (prev != LIBNM_ACTIVE_NETWORK_CONNECTION)
+ case NM_STATE_CONNECTED:
+ /* Call res_init in case DNS servers have changed */
+ res_init();
+ if (ui_ops != NULL && ui_ops->network_connected != NULL)
+ ui_ops->network_connected();
+ prev = state;
break;
- if (ui_ops != NULL && ui_ops->network_disconnected != NULL)
- ui_ops->network_disconnected();
- prev = current;
- break;
- case LIBNM_NO_DBUS:
- case LIBNM_NO_NETWORKMANAGER:
- case LIBNM_INVALID_CONTEXT:
- default:
- break;
+ case NM_STATE_ASLEEP:
+ case NM_STATE_CONNECTING:
+ case NM_STATE_DISCONNECTED:
+ if (prev != NM_STATE_CONNECTED)
+ break;
+ if (ui_ops != NULL && ui_ops->network_disconnected != NULL)
+ ui_ops->network_disconnected();
+ prev = state;
+ break;
+ case NM_STATE_UNKNOWN:
+ default:
+ break;
}
}
+
+static void
+nm_state_change_cb(DBusGProxy *proxy, NMState state, gpointer user_data)
+{
+ purple_debug_info("network", "Got StateChange from NetworkManager: %d.\n", state);
+ nm_update_state(state);
+}
+
+static NMState
+nm_get_network_state(void)
+{
+ GError *err = NULL;
+ NMState state = NM_STATE_UNKNOWN;
+
+ if (!nm_proxy)
+ return NM_STATE_UNKNOWN;
+
+ if (!dbus_g_proxy_call(nm_proxy, "state", &err, G_TYPE_INVALID, G_TYPE_UINT, &state, G_TYPE_INVALID)) {
+ /* XXX: Print an error? */
+ return NM_STATE_UNKNOWN;
+ }
+
+ return state;
+}
+
+static void
+nm_dbus_name_owner_changed_cb(DBusGProxy *proxy, char *service, char *old_owner, char *new_owner, gpointer user_data)
+{
+ if (g_str_equal(service, NM_DBUS_SERVICE)) {
+ gboolean old_owner_good = old_owner && (old_owner[0] != '\0');
+ gboolean new_owner_good = new_owner && (new_owner[0] != '\0');
+
+ purple_debug_info("network", "Got NameOwnerChanged signal, service = '%s', old_owner = '%s', new_owner = '%s'\n", service, old_owner, new_owner);
+ if (!old_owner_good && new_owner_good) { /* Equivalent to old ServiceCreated signal */
+ purple_debug_info("network", "NetworkManager has started.\n");
+ nm_update_state(nm_get_network_state());
+ } else if (old_owner_good && !new_owner_good) { /* Equivalent to old ServiceDeleted signal */
+ purple_debug_info("network", "NetworkManager has gone away.\n");
+ nm_update_state(NM_STATE_UNKNOWN);
+ }
+ }
+}
+
#endif
void *
@@ -659,6 +695,9 @@ purple_network_init(void)
void
purple_network_init(void)
{
+#ifdef HAVE_LIBNM
+ GError *error = NULL;
+#endif
#ifdef _WIN32
GError *err = NULL;
gint cnt = wpurple_get_connected_network_count();
@@ -686,9 +725,26 @@ purple_network_init(void)
purple_upnp_discover(NULL, NULL);
#ifdef HAVE_LIBNM
- nm_context = libnm_glib_init();
- if(nm_context)
- nm_callback_idx = libnm_glib_register_callback(nm_context, nm_callback_func, NULL, g_main_context_default());
+ nm_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (!nm_conn) {
+ purple_debug_warning("network", "Error connecting to DBus System service: %s.\n", error->message);
+ } else {
+ nm_proxy = dbus_g_proxy_new_for_name(nm_conn,
+ NM_DBUS_SERVICE,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE);
+ dbus_g_proxy_add_signal(nm_proxy, NM_DBUS_SIGNAL_STATE_CHANGE, G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(nm_proxy, NM_DBUS_SIGNAL_STATE_CHANGE,
+ G_CALLBACK(nm_state_change_cb), NULL, NULL);
+
+ dbus_proxy = dbus_g_proxy_new_for_name(nm_conn,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ dbus_g_proxy_add_signal(dbus_proxy, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK(nm_dbus_name_owner_changed_cb), NULL, NULL);
+ }
#endif
purple_signal_register(purple_network_get_handle(), "network-configuration-changed",
@@ -702,13 +758,16 @@ purple_network_uninit(void)
purple_network_uninit(void)
{
#ifdef HAVE_LIBNM
- /* FIXME: If anyone can think of a more clever way to shut down libnm without
- * using a global variable + this function, please do. */
- if(nm_context && nm_callback_idx)
- libnm_glib_unregister_callback(nm_context, nm_callback_idx);
-
- if(nm_context)
- libnm_glib_shutdown(nm_context);
+ if (nm_proxy) {
+ dbus_g_proxy_disconnect_signal(nm_proxy, NM_DBUS_SIGNAL_STATE_CHANGE, G_CALLBACK(nm_state_change_cb), NULL);
+ g_object_unref(G_OBJECT(nm_proxy));
+ }
+ if (dbus_proxy) {
+ dbus_g_proxy_disconnect_signal(dbus_proxy, "NameOwnerChanged", G_CALLBACK(nm_dbus_name_owner_changed_cb), NULL);
+ g_object_unref(G_OBJECT(dbus_proxy));
+ }
+ if (nm_conn)
+ dbus_g_connection_unref(nm_conn);
#endif
purple_signal_unregister(purple_network_get_handle(),
More information about the Commits
mailing list