/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2010 Richard Hughes * * 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 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. * */ #include #include "cc-network-panel.h" #include "panel-cell-renderer-mode.h" #include "panel-cell-renderer-signal.h" #include "panel-common.h" G_DEFINE_DYNAMIC_TYPE (CcNetworkPanel, cc_network_panel, CC_TYPE_PANEL) #define NETWORK_PANEL_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_NETWORK_PANEL, CcNetworkPanelPrivate)) struct _CcNetworkPanelPrivate { GCancellable *cancellable; gchar *current_device; GDBusProxy *proxy; GPtrArray *devices; GSettings *proxy_settings; GtkBuilder *builder; guint devices_add_refcount; }; typedef struct { CcNetworkPanel *panel; gchar *active_access_point; gchar *device_id; gchar *ip4_config; gchar *dhcp4_config; gchar *ip6_config; gchar *modem_imei; gchar *operator_name; gchar *udi; GDBusProxy *proxy; GDBusProxy *proxy_additional; GDBusProxy *proxy_ip4; GDBusProxy *proxy_dhcp4; GDBusProxy *proxy_ip6; guint device_add_refcount; NMDeviceType type; } PanelDeviceItem; typedef struct { gchar *access_point; gchar *active_access_point; guint strength; guint mode; CcNetworkPanel *panel; } PanelAccessPointItem; enum { PANEL_DEVICES_COLUMN_ICON, PANEL_DEVICES_COLUMN_TITLE, PANEL_DEVICES_COLUMN_ID, PANEL_DEVICES_COLUMN_SORT, PANEL_DEVICES_COLUMN_TOOLTIP, PANEL_DEVICES_COLUMN_COMPOSITE_DEVICE, PANEL_DEVICES_COLUMN_LAST }; enum { PANEL_WIRELESS_COLUMN_ID, PANEL_WIRELESS_COLUMN_TITLE, PANEL_WIRELESS_COLUMN_SORT, PANEL_WIRELESS_COLUMN_STRENGTH, PANEL_WIRELESS_COLUMN_MODE, PANEL_WIRELESS_COLUMN_LAST }; static void panel_device_refresh_item_ui (PanelDeviceItem *item); static void panel_refresh_devices (CcNetworkPanel *panel); static void cc_network_panel_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_network_panel_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } static void cc_network_panel_dispose (GObject *object) { CcNetworkPanelPrivate *priv = CC_NETWORK_PANEL (object)->priv; if (priv->proxy_settings) { g_object_unref (priv->proxy_settings); priv->proxy_settings = NULL; } if (priv->cancellable != NULL) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->builder != NULL) { g_object_unref (priv->builder); priv->builder = NULL; } if (priv->proxy != NULL) { g_object_unref (priv->proxy); priv->proxy = NULL; } G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object); } static void cc_network_panel_finalize (GObject *object) { CcNetworkPanelPrivate *priv = CC_NETWORK_PANEL (object)->priv; g_free (priv->current_device); g_ptr_array_unref (priv->devices); G_OBJECT_CLASS (cc_network_panel_parent_class)->finalize (object); } static void cc_network_panel_class_init (CcNetworkPanelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (CcNetworkPanelPrivate)); object_class->get_property = cc_network_panel_get_property; object_class->set_property = cc_network_panel_set_property; object_class->dispose = cc_network_panel_dispose; object_class->finalize = cc_network_panel_finalize; } static void cc_network_panel_class_finalize (CcNetworkPanelClass *klass) { } /** * panel_settings_changed: **/ static void panel_settings_changed (GSettings *settings, const gchar *key, CcNetworkPanel *panel) { } /** * panel_proxy_mode_combo_setup_widgets: **/ static void panel_proxy_mode_combo_setup_widgets (CcNetworkPanel *panel, guint value) { GtkWidget *widget; /* hide or show the PAC text box */ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "hbox_proxy_url")); gtk_widget_set_visible (widget, value == 2); /* hide or show the manual entry text boxes */ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "hbox_proxy_http")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "hbox_proxy_shttp")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "hbox_proxy_ftp")); gtk_widget_set_visible (widget, value == 1); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "hbox_proxy_socks")); gtk_widget_set_visible (widget, value == 1); } /** * panel_proxy_mode_combo_changed_cb: **/ static void panel_proxy_mode_combo_changed_cb (GtkWidget *widget, CcNetworkPanel *panel) { gboolean ret; gint value; GtkTreeIter iter; GtkTreeModel *model; /* no selection */ ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); if (!ret) return; /* get entry */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); gtk_tree_model_get (model, &iter, 1, &value, -1); /* set */ g_settings_set_enum (panel->priv->proxy_settings, "mode", value); /* hide or show the correct widgets */ panel_proxy_mode_combo_setup_widgets (panel, value); } /** * panel_set_value_for_combo: **/ static void panel_set_value_for_combo (CcNetworkPanel *panel, GtkComboBox *combo_box, gint value) { gboolean ret; gint value_tmp; GtkTreeIter iter; GtkTreeModel *model; /* get entry */ model = gtk_combo_box_get_model (combo_box); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* try to make the UI match the setting */ do { gtk_tree_model_get (model, &iter, 1, &value_tmp, -1); if (value == value_tmp) { gtk_combo_box_set_active_iter (combo_box, &iter); break; } } while (gtk_tree_model_iter_next (model, &iter)); /* hide or show the correct widgets */ panel_proxy_mode_combo_setup_widgets (panel, value); } static void panel_free_device_item (PanelDeviceItem *item) { g_object_unref (item->panel); g_object_unref (item->proxy); if (item->proxy_additional != NULL) g_object_unref (item->proxy_additional); if (item->proxy_ip4 != NULL) g_object_unref (item->proxy_ip4); if (item->proxy_ip6 != NULL) g_object_unref (item->proxy_ip6); g_free (item->device_id); g_free (item->active_access_point); g_free (item->udi); g_free (item->operator_name); g_free (item->ip4_config); g_free (item->ip6_config); g_free (item->modem_imei); g_free (item); } static void select_first_device (CcNetworkPanel *panel) { GtkTreePath *path; GtkWidget *widget; GtkTreeSelection *selection; widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "treeview_devices")); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); /* select the first device */ path = gtk_tree_path_new_from_string ("0"); gtk_tree_selection_select_path (selection, path); gtk_tree_path_free (path); } /** * panel_add_device_to_listview: **/ static void panel_add_device_to_listview (PanelDeviceItem *item) { GtkListStore *liststore_devices; GtkTreeIter iter; gchar *title = NULL; CcNetworkPanelPrivate *priv = item->panel->priv; g_debug ("device %s type %i", item->device_id, item->type); /* make title a bit bigger */ title = g_strdup_printf ("%s", panel_device_type_to_localized_string (item->type)); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_devices")); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, PANEL_DEVICES_COLUMN_ICON, panel_device_type_to_icon_name (item->type), PANEL_DEVICES_COLUMN_SORT, panel_device_type_to_sortable_string (item->type), PANEL_DEVICES_COLUMN_TITLE, title, PANEL_DEVICES_COLUMN_ID, item->device_id, PANEL_DEVICES_COLUMN_TOOLTIP, NULL, PANEL_DEVICES_COLUMN_COMPOSITE_DEVICE, item, -1); g_free (title); if (--item->panel->priv->devices_add_refcount == 0) select_first_device (item->panel); } /** * panel_got_proxy_access_point_cb: **/ static void panel_got_proxy_access_point_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { gchar *ssid = NULL; gchar tmp; GDBusProxy *proxy; GError *error = NULL; gsize len; GtkListStore *liststore_wireless_network; GtkTreeIter treeiter; GtkWidget *widget; guint i = 0; GVariantIter iter; GVariant *variant_mode = NULL; GVariant *variant_ssid = NULL; GVariant *variant_strength = NULL; PanelAccessPointItem *ap_item = (PanelAccessPointItem *) user_data; CcNetworkPanelPrivate *priv = ap_item->panel->priv; proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (proxy == NULL) { g_printerr ("Error creating proxy: %s\n", error->message); g_error_free (error); goto out; } /* get the strength */ variant_strength = g_dbus_proxy_get_cached_property (proxy, "Strength"); ap_item->strength = g_variant_get_byte (variant_strength); /* get the mode */ variant_mode = g_dbus_proxy_get_cached_property (proxy, "Mode"); ap_item->mode = g_variant_get_uint32 (variant_mode); /* get the (non NULL terminated, urgh) SSID */ variant_ssid = g_dbus_proxy_get_cached_property (proxy, "Ssid"); len = g_variant_iter_init (&iter, variant_ssid); if (len == 0) { g_warning ("invalid ssid?!"); goto out; } /* decode each byte */ ssid = g_new0 (gchar, len + 1); while (g_variant_iter_loop (&iter, "y", &tmp)) ssid[i++] = tmp; g_debug ("adding access point %s (%i%%) [%i]", ssid, ap_item->strength, ap_item->mode); /* add to the model */ liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_wireless_network")); gtk_list_store_append (liststore_wireless_network, &treeiter); gtk_list_store_set (liststore_wireless_network, &treeiter, PANEL_WIRELESS_COLUMN_ID, ap_item->access_point, PANEL_WIRELESS_COLUMN_TITLE, ssid, PANEL_WIRELESS_COLUMN_SORT, ssid, PANEL_WIRELESS_COLUMN_STRENGTH, ap_item->strength, PANEL_WIRELESS_COLUMN_MODE, ap_item->mode, -1); /* is this what we're on already? */ if (g_strcmp0 (ap_item->access_point, ap_item->active_access_point) == 0) { widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "combobox_network_name")); gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &treeiter); } out: g_free (ap_item->access_point); g_free (ap_item->active_access_point); g_object_unref (ap_item->panel); g_free (ap_item); g_free (ssid); if (variant_ssid != NULL) g_variant_unref (variant_ssid); if (variant_strength != NULL) g_variant_unref (variant_strength); if (variant_mode != NULL) g_variant_unref (variant_mode); if (proxy != NULL) g_object_unref (proxy); return; } /** * panel_get_access_point_data: **/ static void panel_get_access_point_data (PanelDeviceItem *item, const gchar *access_point_id) { PanelAccessPointItem *ap_item; ap_item = g_new0 (PanelAccessPointItem, 1); ap_item->access_point = g_strdup (access_point_id); ap_item->active_access_point = g_strdup (item->active_access_point); ap_item->panel = g_object_ref (item->panel); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", access_point_id, "org.freedesktop.NetworkManager.AccessPoint", item->panel->priv->cancellable, panel_got_proxy_access_point_cb, ap_item); } /** * panel_get_access_points_cb: **/ static void panel_get_access_points_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { const gchar *object_path; GError *error = NULL; gsize len; GVariantIter iter; GVariant *result = NULL; GVariant *test; GtkListStore *liststore_wireless_network; PanelDeviceItem *item = (PanelDeviceItem *) user_data; CcNetworkPanelPrivate *priv = item->panel->priv; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_printerr ("Error getting access points: %s\n", error->message); g_error_free (error); return; } /* clear list of access points */ liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_wireless_network")); gtk_list_store_clear (liststore_wireless_network); test = g_variant_get_child_value (result, 0); len = g_variant_iter_init (&iter, test); if (len == 0) { g_warning ("no access points?!"); goto out; } /* for each entry in the array */ while (g_variant_iter_loop (&iter, "o", &object_path)) { g_debug ("adding access point %s", object_path); panel_get_access_point_data (item, object_path); } out: g_variant_unref (result); g_variant_unref (test); } /** * panel_got_device_proxy_additional_cb: **/ static void panel_got_device_proxy_additional_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *result = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy_additional = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy_additional == NULL) { g_printerr ("Error creating additional proxy: %s\n", error->message); g_error_free (error); goto out; } /* async populate the list of access points */ if (item->type == NM_DEVICE_TYPE_WIFI) { /* get the currently active access point */ result = g_dbus_proxy_get_cached_property (item->proxy_additional, "ActiveAccessPoint"); item->active_access_point = g_variant_dup_string (result, NULL); g_dbus_proxy_call (item->proxy_additional, "GetAccessPoints", NULL, G_DBUS_CALL_FLAGS_NONE, -1, item->panel->priv->cancellable, panel_get_access_points_cb, item); } /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); out: if (result != NULL) g_variant_unref (result); return; } /** * panel_get_registration_info_cb: **/ static void panel_get_registration_info_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { gchar *operator_code = NULL; GError *error = NULL; guint registration_status; GVariant *result = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_printerr ("Error getting registration info: %s\n", error->message); g_error_free (error); return; } /* get values */ g_variant_get (result, "((uss))", ®istration_status, &operator_code, &item->operator_name); g_free (operator_code); g_variant_unref (result); } /** * panel_got_device_proxy_modem_manager_gsm_network_cb: **/ static void panel_got_device_proxy_modem_manager_gsm_network_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *result = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy_additional = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy_additional == NULL) { g_printerr ("Error creating additional proxy: %s\n", error->message); g_error_free (error); goto out; } /* get the currently active access point */ result = g_dbus_proxy_get_cached_property (item->proxy_additional, "AccessTechnology"); // item->active_access_point = g_variant_dup_string (result, NULL); g_dbus_proxy_call (item->proxy_additional, "GetRegistrationInfo", NULL, G_DBUS_CALL_FLAGS_NONE, -1, item->panel->priv->cancellable, panel_get_registration_info_cb, item); /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); out: if (result != NULL) g_variant_unref (result); return; } /** * panel_got_device_proxy_modem_manager_cb: **/ static void panel_got_device_proxy_modem_manager_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *result = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy_additional = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy_additional == NULL) { g_printerr ("Error creating additional proxy: %s\n", error->message); g_error_free (error); goto out; } /* get the IMEI */ result = g_dbus_proxy_get_cached_property (item->proxy_additional, "EquipmentIdentifier"); item->modem_imei = g_variant_dup_string (result, NULL); /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); out: if (result != NULL) g_variant_unref (result); return; } /** * panel_device_properties_changed_cb: **/ static void panel_device_properties_changed_cb (GDBusProxy *proxy, GVariant *changed_properties, const gchar* const *invalidated_properties, gpointer user_data) { PanelDeviceItem *item = (PanelDeviceItem *) user_data; CcNetworkPanelPrivate *priv = item->panel->priv; /* only refresh the selected device */ if (g_strcmp0 (priv->current_device, item->device_id) == 0) panel_device_refresh_item_ui (item); } /** * panel_got_device_proxy_ip4_cb: **/ static void panel_got_device_proxy_ip4_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy_ip4 = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy_ip4 == NULL) { g_printerr ("Error creating ip4 proxy: %s\n", error->message); g_error_free (error); goto out; } /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); out: return; } /** * panel_got_device_proxy_dhcp4_cb: **/ static void panel_got_device_proxy_dhcp4_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy_dhcp4 = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy_dhcp4 == NULL) { g_printerr ("Error creating dhcp4 proxy: %s\n", error->message); g_error_free (error); goto out; } /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); out: return; } /** * panel_got_device_proxy_ip6_cb: **/ static void panel_got_device_proxy_ip6_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy_ip6 = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy_ip6 == NULL) { g_printerr ("Error creating ip6 proxy: %s\n", error->message); g_error_free (error); goto out; } /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); out: return; } /** * panel_got_device_proxy_cb: **/ static void panel_got_device_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *variant_ip4 = NULL; GVariant *variant_dhcp4 = NULL; GVariant *variant_ip6 = NULL; GVariant *variant_type = NULL; GVariant *variant_udi = NULL; PanelDeviceItem *item = (PanelDeviceItem *) user_data; item->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (item->proxy == NULL) { g_printerr ("Error creating proxy: %s\n", error->message); g_error_free (error); goto out; } /* get the UDI, so we can query ModemManager devices */ variant_udi = g_dbus_proxy_get_cached_property (item->proxy, "Udi"); g_variant_get (variant_udi, "s", &item->udi); /* get the IP object paths */ variant_ip4 = g_dbus_proxy_get_cached_property (item->proxy, "Ip4Config"); g_variant_get (variant_ip4, "o", &item->ip4_config); variant_ip6 = g_dbus_proxy_get_cached_property (item->proxy, "Ip6Config"); g_variant_get (variant_ip6, "o", &item->ip6_config); /* get the IP DHCP object paths */ variant_dhcp4 = g_dbus_proxy_get_cached_property (item->proxy, "Dhcp4Config"); g_variant_get (variant_dhcp4, "o", &item->dhcp4_config); /* get the IP information */ if (g_strcmp0 (item->dhcp4_config, "/") != 0) { item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", item->dhcp4_config, "org.freedesktop.NetworkManager.DHCP4Config", item->panel->priv->cancellable, panel_got_device_proxy_dhcp4_cb, item); } else if (g_strcmp0 (item->ip4_config, "/") != 0) { item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", item->ip4_config, "org.freedesktop.NetworkManager.IP4Config", item->panel->priv->cancellable, panel_got_device_proxy_ip4_cb, item); } if (g_strcmp0 (item->ip6_config, "/") != 0) { item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", item->ip6_config, "org.freedesktop.NetworkManager.IP6Config", item->panel->priv->cancellable, panel_got_device_proxy_ip6_cb, item); } /* get the additional interface for this device type */ variant_type = g_dbus_proxy_get_cached_property (item->proxy, "DeviceType"); g_variant_get (variant_type, "u", &item->type); if (item->type == NM_DEVICE_TYPE_ETHERNET) { item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", item->device_id, "org.freedesktop.NetworkManager.Device.Wired", item->panel->priv->cancellable, panel_got_device_proxy_additional_cb, item); } else if (item->type == NM_DEVICE_TYPE_WIFI) { item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", item->device_id, "org.freedesktop.NetworkManager.Device.Wireless", item->panel->priv->cancellable, panel_got_device_proxy_additional_cb, item); } else if (item->type == NM_DEVICE_TYPE_GSM || item->type == NM_DEVICE_TYPE_CDMA) { item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.ModemManager", item->udi, "org.freedesktop.ModemManager.Modem", item->panel->priv->cancellable, panel_got_device_proxy_modem_manager_cb, item); item->device_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.ModemManager", item->udi, "org.freedesktop.ModemManager.Modem.Gsm.Network", item->panel->priv->cancellable, panel_got_device_proxy_modem_manager_gsm_network_cb, item); } /* add device if there are no more pending actions */ if (--item->device_add_refcount == 0) panel_add_device_to_listview (item); /* we want to update the UI */ g_signal_connect (item->proxy, "g-properties-changed", G_CALLBACK (panel_device_properties_changed_cb), item); out: if (variant_ip4 != NULL) g_variant_unref (variant_ip4); if (variant_dhcp4 != NULL) g_variant_unref (variant_dhcp4); if (variant_ip6 != NULL) g_variant_unref (variant_ip6); if (variant_udi != NULL) g_variant_unref (variant_udi); if (variant_type != NULL) g_variant_unref (variant_type); return; } /** * panel_add_device: **/ static void panel_add_device (CcNetworkPanel *panel, const gchar *device_id) { PanelDeviceItem *item; /* create temp device */ item = g_new0 (PanelDeviceItem, 1); item->panel = g_object_ref (panel); item->device_id = g_strdup (device_id); /* add to array */ g_ptr_array_add (panel->priv->devices, item); /* get initial device state */ item->device_add_refcount++; panel->priv->devices_add_refcount++; g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", device_id, "org.freedesktop.NetworkManager.Device", panel->priv->cancellable, panel_got_device_proxy_cb, item); } /** * panel_remove_device: **/ static void panel_remove_device (CcNetworkPanel *panel, const gchar *device_id) { gboolean ret; gchar *id_tmp; GtkTreeIter iter; GtkTreeModel *model; guint i; PanelDeviceItem *item; /* remove device from array */ for (i=0; ipriv->devices->len; i++) { item = g_ptr_array_index (panel->priv->devices, i); if (g_strcmp0 (item->device_id, device_id) == 0) { g_ptr_array_remove_index_fast (panel->priv->devices, i); break; } } /* remove device from model */ model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); ret = gtk_tree_model_get_iter_first (model, &iter); if (!ret) return; /* get the other elements */ do { gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_ID, &id_tmp, -1); if (g_strcmp0 (id_tmp, device_id) == 0) { gtk_list_store_remove (GTK_LIST_STORE (model), &iter); g_free (id_tmp); break; } g_free (id_tmp); } while (gtk_tree_model_iter_next (model, &iter)); } /** * panel_get_devices_cb: **/ static void panel_get_devices_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); const gchar *object_path; GError *error = NULL; gsize len; GVariantIter iter; GVariant *child; GVariant *result; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_printerr ("Error getting devices: %s\n", error->message); g_error_free (error); return; } child = g_variant_get_child_value (result, 0); len = g_variant_iter_init (&iter, child); if (len == 0) { g_warning ("no devices?!"); goto out; } /* for each entry in the array */ while (g_variant_iter_loop (&iter, "o", &object_path)) { g_debug ("adding network device %s", object_path); panel_add_device (panel, object_path); } out: g_variant_unref (result); g_variant_unref (child); } /** * panel_dbus_manager_signal_cb: **/ static void panel_dbus_manager_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { gchar *object_path = NULL; CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); /* get the new state */ if (g_strcmp0 (signal_name, "StateChanged") == 0) { g_debug ("ensure devices are correct"); /* refresh devices */ panel_refresh_devices (panel); goto out; } /* device added or removed */ if (g_strcmp0 (signal_name, "DeviceAdded") == 0) { g_variant_get (parameters, "(o)", &object_path); panel_add_device (panel, object_path); goto out; } /* device added or removed */ if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) { g_variant_get (parameters, "(o)", &object_path); panel_remove_device (panel, object_path); goto out; } out: g_free (object_path); } /** * panel_refresh_devices: **/ static void panel_refresh_devices (CcNetworkPanel *panel) { GtkListStore *liststore_devices; CcNetworkPanelPrivate *priv = panel->priv; /* clear the existing list */ liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_devices")); gtk_list_store_clear (liststore_devices); /* get the new state */ g_dbus_proxy_call (priv->proxy, "GetDevices", NULL, G_DBUS_CALL_FLAGS_NONE, -1, priv->cancellable, panel_get_devices_cb, panel); } /** * panel_got_network_proxy_cb: **/ static void panel_got_network_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); CcNetworkPanelPrivate *priv = panel->priv; priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (priv->proxy == NULL) { g_printerr ("Error creating proxy: %s\n", error->message); g_error_free (error); select_first_device (panel); goto out; } /* we want to change the UI in reflection to device events */ g_signal_connect (priv->proxy, "g-signal", G_CALLBACK (panel_dbus_manager_signal_cb), user_data); /* refresh devices */ panel_refresh_devices (panel); out: return; } /** * panel_add_devices_columns: **/ static void panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview) { CcNetworkPanelPrivate *priv = panel->priv; GtkCellRenderer *renderer; GtkListStore *liststore_devices; GtkTreeViewColumn *column; /* image */ renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DND, NULL); column = gtk_tree_view_column_new_with_attributes ("", renderer, "icon-name", PANEL_DEVICES_COLUMN_ICON, NULL); gtk_tree_view_append_column (treeview, column); /* column for text */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "wrap-mode", PANGO_WRAP_WORD, NULL); column = gtk_tree_view_column_new_with_attributes ("", renderer, "markup", PANEL_DEVICES_COLUMN_TITLE, NULL); gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_SORT); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_devices")); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore_devices), PANEL_DEVICES_COLUMN_SORT, GTK_SORT_ASCENDING); gtk_tree_view_append_column (treeview, column); gtk_tree_view_column_set_expand (column, TRUE); } /** * panel_set_label_for_variant_string: **/ static void panel_set_label_for_variant_string (GtkWidget *widget, GVariant *variant) { gchar *tmp; g_variant_get (variant, "s", &tmp); gtk_label_set_label (GTK_LABEL (widget), tmp); g_free (tmp); } /** * panel_set_label_for_variant_speed: **/ static void panel_set_label_for_variant_speed (GtkWidget *widget, GVariant *variant) { guint speed; gchar *tmp; /* format with correct scale */ g_variant_get (variant, "u", &speed); if (speed < 1000) { tmp = g_strdup_printf (_("%i Mb/s"), speed); } else { tmp = g_strdup_printf (_("%i Gb/s"), speed / 1000); } gtk_label_set_label (GTK_LABEL (widget), tmp); g_free (tmp); } /** * panel_set_label_for_variant_bitrate: **/ static void panel_set_label_for_variant_bitrate (GtkWidget *widget, GVariant *variant) { guint bitrate; gchar *tmp; /* format with correct scale */ g_variant_get (variant, "u", &bitrate); if (bitrate < 1000) { tmp = g_strdup_printf (_("%i kb/s"), bitrate); } else { tmp = g_strdup_printf (_("%i Mb/s"), bitrate / 1000); } gtk_label_set_label (GTK_LABEL (widget), tmp); g_free (tmp); } /** * panel_set_label_for_variant_ipv4: **/ static void panel_set_label_for_variant_ipv4 (GtkWidget *widget, GVariant *variant) { gchar *ip_str; ip_str = panel_ipv4_to_string (variant); gtk_label_set_label (GTK_LABEL (widget), ip_str); g_free (ip_str); } /** * panel_set_label_for_variant_ipv4_array_array: * * This is some crazy shit. NM sends us the following data type: * "array of [array of [uint32]]" **/ static gboolean panel_set_label_for_variant_ipv4_array_array (GtkWidget *widget, GVariant *variant) { gboolean ret; gchar *tmp; gsize len; GString *string; guint i; GVariantIter iter; GVariant *outer; GVariant *value; string = g_string_new (""); /* get an iter of the outer array */ len = g_variant_iter_init (&iter, variant); /* unwrap the outer array */ outer = g_variant_iter_next_value (&iter); while (outer != NULL) { /* unwrap the inner array */ len = g_variant_n_children (outer); if (len == 0) { g_warning ("invalid ipv4 address on inner?!"); goto out; } for (i=0; ilen > 2) g_string_set_size (string, string->len - 2); /* set label */ gtk_label_set_label (GTK_LABEL (widget), string->str); out: ret = string->len > 0; g_string_free (string, TRUE); return ret; } /** * panel_set_label_for_variant_ipv4_array: * * TNM sends us the following data type "array of [uint32]" **/ static void panel_set_label_for_variant_ipv4_array (GtkWidget *widget, GVariant *variant) { gchar *tmp; gsize len; GString *string; guint i; GVariant *value; string = g_string_new (""); /* unwrap the array */ len = g_variant_n_children (variant); if (len == 0) { g_warning ("invalid ipv4 address on inner?!"); goto out; } for (i=0; ilen > 2) g_string_set_size (string, string->len - 2); /* set label */ gtk_label_set_label (GTK_LABEL (widget), string->str); out: g_string_free (string, TRUE); } /** * panel_set_label_for_variant_ipv6_prefixed_array: * * This is some crazy shit. NM sends us the following data type: * "array of [struct of (array of [byte], uint32, array of [byte])]" **/ static gboolean panel_set_label_for_variant_ipv6_prefixed_array (GtkWidget *widget, GVariant *variant) { GString *string; gchar *tmp; GVariant *outer; GVariantIter iter; gsize len; GVariant *address; guint32 prefix; gboolean ret = FALSE; string = g_string_new (""); /* get an iter of the outer array */ len = g_variant_iter_init (&iter, variant); if (len == 0) { g_debug ("no ipv6 address"); goto out; } /* unwrap the outer array */ outer = g_variant_iter_next_value (&iter); while (outer != NULL) { /* format the address and add to the string */ address = g_variant_get_child_value (outer, 0); tmp = panel_ipv6_to_string (address); g_variant_get_child (outer, 1, "u", &prefix); g_string_append_printf (string, "%s/%i, ", tmp, prefix); outer = g_variant_iter_next_value (&iter); } /* remove trailing space comma */ if (string->len > 2) g_string_set_size (string, string->len - 2); /* set label */ gtk_label_set_label (GTK_LABEL (widget), string->str); out: ret = string->len > 0; g_string_free (string, TRUE); return ret; } /** * panel_set_label_for_variant_ipv6_array: * * NM sends us the following data type: * "array of [array of (byte)]" **/ static gboolean panel_set_label_for_variant_ipv6_array (GtkWidget *widget, GVariant *variant) { gboolean ret = FALSE; GString *string; gchar *tmp; GVariantIter iter; gsize len; GVariant *address; string = g_string_new (""); /* get an iter of the outer array */ len = g_variant_iter_init (&iter, variant); if (len == 0) { g_debug ("no ipv6 address"); goto out; } /* unwrap the outer array */ address = g_variant_iter_next_value (&iter); while (address != NULL) { /* format the address and add to the string */ tmp = panel_ipv6_to_string (address); g_string_append_printf (string, "%s, ", tmp); address = g_variant_iter_next_value (&iter); } /* remove trailing space comma */ if (string->len > 2) g_string_set_size (string, string->len - 2); /* set label */ gtk_label_set_label (GTK_LABEL (widget), string->str); out: ret = string->len > 0; g_string_free (string, TRUE); return ret; } /** * panel_variant_hash_from_variant: **/ static GHashTable * panel_variant_hash_from_variant (GVariant *variant) { GVariantIter *iter = NULL; const gchar *prop_key; GVariant *prop_value; GHashTable *hash_table = NULL; /* insert the new metadata */ g_variant_get (variant, "a{sv}", &iter); if (iter == NULL) goto out; /* remove old entries */ hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref); while (g_variant_iter_loop (iter, "{sv}", &prop_key, &prop_value)) { g_hash_table_insert (hash_table, g_strdup (prop_key), g_variant_ref (prop_value)); } out: return hash_table; } /** * panel_populate_wired_device: **/ static void panel_populate_wired_device (PanelDeviceItem *item) { gboolean ret; GtkWidget *widget; GVariant *hw_address; GVariant *ip4 = NULL; GVariant *ip6 = NULL; GVariant *nameservers = NULL; GVariant *routes = NULL; GVariant *options = NULL; GVariant *speed; GVariant *tmp; GHashTable *hash_table = NULL; CcNetworkPanelPrivate *priv = item->panel->priv; /* set IPv6 */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_ip6")); if (item->proxy_ip6 != NULL) { gtk_widget_show (widget); /* array of (ipdata, prefix, route) */ ip6 = g_dbus_proxy_get_cached_property (item->proxy_ip6, "Addresses"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_ip6")); panel_set_label_for_variant_ipv6_prefixed_array (widget, ip6); /* array of (ipdata, prefix, route) */ routes = g_dbus_proxy_get_cached_property (item->proxy_ip6, "Routes"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_route")); ret = panel_set_label_for_variant_ipv6_prefixed_array (widget, routes); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_route")); gtk_widget_set_visible (widget, ret); /* array of ipdata */ nameservers = g_dbus_proxy_get_cached_property (item->proxy_ip6, "Nameservers"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_dns")); ret = panel_set_label_for_variant_ipv6_array (widget, nameservers); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_dns")); gtk_widget_set_visible (widget, ret); /* Domains = array of string */ //no widget /* i'm not sure how to get this yet */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_subnet")); gtk_widget_hide (widget); } else { gtk_widget_hide (widget); } /* set DHCPv4 */ if (item->proxy_dhcp4 != NULL) { /* array of (string, variant) */ options = g_dbus_proxy_get_cached_property (item->proxy_dhcp4, "Options"); if (options != NULL) { hash_table = panel_variant_hash_from_variant (options); tmp = g_hash_table_lookup (hash_table, "subnet_mask"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_subnet")); if (tmp != NULL) { widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_subnet")); gtk_label_set_label (GTK_LABEL (widget), g_variant_get_string (tmp, NULL)); } gtk_widget_show (widget); } } /* set IPv4 */ if (item->proxy_ip4 != NULL) { /* array of (array of uint32) */ ip4 = g_dbus_proxy_get_cached_property (item->proxy_ip4, "Addresses"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_ip4")); panel_set_label_for_variant_ipv4_array_array (widget, ip4); /* array of (array of uint32) */ routes = g_dbus_proxy_get_cached_property (item->proxy_ip4, "Routes"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_route")); ret = panel_set_label_for_variant_ipv4_array_array (widget, routes); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_route")); gtk_widget_set_visible (widget, ret); /* array of uint32 */ nameservers = g_dbus_proxy_get_cached_property (item->proxy_ip4, "Nameservers"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_dns")); panel_set_label_for_variant_ipv4_array (widget, nameservers); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_dns")); gtk_widget_show (widget); /* Domains = array of string */ //no widget /* WinsServers = array of uint32 */ //no widget /* i'm not sure how to get this yet */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_subnet")); gtk_widget_hide (widget); } else { ip4 = g_dbus_proxy_get_cached_property (item->proxy, "Ip4Address"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_ip4")); panel_set_label_for_variant_ipv4 (widget, ip4); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_route")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_dns")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wired_subnet")); gtk_widget_hide (widget); } /* set MAC */ hw_address = g_dbus_proxy_get_cached_property (item->proxy_additional, "HwAddress"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_mac")); panel_set_label_for_variant_string (widget, hw_address); /* set speed */ speed = g_dbus_proxy_get_cached_property (item->proxy_additional, "Speed"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wired_speed")); panel_set_label_for_variant_speed (widget, speed); if (ip4 != NULL) g_variant_unref (ip4); if (ip6 != NULL) g_variant_unref (ip6); if (routes != NULL) g_variant_unref (routes); if (options != NULL) g_variant_unref (options); if (nameservers != NULL) g_variant_unref (nameservers); if (hash_table != NULL) g_hash_table_unref (hash_table); g_variant_unref (hw_address); g_variant_unref (speed); } /** * panel_populate_wireless_device: **/ static void panel_populate_wireless_device (PanelDeviceItem *item) { gboolean ret; GtkWidget *widget; GVariant *bitrate; GVariant *hw_address; GVariant *ip4; GVariant *ip6; GVariant *nameservers = NULL; GVariant *routes = NULL; CcNetworkPanelPrivate *priv = item->panel->priv; /* set IPv6 */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_ip6")); if (item->proxy_ip6 != NULL) { gtk_widget_show (widget); /* array of (ipdata, prefix, route) */ ip6 = g_dbus_proxy_get_cached_property (item->proxy_ip6, "Addresses"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_ip6")); panel_set_label_for_variant_ipv6_prefixed_array (widget, ip6); /* array of (ipdata, prefix, route) */ routes = g_dbus_proxy_get_cached_property (item->proxy_ip6, "Routes"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_route")); ret = panel_set_label_for_variant_ipv6_prefixed_array (widget, routes); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_route")); gtk_widget_set_visible (widget, ret); /* array of ipdata */ nameservers = g_dbus_proxy_get_cached_property (item->proxy_ip6, "Nameservers"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_dns")); ret = panel_set_label_for_variant_ipv6_array (widget, nameservers); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_dns")); gtk_widget_set_visible (widget, ret); /* Domains = array of string */ //no widget } else { gtk_widget_hide (widget); } /* set IPv4 */ if (item->proxy_ip4 != NULL) { /* array of (array of uint32) */ ip4 = g_dbus_proxy_get_cached_property (item->proxy_ip4, "Addresses"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_ip4")); panel_set_label_for_variant_ipv4_array_array (widget, ip4); /* array of (array of uint32) */ routes = g_dbus_proxy_get_cached_property (item->proxy_ip4, "Routes"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_route")); panel_set_label_for_variant_ipv4_array_array (widget, routes); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_route")); gtk_widget_show (widget); /* array of uint32 */ nameservers = g_dbus_proxy_get_cached_property (item->proxy_ip4, "Nameservers"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_dns")); panel_set_label_for_variant_ipv4_array (widget, nameservers); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_dns")); gtk_widget_show (widget); /* Domains = array of string */ //no widget /* WinsServers = array of uint32 */ //no widget } else { ip4 = g_dbus_proxy_get_cached_property (item->proxy, "Ip4Address"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_ip4")); panel_set_label_for_variant_ipv4 (widget, ip4); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_route")); gtk_widget_hide (widget); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_wireless_dns")); gtk_widget_hide (widget); } /* set MAC */ hw_address = g_dbus_proxy_get_cached_property (item->proxy_additional, "HwAddress"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_mac")); panel_set_label_for_variant_string (widget, hw_address); /* set speed */ bitrate = g_dbus_proxy_get_cached_property (item->proxy_additional, "Bitrate"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_speed")); panel_set_label_for_variant_bitrate (widget, bitrate); g_variant_unref (ip4); if (ip6 != NULL) g_variant_unref (ip6); if (routes != NULL) g_variant_unref (routes); if (nameservers != NULL) g_variant_unref (nameservers); g_variant_unref (hw_address); g_variant_unref (bitrate); } /** * panel_populate_mobilebb_device: **/ static void panel_populate_mobilebb_device (PanelDeviceItem *item) { GtkWidget *widget; GVariant *ip4; CcNetworkPanelPrivate *priv = item->panel->priv; /* set IP */ ip4 = g_dbus_proxy_get_cached_property (item->proxy, "Ip4Address"); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_wireless_ip")); panel_set_label_for_variant_ipv4 (widget, ip4); /* use data from ModemManager */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_mobilebb_provider")); gtk_label_set_text (GTK_LABEL (widget), item->operator_name); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_mobilebb_imei")); gtk_label_set_text (GTK_LABEL (widget), item->modem_imei); /* I'm not sure where to get this data from */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_mobilebb_speed")); gtk_widget_set_visible (widget, FALSE); g_variant_unref (ip4); } /** * panel_device_refresh_item_ui: **/ static void panel_device_refresh_item_ui (PanelDeviceItem *item) { GtkWidget *widget; guint state; GVariant *variant_id; GVariant *variant_state; CcNetworkPanelPrivate *priv = item->panel->priv; /* we have a new device */ g_debug ("selected device is: %s", item->device_id); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_device_header")); gtk_widget_set_visible (widget, TRUE); variant_id = g_dbus_proxy_get_cached_property (item->proxy, "Interface"); // g_variant_get (variant_id, "s", &interface); variant_state = g_dbus_proxy_get_cached_property (item->proxy, "State"); g_variant_get (variant_state, "u", &state); g_debug ("device %s type %i @ %s", item->device_id, item->type, item->udi); /* set device icon */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "image_device")); gtk_image_set_from_icon_name (GTK_IMAGE (widget), panel_device_type_to_icon_name (item->type), GTK_ICON_SIZE_DIALOG); /* set device kind */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_device")); gtk_label_set_label (GTK_LABEL (widget), panel_device_type_to_localized_string (item->type)); /* set device state */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_status")); gtk_label_set_label (GTK_LABEL (widget), panel_device_state_to_localized_string (state)); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "notebook_types")); if (item->type == NM_DEVICE_TYPE_ETHERNET) { gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0); panel_populate_wired_device (item); } else if (item->type == NM_DEVICE_TYPE_WIFI) { gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1); panel_populate_wireless_device (item); } else if (item->type == NM_DEVICE_TYPE_GSM || item->type == NM_DEVICE_TYPE_CDMA) { gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 4); panel_populate_mobilebb_device (item); } g_variant_unref (variant_state); g_variant_unref (variant_id); } /** * panel_devices_treeview_clicked_cb: **/ static void panel_devices_treeview_clicked_cb (GtkTreeSelection *selection, CcNetworkPanel *panel) { GtkTreeIter iter; GtkTreeModel *model; GtkWidget *widget; PanelDeviceItem *item; CcNetworkPanelPrivate *priv = panel->priv; /* will only work in single or browse selection mode! */ if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { g_debug ("no row selected"); goto out; } /* get id */ gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_COMPOSITE_DEVICE, &item, -1); /* this is the proxy settings device */ if (item == NULL) { widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hbox_device_header")); gtk_widget_set_visible (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "notebook_types")); gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2); /* save so we ignore */ g_free (priv->current_device); priv->current_device = NULL; goto out; } /* save so we can update */ g_free (priv->current_device); priv->current_device = g_strdup (item->device_id); /* refresh item */ panel_device_refresh_item_ui (item); out: return; } /** * panel_add_proxy_device: **/ static void panel_add_proxy_device (CcNetworkPanel *panel) { gchar *title; GtkListStore *liststore_devices; GtkTreeIter iter; liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); title = g_strdup_printf ("%s", _("Network proxy")); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, PANEL_DEVICES_COLUMN_ICON, "preferences-system-network", PANEL_DEVICES_COLUMN_TITLE, title, PANEL_DEVICES_COLUMN_ID, NULL, PANEL_DEVICES_COLUMN_SORT, "9", PANEL_DEVICES_COLUMN_TOOLTIP, _("Set the system proxy settings"), PANEL_DEVICES_COLUMN_COMPOSITE_DEVICE, NULL, -1); g_free (title); } /** * panel_enable_cb: **/ static void panel_enable_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GError *error = NULL; GVariant *result; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { g_printerr ("Error enabling NetworkManager: %s\n", error->message); g_error_free (error); goto out; } out: if (result != NULL) g_variant_unref (result); } /** * cc_network_panel_notify_enable_active_cb: **/ static void cc_network_panel_notify_enable_active_cb (GtkSwitch *sw, GParamSpec *pspec, CcNetworkPanel *panel) { gboolean enable; CcNetworkPanelPrivate *priv = panel->priv; /* get enabled state */ enable = !gtk_switch_get_active (sw); /* get the new state */ g_dbus_proxy_call (priv->proxy, "Enable", g_variant_new ("(b)", enable), G_DBUS_CALL_FLAGS_NONE, -1, priv->cancellable, panel_enable_cb, panel); } /** * cc_network_panel_init: **/ static void cc_network_panel_init (CcNetworkPanel *panel) { GError *error; gint value; GSettings *settings_tmp; GtkAdjustment *adjustment; GtkCellRenderer *renderer; GtkComboBox *combobox; GtkTreeSelection *selection; GtkTreeSortable *sortable; GtkWidget *widget; GtkStyleContext *context; panel->priv = NETWORK_PANEL_PRIVATE (panel); panel->priv->builder = gtk_builder_new (); error = NULL; gtk_builder_add_from_file (panel->priv->builder, GNOMECC_UI_DIR "/network.ui", &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } panel->priv->cancellable = g_cancellable_new (); panel->priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify )panel_free_device_item); /* get initial icon state */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", panel->priv->cancellable, panel_got_network_proxy_cb, panel); panel->priv->proxy_settings = g_settings_new ("org.gnome.system.proxy"); g_signal_connect (panel->priv->proxy_settings, "changed", G_CALLBACK (panel_settings_changed), panel); /* actions */ value = g_settings_get_enum (panel->priv->proxy_settings, "mode"); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "combobox_proxy_mode")); panel_set_value_for_combo (panel, GTK_COMBO_BOX (widget), value); g_signal_connect (widget, "changed", G_CALLBACK (panel_proxy_mode_combo_changed_cb), panel); /* bind the proxy values */ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "entry_proxy_url")); g_settings_bind (panel->priv->proxy_settings, "autoconfig-url", widget, "text", G_SETTINGS_BIND_DEFAULT); /* bind the proxy values */ settings_tmp = g_settings_new ("org.gnome.system.proxy.http"); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "entry_proxy_http")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder, "adjustment_proxy_port_http")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* bind the proxy values */ settings_tmp = g_settings_new ("org.gnome.system.proxy.https"); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "entry_proxy_https")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder, "adjustment_proxy_port_https")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* bind the proxy values */ settings_tmp = g_settings_new ("org.gnome.system.proxy.ftp"); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "entry_proxy_ftp")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder, "adjustment_proxy_port_ftp")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); /* bind the proxy values */ settings_tmp = g_settings_new ("org.gnome.system.proxy.socks"); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "entry_proxy_socks")); g_settings_bind (settings_tmp, "host", widget, "text", G_SETTINGS_BIND_DEFAULT); adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder, "adjustment_proxy_port_socks")); g_settings_bind (settings_tmp, "port", adjustment, "value", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings_tmp); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "treeview_devices")); panel_add_devices_columns (panel, GTK_TREE_VIEW (widget)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); g_signal_connect (selection, "changed", G_CALLBACK (panel_devices_treeview_clicked_cb), panel); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "devices_scrolledwindow")); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "devices_toolbar")); context = gtk_widget_get_style_context (widget); gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP); /* add the virtual proxy device */ panel_add_proxy_device (panel); /* setup wireless combobox model */ combobox = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder, "combobox_network_name")); renderer = panel_cell_renderer_mode_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, "mode", PANEL_WIRELESS_COLUMN_MODE, NULL); /* sort networks in drop down */ sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (panel->priv->builder, "liststore_wireless_network")); gtk_tree_sortable_set_sort_column_id (sortable, PANEL_WIRELESS_COLUMN_SORT, GTK_SORT_ASCENDING); renderer = panel_cell_renderer_signal_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, "signal", PANEL_WIRELESS_COLUMN_STRENGTH, NULL); /* disable for now */ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "add_toolbutton")); gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "remove_toolbutton")); gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "button_unlock")); gtk_widget_set_sensitive (widget, FALSE); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "switch_flight_mode")); g_signal_connect (GTK_SWITCH (widget), "notify::active", G_CALLBACK (cc_network_panel_notify_enable_active_cb), panel); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "notebook_types")); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "vbox1")); gtk_widget_reparent (widget, (GtkWidget *) panel); } void cc_network_panel_register (GIOModule *module) { cc_network_panel_register_type (G_TYPE_MODULE (module)); g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, CC_TYPE_NETWORK_PANEL, "network", 0); }