~ubuntu-branches/ubuntu/utopic/network-manager-applet/utopic-proposed

« back to all changes in this revision

Viewing changes to src/connection-editor/page-wifi.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2012-11-19 14:46:29 UTC
  • mfrom: (1.2.31)
  • Revision ID: package-import@ubuntu.com-20121119144629-5423hii02a4vrh2n
Tags: 0.9.6.2+git201211052130.2d666bc-0ubuntu1
* upstream snapshot 2012-11-05 21:30:03 (GMT)
  + 2d666bc7aa6f0b731d131319b36f07b0f2bdce16
* debian/patches/git_fix_some_leaks_80ef61b.patch,
  debian/patches/git_indicate_hspa+_lte_tech_dbe3b12.patch,
  debian/patches/git_mac_addr_string_leakage_6dae878.patch: dropped, included
  in upstream tarball.
* debian/patches/lp328572-dxteam-connect-text.patch: refreshed.
* debian/patches/lp330571_dxteam_wired_connect_text.patch: refreshed.
* debian/patches/lp337960_dxteam_notification_icon_names.diff,
  debian/patches/lp337960_dxteam_notification_icon_names_part2-images.diff:
  disabled patches, they don't seem to be used (the icons don't match up with
  what is currently observable on the desktop). Let's see if someone screams.
* debian/patches/applet-wifi-menu-before-vpn.patch: refreshed.
* debian/patches/lp830178_adhoc_ip6_ignore.patch: refreshed.
* debian/patches/lp829673_gconf_hide_applet.patch: refreshed.
* debian/patches/nm-applet-use-indicator.patch: refreshed.
* debian/patches/hide_policy_items_env_var.patch: refreshed.
* debian/patches/applet_adhoc_use_wpa_rsn_part1.patch: refreshed.
* debian/patches/lp341684_device_sensitive_disconnect_notify.patch:
  refreshed.
* debian/patches/lp460144_correctly_update_notification.patch: refreshed.
* debian/patches/make_menu_items_insensitive_based_on_permissions.patch:
  refreshed.
* debian/control:
  - add gobject-introspection to Build-Depends.
  - add gudev-dev to Build-Depends.
  - bump network-manager and libnm-* Build-Depends and Depends to require
    at least 0.9.6.0+git201211131441.e9e2c56-0ubuntu1.
* debian/rules:
  - use autogen.sh with dh_autoreconf instead of calling intltoolize and
    gtkdocize manually.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 
2
/* NetworkManager Connection editor -- Connection editor for NetworkManager
 
3
 *
 
4
 * Dan Williams <dcbw@redhat.com>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License along
 
17
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
19
 *
 
20
 * (C) Copyright 2008 - 2012 Red Hat, Inc.
 
21
 */
 
22
 
 
23
#include "config.h"
 
24
 
 
25
#include <string.h>
 
26
#include <math.h>
 
27
 
 
28
#include <gtk/gtk.h>
 
29
#include <glib/gi18n.h>
 
30
 
 
31
#include <nm-setting-connection.h>
 
32
#include <nm-setting-wireless.h>
 
33
#include <nm-device-wifi.h>
 
34
#include <nm-utils.h>
 
35
 
 
36
#include "page-wifi.h"
 
37
 
 
38
G_DEFINE_TYPE (CEPageWifi, ce_page_wifi, CE_TYPE_PAGE)
 
39
 
 
40
#define CE_PAGE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_WIFI, CEPageWifiPrivate))
 
