[gnome-control-center] network: Add new hotspot creation dialog
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] network: Add new hotspot creation dialog
- Date: Tue, 17 Sep 2019 12:15:22 +0000 (UTC)
commit 642be837984210b3683ccb1d6e3802854fdea02a
Author: Mohammed Sadiq <sadiq sadiqpk org>
Date: Tue Sep 17 12:15:11 2019 +0000
network: Add new hotspot creation dialog
panels/network/cc-wifi-hotspot-dialog.c | 519 +++++++++++++++++++++++++++++++
panels/network/cc-wifi-hotspot-dialog.h | 44 +++
panels/network/cc-wifi-hotspot-dialog.ui | 141 +++++++++
panels/network/meson.build | 4 +-
panels/network/net-device-wifi.c | 312 +++----------------
panels/network/network.gresource.xml | 1 +
6 files changed, 748 insertions(+), 273 deletions(-)
---
diff --git a/panels/network/cc-wifi-hotspot-dialog.c b/panels/network/cc-wifi-hotspot-dialog.c
new file mode 100644
index 000000000..6f49dfa6f
--- /dev/null
+++ b/panels/network/cc-wifi-hotspot-dialog.c
@@ -0,0 +1,519 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* cc-wifi-hotspot-dialog.c
+ *
+ * Copyright 2019 Purism SPC
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s):
+ * Mohammed Sadiq <sadiq sadiqpk org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "cc-wifi-hotspot-dialog"
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <libmm-glib.h>
+
+#include "list-box-helper.h"
+#include "connection-editor/ui-helpers.h"
+#include "cc-wifi-hotspot-dialog.h"
+#include "cc-network-resources.h"
+
+/**
+ * @short_description: WWAN network type selection dialog
+ */
+
+struct _CcWifiHotspotDialog
+{
+ GtkMessageDialog parent_instance;
+
+ GtkLabel *connection_label;
+ GtkEntry *name_entry;
+ GtkEntry *password_entry;
+ GtkLabel *error_label;
+ GtkButton *ok_button;
+
+ NMDeviceWifi *device;
+ NMConnection *connection;
+ gchar *host_name;
+ gboolean wpa_supported; /* WPA/WPA2 supported */
+};
+
+G_DEFINE_TYPE (CcWifiHotspotDialog, cc_wifi_hotspot_dialog, GTK_TYPE_MESSAGE_DIALOG)
+
+static gchar *
+get_random_wpa_key (void)
+{
+ gchar *key;
+ gint i;
+
+ key = g_malloc (10 * sizeof (key));
+ for (i = 0; i < 8; i++)
+ {
+ gint c = 0;
+ /* too many non alphanumeric characters are hard to remember for humans */
+ while (!g_ascii_isalnum (c))
+ c = g_random_int_range (33, 126);
+
+ key[i] = (gchar) c;
+ }
+ key[i] = '\0';
+
+ return key;
+}
+
+static gchar *
+get_random_wep_key (void)
+{
+ const gchar *hexdigits = "0123456789abcdef";
+ gchar *key;
+ gint i;
+
+ key = g_malloc (12 * sizeof (key));
+
+ /* generate a 10-digit hex WEP key */
+ for (i = 0; i < 10; i++)
+ {
+ gint digit;
+ digit = g_random_int_range (0, 16);
+ key[i] = hexdigits[digit];
+ }
+
+ key[i] = '\0';
+
+ return key;
+}
+
+static void
+wifi_hotspot_dialog_update_main_label (CcWifiHotspotDialog *self)
+{
+ NMAccessPoint *ap;
+ GBytes *ssid = NULL;
+ g_autofree gchar *active_ssid = NULL;
+ g_autofree gchar *escape = NULL;
+ g_autofree gchar *label = NULL;
+
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ if (!self->device)
+ return;
+
+ ap = nm_device_wifi_get_active_access_point (self->device);
+
+ if (ap)
+ ssid = nm_access_point_get_ssid (ap);
+ if (ssid)
+ active_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
+
+ if (!active_ssid || !*active_ssid)
+ return;
+
+ escape = g_markup_escape_text (active_ssid, -1);
+ /* TRANSLATORS: ā%sā is a Wi-Fi Network(SSID) name */
+ label = g_strdup_printf (_("Turning on the hotspot will disconnect from <b>%s</b>, "
+ "and it will not be possible to access the internet through Wi-Fi."), escape);
+ gtk_label_set_markup (self->connection_label, label);
+}
+
+static void
+wifi_hotspot_dialog_update_entries (CcWifiHotspotDialog *self)
+{
+ NMSettingWirelessSecurity *security_setting;
+ NMSettingWireless *setting;
+ GBytes *ssid;
+ g_autoptr(GVariant) secrets = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autofree gchar *ssid_text = NULL;
+ const gchar *key;
+
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ gtk_entry_set_text (self->name_entry, "");
+ gtk_entry_set_text (self->password_entry, "");
+
+ if (!self->connection)
+ return;
+
+ setting = nm_connection_get_setting_wireless (self->connection);
+ security_setting = nm_connection_get_setting_wireless_security (self->connection);
+
+ ssid = nm_setting_wireless_get_ssid (setting);
+ ssid_text = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
+
+ if (!ssid_text && self->host_name)
+ ssid_text = g_strdup (self->host_name);
+
+ if (ssid_text)
+ gtk_entry_set_text (self->name_entry, ssid_text);
+
+ if (!NM_IS_REMOTE_CONNECTION (self->connection))
+ return;
+
+ /* Secrets may not be already loaded, we have to manually load it. */
+ secrets = nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (self->connection),
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL, &error);
+ if (error)
+ {
+ g_warning ("Error loading secrets: %s", error->message);
+ return;
+ }
+
+ nm_connection_update_secrets (self->connection,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ secrets, &error);
+ if (error)
+ {
+ g_warning ("Error updating secrets: %s", error->message);
+ return;
+ }
+
+ if (self->wpa_supported)
+ key = nm_setting_wireless_security_get_psk (security_setting);
+ else
+ key = nm_setting_wireless_security_get_wep_key (security_setting, 0);
+
+ if (key)
+ gtk_entry_set_text (self->password_entry, key);
+
+ nm_connection_clear_secrets (self->connection);
+}
+
+static gboolean
+hotspot_password_is_valid (CcWifiHotspotDialog *self,
+ const gchar *password)
+{
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ if (!self->device)
+ return FALSE;
+
+ if (!password || !*password)
+ return TRUE;
+
+ if (self->wpa_supported)
+ return nm_utils_wpa_psk_valid (password);
+ else
+ return nm_utils_wep_key_valid (password, NM_WEP_KEY_TYPE_KEY);
+}
+
+static void
+hotspot_entry_changed_cb (CcWifiHotspotDialog *self)
+{
+ const gchar *ssid, *password, *error_label;
+ gboolean valid_ssid, valid_password;
+
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ valid_ssid = valid_password = FALSE;
+ ssid = gtk_entry_get_text (self->name_entry);
+ password = gtk_entry_get_text (self->password_entry);
+
+ if (ssid && *ssid)
+ {
+ valid_ssid = TRUE;
+ widget_unset_error (GTK_WIDGET (self->name_entry));
+ }
+ else
+ widget_set_error (GTK_WIDGET (self->name_entry));
+
+ valid_password = hotspot_password_is_valid (self, password);
+
+ if (valid_password)
+ {
+ error_label = "";
+ widget_unset_error (GTK_WIDGET (self->password_entry));
+ }
+ else
+ {
+ error_label = _("Must have a minimum of 8 characters");
+ widget_set_error (GTK_WIDGET(self->password_entry));
+ }
+
+ gtk_label_set_label (self->error_label, error_label);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->ok_button),
+ valid_ssid && valid_password);
+}
+
+static void
+generate_password_clicked_cb (CcWifiHotspotDialog *self)
+{
+ g_autofree gchar *key = NULL;
+
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ if (self->wpa_supported)
+ key = get_random_wpa_key ();
+ else
+ key = get_random_wep_key ();
+
+ gtk_entry_set_text (self->password_entry, key);
+}
+
+static void
+hotspot_update_wireless_settings (CcWifiHotspotDialog *self)
+{
+ NMSettingWireless *setting;
+ g_autoptr(GBytes) ssid = NULL;
+ const gchar *ssid_text;
+ NMDeviceWifiCapabilities capabilities;
+
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ if (nm_connection_get_setting_wireless (self->connection) == NULL)
+ nm_connection_add_setting (self->connection, nm_setting_wireless_new ());
+
+ setting = nm_connection_get_setting_wireless (self->connection);
+
+ capabilities = nm_device_wifi_get_capabilities (self->device);
+ if (capabilities & NM_WIFI_DEVICE_CAP_AP)
+ g_object_set (setting, "mode", "ap", NULL);
+ else
+ g_object_set (setting, "mode", "adhoc", NULL);
+
+ ssid_text = gtk_entry_get_text (self->name_entry);
+ ssid = g_bytes_new (ssid_text, strlen (ssid_text));
+ g_object_set (setting, "ssid", ssid, NULL);
+}
+
+static void
+hotspot_update_wireless_security_settings (CcWifiHotspotDialog *self)
+{
+ NMSettingWirelessSecurity *setting;
+ const gchar *value, *key_type;
+
+ g_assert (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ if (nm_connection_get_setting_wireless_security (self->connection) == NULL)
+ nm_connection_add_setting (self->connection, nm_setting_wireless_security_new ());
+
+ setting = nm_connection_get_setting_wireless_security (self->connection);
+ nm_setting_wireless_security_clear_protos (setting);
+ nm_setting_wireless_security_clear_pairwise (setting);
+ nm_setting_wireless_security_clear_groups (setting);
+ value = gtk_entry_get_text (self->password_entry);
+
+ if (self->wpa_supported)
+ key_type = "psk";
+ else
+ key_type = "wep-key0";
+
+ if (self->wpa_supported)
+ g_object_set (setting, "key-mgmt", "wpa-psk", NULL);
+ else
+ g_object_set (setting,
+ "key-mgmt", "none",
+ "wep-key-type", NM_WEP_KEY_TYPE_KEY,
+ NULL);
+
+ if (!value || !*value)
+ {
+ g_autofree gchar *key = NULL;
+
+ if (self->wpa_supported)
+ key = get_random_wpa_key ();
+ else
+ key = get_random_wep_key ();
+
+ g_object_set (setting, key_type, key, NULL);
+ }
+ else
+ g_object_set (setting, key_type, value, NULL);
+
+ if (self->wpa_supported)
+ {
+ NMDeviceWifiCapabilities caps;
+
+ caps = nm_device_wifi_get_capabilities (self->device);
+
+ if (caps & NM_WIFI_DEVICE_CAP_RSN)
+ {
+ nm_setting_wireless_security_add_proto (setting, "rsn");
+ nm_setting_wireless_security_add_pairwise (setting, "ccmp");
+ nm_setting_wireless_security_add_group (setting, "ccmp");
+ }
+ else if (caps & NM_WIFI_DEVICE_CAP_WPA)
+ {
+ nm_setting_wireless_security_add_proto (setting, "wpa");
+ nm_setting_wireless_security_add_pairwise (setting, "tkip");
+ nm_setting_wireless_security_add_group (setting, "tkip");
+ }
+ }
+}
+
+static void
+cc_wifi_hotspot_dialog_finalize (GObject *object)
+{
+ CcWifiHotspotDialog *self = (CcWifiHotspotDialog *)object;
+
+ g_free (self->host_name);
+ g_clear_object (&self->device);
+ g_clear_object (&self->connection);
+
+ G_OBJECT_CLASS (cc_wifi_hotspot_dialog_parent_class)->finalize (object);
+}
+
+static void
+cc_wifi_hotspot_dialog_show (GtkWidget *widget)
+{
+ CcWifiHotspotDialog *self = (CcWifiHotspotDialog *)widget;
+ g_warn_if_fail (self->device != NULL);
+
+ gtk_widget_grab_focus (GTK_WIDGET (self->ok_button));
+ wifi_hotspot_dialog_update_entries (self);
+
+ if (!self->connection)
+ if (self->host_name)
+ gtk_entry_set_text (self->name_entry, self->host_name);
+
+ GTK_WIDGET_CLASS (cc_wifi_hotspot_dialog_parent_class)->show (widget);
+}
+
+static void
+cc_wifi_hotspot_dialog_response (GtkDialog *dialog,
+ gint response_id)
+{
+ CcWifiHotspotDialog *self = CC_WIFI_HOTSPOT_DIALOG (dialog);
+ NMSetting *setting;
+
+ if (response_id != GTK_RESPONSE_APPLY)
+ return;
+
+ if (!self->connection)
+ self->connection = NM_CONNECTION (nm_simple_connection_new ());
+
+ if (nm_connection_get_setting_connection (self->connection) == NULL)
+ {
+ setting = nm_setting_connection_new ();
+ g_object_set (setting,
+ "type", "802-11-wireless",
+ "id", "Hotspot",
+ "autoconnect", FALSE,
+ NULL);
+ nm_connection_add_setting (self->connection, setting);
+ }
+
+ if (nm_connection_get_setting_ip4_config (self->connection) == NULL)
+ {
+ setting = nm_setting_ip4_config_new ();
+ g_object_set (setting, "method", "shared", NULL);
+ nm_connection_add_setting (self->connection, setting);
+ }
+
+ hotspot_update_wireless_settings (self);
+ hotspot_update_wireless_security_settings (self);
+}
+
+static void
+cc_wifi_hotspot_dialog_class_init (CcWifiHotspotDialogClass *klass)
+{
+ GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = cc_wifi_hotspot_dialog_finalize;
+
+ widget_class->show = cc_wifi_hotspot_dialog_show;
+ dialog_class->response = cc_wifi_hotspot_dialog_response;
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+
"/org/gnome/control-center/network/cc-wifi-hotspot-dialog.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcWifiHotspotDialog, connection_label);
+ gtk_widget_class_bind_template_child (widget_class, CcWifiHotspotDialog, name_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcWifiHotspotDialog, password_entry);
+ gtk_widget_class_bind_template_child (widget_class, CcWifiHotspotDialog, error_label);
+ gtk_widget_class_bind_template_child (widget_class, CcWifiHotspotDialog, ok_button);
+
+ gtk_widget_class_bind_template_callback (widget_class, hotspot_entry_changed_cb);
+ gtk_widget_class_bind_template_callback (widget_class, generate_password_clicked_cb);
+}
+
+static void
+cc_wifi_hotspot_dialog_init (CcWifiHotspotDialog *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+CcWifiHotspotDialog *
+cc_wifi_hotspot_dialog_new (GtkWindow *parent_window)
+{
+ g_return_val_if_fail (GTK_IS_WINDOW (parent_window), NULL);
+
+ return g_object_new (CC_TYPE_WIFI_HOTSPOT_DIALOG,
+ "transient-for", parent_window,
+ "message-type", GTK_MESSAGE_OTHER,
+ NULL);
+}
+
+void
+cc_wifi_hotspot_dialog_set_hostname (CcWifiHotspotDialog *self,
+ const gchar *host_name)
+{
+ g_return_if_fail (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+
+ g_free (self->host_name);
+ self->host_name = g_strdup (host_name);
+}
+
+void
+cc_wifi_hotspot_dialog_set_device (CcWifiHotspotDialog *self,
+ NMDeviceWifi *device)
+{
+ g_return_if_fail (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+ g_return_if_fail (NM_IS_DEVICE_WIFI (device));
+
+ g_set_object (&self->device, device);
+
+ if (device)
+ {
+ NMDeviceWifiCapabilities caps;
+
+ caps = nm_device_wifi_get_capabilities (device);
+ self->wpa_supported = FALSE;
+
+ if (caps & NM_WIFI_DEVICE_CAP_AP)
+ if (caps & (NM_WIFI_DEVICE_CAP_RSN | NM_WIFI_DEVICE_CAP_WPA))
+ self->wpa_supported = TRUE;
+ }
+
+ wifi_hotspot_dialog_update_main_label (self);
+}
+
+NMConnection *
+cc_wifi_hotspot_dialog_get_connection (CcWifiHotspotDialog *self)
+{
+ g_return_val_if_fail (CC_IS_WIFI_HOTSPOT_DIALOG (self), NULL);
+
+ return self->connection;
+}
+
+void
+cc_wifi_hotspot_dialog_set_connection (CcWifiHotspotDialog *self,
+ NMConnection *connection)
+{
+ NMSettingWireless *setting;
+
+ g_return_if_fail (CC_IS_WIFI_HOTSPOT_DIALOG (self));
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ setting = nm_connection_get_setting_wireless (connection);
+ g_return_if_fail (setting);
+
+ g_set_object (&self->connection, connection);
+}
diff --git a/panels/network/cc-wifi-hotspot-dialog.h b/panels/network/cc-wifi-hotspot-dialog.h
new file mode 100644
index 000000000..585d7f1d0
--- /dev/null
+++ b/panels/network/cc-wifi-hotspot-dialog.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* wifi-hotspot-dialog.h
+ *
+ * Copyright 2019 Purism SPC
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s):
+ * Mohammed Sadiq <sadiq sadiqpk org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+#include <NetworkManager.h>
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_WIFI_HOTSPOT_DIALOG (cc_wifi_hotspot_dialog_get_type())
+G_DECLARE_FINAL_TYPE (CcWifiHotspotDialog, cc_wifi_hotspot_dialog, CC, WIFI_HOTSPOT_DIALOG, GtkMessageDialog)
+
+CcWifiHotspotDialog *cc_wifi_hotspot_dialog_new (GtkWindow *parent_window);
+void cc_wifi_hotspot_dialog_set_hostname (CcWifiHotspotDialog *self,
+ const gchar *host_name);
+void cc_wifi_hotspot_dialog_set_device (CcWifiHotspotDialog *self,
+ NMDeviceWifi *device);
+NMConnection *cc_wifi_hotspot_dialog_get_connection (CcWifiHotspotDialog *self);
+void cc_wifi_hotspot_dialog_set_connection (CcWifiHotspotDialog *self,
+ NMConnection *connection);
+
+G_END_DECLS
diff --git a/panels/network/cc-wifi-hotspot-dialog.ui b/panels/network/cc-wifi-hotspot-dialog.ui
new file mode 100644
index 000000000..f062ad5ff
--- /dev/null
+++ b/panels/network/cc-wifi-hotspot-dialog.ui
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="CcWifiHotspotDialog" parent="GtkMessageDialog">
+ <property name="modal">1</property>
+ <property name="destroy-with-parent">1</property>
+ <property name="text" translatable="yes" comments="Translate the text only"><big><b>Turn On
Wi-Fi Hotspot?</b></big></property>
+ <property name="use-markup">1</property>
+ <property name="message-type">other</property>
+ <signal name="delete-event" handler="gtk_widget_hide_on_delete"/>
+
+ <child internal-child="message_area">
+ <object class="GtkBox">
+ <property name="visible">1</property>
+ <property name="margin-top">0</property>
+
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">1</property>
+ <property name="wrap">1</property>
+ <property name="max-width-chars">50</property>
+ <property name="label" translatable="yes">Wi-Fi hotspot allows others to share your internet
connection, by creating a Wi-Fi network that they can connect to. To do this, you must have an internet
connection through a source other than Wi-Fi.</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="connection_label">
+ <property name="visible">1</property>
+ <property name="margin-bottom">18</property>
+ <property name="wrap">1</property>
+ <property name="max-width-chars">40</property>
+ <property name="use-markup">1</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">1</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+
+ <!-- Hotspot SSID Name -->
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Network Name</property>
+ <property name="halign">end</property>
+ <property name="visible">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name_entry">
+ <property name="visible">1</property>
+ <property name="hexpand">1</property>
+ <property name="max-length">64</property>
+ <signal name="changed" handler="hotspot_entry_changed_cb" swapped="yes" />
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+
+ <!-- Hotspot Password -->
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Password</property>
+ <property name="halign">end</property>
+ <property name="visible">1</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="password_entry">
+ <property name="visible">1</property>
+ <property name="max-length">64</property>
+ <property name="secondary-icon-name">view-refresh-symbolic</property>
+ <property name="secondary-icon-tooltip-text" translatable="yes">Generate Random
Password</property>
+ <property name="placeholder-text" translatable="yes">Autogenerate Password</property>
+ <signal name="icon-press" handler="generate_password_clicked_cb" swapped="yes" />
+ <signal name="changed" handler="hotspot_entry_changed_cb" swapped="yes" />
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+
+ <!-- Error Label -->
+ <child>
+ <object class="GtkLabel" id="error_label">
+ <property name="halign">start</property>
+ <property name="visible">1</property>
+ <style>
+ <class name="dim-label" />
+ </style>
+ <attributes>
+ <attribute name="scale" value="0.83"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">2</property>
+ </packing>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child type="action">
+ <object class="GtkButton" id="cancel_button">
+ <property name="visible">1</property>
+ <property name="use-underline">1</property>
+ <property name="label" translatable="yes">_Cancel</property>
+ </object>
+ </child>
+ <child type="action">
+ <object class="GtkButton" id="ok_button">
+ <property name="visible">1</property>
+ <property name="can-default">1</property>
+ <property name="use-underline">1</property>
+ <property name="label" translatable="yes">_Turn On</property>
+ </object>
+ </child>
+
+ <action-widgets>
+ <action-widget response="cancel">cancel_button</action-widget>
+ <action-widget response="apply" default="true">ok_button</action-widget>
+ </action-widgets>
+ </template>
+</interface>
diff --git a/panels/network/meson.build b/panels/network/meson.build
index 576fdd3c3..18582f6c3 100644
--- a/panels/network/meson.build
+++ b/panels/network/meson.build
@@ -38,6 +38,7 @@ sources = files(
'cc-wifi-connection-row.c',
'cc-wifi-connection-list.c',
'cc-wifi-panel.c',
+ 'cc-wifi-hotspot-dialog.c',
'net-device.c',
'net-device-ethernet.c',
'net-device-mobile.c',
@@ -54,6 +55,7 @@ resource_data = files(
'cc-network-panel.ui',
'cc-wifi-connection-row.ui',
'cc-wifi-panel.ui',
+ 'cc-wifi-hotspot-dialog.ui',
'network-ethernet.ui',
'network-mobile.ui',
'network-proxy.ui',
@@ -78,4 +80,4 @@ network_panel_lib = static_library(
c_args: cflags,
link_with: libconnection_editor
)
-panels_libs += network_panel_lib
\ No newline at end of file
+panels_libs += network_panel_lib
diff --git a/panels/network/net-device-wifi.c b/panels/network/net-device-wifi.c
index d66492a94..9efed8cc6 100644
--- a/panels/network/net-device-wifi.c
+++ b/panels/network/net-device-wifi.c
@@ -32,6 +32,7 @@
#include <NetworkManager.h>
#include <polkit/polkit.h>
+#include "cc-wifi-hotspot-dialog.h"
#include "list-box-helper.h"
#include "hostname-helper.h"
#include "network-dialogs.h"
@@ -64,6 +65,7 @@ struct _NetDeviceWifi
gchar *selected_ssid_title;
gchar *selected_connection_id;
gchar *selected_ap_id;
+ CcWifiHotspotDialog *hotspot_dialog;
gint64 last_scan;
gboolean scanning;
@@ -797,71 +799,6 @@ get_hostname (void)
return g_variant_dup_string (inner, NULL);
}
-static GBytes *
-generate_ssid_for_hotspot (NetDeviceWifi *device_wifi)
-{
- GBytes *ssid_bytes;
- g_autofree gchar *hostname = NULL;
- gchar *ssid;
-
- hostname = get_hostname ();
- ssid = pretty_hostname_to_ssid (hostname);
-
- ssid_bytes = g_bytes_new_with_free_func (ssid,
- strlen (ssid),
- g_free,
- NULL);
-
- return ssid_bytes;
-}
-
-#define WPA_PASSKEY_SIZE 8
-static void
-set_wpa_key (NMSettingWirelessSecurity *sws)
-{
- /* generate a 8-chars ASCII WPA key */
- char key[WPA_PASSKEY_SIZE + 1];
- guint i;
-
- for (i = 0; i < WPA_PASSKEY_SIZE; i++) {
- gint c;
- c = g_random_int_range (33, 126);
- /* too many non alphanumeric characters are hard to remember for humans */
- while (!g_ascii_isalnum (c))
- c = g_random_int_range (33, 126);
-
- key[i] = (gchar) c;
- }
- key[WPA_PASSKEY_SIZE] = '\0';
-
- g_object_set (sws,
- "key-mgmt", "wpa-psk",
- "psk", key,
- NULL);
-}
-
-static void
-set_wep_key (NMSettingWirelessSecurity *sws)
-{
- gchar key[11];
- gint i;
- const gchar *hexdigits = "0123456789abcdef";
-
- /* generate a 10-digit hex WEP key */
- for (i = 0; i < 10; i++) {
- gint digit;
- digit = g_random_int_range (0, 16);
- key[i] = hexdigits[digit];
- }
- key[10] = 0;
-
- g_object_set (sws,
- "key-mgmt", "none",
- "wep-key0", key,
- "wep-key-type", NM_WEP_KEY_TYPE_KEY,
- NULL);
-}
-
static gboolean
is_hotspot_connection (NMConnection *connection)
{
@@ -1002,228 +939,59 @@ overwrite_ssid_cb (GObject *source_object,
device_wifi);
}
-static void
-start_shared_connection (NetDeviceWifi *device_wifi)
-{
- NMConnection *hotspot_connection;
- g_autoptr(NMConnection) c = NULL;
- NMSettingConnection *sc;
- NMSettingWireless *sw;
- NMSettingIP4Config *sip;
- NMSettingWirelessSecurity *sws;
- NMDevice *device;
- g_autoptr(GBytes) ssid = NULL;
- const gchar *str_mac;
- struct ether_addr *bin_mac;
- NMClient *client;
- const char *mode;
- NMDeviceWifiCapabilities caps;
- GCancellable *cancellable;
-
- device = net_device_get_nm_device (NET_DEVICE (device_wifi));
- g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI);
-
- hotspot_connection = net_device_wifi_get_hotspot_connection (device_wifi);
-
- ssid = generate_ssid_for_hotspot (device_wifi);
-
- client = net_object_get_client (NET_OBJECT (device_wifi));
- cancellable = net_object_get_cancellable (NET_OBJECT (device_wifi));
- if (hotspot_connection != NULL) {
- NMSettingWireless *sw;
- const char *c_path;
- NMRemoteConnection *connection;
-
- sw = nm_connection_get_setting_wireless (hotspot_connection);
- g_object_set (sw, "ssid", ssid, NULL);
-
- c_path = nm_connection_get_path (hotspot_connection);
- connection = nm_client_get_connection_by_path (client, c_path);
-
- g_debug ("overwriting ssid to %s", (char *) g_bytes_get_data (ssid, NULL));
-
- nm_remote_connection_commit_changes_async (connection,
- TRUE,
- cancellable,
- overwrite_ssid_cb,
- device_wifi);
- return;
- }
-
- g_debug ("create new hotspot connection with SSID '%s'",
- (char *) g_bytes_get_data (ssid, NULL));
- c = nm_simple_connection_new ();
-
- sc = (NMSettingConnection *)nm_setting_connection_new ();
- g_object_set (sc,
- "type", "802-11-wireless",
- "id", "Hotspot",
- "autoconnect", FALSE,
- NULL);
- nm_connection_add_setting (c, (NMSetting *)sc);
-
- sw = (NMSettingWireless *)nm_setting_wireless_new ();
-
- /* Use real AP mode if the device supports it */
- caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
- if (caps & NM_WIFI_DEVICE_CAP_AP)
- mode = NM_SETTING_WIRELESS_MODE_AP;
- else
- mode = NM_SETTING_WIRELESS_MODE_ADHOC;
-
- g_object_set (sw,
- "mode", mode,
- NULL);
-
- str_mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device));
- bin_mac = ether_aton (str_mac);
- if (bin_mac) {
- g_autoptr(GByteArray) hw_address = NULL;
-
- hw_address = g_byte_array_sized_new (ETH_ALEN);
- g_byte_array_append (hw_address, bin_mac->ether_addr_octet, ETH_ALEN);
- g_object_set (sw,
- "mac-address", hw_address,
- NULL);
- }
- nm_connection_add_setting (c, (NMSetting *)sw);
-
- sip = (NMSettingIP4Config*) nm_setting_ip4_config_new ();
- g_object_set (sip, "method", "shared", NULL);
- nm_connection_add_setting (c, (NMSetting *)sip);
-
- g_object_set (sw, "ssid", ssid, NULL);
-
- sws = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new ();
-
- if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) {
- if (caps & NM_WIFI_DEVICE_CAP_RSN) {
- set_wpa_key (sws);
- nm_setting_wireless_security_add_proto (sws, "rsn");
- nm_setting_wireless_security_add_pairwise (sws, "ccmp");
- nm_setting_wireless_security_add_group (sws, "ccmp");
- } else if (caps & NM_WIFI_DEVICE_CAP_WPA) {
- set_wpa_key (sws);
- nm_setting_wireless_security_add_proto (sws, "wpa");
- nm_setting_wireless_security_add_pairwise (sws, "tkip");
- nm_setting_wireless_security_add_group (sws, "tkip");
- } else {
- set_wep_key (sws);
- }
- } else {
- set_wep_key (sws);
- }
-
- nm_connection_add_setting (c, (NMSetting *)sws);
-
- nm_client_add_and_activate_connection_async (client,
- c,
- device,
- NULL,
- cancellable,
- activate_new_cb,
- device_wifi);
-}
-
-static void
-start_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi)
-{
- if (response == GTK_RESPONSE_OK) {
- start_shared_connection (device_wifi);
- }
- gtk_widget_destroy (dialog);
-}
-
static void
start_hotspot (GtkButton *button, NetDeviceWifi *device_wifi)
{
NMDevice *device;
- const GPtrArray *connections;
g_autofree gchar *active_ssid = NULL;
NMClient *client;
- GtkWidget *dialog;
GtkWidget *window;
- GtkWidget *message_area;
- GtkWidget *label;
- GString *str;
+ NMConnection *c;
+ g_autofree gchar *hostname = NULL;
+ g_autofree gchar *ssid = NULL;
+ gint response;
client = net_object_get_client (NET_OBJECT (device_wifi));
device = net_device_get_nm_device (NET_DEVICE (device_wifi));
- connections = nm_client_get_active_connections (client);
- if (connections) {
- gint i;
- for (i = 0; i < connections->len; i++) {
- NMActiveConnection *c;
- const GPtrArray *devices;
- c = (NMActiveConnection *)connections->pdata[i];
- devices = nm_active_connection_get_devices (c);
- if (devices && devices->pdata[0] == device) {
- NMAccessPoint *ap;
- GBytes *ssid;
- ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
- ssid = nm_access_point_get_ssid (ap);
- active_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL),
g_bytes_get_size (ssid));
- break;
- }
- }
- }
window = gtk_widget_get_toplevel (GTK_WIDGET (button));
- str = g_string_new ("");
-
- if (active_ssid) {
- g_string_append_printf (str, _("Switching on the wireless hotspot will disconnect you from
<b>%s</b>."), active_ssid);
- g_string_append (str, " ");
+ if (!device_wifi->hotspot_dialog)
+ device_wifi->hotspot_dialog = cc_wifi_hotspot_dialog_new (GTK_WINDOW (window));
+ cc_wifi_hotspot_dialog_set_device (device_wifi->hotspot_dialog, NM_DEVICE_WIFI (device));
+ hostname = get_hostname ();
+ ssid = pretty_hostname_to_ssid (hostname);
+ cc_wifi_hotspot_dialog_set_hostname (device_wifi->hotspot_dialog, ssid);
+ c = net_device_wifi_get_hotspot_connection (device_wifi);
+ if (c)
+ cc_wifi_hotspot_dialog_set_connection (device_wifi->hotspot_dialog, c);
+
+ response = gtk_dialog_run (GTK_DIALOG (device_wifi->hotspot_dialog));
+
+ if (response == GTK_RESPONSE_APPLY) {
+ NMConnection *connection;
+ GCancellable *cancellable;
+
+ cancellable = net_object_get_cancellable (NET_OBJECT (device_wifi));
+
+ connection = cc_wifi_hotspot_dialog_get_connection (device_wifi->hotspot_dialog);
+ if (NM_IS_REMOTE_CONNECTION (connection))
+ nm_remote_connection_commit_changes_async (NM_REMOTE_CONNECTION (connection),
+ TRUE,
+ cancellable,
+ overwrite_ssid_cb,
+ device_wifi);
+ else
+ nm_client_add_and_activate_connection_async (client,
+ connection,
+ device,
+ NULL,
+ cancellable,
+ activate_new_cb,
+ device_wifi);
}
- g_string_append (str, _("It is not possible to access the Internet through your wireless while the
hotspot is active."));
-
- dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (window),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_OTHER,
- GTK_BUTTONS_NONE,
- "<big><b>%s</b></big>",
- _("Turn On Wi-Fi Hotspot?"));
-
- /* Because we can't control the text alignment with markup, add
- * the strings as labels directly */
- message_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog));
-
- label = g_object_new (GTK_TYPE_LABEL,
- "use-markup", TRUE,
- "xalign", 0.5,
- "max-width-chars", 50,
- "wrap", TRUE,
- "label", str->str,
- "justify", GTK_JUSTIFY_CENTER,
- "halign", GTK_ALIGN_CENTER,
- NULL);
- gtk_container_add (GTK_CONTAINER (message_area), label);
-
- label = g_object_new (GTK_TYPE_LABEL,
- "use-markup", TRUE,
- "xalign", 0.5,
- "max-width-chars", 50,
- "wrap", TRUE,
- "label", _("Wi-Fi hotspots are usually used to share an additional Internet
connection over Wi-Fi."),
- "justify", GTK_JUSTIFY_CENTER,
- "halign", GTK_ALIGN_CENTER,
- NULL);
- gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
- gtk_container_add (GTK_CONTAINER (message_area), label);
-
- gtk_widget_show_all (message_area);
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- _("_Cancel"), GTK_RESPONSE_CANCEL,
- _("_Turn On"), GTK_RESPONSE_OK,
- NULL);
- g_signal_connect (dialog, "response",
- G_CALLBACK (start_hotspot_response_cb), device_wifi);
-
- gtk_window_present (GTK_WINDOW (dialog));
- g_string_free (str, TRUE);
+ gtk_widget_hide (GTK_WIDGET (device_wifi->hotspot_dialog));
}
static void
diff --git a/panels/network/network.gresource.xml b/panels/network/network.gresource.xml
index a3691b1a9..0fc1651e1 100644
--- a/panels/network/network.gresource.xml
+++ b/panels/network/network.gresource.xml
@@ -4,6 +4,7 @@
<!-- Network panel -->
<file preprocess="xml-stripblanks">cc-network-panel.ui</file>
<file preprocess="xml-stripblanks">cc-wifi-connection-row.ui</file>
+ <file preprocess="xml-stripblanks">cc-wifi-hotspot-dialog.ui</file>
<file preprocess="xml-stripblanks">network-proxy.ui</file>
<file preprocess="xml-stripblanks">network-vpn.ui</file>
<file preprocess="xml-stripblanks">network-wifi.ui</file>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]