41
 
 
42
typedef struct {
 
43
        NMSettingWireless *setting;
 
44
 
 
45
        GtkEntry *ssid;
 
46
#if GTK_CHECK_VERSION (2,24,0)
 
47
        GtkComboBoxText *bssid;
 
48
#else
 
49
        GtkComboBoxEntry *bssid;
 
50
#endif
 
51
#if GTK_CHECK_VERSION (2,24,0)
 
52
        GtkComboBoxText *device_mac;  /* Permanent MAC of the device */
 
53
#else
 
54
        GtkComboBoxEntry *device_mac;
 
55
#endif
 
56
        GtkEntry *cloned_mac;         /* Cloned MAC - used for MAC spoofing */
 
57
        GtkComboBox *mode;
 
58
        GtkComboBox *band;
 
59
        GtkSpinButton *channel;
 
60
        GtkSpinButton *rate;
 
61
        GtkSpinButton *tx_power;
 
62
        GtkSpinButton *mtu;
 
63
 
 
64
        GtkSizeGroup *group;
 
65
 
 
66
        int last_channel;
 
67
        gboolean disposed;
 
68
} CEPageWifiPrivate;
 
69
 
 
70
static void
 
71
wifi_private_init (CEPageWifi *self)
 
72
{
 
73
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
74
        GtkBuilder *builder;
 
75
        GtkWidget *widget;
 
76
        GtkWidget *align;
 
77
        GtkLabel *label;
 
78
 
 
79
        builder = CE_PAGE (self)->builder;
 
80
 
 
81
        priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
82
 
 
83
        priv->ssid     = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_ssid")));
 
84
        priv->cloned_mac = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_cloned_mac")));
 
85
        priv->mode     = GTK_COMBO_BOX (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_mode")));
 
86
        priv->band     = GTK_COMBO_BOX (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_band")));
 
87
        priv->channel  = GTK_SPIN_BUTTON (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_channel")));
 
88
 
 
89
        /* BSSID */
 
90
#if GTK_CHECK_VERSION(2,24,0)
 
91
        priv->bssid = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
 
92
        gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (priv->bssid), 0);
 
93
#else
 
94
        priv->bssid = GTK_COMBO_BOX_ENTRY (gtk_combo_box_entry_new_text ());
 
95
        gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (priv->bssid), 0);
 
96
#endif
 
97
        gtk_widget_set_tooltip_text (GTK_WIDGET (priv->bssid),
 
98
                                     _("This option locks this connection to the Wi-Fi access point (AP) specified by the BSSID entered here.  Example: 00:11:22:33:44:55"));
 
99
 
 
100
        align = GTK_WIDGET (gtk_builder_get_object (builder, "wifi_bssid_alignment"));
 
101
        gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (priv->bssid));
 
102
        gtk_widget_show_all (GTK_WIDGET (priv->bssid));
 
103
 
 
104
        /* Device MAC */
 
105
#if GTK_CHECK_VERSION(2,24,0)
 
106
        priv->device_mac = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
 
107
        gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (priv->device_mac), 0);
 
108
#else
 
109
        priv->device_mac = GTK_COMBO_BOX_ENTRY (gtk_combo_box_entry_new_text ());
 
110
        gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (priv->device_mac), 0);
 
111
#endif
 
112
        gtk_widget_set_tooltip_text (GTK_WIDGET (priv->device_mac),
 
113
                                     _("This option locks this connection to the network device specified by its permanent MAC address entered here.  Example: 00:11:22:33:44:55"));
 
114
 
 
115
        align = GTK_WIDGET (gtk_builder_get_object (builder, "wifi_device_mac_alignment"));
 
116
        gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (priv->device_mac));
 
117
        gtk_widget_show_all (GTK_WIDGET (priv->device_mac));
 
118
 
 
119
        /* Set mnemonic widget for device MAC label */
 
120
        label = GTK_LABEL (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_device_mac_label")));
 
121
        gtk_label_set_mnemonic_widget (label, GTK_WIDGET (priv->device_mac));
 
122
 
 
123
        priv->rate     = GTK_SPIN_BUTTON (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_rate")));
 
124
        widget = GTK_WIDGET (gtk_builder_get_object (builder, "rate_units"));
 
125
        gtk_size_group_add_widget (priv->group, widget);
 
126
 
 
127
        priv->tx_power = GTK_SPIN_BUTTON (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_tx_power")));
 
128
        widget = GTK_WIDGET (gtk_builder_get_object (builder, "tx_power_units"));
 
129
        gtk_size_group_add_widget (priv->group, widget);
 
130
 
 
131
        priv->mtu      = GTK_SPIN_BUTTON (GTK_WIDGET (gtk_builder_get_object (builder, "wifi_mtu")));
 
132
        widget = GTK_WIDGET (gtk_builder_get_object (builder, "mtu_units"));
 
133
        gtk_size_group_add_widget (priv->group, widget);
 
134
}
 
135
 
 
136
static gboolean
 
137
band_helper (CEPageWifi *self, gboolean *aband, gboolean *gband)
 
138
{
 
139
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
140
 
 
141
        switch (gtk_combo_box_get_active (priv->band)) {
 
142
        case 1: /* A */
 
143
                *gband = FALSE;
 
144
                return TRUE;
 
145
        case 2: /* B/G */
 
146
                *aband = FALSE;
 
147
                return TRUE;
 
148
        default:
 
149
                return FALSE;
 
150
        }
 
151
}
 
152
 
 
153
static gint
 
154
channel_spin_input_cb (GtkSpinButton *spin, gdouble *new_val, gpointer user_data)
 
155
{
 
156
        CEPageWifi *self = CE_PAGE_WIFI (user_data);
 
157
        gdouble channel;
 
158
        guint32 int_channel = 0;
 
159
        gboolean aband = TRUE;
 
160
        gboolean gband = TRUE;
 
161
 
 
162
        if (!band_helper (self, &aband, &gband))
 
163
                return GTK_INPUT_ERROR;
 
164
 
 
165
        channel = g_strtod (gtk_entry_get_text (GTK_ENTRY (spin)), NULL);
 
166
        if (channel - floor (channel) < ceil (channel) - channel)
 
167
                int_channel = floor (channel);
 
168
        else
 
169
                int_channel = ceil (channel);
 
170
 
 
171
        if (nm_utils_wifi_channel_to_freq (int_channel, aband ? "a" : "bg") == -1)
 
172
                return GTK_INPUT_ERROR;
 
173
 
 
174
        *new_val = channel;
 
175
        return 1;
 
176
}
 
177
 
 
178
static gint
 
179
channel_spin_output_cb (GtkSpinButton *spin, gpointer user_data)
 
180
{
 
181
        CEPageWifi *self = CE_PAGE_WIFI (user_data);
 
182
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
183
        int channel;
 
184
        gchar *buf = NULL;
 
185
        guint32 freq;
 
186
        gboolean aband = TRUE;
 
187
        gboolean gband = TRUE;
 
188
 
 
189
        if (!band_helper (self, &aband, &gband))
 
190
                buf = g_strdup (_("default"));
 
191
        else {
 
192
                channel = gtk_spin_button_get_value_as_int (spin);
 
193
                if (channel == 0)
 
194
                        buf = g_strdup (_("default"));
 
195
                else {
 
196
                        int direction = 0;
 
197
                        freq = nm_utils_wifi_channel_to_freq (channel, aband ? "a" : "bg");
 
198
                        if (freq == -1) {
 
199
                                if (priv->last_channel < channel)
 
200
                                        direction = 1;
 
201
                                else if (priv->last_channel > channel)
 
202
                                        direction = -1;
 
203
                                channel = nm_utils_wifi_find_next_channel (channel, direction, aband ? "a" : "bg");
 
204
                                gtk_spin_button_set_value (spin, channel);
 
205
                                freq = nm_utils_wifi_channel_to_freq (channel, aband ? "a" : "bg");
 
206
                                if (freq == -1) {
 
207
                                        g_warning ("%s: invalid channel %d!", __func__, channel);
 
208
                                        gtk_spin_button_set_value (spin, 0);
 
209
                                        goto out;
 
210
                                }
 
211
 
 
212
                        }
 
213
                        /* Set spin button to zero to go to "default" from the lowest channel */
 
214
                        if (direction == -1 && priv->last_channel == channel) {
 
215
                                buf = g_strdup_printf (_("default"));
 
216
                                gtk_spin_button_set_value (spin, 0);
 
217
                                channel = 0;
 
218
                        } else
 
219
                                buf = g_strdup_printf (_("%u (%u MHz)"), channel, freq);
 
220
                }
 
221
                priv->last_channel = channel;
 
222
        }
 
223
 
 
224
        if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin))))
 
225
                gtk_entry_set_text (GTK_ENTRY (spin), buf);
 
226
 
 
227
out:
 
228
        g_free (buf);
 
229
        return 1;
 
230
}
 
231
 
 
232
static void
 
233
band_value_changed_cb (GtkComboBox *box, gpointer user_data)
 
234
{
 
235
        CEPageWifi *self = CE_PAGE_WIFI (user_data);
 
236
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
237
        gboolean sensitive;
 
238
 
 
239
        priv->last_channel = 0;
 
240
        gtk_spin_button_set_value (priv->channel, 0);
 
241
 
 
242
        switch (gtk_combo_box_get_active (GTK_COMBO_BOX (box))) {
 
243
        case 1: /* A */
 
244
        case 2: /* B/G */
 
245
                sensitive = TRUE;
 
246
                break;
 
247
        default:
 
248
                sensitive = FALSE;
 
249
                break;
 
250
        }
 
251
 
 
252
        gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), sensitive);
 
253
 
 
254
        ce_page_changed (CE_PAGE (self));
 
255
}
 
256
 
 
257
static void
 
258
mode_combo_changed_cb (GtkComboBox *combo,
 
259
                       gpointer user_data)
 
260
{
 
261
        CEPageWifi *self = CE_PAGE_WIFI (user_data);
 
262
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
263
        CEPage *parent = CE_PAGE (self);
 
264
        GtkWidget *widget;
 
265
        gboolean show;
 
266
 
 
267
        switch (gtk_combo_box_get_active (GTK_COMBO_BOX (combo))) {
 
268
        case 1: /* adhoc */
 
269
                show = TRUE;
 
270
                break;
 
271
        default: /* infrastructure */
 
272
                show = FALSE;
 
273
                break;
 
274
        }
 
275
 
 
276
        if (show) {
 
277
                widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_band_label"));
 
278
                gtk_widget_show (widget);
 
279
                gtk_widget_show (GTK_WIDGET (priv->band));
 
280
                widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_channel_label"));
 
281
                gtk_widget_show (widget);
 
282
                gtk_widget_show (GTK_WIDGET (priv->channel));
 
283
        } else {
 
284
                widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_band_label"));
 
285
                gtk_widget_hide (widget);
 
286
                gtk_widget_hide (GTK_WIDGET (priv->band));
 
287
                widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_channel_label"));
 
288
                gtk_widget_hide (widget);
 
289
                gtk_widget_hide (GTK_WIDGET (priv->channel));
 
290
        }
 
291
 
 
292
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_band_label"));
 
293
        gtk_widget_set_sensitive (GTK_WIDGET (widget), show);
 
294
        gtk_widget_set_sensitive (GTK_WIDGET (priv->band), show);
 
295
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_channel_label"));
 
296
        gtk_widget_set_sensitive (GTK_WIDGET (widget), show);
 
297
        gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), show);
 
298
 
 
299
        ce_page_changed (CE_PAGE (self));
 
300
}
 
301
 
 
302
static void
 
303
populate_ui (CEPageWifi *self)
 
304
{
 
305
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
306
        NMSettingWireless *setting = priv->setting;
 
307
        GByteArray *ssid = NULL;
 
308
        char *mode = NULL;
 
309
        char *band = NULL;
 
310
        int band_idx = 0;
 
311
        int rate_def;
 
312
        int tx_power_def;
 
313
        int mtu_def;
 
314
        char *utf8_ssid;
 
315
        char **mac_list;
 
316
        const GByteArray *s_mac, *s_bssid;
 
317
        char *s_mac_str, *s_bssid_str;
 
318
        GPtrArray *bssid_array;
 
319
        char **bssid_list;
 
320
        guint32 idx;
 
321
 
 
322
        rate_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_RATE);
 
323
        g_signal_connect (priv->rate, "output",
 
324
                          G_CALLBACK (ce_spin_output_with_default),
 
325
                          GINT_TO_POINTER (rate_def));
 
326
        g_signal_connect_swapped (priv->rate, "value-changed", G_CALLBACK (ce_page_changed), self);
 
327
 
 
328
        tx_power_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_TX_POWER);
 
329
        g_signal_connect (priv->tx_power, "output",
 
330
                          G_CALLBACK (ce_spin_output_with_default),
 
331
                          GINT_TO_POINTER (tx_power_def));
 
332
        g_signal_connect_swapped (priv->tx_power, "value-changed", G_CALLBACK (ce_page_changed), self);
 
333
 
 
334
        mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_MTU);
 
335
        g_signal_connect (priv->mtu, "output",
 
336
                          G_CALLBACK (ce_spin_output_with_default),
 
337
                          GINT_TO_POINTER (mtu_def));
 
338
        g_signal_connect_swapped (priv->mtu, "value-changed", G_CALLBACK (ce_page_changed), self);
 
339
 
 
340
        g_object_get (setting,
 
341
                      NM_SETTING_WIRELESS_SSID, &ssid,
 
342
                      NM_SETTING_WIRELESS_MODE, &mode,
 
343
                      NM_SETTING_WIRELESS_BAND, &band,
 
344
                      NULL);
 
345
 
 
346
        if (ssid)
 
347
                utf8_ssid = nm_utils_ssid_to_utf8 (ssid);
 
348
        else
 
349
                utf8_ssid = g_strdup ("");
 
350
        gtk_entry_set_text (priv->ssid, utf8_ssid);
 
351
        g_signal_connect_swapped (priv->ssid, "changed", G_CALLBACK (ce_page_changed), self);
 
352
        g_free (utf8_ssid);
 
353
        g_byte_array_unref (ssid);
 
354
 
 
355
        /* Default to Infrastructure */
 
356
        gtk_combo_box_set_active (priv->mode, 0);
 
357
        if (mode && !strcmp (mode, "adhoc"))
 
358
                gtk_combo_box_set_active (priv->mode, 1);
 
359
        mode_combo_changed_cb (priv->mode, self);
 
360
        g_signal_connect (priv->mode, "changed", G_CALLBACK (mode_combo_changed_cb), self);
 
361
        g_free (mode);
 
362
 
 
363
        g_signal_connect (priv->channel, "output",
 
364
                          G_CALLBACK (channel_spin_output_cb),
 
365
                          self);
 
366
        g_signal_connect (priv->channel, "input",
 
367
                          G_CALLBACK (channel_spin_input_cb),
 
368
                          self);
 
369
 
 
370
        gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), FALSE);
 
371
        if (band) {
 
372
                if (!strcmp (band ? band : "", "a")) {
 
373
                        band_idx = 1;
 
374
                        gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE);
 
375
                } else if (!strcmp (band ? band : "", "bg")) {
 
376
                        band_idx = 2;
 
377
                        gtk_widget_set_sensitive (GTK_WIDGET (priv->channel), TRUE);
 
378
                }
 
379
                g_free (band);
 
380
        }
 
381
 
 
382
        gtk_combo_box_set_active (priv->band, band_idx);
 
383
        g_signal_connect (priv->band, "changed",
 
384
                          G_CALLBACK (band_value_changed_cb),
 
385
                          self);
 
386
 
 
387
        /* Update the channel _after_ the band has been set so that it gets
 
388
         * the right values */
 
389
        priv->last_channel = nm_setting_wireless_get_channel (setting);
 
390
        gtk_spin_button_set_value (priv->channel, (gdouble) priv->last_channel);
 
391
        g_signal_connect_swapped (priv->channel, "value-changed", G_CALLBACK (ce_page_changed), self);
 
392
 
 
393
        /* BSSID */
 
394
        bssid_array = g_ptr_array_new ();
 
395
        for (idx = 0; idx < nm_setting_wireless_get_num_seen_bssids (setting); idx++)
 
396
                g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (setting, idx)));
 
397
        g_ptr_array_add (bssid_array, NULL);
 
398
        bssid_list = (char **) g_ptr_array_free (bssid_array, FALSE);
 
399
        s_bssid = nm_setting_wireless_get_bssid (setting);
 
400
        s_bssid_str = s_bssid ? nm_utils_hwaddr_ntoa (s_bssid->data, ARPHRD_ETHER) : NULL;
 
401
        ce_page_setup_mac_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->bssid),
 
402
                                 s_bssid_str, bssid_list);
 
403
        g_free (s_bssid_str);
 
404
        g_strfreev (bssid_list);
 
405
        g_signal_connect_swapped (priv->bssid, "changed", G_CALLBACK (ce_page_changed), self);
 
406
 
 
407
        /* Device MAC address */
 
408
        mac_list = ce_page_get_mac_list (CE_PAGE (self), NM_TYPE_DEVICE_WIFI,
 
409
                                         NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
 
410
        s_mac = nm_setting_wireless_get_mac_address (setting);
 
411
        s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL;
 
412
        ce_page_setup_mac_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->device_mac),
 
413
                                 s_mac_str, mac_list);
 
414
        g_free (s_mac_str);
 
415
        g_strfreev (mac_list);
 
416
        g_signal_connect_swapped (priv->device_mac, "changed", G_CALLBACK (ce_page_changed), self);
 
417
 
 
418
        /* Cloned MAC address */
 
419
        ce_page_mac_to_entry (nm_setting_wireless_get_cloned_mac_address (setting),
 
420
                              ARPHRD_ETHER, priv->cloned_mac);
 
421
        g_signal_connect_swapped (priv->cloned_mac, "changed", G_CALLBACK (ce_page_changed), self);
 
422
 
 
423
        gtk_spin_button_set_value (priv->rate, (gdouble) nm_setting_wireless_get_rate (setting));
 
424
        gtk_spin_button_set_value (priv->tx_power, (gdouble) nm_setting_wireless_get_tx_power (setting));
 
425
        gtk_spin_button_set_value (priv->mtu, (gdouble) nm_setting_wireless_get_mtu (setting));
 
426
}
 
427
 
 
428
static void
 
429
finish_setup (CEPageWifi *self, gpointer unused, GError *error, gpointer user_data)
 
430
{
 
431
        CEPage *parent = CE_PAGE (self);
 
432
        GtkWidget *widget;
 
433
 
 
434
        if (error)
 
435
                return;
 
436
 
 
437
        populate_ui (self);
 
438
 
 
439
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_tx_power_label"));
 
440
        gtk_widget_hide (widget);
 
441
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_tx_power_hbox"));
 
442
        gtk_widget_hide (widget);
 
443
 
 
444
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_rate_label"));
 
445
        gtk_widget_hide (widget);
 
446
        widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wifi_rate_hbox"));
 
447
        gtk_widget_hide (widget);
 
448
}
 
449
 
 
450
CEPage *
 
451
ce_page_wifi_new (NMConnection *connection,
 
452
                  GtkWindow *parent_window,
 
453
                  NMClient *client,
 
454
                  NMRemoteSettings *settings,
 
455
                  const char **out_secrets_setting_name,
 
456
                  GError **error)
 
457
{
 
458
        CEPageWifi *self;
 
459
        CEPageWifiPrivate *priv;
 
460
 
 
461
        g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
 
462
 
 
463
        self = CE_PAGE_WIFI (ce_page_new (CE_TYPE_PAGE_WIFI,
 
464
                                          connection,
 
465
                                          parent_window,
 
466
                                          client,
 
467
                                          settings,
 
468
                                          UIDIR "/ce-page-wifi.ui",
 
469
                                          "WifiPage",
 
470
                                          _("Wi-Fi")));
 
471
        if (!self) {
 
472
                g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load Wi-Fi user interface."));
 
473
                return NULL;
 
474
        }
 
475
 
 
476
        wifi_private_init (self);
 
477
        priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
478
 
 
479
        priv->setting = nm_connection_get_setting_wireless (connection);
 
480
        if (!priv->setting) {
 
481
                priv->setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
 
482
                nm_connection_add_setting (connection, NM_SETTING (priv->setting));
 
483
        }
 
484
 
 
485
        g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);
 
486
 
 
487
        return CE_PAGE (self);
 
488
}
 
489
 
 
490
GByteArray *
 
491
ce_page_wifi_get_ssid (CEPageWifi *self)
 
492
{
 
493
        CEPageWifiPrivate *priv;
 
494
        const char *txt_ssid;
 
495
        GByteArray *ssid;
 
496
 
 
497
        g_return_val_if_fail (CE_IS_PAGE_WIFI (self), NULL);
 
498
 
 
499
        priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
500
        txt_ssid = gtk_entry_get_text (priv->ssid);
 
501
        if (!txt_ssid || !strlen (txt_ssid))
 
502
                return NULL;
 
503
 
 
504
        ssid = g_byte_array_sized_new (strlen (txt_ssid));
 
505
        g_byte_array_append (ssid, (const guint8 *) txt_ssid, strlen (txt_ssid));
 
506
 
 
507
        return ssid;
 
508
}
 
509
 
 
510
static void
 
511
ui_to_setting (CEPageWifi *self)
 
512
{
 
513
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
514
        GByteArray *ssid;
 
515
        GByteArray *bssid = NULL;
 
516
        GByteArray *device_mac = NULL;
 
517
        GByteArray *cloned_mac = NULL;
 
518
        const char *mode;
 
519
        const char *band;
 
520
        GtkWidget *entry;
 
521
 
 
522
        ssid = ce_page_wifi_get_ssid (self);
 
523
 
 
524
        if (gtk_combo_box_get_active (priv->mode) == 1)
 
525
                mode = "adhoc";
 
526
        else
 
527
                mode = "infrastructure";
 
528
 
 
529
        switch (gtk_combo_box_get_active (priv->band)) {
 
530
        case 1:
 
531
                band = "a";
 
532
                break;
 
533
        case 2:
 
534
                band = "bg";
 
535
                break;
 
536
        case 0:
 
537
        default:
 
538
                band = NULL;
 
539
                break;
 
540
        }
 
541
 
 
542
        entry = gtk_bin_get_child (GTK_BIN (priv->bssid));
 
543
        if (entry)
 
544
                bssid = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
 
545
        entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
 
546
        if (entry)
 
547
                device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
 
548
        cloned_mac = ce_page_entry_to_mac (priv->cloned_mac, ARPHRD_ETHER, NULL);
 
549
 
 
550
        g_object_set (priv->setting,
 
551
                      NM_SETTING_WIRELESS_SSID, ssid,
 
552
                      NM_SETTING_WIRELESS_BSSID, bssid,
 
553
                      NM_SETTING_WIRELESS_MAC_ADDRESS, device_mac,
 
554
                      NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac,
 
555
                      NM_SETTING_WIRELESS_MODE, mode,
 
556
                      NM_SETTING_WIRELESS_BAND, band,
 
557
                      NM_SETTING_WIRELESS_CHANNEL, gtk_spin_button_get_value_as_int (priv->channel),
 
558
                      NM_SETTING_WIRELESS_RATE, gtk_spin_button_get_value_as_int (priv->rate),
 
559
                      NM_SETTING_WIRELESS_TX_POWER, gtk_spin_button_get_value_as_int (priv->tx_power),
 
560
                      NM_SETTING_WIRELESS_MTU, gtk_spin_button_get_value_as_int (priv->mtu),
 
561
                      NULL);
 
562
 
 
563
        if (ssid)
 
564
                g_byte_array_free (ssid, TRUE);
 
565
        if (device_mac)
 
566
                g_byte_array_free (device_mac, TRUE);
 
567
        if (cloned_mac)
 
568
                g_byte_array_free (cloned_mac, TRUE);
 
569
        if (bssid)
 
570
                g_byte_array_free (bssid, TRUE);
 
571
}
 
572
 
 
573
static gboolean
 
574
validate (CEPage *page, NMConnection *connection, GError **error)
 
575
{
 
576
        CEPageWifi *self = CE_PAGE_WIFI (page);
 
577
        CEPageWifiPrivate *priv = CE_PAGE_WIFI_GET_PRIVATE (self);
 
578
        char *security;
 
579
        gboolean success;
 
580
        gboolean invalid = FALSE;
 
581
        GByteArray *ignore;
 
582
        GtkWidget *entry;
 
583
 
 
584
        entry = gtk_bin_get_child (GTK_BIN (priv->bssid));
 
585
        if (entry) {
 
586
                ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
 
587
                if (invalid)
 
588
                        return FALSE;
 
589
                if (ignore)
 
590
                        g_byte_array_free (ignore, TRUE);
 
591
        }
 
592
 
 
593
        entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
 
594
        if (entry) {
 
595
                ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
 
596
                if (invalid)
 
597
                        return FALSE;
 
598
                if (ignore)
 
599
                        g_byte_array_free (ignore, TRUE);
 
600
        }
 
601
 
 
602
        ignore = ce_page_entry_to_mac (priv->cloned_mac, ARPHRD_ETHER, &invalid);
 
603
        if (invalid)
 
604
                return FALSE;
 
605
        if (ignore)
 
606
                g_byte_array_free (ignore, TRUE);
 
607
 
 
608
        ui_to_setting (self);
 
609
 
 
610
        /* A hack to not check the wifi security here */
 
611
        security = g_strdup (nm_setting_wireless_get_security (priv->setting));
 
612
        g_object_set (priv->setting, NM_SETTING_WIRELESS_SEC, NULL, NULL);
 
613
 
 
614
        success = nm_setting_verify (NM_SETTING (priv->setting), NULL, error);
 
615
        g_object_set (priv->setting, NM_SETTING_WIRELESS_SEC, security, NULL);
 
616
        g_free (security);
 
617
 
 
618
        return success;
 
619
}
 
620
 
 
621
static void
 
622
ce_page_wifi_init (CEPageWifi *self)
 
623
{
 
624
}
 
625
 
 
626
static void
 
627
ce_page_wifi_class_init (CEPageWifiClass *wifi_class)
 
628
{
 
629
        GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
 
630
        CEPageClass *parent_class = CE_PAGE_CLASS (wifi_class);
 
631
 
 
632
        g_type_class_add_private (object_class, sizeof (CEPageWifiPrivate));
 
633
 
 
634
        /* virtual methods */
 
635
        parent_class->validate = validate;
 
636
}
 
637
 
 
638
 
 
639
void
 
640
wifi_connection_new (GtkWindow *parent,
 
641
                     const char *detail,
 
642
                     NMRemoteSettings *settings,
 
643
                     PageNewConnectionResultFunc result_func,
 
644
                     gpointer user_data)
 
645
{
 
646
        NMConnection *connection;
 
647
        NMSetting *s_wifi;
 
648
 
 
649
        connection = ce_page_new_connection (_("Wi-Fi connection %d"),
 
650
                                             NM_SETTING_WIRELESS_SETTING_NAME,
 
651
                                             TRUE,
 
652
                                             settings,
 
653
                                             user_data);
 
654
        s_wifi = nm_setting_wireless_new ();
 
655
        g_object_set (s_wifi, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL);
 
656
        nm_connection_add_setting (connection, s_wifi);
 
657
 
 
658
        (*result_func) (connection, FALSE, NULL, user_data);
 
659
}
 
660
 
 
661