~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/network/net-device-wifi.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2011-2012 Richard Hughes <richard@hughsie.com>
 
4
 *
 
5
 * Licensed under the GNU General Public License Version 2
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <glib-object.h>
 
25
#include <glib/gi18n.h>
 
26
 
 
27
//#include <arpa/inet.h>
 
28
#include <netinet/ether.h>
 
29
 
 
30
#include <nm-client.h>
 
31
#include <nm-utils.h>
 
32
#include <nm-device.h>
 
33
#include <nm-device-wifi.h>
 
34
#include <nm-device-ethernet.h>
 
35
#include <nm-setting-wireless-security.h>
 
36
#include <nm-remote-connection.h>
 
37
#include <nm-setting-wireless.h>
 
38
 
 
39
#include "network-dialogs.h"
 
40
#include "panel-common.h"
 
41
#include "panel-cell-renderer-mode.h"
 
42
#include "panel-cell-renderer-signal.h"
 
43
#include "panel-cell-renderer-security.h"
 
44
#include "panel-cell-renderer-separator.h"
 
45
#include "panel-cell-renderer-text.h"
 
46
#include "panel-cell-renderer-pixbuf.h"
 
47
 
 
48
#include "net-device-wifi.h"
 
49
 
 
50
#define NET_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiPrivate))
 
51
 
 
52
static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi);
 
53
static void show_wifi_list (NetDeviceWifi *device_wifi);
 
54
 
 
55
struct _NetDeviceWifiPrivate
 
56
{
 
57
        GtkBuilder              *builder;
 
58
        gboolean                 updating_device;
 
59
        gchar                   *selected_ssid_title;
 
60
        gchar                   *selected_connection_id;
 
61
        gchar                   *selected_ap_id;
 
62
};
 
63
 
 
64
G_DEFINE_TYPE (NetDeviceWifi, net_device_wifi, NET_TYPE_DEVICE)
 
65
 
 
66
enum {
 
67
        COLUMN_CONNECTION_ID,
 
68
        COLUMN_ACCESS_POINT_ID,
 
69
        COLUMN_TITLE,
 
70
        COLUMN_SORT,
 
71
        COLUMN_STRENGTH,
 
72
        COLUMN_MODE,
 
73
        COLUMN_SECURITY,
 
74
        COLUMN_ACTIVE,
 
75
        COLUMN_AP_IN_RANGE,
 
76
        COLUMN_AP_OUT_OF_RANGE,
 
77
        COLUMN_AP_IS_SAVED,
 
78
        COLUMN_LAST
 
79
};
 
80
 
 
81
static GtkWidget *
 
82
device_wifi_proxy_add_to_notebook (NetObject *object,
 
83
                                    GtkNotebook *notebook,
 
84
                                    GtkSizeGroup *heading_size_group)
 
85
{
 
86
        GtkWidget *widget;
 
87
        GtkWindow *window;
 
88
        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object);
 
89
 
 
90
        /* add widgets to size group */
 
91
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
92
                                                     "heading_ipv4"));
 
93
        gtk_size_group_add_widget (heading_size_group, widget);
 
94
 
 
95
        /* reparent */
 
96
        window = GTK_WINDOW (gtk_builder_get_object (device_wifi->priv->builder,
 
97
                                                     "window_tmp"));
 
98
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
99
                                                     "notebook_view"));
 
100
        g_object_ref (widget);
 
101
        gtk_container_remove (GTK_CONTAINER (window), widget);
 
102
        gtk_notebook_append_page (notebook, widget, NULL);
 
103
        g_object_unref (widget);
 
104
 
 
105
        return widget;
 
106
}
 
107
 
 
108
static guint
 
109
get_access_point_security (NMAccessPoint *ap)
 
110
{
 
111
        NM80211ApFlags flags;
 
112
        NM80211ApSecurityFlags wpa_flags;
 
113
        NM80211ApSecurityFlags rsn_flags;
 
114
        guint type;
 
115
 
 
116
        flags = nm_access_point_get_flags (ap);
 
117
        wpa_flags = nm_access_point_get_wpa_flags (ap);
 
118
        rsn_flags = nm_access_point_get_rsn_flags (ap);
 
119
 
 
120
        if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) &&
 
121
            wpa_flags == NM_802_11_AP_SEC_NONE &&
 
122
            rsn_flags == NM_802_11_AP_SEC_NONE)
 
123
                type = NM_AP_SEC_NONE;
 
124
        else if ((flags & NM_802_11_AP_FLAGS_PRIVACY) &&
 
125
                 wpa_flags == NM_802_11_AP_SEC_NONE &&
 
126
                 rsn_flags == NM_802_11_AP_SEC_NONE)
 
127
                type = NM_AP_SEC_WEP;
 
128
        else if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) &&
 
129
                 wpa_flags != NM_802_11_AP_SEC_NONE &&
 
130
                 rsn_flags != NM_802_11_AP_SEC_NONE)
 
131
                type = NM_AP_SEC_WPA;
 
132
        else
 
133
                type = NM_AP_SEC_WPA2;
 
134
 
 
135
        return type;
 
136
}
 
137
 
 
138
static void
 
139
add_access_point (NetDeviceWifi *device_wifi, NMAccessPoint *ap, NMAccessPoint *active, NMDevice *device)
 
140
{
 
141
        const GByteArray *ssid;
 
142
        const gchar *object_path;
 
143
        const gchar *ssid_text;
 
144
        gboolean is_active_ap;
 
145
        gchar *title;
 
146
        GtkListStore *liststore_network;
 
147
        GtkTreeIter treeiter;
 
148
        NetDeviceWifiPrivate *priv = device_wifi->priv;
 
149
 
 
150
        ssid = nm_access_point_get_ssid (ap);
 
151
        if (ssid == NULL)
 
152
                return;
 
153
        ssid_text = nm_utils_ssid_to_utf8 (ssid);
 
154
        title = g_markup_escape_text (ssid_text, -1);
 
155
 
 
156
        is_active_ap = active && nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE);
 
157
        liststore_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
 
158
                                            "liststore_network"));
 
159
 
 
160
        object_path = nm_object_get_path (NM_OBJECT (ap));
 
161
        gtk_list_store_insert_with_values (liststore_network,
 
162
                                           &treeiter,
 
163
                                           -1,
 
164
                                           COLUMN_ACCESS_POINT_ID, object_path,
 
165
                                           COLUMN_TITLE, title,
 
166
                                           COLUMN_SORT, ssid_text,
 
167
                                           COLUMN_STRENGTH, nm_access_point_get_strength (ap),
 
168
                                           COLUMN_MODE, nm_access_point_get_mode (ap),
 
169
                                           COLUMN_SECURITY, get_access_point_security (ap),
 
170
                                           COLUMN_ACTIVE, is_active_ap,
 
171
                                           COLUMN_AP_IN_RANGE, TRUE,
 
172
                                           COLUMN_AP_OUT_OF_RANGE, FALSE,
 
173
                                           COLUMN_AP_IS_SAVED, FALSE,
 
174
                                           -1);
 
175
        g_free (ssid_text);
 
176
        g_free (title);
 
177
}
 
178
 
 
179
static GPtrArray *
 
180
panel_get_strongest_unique_aps (const GPtrArray *aps)
 
181
{
 
182
        const GByteArray *ssid;
 
183
        const GByteArray *ssid_tmp;
 
184
        GPtrArray *aps_unique = NULL;
 
185
        gboolean add_ap;
 
186
        guint i;
 
187
        guint j;
 
188
        NMAccessPoint *ap;
 
189
        NMAccessPoint *ap_tmp;
 
190
 
 
191
        /* we will have multiple entries for typical hotspots, just
 
192
         * filter to the one with the strongest signal */
 
193
        aps_unique = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
 
194
        if (aps != NULL)
 
195
                for (i = 0; i < aps->len; i++) {
 
196
                        ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
 
197
 
 
198
                        /* Hidden SSIDs don't get shown in the list */
 
199
                        ssid = nm_access_point_get_ssid (ap);
 
200
                        if (!ssid)
 
201
                                continue;
 
202
 
 
203
                        add_ap = TRUE;
 
204
 
 
205
                        /* get already added list */
 
206
                        for (j=0; j<aps_unique->len; j++) {
 
207
                                ap_tmp = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, j));
 
208
                                ssid_tmp = nm_access_point_get_ssid (ap_tmp);
 
209
                                g_assert (ssid_tmp);
 
210
 
 
211
                                /* is this the same type and data? */
 
212
                                if (nm_utils_same_ssid (ssid, ssid_tmp, TRUE)) {
 
213
 
 
214
                                        g_debug ("found duplicate: %s",
 
215
                                                 nm_utils_escape_ssid (ssid_tmp->data,
 
216
                                                                       ssid_tmp->len));
 
217
 
 
218
                                        /* the new access point is stronger */
 
219
                                        if (nm_access_point_get_strength (ap) >
 
220
                                            nm_access_point_get_strength (ap_tmp)) {
 
221
                                                g_debug ("removing %s",
 
222
                                                         nm_utils_escape_ssid (ssid_tmp->data,
 
223
                                                                               ssid_tmp->len));
 
224
                                                g_ptr_array_remove (aps_unique, ap_tmp);
 
225
                                                add_ap = TRUE;
 
226
                                        } else {
 
227
                                                add_ap = FALSE;
 
228
                                        }
 
229
 
 
230
                                        break;
 
231
                                }
 
232
                        }
 
233
                        if (add_ap) {
 
234
                                g_debug ("adding %s",
 
235
                                         nm_utils_escape_ssid (ssid->data,
 
236
                                                               ssid->len));
 
237
                                g_ptr_array_add (aps_unique, g_object_ref (ap));
 
238
                        }
 
239
                }
 
240
        return aps_unique;
 
241
}
 
242
 
 
243
static gchar *
 
244
get_ap_security_string (NMAccessPoint *ap)
 
245
{
 
246
        NM80211ApSecurityFlags wpa_flags, rsn_flags;
 
247
        NM80211ApFlags flags;
 
248
        GString *str;
 
249
 
 
250
        flags = nm_access_point_get_flags (ap);
 
251
        wpa_flags = nm_access_point_get_wpa_flags (ap);
 
252
        rsn_flags = nm_access_point_get_rsn_flags (ap);
 
253
 
 
254
        str = g_string_new ("");
 
255
        if ((flags & NM_802_11_AP_FLAGS_PRIVACY) &&
 
256
            (wpa_flags == NM_802_11_AP_SEC_NONE) &&
 
257
            (rsn_flags == NM_802_11_AP_SEC_NONE)) {
 
258
                /* TRANSLATORS: this WEP WiFi security */
 
259
                g_string_append_printf (str, "%s, ", _("WEP"));
 
260
        }
 
261
        if (wpa_flags != NM_802_11_AP_SEC_NONE) {
 
262
                /* TRANSLATORS: this WPA WiFi security */
 
263
                g_string_append_printf (str, "%s, ", _("WPA"));
 
264
        }
 
265
        if (rsn_flags != NM_802_11_AP_SEC_NONE) {
 
266
                /* TRANSLATORS: this WPA WiFi security */
 
267
                g_string_append_printf (str, "%s, ", _("WPA2"));
 
268
        }
 
269
        if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ||
 
270
            (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
 
271
                /* TRANSLATORS: this Enterprise WiFi security */
 
272
                g_string_append_printf (str, "%s, ", _("Enterprise"));
 
273
        }
 
274
        if (str->len > 0)
 
275
                g_string_set_size (str, str->len - 2);
 
276
        else {
 
277
                g_string_append (str, C_("Wifi security", "None"));
 
278
        }
 
279
        return g_string_free (str, FALSE);
 
280
}
 
281
 
 
282
static void
 
283
wireless_enabled_toggled (NMClient       *client,
 
284
                          GParamSpec     *pspec,
 
285
                          NetDeviceWifi *device_wifi)
 
286
{
 
287
        gboolean enabled;
 
288
        GtkSwitch *sw;
 
289
        NMDevice *device;
 
290
 
 
291
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
292
        if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI)
 
293
                return;
 
294
 
 
295
        enabled = nm_client_wireless_get_enabled (client);
 
296
        sw = GTK_SWITCH (gtk_builder_get_object (device_wifi->priv->builder,
 
297
                                                 "device_off_switch"));
 
298
 
 
299
        device_wifi->priv->updating_device = TRUE;
 
300
        gtk_switch_set_active (sw, enabled);
 
301
        device_wifi->priv->updating_device = FALSE;
 
302
}
 
303
 
 
304
#if 0
 
305
static void
 
306
update_off_switch_from_device_state (GtkSwitch *sw,
 
307
                                     NMDeviceState state,
 
308
                                     NetDeviceWifi *device_wifi)
 
309
{
 
310
        device_wifi->priv->updating_device = TRUE;
 
311
        switch (state) {
 
312
                case NM_DEVICE_STATE_UNMANAGED:
 
313
                case NM_DEVICE_STATE_UNAVAILABLE:
 
314
                case NM_DEVICE_STATE_DISCONNECTED:
 
315
                case NM_DEVICE_STATE_DEACTIVATING:
 
316
                case NM_DEVICE_STATE_FAILED:
 
317
                        gtk_switch_set_active (sw, FALSE);
 
318
                        break;
 
319
                default:
 
320
                        gtk_switch_set_active (sw, TRUE);
 
321
                        break;
 
322
        }
 
323
        device_wifi->priv->updating_device = FALSE;
 
324
}
 
325
#endif
 
326
 
 
327
static NMConnection *
 
328
find_connection_for_device (NetDeviceWifi *device_wifi,
 
329
                            NMDevice       *device)
 
330
{
 
331
        NetDevice *tmp;
 
332
        NMConnection *connection;
 
333
        NMRemoteSettings *remote_settings;
 
334
        NMClient *client;
 
335
 
 
336
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
337
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
338
        tmp = g_object_new (NET_TYPE_DEVICE,
 
339
                            "client", client,
 
340
                            "remote-settings", remote_settings,
 
341
                            "nm-device", device,
 
342
                            NULL);
 
343
        connection = net_device_get_find_connection (tmp);
 
344
        g_object_unref (tmp);
 
345
        return connection;
 
346
}
 
347
 
 
348
static gboolean
 
349
connection_is_shared (NMConnection *c)
 
350
{
 
351
        NMSettingIP4Config *s_ip4;
 
352
 
 
353
        s_ip4 = nm_connection_get_setting_ip4_config (c);
 
354
        if (g_strcmp0 (nm_setting_ip4_config_get_method (s_ip4),
 
355
                       NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) {
 
356
                return FALSE;
 
357
        }
 
358
 
 
359
        return TRUE;
 
360
}
 
361
 
 
362
static gboolean
 
363
device_is_hotspot (NetDeviceWifi *device_wifi)
 
364
{
 
365
        NMConnection *c;
 
366
        NMDevice *device;
 
367
 
 
368
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
369
        c = find_connection_for_device (device_wifi, device);
 
370
        if (c == NULL)
 
371
                return FALSE;
 
372
 
 
373
        return connection_is_shared (c);
 
374
}
 
375
 
 
376
static const GByteArray *
 
377
device_get_hotspot_ssid (NetDeviceWifi *device_wifi,
 
378
                         NMDevice *device)
 
379
{
 
380
        NMConnection *c;
 
381
        NMSettingWireless *sw;
 
382
 
 
383
        c = find_connection_for_device (device_wifi, device);
 
384
        if (c == NULL) {
 
385
                return FALSE;
 
386
        }
 
387
 
 
388
        sw = nm_connection_get_setting_wireless (c);
 
389
        return nm_setting_wireless_get_ssid (sw);
 
390
}
 
391
 
 
392
static void
 
393
get_secrets_cb (NMRemoteConnection *c,
 
394
                GHashTable         *secrets,
 
395
                GError             *error,
 
396
                gpointer            data)
 
397
{
 
398
        NetDeviceWifi *device_wifi = data;
 
399
        NMSettingWireless *sw;
 
400
 
 
401
        sw = nm_connection_get_setting_wireless (NM_CONNECTION (c));
 
402
 
 
403
        nm_connection_update_secrets (NM_CONNECTION (c),
 
404
                                      nm_setting_wireless_get_security (sw),
 
405
                                      secrets, NULL);
 
406
 
 
407
        nm_device_wifi_refresh_ui (device_wifi);
 
408
}
 
409
 
 
410
static void
 
411
device_get_hotspot_security_details (NetDeviceWifi *device_wifi,
 
412
                                     NMDevice *device,
 
413
                                     gchar **secret,
 
414
                                     gchar **security)
 
415
{
 
416
        NMConnection *c;
 
417
        NMSettingWireless *sw;
 
418
        NMSettingWirelessSecurity *sws;
 
419
        const gchar *key_mgmt;
 
420
        const gchar *tmp_secret;
 
421
        const gchar *tmp_security;
 
422
 
 
423
        c = find_connection_for_device (device_wifi, device);
 
424
        if (c == NULL)
 
425
                return;
 
426
 
 
427
        sw = nm_connection_get_setting_wireless (c);
 
428
        sws = nm_connection_get_setting_wireless_security (c);
 
429
        if (sw == NULL || sws == NULL)
 
430
                return;
 
431
 
 
432
        tmp_secret = NULL;
 
433
        tmp_security = C_("Wifi security", "None");
 
434
 
 
435
        key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws);
 
436
        if (strcmp (key_mgmt, "none") == 0) {
 
437
                tmp_secret = nm_setting_wireless_security_get_wep_key (sws, 0);
 
438
                tmp_security = _("WEP");
 
439
        }
 
440
        else if (strcmp (key_mgmt, "wpa-none") == 0) {
 
441
                tmp_secret = nm_setting_wireless_security_get_psk (sws);
 
442
                tmp_security = _("WPA");
 
443
        } else {
 
444
                g_warning ("unhandled security key-mgmt: %s", key_mgmt);
 
445
        }
 
446
 
 
447
        /* If we don't have secrets, request them from NM and bail.
 
448
         * We'll refresh the UI when secrets arrive.
 
449
         */
 
450
        if (tmp_secret == NULL) {
 
451
                nm_remote_connection_get_secrets ((NMRemoteConnection*)c,
 
452
                                                  nm_setting_wireless_get_security (sw),
 
453
                                                  get_secrets_cb,
 
454
                                                  device_wifi);
 
455
                return;
 
456
        }
 
457
 
 
458
        if (secret)
 
459
                *secret = g_strdup (tmp_secret);
 
460
        if (security)
 
461
                *security = g_strdup (tmp_security);
 
462
}
 
463
 
 
464
static void
 
465
device_wifi_refresh_aps (NetDeviceWifi *device_wifi)
 
466
{
 
467
        const GPtrArray *aps;
 
468
        GPtrArray *aps_unique = NULL;
 
469
        GtkListStore *liststore_network;
 
470
        guint i;
 
471
        NMAccessPoint *active_ap;
 
472
        NMAccessPoint *ap;
 
473
        NMDevice *nm_device;
 
474
 
 
475
        /* populate access points */
 
476
        liststore_network = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder,
 
477
                                                                    "liststore_network"));
 
478
        device_wifi->priv->updating_device = TRUE;
 
479
        gtk_list_store_clear (liststore_network);
 
480
        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
481
        aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device));
 
482
        aps_unique = panel_get_strongest_unique_aps (aps);
 
483
        active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
 
484
 
 
485
        for (i = 0; i < aps_unique->len; i++) {
 
486
                ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i));
 
487
                add_access_point (device_wifi, ap, active_ap, nm_device);
 
488
        }
 
489
 
 
490
        device_wifi->priv->updating_device = FALSE;
 
491
        g_ptr_array_unref (aps_unique);
 
492
}
 
493
 
 
494
static gboolean
 
495
find_ssid_in_store (GtkTreeModel *model, GtkTreeIter *iter, const gchar *ssid)
 
496
{
 
497
        gboolean found;
 
498
        gchar *sort;
 
499
 
 
500
        found = gtk_tree_model_get_iter_first (model, iter);
 
501
 
 
502
        while (found) {
 
503
                gtk_tree_model_get (model, iter,
 
504
                                    COLUMN_SORT, &sort,
 
505
                                    -1);
 
506
                if (g_strcmp0 (ssid, sort) == 0) {
 
507
                        g_free (sort);
 
508
                        return TRUE;
 
509
                }
 
510
                g_free (sort);
 
511
                found = gtk_tree_model_iter_next (model, iter);
 
512
        }
 
513
 
 
514
        return FALSE;
 
515
 
 
516
}
 
517
 
 
518
static void
 
519
add_saved_connection (NetDeviceWifi *device_wifi, NMConnection *connection, NMDevice *nm_device)
 
520
{
 
521
        const GByteArray *ssid;
 
522
        const gchar *id;
 
523
        const gchar *ssid_text;
 
524
        gchar *title;
 
525
        GtkListStore *store;
 
526
        GtkTreeIter iter;
 
527
        NMSetting *setting;
 
528
 
 
529
        setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME);
 
530
 
 
531
        if (setting == NULL)
 
532
                return;
 
533
 
 
534
        ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting));
 
535
        ssid_text = nm_utils_ssid_to_utf8 (ssid);
 
536
        title = g_markup_escape_text (ssid_text, -1);
 
537
        g_debug ("got saved %s", title);
 
538
 
 
539
        id = nm_connection_get_path (connection);
 
540
 
 
541
        store = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder,
 
542
                                                        "liststore_network"));
 
543
        if (find_ssid_in_store (GTK_TREE_MODEL (store), &iter, ssid_text))
 
544
                gtk_list_store_set (store, &iter,
 
545
                                    COLUMN_CONNECTION_ID, id,
 
546
                                    COLUMN_AP_IS_SAVED, TRUE,
 
547
                                    -1);
 
548
        else
 
549
                gtk_list_store_insert_with_values (store, &iter,
 
550
                                                   -1,
 
551
                                                   COLUMN_CONNECTION_ID, id,
 
552
                                                   COLUMN_TITLE, title,
 
553
                                                   COLUMN_SORT, ssid_text,
 
554
                                                   COLUMN_STRENGTH, 0,
 
555
                                                   COLUMN_MODE, 0,
 
556
                                                   COLUMN_SECURITY, 0,
 
557
                                                   COLUMN_ACTIVE, FALSE,
 
558
                                                   COLUMN_AP_IN_RANGE, FALSE,
 
559
                                                   COLUMN_AP_OUT_OF_RANGE, TRUE,
 
560
                                                   COLUMN_AP_IS_SAVED, TRUE,
 
561
                                                   -1);
 
562
        g_free (title);
 
563
        g_free (ssid_text);
 
564
}
 
565
 
 
566
static void
 
567
device_wifi_refresh_saved_connections (NetDeviceWifi *device_wifi)
 
568
{
 
569
        GSList *connections;
 
570
        GSList *filtered;
 
571
        GSList *l;
 
572
        NMDevice *nm_device;
 
573
        NMRemoteSettings *remote_settings;
 
574
 
 
575
        /* add stored connections */
 
576
        device_wifi->priv->updating_device = TRUE;
 
577
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
578
        connections = nm_remote_settings_list_connections (remote_settings);
 
579
        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
580
        filtered = nm_device_filter_connections (nm_device, connections);
 
581
        for (l = filtered; l; l = l->next) {
 
582
                NMConnection *connection = l->data;
 
583
                if (!connection_is_shared (connection))
 
584
                        add_saved_connection (device_wifi, connection, nm_device);
 
585
        }
 
586
        device_wifi->priv->updating_device = FALSE;
 
587
 
 
588
        g_slist_free (connections);
 
589
        g_slist_free (filtered);
 
590
}
 
591
 
 
592
static void
 
593
nm_device_wifi_refresh_hotspot (NetDeviceWifi *device_wifi)
 
594
{
 
595
        const GByteArray *ssid;
 
596
        gchar *hotspot_secret = NULL;
 
597
        gchar *hotspot_security = NULL;
 
598
        gchar *hotspot_ssid = NULL;
 
599
        NMDevice *nm_device;
 
600
 
 
601
        /* refresh hotspot ui */
 
602
        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
603
        ssid = device_get_hotspot_ssid (device_wifi, nm_device);
 
604
        if (ssid)
 
605
                hotspot_ssid = nm_utils_ssid_to_utf8 (ssid);
 
606
        device_get_hotspot_security_details (device_wifi,
 
607
                                             nm_device,
 
608
                                             &hotspot_secret,
 
609
                                             &hotspot_security);
 
610
 
 
611
        panel_set_device_widget_details (device_wifi->priv->builder,
 
612
                                         "hotspot_network_name",
 
613
                                         hotspot_ssid);
 
614
        panel_set_device_widget_details (device_wifi->priv->builder,
 
615
                                         "hotspot_security_key",
 
616
                                         hotspot_secret);
 
617
        panel_set_device_widget_details (device_wifi->priv->builder,
 
618
                                         "hotspot_security",
 
619
                                         hotspot_security);
 
620
        panel_set_device_widget_details (device_wifi->priv->builder,
 
621
                                         "hotspot_connected",
 
622
                                         NULL);
 
623
 
 
624
        g_free (hotspot_secret);
 
625
        g_free (hotspot_security);
 
626
        g_free (hotspot_ssid);
 
627
}
 
628
 
 
629
static void
 
630
update_last_used (NetDeviceWifi *device_wifi)
 
631
{
 
632
        NetDeviceWifiPrivate *priv = device_wifi->priv;
 
633
        gchar *last_used = NULL;
 
634
        GDateTime *now = NULL;
 
635
        GDateTime *then = NULL;
 
636
        gint days;
 
637
        GTimeSpan diff;
 
638
        guint64 timestamp;
 
639
        NMRemoteConnection *connection;
 
640
        NMRemoteSettings *settings;
 
641
        NMSettingConnection *s_con;
 
642
 
 
643
        if (priv->selected_connection_id == NULL)
 
644
                goto out;
 
645
 
 
646
        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
647
        connection = nm_remote_settings_get_connection_by_path (settings,
 
648
                                                                priv->selected_connection_id);
 
649
        s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
 
650
        if (s_con == NULL)
 
651
                goto out;
 
652
        timestamp = nm_setting_connection_get_timestamp (s_con);
 
653
        if (timestamp == 0) {
 
654
                last_used = g_strdup (_("never"));
 
655
                goto out;
 
656
        }
 
657
 
 
658
        /* calculate the amount of time that has elapsed */
 
659
        now = g_date_time_new_now_utc ();
 
660
        then = g_date_time_new_from_unix_utc (timestamp);
 
661
        diff = g_date_time_difference  (now, then);
 
662
        days = diff / G_TIME_SPAN_DAY;
 
663
        if (days == 0)
 
664
                last_used = g_strdup (_("today"));
 
665
        else if (days == 1)
 
666
                last_used = g_strdup (_("yesterday"));
 
667
        else
 
668
                last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days);
 
669
out:
 
670
        panel_set_device_widget_details (device_wifi->priv->builder,
 
671
                                         "last_used",
 
672
                                         last_used);
 
673
        if (now != NULL)
 
674
                g_date_time_unref (now);
 
675
        if (then != NULL)
 
676
                g_date_time_unref (then);
 
677
        g_free (last_used);
 
678
}
 
679
 
 
680
static void
 
681
nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi)
 
682
{
 
683
        const gchar *str;
 
684
        gboolean is_hotspot;
 
685
        gchar *str_tmp = NULL;
 
686
        GtkWidget *widget;
 
687
        gint strength = 0;
 
688
        guint speed = 0;
 
689
        NMAccessPoint *active_ap;
 
690
        NMDevice *nm_device;
 
691
        NMDeviceState state;
 
692
        NMClient *client;
 
693
        NMAccessPoint *ap;
 
694
        NetDeviceWifiPrivate *priv = device_wifi->priv;
 
695
 
 
696
        is_hotspot = device_is_hotspot (device_wifi);
 
697
        if (is_hotspot) {
 
698
                nm_device_wifi_refresh_hotspot (device_wifi);
 
699
                return;
 
700
        }
 
701
 
 
702
        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
703
 
 
704
        if (priv->selected_ap_id) {
 
705
                ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (nm_device),
 
706
                                                              priv->selected_ap_id);
 
707
        }
 
708
        else {
 
709
                ap = NULL;
 
710
        }
 
711
 
 
712
        active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
 
713
 
 
714
        state = nm_device_get_state (nm_device);
 
715
 
 
716
        /* keep this in sync with the signal handler setup in cc_network_panel_init */
 
717
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
718
        wireless_enabled_toggled (client, NULL, device_wifi);
 
719
 
 
720
        if (ap != active_ap)
 
721
                speed = 0;
 
722
        else if (state != NM_DEVICE_STATE_UNAVAILABLE)
 
723
                speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (nm_device));
 
724
        speed /= 1000;
 
725
        if (speed > 0) {
 
726
                /* Translators: network device speed */
 
727
                str_tmp = g_strdup_printf (_("%d Mb/s"), speed);
 
728
        }
 
729
        panel_set_device_widget_details (device_wifi->priv->builder,
 
730
                                         "speed",
 
731
                                         str_tmp);
 
732
 
 
733
        /* set device state, with status and optionally speed */
 
734
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "label_status"));
 
735
        if (ap != active_ap) {
 
736
                if (ap)
 
737
                        gtk_label_set_label (GTK_LABEL (widget), _("Not connected"));
 
738
                else
 
739
                        gtk_label_set_label (GTK_LABEL (widget), _("Out of range"));
 
740
                gtk_widget_set_tooltip_text (widget, "");
 
741
        } else {
 
742
                gtk_label_set_label (GTK_LABEL (widget),
 
743
                                     panel_device_state_to_localized_string (nm_device));
 
744
                gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (nm_device));
 
745
        }
 
746
 
 
747
        /* device MAC */
 
748
        str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device));
 
749
        panel_set_device_widget_details (device_wifi->priv->builder,
 
750
                                         "mac",
 
751
                                         str);
 
752
        /* security */
 
753
        if (ap != active_ap)
 
754
                str_tmp = NULL;
 
755
        else if (active_ap != NULL)
 
756
                str_tmp = get_ap_security_string (active_ap);
 
757
        panel_set_device_widget_details (device_wifi->priv->builder,
 
758
                                         "security",
 
759
                                         str_tmp);
 
760
        g_free (str_tmp);
 
761
 
 
762
        /* signal strength */
 
763
        if (ap != NULL)
 
764
                strength = nm_access_point_get_strength (ap);
 
765
        else
 
766
                strength = 0;
 
767
        if (strength <= 0)
 
768
                str = NULL;
 
769
        else if (strength < 20)
 
770
                str = C_("Signal strength", "None");
 
771
        else if (strength < 40)
 
772
                str = C_("Signal strength", "Weak");
 
773
        else if (strength < 50)
 
774
                str = C_("Signal strength", "Ok");
 
775
        else if (strength < 80)
 
776
                str = C_("Signal strength", "Good");
 
777
        else
 
778
                str = C_("Signal strength", "Excellent");
 
779
        panel_set_device_widget_details (device_wifi->priv->builder,
 
780
                                         "strength",
 
781
                                         str);
 
782
 
 
783
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "label_device"));
 
784
        gtk_label_set_label (GTK_LABEL (widget),
 
785
                             priv->selected_ssid_title ? priv->selected_ssid_title : panel_device_to_localized_string (nm_device));
 
786
 
 
787
        /* only disconnect when connection active */
 
788
        if (ap == active_ap) {
 
789
                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
790
                                                             "button_disconnect1"));
 
791
                gtk_widget_set_sensitive (widget, state == NM_DEVICE_STATE_ACTIVATED);
 
792
                gtk_widget_show (widget);
 
793
                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
794
                                                             "button_connect1"));
 
795
                gtk_widget_hide (widget);
 
796
        } else {
 
797
                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
798
                                                             "button_disconnect1"));
 
799
                gtk_widget_hide (widget);
 
800
                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
801
                                                             "button_connect1"));
 
802
                gtk_widget_show (widget);
 
803
                gtk_widget_set_sensitive (widget, ap != NULL);
 
804
        }
 
805
 
 
806
        /* device MAC */
 
807
        if (ap != active_ap)
 
808
                str = NULL;
 
809
        else
 
810
                str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device));
 
811
        panel_set_device_widget_details (priv->builder, "mac", str);
 
812
 
 
813
        /* set IP entries */
 
814
        if (ap != active_ap)
 
815
                panel_unset_device_widgets (priv->builder);
 
816
        else
 
817
                panel_set_device_widgets (priv->builder, nm_device);
 
818
 
 
819
        if (ap != active_ap)
 
820
                update_last_used (device_wifi);
 
821
        else
 
822
                panel_set_device_widget_details (priv->builder, "last_used", NULL);
 
823
 
 
824
        /* update list of APs */
 
825
        device_wifi_refresh_aps (device_wifi);
 
826
        device_wifi_refresh_saved_connections (device_wifi);
 
827
}
 
828
 
 
829
static void
 
830
device_wifi_refresh (NetObject *object)
 
831
{
 
832
        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object);
 
833
        nm_device_wifi_refresh_ui (device_wifi);
 
834
}
 
835
 
 
836
static void
 
837
device_off_toggled (GtkSwitch *sw,
 
838
                    GParamSpec *pspec,
 
839
                    NetDeviceWifi *device_wifi)
 
840
{
 
841
        NMClient *client;
 
842
        gboolean active;
 
843
 
 
844
        if (device_wifi->priv->updating_device)
 
845
                return;
 
846
 
 
847
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
848
        active = gtk_switch_get_active (sw);
 
849
        nm_client_wireless_set_enabled (client, active);
 
850
}
 
851
 
 
852
 
 
853
static gboolean
 
854
find_connection_id_in_store (GtkTreeModel *model,
 
855
                             GtkTreeIter  *iter,
 
856
                             const gchar  *connection_id)
 
857
{
 
858
        gboolean found;
 
859
        gchar *id;
 
860
 
 
861
        found = gtk_tree_model_get_iter_first (model, iter);
 
862
        while (found) {
 
863
                gtk_tree_model_get (model, iter,
 
864
                                    COLUMN_CONNECTION_ID, &id,
 
865
                                    -1);
 
866
                if (g_strcmp0 (connection_id, id) == 0) {
 
867
                        g_free (id);
 
868
                        return TRUE;
 
869
                }
 
870
                g_free (id);
 
871
                found = gtk_tree_model_iter_next (model, iter);
 
872
        }
 
873
        return FALSE;
 
874
}
 
875
 
 
876
static void
 
877
forget_network_connection_delete_cb (NMRemoteConnection *connection,
 
878
                                     GError *error,
 
879
                                     gpointer user_data)
 
880
{
 
881
        gboolean ret;
 
882
        GtkTreeIter iter;
 
883
        GtkTreeModel *model;
 
884
        GtkTreeView *treeview;
 
885
 
 
886
        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (user_data);
 
887
 
 
888
        if (error != NULL) {
 
889
                g_warning ("failed to delete connection %s: %s",
 
890
                           nm_object_get_path (NM_OBJECT (connection)),
 
891
                           error->message);
 
892
                return;
 
893
        }
 
894
 
 
895
        /* remove the entry from the list */
 
896
        treeview = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder,
 
897
                                                         "treeview_list"));
 
898
        model = gtk_tree_view_get_model (treeview);
 
899
        ret = find_connection_id_in_store (model, &iter,
 
900
                                           device_wifi->priv->selected_connection_id);
 
901
        if (ret)
 
902
                gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
 
903
        show_wifi_list (device_wifi);
 
904
}
 
905
 
 
906
static void
 
907
forget_network_response_cb (GtkWidget *dialog,
 
908
                            gint response,
 
909
                            NetDeviceWifi *device_wifi)
 
910
{
 
911
        NMRemoteConnection *connection;
 
912
        NMRemoteSettings *remote_settings;
 
913
 
 
914
        if (response != GTK_RESPONSE_OK)
 
915
                goto out;
 
916
 
 
917
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
918
        connection = nm_remote_settings_get_connection_by_path (remote_settings, device_wifi->priv->selected_connection_id);
 
919
        if (connection == NULL) {
 
920
                g_warning ("failed to get remote connection");
 
921
                goto out;
 
922
        }
 
923
 
 
924
        /* delete the connection */
 
925
        g_debug ("deleting %s", device_wifi->priv->selected_connection_id);
 
926
        nm_remote_connection_delete (connection,
 
927
                                     forget_network_connection_delete_cb,
 
928
                                     device_wifi);
 
929
out:
 
930
        gtk_widget_destroy (dialog);
 
931
}
 
932
 
 
933
static void
 
934
disconnect_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi)
 
935
{
 
936
        NMDevice *device;
 
937
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
938
        if (device == NULL)
 
939
                return;
 
940
        nm_device_disconnect (device, NULL, NULL);
 
941
}
 
942
 
 
943
static void activate_connection (NetDeviceWifi *device, const gchar *id);
 
944
 
 
945
static void
 
946
connect_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi)
 
947
{
 
948
        if (device_wifi->priv->selected_connection_id)
 
949
                activate_connection (device_wifi, device_wifi->priv->selected_connection_id);
 
950
}
 
951
 
 
952
static void
 
953
forget_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi)
 
954
{
 
955
        gchar *ssid_pretty = NULL;
 
956
        gchar *warning = NULL;
 
957
        GtkWidget *dialog;
 
958
        GtkWidget *window;
 
959
        CcNetworkPanel *panel;
 
960
 
 
961
        ssid_pretty = g_strdup_printf ("<b>%s</b>", device_wifi->priv->selected_ssid_title);
 
962
        warning = g_strdup_printf (_("Network details for %s including password and any custom configuration will be lost."), ssid_pretty);
 
963
        panel = net_object_get_panel (NET_OBJECT (device_wifi));
 
964
        window = gtk_widget_get_toplevel (GTK_WIDGET (panel));
 
965
        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
 
966
                                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
 
967
                                         GTK_MESSAGE_OTHER,
 
968
                                         GTK_BUTTONS_NONE,
 
969
                                         NULL);
 
970
        gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), warning);
 
971
        gtk_dialog_add_buttons (GTK_DIALOG (dialog),
 
972
                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
973
                                _("Forget"), GTK_RESPONSE_OK,
 
974
                                NULL);
 
975
        g_signal_connect (dialog, "response",
 
976
                          G_CALLBACK (forget_network_response_cb), device_wifi);
 
977
        gtk_window_present (GTK_WINDOW (dialog));
 
978
 
 
979
        g_free (ssid_pretty);
 
980
        g_free (warning);
 
981
}
 
982
 
 
983
 
 
984
static void
 
985
connect_to_hidden_network (NetDeviceWifi *device_wifi)
 
986
{
 
987
        NMRemoteSettings *remote_settings;
 
988
        NMClient *client;
 
989
        CcNetworkPanel *panel;
 
990
 
 
991
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
992
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
993
        panel = net_object_get_panel (NET_OBJECT (device_wifi));
 
994
        cc_network_panel_connect_to_hidden_network (panel, client, remote_settings);
 
995
}
 
996
 
 
997
static void
 
998
connection_add_activate_cb (NMClient *client,
 
999
                            NMActiveConnection *connection,
 
1000
                            const char *path,
 
1001
                            GError *error,
 
1002
                            gpointer user_data)
 
1003
{
 
1004
        NetDeviceWifi *device_wifi = user_data;
 
1005
 
 
1006
        if (connection == NULL) {
 
1007
                /* failed to activate */
 
1008
                g_debug ("Failed to add and activate connection '%d': %s",
 
1009
                         error->code,
 
1010
                         error->message);
 
1011
                nm_device_wifi_refresh_ui (device_wifi);
 
1012
        }
 
1013
}
 
1014
 
 
1015
static void
 
1016
connection_activate_cb (NMClient *client,
 
1017
                        NMActiveConnection *connection,
 
1018
                        GError *error,
 
1019
                        gpointer user_data)
 
1020
{
 
1021
        NetDeviceWifi *device_wifi = user_data;
 
1022
 
 
1023
        if (connection == NULL) {
 
1024
                /* failed to activate */
 
1025
                g_debug ("Failed to activate connection '%d': %s",
 
1026
                         error->code,
 
1027
                         error->message);
 
1028
                nm_device_wifi_refresh_ui (device_wifi);
 
1029
        }
 
1030
}
 
1031
 
 
1032
static void
 
1033
activate_connection (NetDeviceWifi *device_wifi,
 
1034
                     const gchar   *connection_id)
 
1035
{
 
1036
        NMDevice *device;
 
1037
        NMClient *client;
 
1038
        NMRemoteSettings *settings;
 
1039
        NMRemoteConnection *connection;
 
1040
 
 
1041
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
1042
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
1043
        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
1044
        connection = nm_remote_settings_get_connection_by_path (settings, connection_id);
 
1045
        nm_client_activate_connection (client,
 
1046
                                       NM_CONNECTION (connection),
 
1047
                                       device, NULL,
 
1048
                                       connection_activate_cb, device_wifi);
 
1049
}
 
1050
 
 
1051
static gboolean
 
1052
is_8021x (NMDevice   *device,
 
1053
          const char *ap_object_path)
 
1054
{
 
1055
        NM80211ApSecurityFlags wpa_flags, rsn_flags;
 
1056
        NMAccessPoint *ap;
 
1057
 
 
1058
        ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device),
 
1059
                                                      ap_object_path);
 
1060
        if (!ap)
 
1061
                return FALSE;
 
1062
 
 
1063
        rsn_flags = nm_access_point_get_rsn_flags (ap);
 
1064
        if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
 
1065
                return TRUE;
 
1066
 
 
1067
        wpa_flags = nm_access_point_get_wpa_flags (ap);
 
1068
        if (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
 
1069
                return TRUE;
 
1070
        return FALSE;
 
1071
}
 
1072
 
 
1073
static void
 
1074
wireless_try_to_connect (NetDeviceWifi *device_wifi,
 
1075
                         const gchar *ssid_target,
 
1076
                         const gchar *ap_object_path)
 
1077
{
 
1078
        const GByteArray *ssid;
 
1079
        const gchar *ssid_tmp = NULL;
 
1080
        GSList *list, *l;
 
1081
        GSList *filtered;
 
1082
        NMConnection *connection_activate = NULL;
 
1083
        NMDevice *device;
 
1084
        NMSettingWireless *setting_wireless;
 
1085
        NMRemoteSettings *remote_settings;
 
1086
        NMClient *client;
 
1087
 
 
1088
        if (device_wifi->priv->updating_device)
 
1089
                goto out;
 
1090
 
 
1091
        if (ap_object_path == NULL || ap_object_path[0] == 0)
 
1092
                goto out;
 
1093
 
 
1094
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
1095
        if (device == NULL)
 
1096
                goto out;
 
1097
 
 
1098
        g_debug ("try to connect to WIFI network %s [%s]",
 
1099
                 ssid_target, ap_object_path);
 
1100
 
 
1101
        /* look for an existing connection we can use */
 
1102
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
1103
        list = nm_remote_settings_list_connections (remote_settings);
 
1104
        g_debug ("%i existing remote connections available", g_slist_length (list));
 
1105
        filtered = nm_device_filter_connections (device, list);
 
1106
        g_debug ("%i suitable remote connections to check", g_slist_length (filtered));
 
1107
        for (l = filtered; l; l = g_slist_next (l)) {
 
1108
                NMConnection *connection;
 
1109
 
 
1110
                connection = NM_CONNECTION (l->data);
 
1111
                setting_wireless = nm_connection_get_setting_wireless (connection);
 
1112
                if (!NM_IS_SETTING_WIRELESS (setting_wireless))
 
1113
                        continue;
 
1114
                ssid = nm_setting_wireless_get_ssid (setting_wireless);
 
1115
                if (ssid == NULL)
 
1116
                        continue;
 
1117
                ssid_tmp = nm_utils_ssid_to_utf8 (ssid);
 
1118
                if (g_strcmp0 (ssid_target, ssid_tmp) == 0) {
 
1119
                        g_debug ("we found an existing connection %s to activate!",
 
1120
                                 nm_connection_get_id (connection));
 
1121
                        connection_activate = connection;
 
1122
                        break;
 
1123
                }
 
1124
                g_free (ssid_tmp);
 
1125
                ssid_tmp = NULL;
 
1126
        }
 
1127
 
 
1128
        g_free (ssid_tmp);
 
1129
        g_slist_free (list);
 
1130
        g_slist_free (filtered);
 
1131
 
 
1132
        /* activate the connection */
 
1133
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
1134
        if (connection_activate != NULL) {
 
1135
                nm_client_activate_connection (client,
 
1136
                                               connection_activate,
 
1137
                                               device, NULL,
 
1138
                                               connection_activate_cb, device_wifi);
 
1139
                goto out;
 
1140
        }
 
1141
 
 
1142
        /* create one, as it's missing */
 
1143
        g_debug ("no existing connection found for %s, creating", ssid_target);
 
1144
 
 
1145
        if (!is_8021x (device, ap_object_path)) {
 
1146
                g_debug ("no existing connection found for %s, creating and activating one", ssid_target);
 
1147
                nm_client_add_and_activate_connection (client,
 
1148
                                                       NULL,
 
1149
                                                       device, ap_object_path,
 
1150
                                                       connection_add_activate_cb, device_wifi);
 
1151
        } else {
 
1152
                CcNetworkPanel *panel;
 
1153
                GPtrArray *array;
 
1154
 
 
1155
                g_debug ("no existing connection found for %s, creating", ssid_target);
 
1156
                array = g_ptr_array_new ();
 
1157
                g_ptr_array_add (array, "connect-8021x-wifi");
 
1158
                g_ptr_array_add (array, (gpointer) nm_object_get_path (NM_OBJECT (device)));
 
1159
                g_ptr_array_add (array, (gpointer) ap_object_path);
 
1160
                g_ptr_array_add (array, NULL);
 
1161
 
 
1162
                panel = net_object_get_panel (NET_OBJECT (device_wifi));
 
1163
                g_object_set (G_OBJECT (panel), "argv", array->pdata, NULL);
 
1164
 
 
1165
                g_ptr_array_free (array, FALSE);
 
1166
        }
 
1167
out:
 
1168
        return;
 
1169
}
 
1170
 
 
1171
static gint
 
1172
wireless_ap_model_sort_cb (GtkTreeModel *model,
 
1173
                           GtkTreeIter *a,
 
1174
                           GtkTreeIter *b,
 
1175
                           gpointer user_data)
 
1176
{
 
1177
        gboolean active_a;
 
1178
        gboolean active_b;
 
1179
        gboolean ap_a;
 
1180
        gboolean ap_b;
 
1181
        gchar *str_a;
 
1182
        gchar *str_b;
 
1183
        gint retval;
 
1184
        gint strength_a;
 
1185
        gint strength_b;
 
1186
 
 
1187
        gtk_tree_model_get (model, a,
 
1188
                            COLUMN_SORT, &str_a,
 
1189
                            COLUMN_STRENGTH, &strength_a,
 
1190
                            COLUMN_ACTIVE, &active_a,
 
1191
                            COLUMN_AP_IN_RANGE, &ap_a,
 
1192
                            -1);
 
1193
        gtk_tree_model_get (model, b,
 
1194
                            COLUMN_SORT, &str_b,
 
1195
                            COLUMN_STRENGTH, &strength_b,
 
1196
                            COLUMN_ACTIVE, &active_b,
 
1197
                            COLUMN_AP_IN_RANGE, &ap_b,
 
1198
                            -1);
 
1199
 
 
1200
        /* active entry first */
 
1201
        if (active_a) {
 
1202
                retval = -1;
 
1203
                goto out;
 
1204
        }
 
1205
 
 
1206
        if (active_b) {
 
1207
                retval = 1;
 
1208
                goto out;
 
1209
        }
 
1210
 
 
1211
        /* aps before connections */
 
1212
        if (ap_a && !ap_b) {
 
1213
                retval = -1;
 
1214
                goto out;
 
1215
        }
 
1216
        if (!ap_a && ap_b) {
 
1217
                retval = 1;
 
1218
                goto out;
 
1219
        }
 
1220
 
 
1221
        /* case sensitive search like before */
 
1222
        retval = strength_b - strength_a;
 
1223
out:
 
1224
        g_free (str_a);
 
1225
        g_free (str_b);
 
1226
 
 
1227
        return retval;
 
1228
}
 
1229
 
 
1230
static GByteArray *
 
1231
ssid_to_byte_array (const gchar *ssid)
 
1232
{
 
1233
        guint32 len;
 
1234
        GByteArray *ba;
 
1235
 
 
1236
        len = strlen (ssid);
 
1237
        ba = g_byte_array_sized_new (len);
 
1238
        g_byte_array_append (ba, (guchar *)ssid, len);
 
1239
 
 
1240
        return ba;
 
1241
}
 
1242
 
 
1243
static gchar *
 
1244
get_hostname (void)
 
1245
{
 
1246
        GDBusConnection *bus;
 
1247
        GVariant *res;
 
1248
        GVariant *inner;
 
1249
        gchar *str;
 
1250
        GError *error;
 
1251
 
 
1252
        error = NULL;
 
1253
        bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
 
1254
        if (error != NULL) {
 
1255
                g_warning ("Failed to get system bus connection: %s", error->message);
 
1256
                g_error_free (error);
 
1257
 
 
1258
                return NULL;
 
1259
        }
 
1260
        res = g_dbus_connection_call_sync (bus,
 
1261
                                           "org.freedesktop.hostname1",
 
1262
                                           "/org/freedesktop/hostname1",
 
1263
                                           "org.freedesktop.DBus.Properties",
 
1264
                                           "Get",
 
1265
                                           g_variant_new ("(ss)",
 
1266
                                                          "org.freedesktop.hostname1",
 
1267
                                                          "PrettyHostname"),
 
1268
                                           (GVariantType*)"(v)",
 
1269
                                           G_DBUS_CALL_FLAGS_NONE,
 
1270
                                           -1,
 
1271
                                           NULL,
 
1272
                                           &error);
 
1273
        g_object_unref (bus);
 
1274
 
 
1275
        if (error != NULL) {
 
1276
                g_warning ("Getting pretty hostname failed: %s", error->message);
 
1277
                g_error_free (error);
 
1278
        }
 
1279
 
 
1280
        str = NULL;
 
1281
 
 
1282
        if (res != NULL) {
 
1283
                g_variant_get (res, "(v)", &inner);
 
1284
                str = g_variant_dup_string (inner, NULL);
 
1285
                g_variant_unref (res);
 
1286
        }
 
1287
 
 
1288
        if (str == NULL || *str == '\0') {
 
1289
                str = g_strdup (g_get_host_name ());
 
1290
        }
 
1291
 
 
1292
        if (str == NULL || *str == '\0') {
 
1293
                str = g_strdup ("GNOME");
 
1294
        }
 
1295
 
 
1296
        return str;
 
1297
}
 
1298
 
 
1299
static GByteArray *
 
1300
generate_ssid_for_hotspot (NetDeviceWifi *device_wifi)
 
1301
{
 
1302
        GByteArray *ssid_array;
 
1303
        gchar *ssid;
 
1304
 
 
1305
        ssid = get_hostname ();
 
1306
        ssid_array = ssid_to_byte_array (ssid);
 
1307
        g_free (ssid);
 
1308
 
 
1309
        return ssid_array;
 
1310
}
 
1311
 
 
1312
static gchar *
 
1313
generate_wep_key (NetDeviceWifi *device_wifi)
 
1314
{
 
1315
        gchar key[11];
 
1316
        gint i;
 
1317
        const gchar *hexdigits = "0123456789abcdef";
 
1318
 
 
1319
        /* generate a 10-digit hex WEP key */
 
1320
        for (i = 0; i < 10; i++) {
 
1321
                gint digit;
 
1322
                digit = g_random_int_range (0, 16);
 
1323
                key[i] = hexdigits[digit];
 
1324
        }
 
1325
        key[10] = 0;
 
1326
 
 
1327
        return g_strdup (key);
 
1328
}
 
1329
 
 
1330
static gboolean
 
1331
is_hotspot_connection (NMConnection *connection)
 
1332
{
 
1333
        NMSettingConnection *sc;
 
1334
        NMSettingWireless *sw;
 
1335
        NMSettingIP4Config *sip;
 
1336
 
 
1337
        sc = nm_connection_get_setting_connection (connection);
 
1338
        if (g_strcmp0 (nm_setting_connection_get_connection_type (sc), "802-11-wireless") != 0) {
 
1339
                return FALSE;
 
1340
        }
 
1341
        sw = nm_connection_get_setting_wireless (connection);
 
1342
        if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0) {
 
1343
                return FALSE;
 
1344
        }
 
1345
        if (g_strcmp0 (nm_setting_wireless_get_security (sw), "802-11-wireless-security") != 0) {
 
1346
                return FALSE;
 
1347
        }
 
1348
        sip = nm_connection_get_setting_ip4_config (connection);
 
1349
        if (g_strcmp0 (nm_setting_ip4_config_get_method (sip), "shared") != 0) {
 
1350
                return FALSE;
 
1351
        }
 
1352
 
 
1353
        return TRUE;
 
1354
}
 
1355
 
 
1356
static void
 
1357
show_hotspot_ui (NetDeviceWifi *device_wifi)
 
1358
{
 
1359
        GtkWidget *widget;
 
1360
        GtkSwitch *sw;
 
1361
 
 
1362
        /* show hotspot tab */
 
1363
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
 
1364
        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 3);
 
1365
 
 
1366
        /* force switch to on as this succeeded */
 
1367
        sw = GTK_SWITCH (gtk_builder_get_object (device_wifi->priv->builder,
 
1368
                                                 "switch_hotspot_off"));
 
1369
        device_wifi->priv->updating_device = TRUE;
 
1370
        gtk_switch_set_active (sw, TRUE);
 
1371
        device_wifi->priv->updating_device = FALSE;
 
1372
}
 
1373
 
 
1374
static void
 
1375
activate_cb (NMClient           *client,
 
1376
             NMActiveConnection *connection,
 
1377
             GError             *error,
 
1378
             NetDeviceWifi     *device_wifi)
 
1379
{
 
1380
        if (error != NULL) {
 
1381
                g_warning ("Failed to add new connection: (%d) %s",
 
1382
                           error->code,
 
1383
                           error->message);
 
1384
                return;
 
1385
        }
 
1386
 
 
1387
        /* show hotspot tab */
 
1388
        nm_device_wifi_refresh_ui (device_wifi);
 
1389
        show_hotspot_ui (device_wifi);
 
1390
}
 
1391
 
 
1392
static void
 
1393
activate_new_cb (NMClient           *client,
 
1394
                 NMActiveConnection *connection,
 
1395
                 const gchar        *path,
 
1396
                 GError             *error,
 
1397
                 NetDeviceWifi     *device_wifi)
 
1398
{
 
1399
        activate_cb (client, connection, error, device_wifi);
 
1400
}
 
1401
 
 
1402
static void
 
1403
start_shared_connection (NetDeviceWifi *device_wifi)
 
1404
{
 
1405
        NMConnection *c;
 
1406
        NMConnection *tmp;
 
1407
        NMSettingConnection *sc;
 
1408
        NMSettingWireless *sw;
 
1409
        NMSettingIP4Config *sip;
 
1410
        NMSettingWirelessSecurity *sws;
 
1411
        NMDevice *device;
 
1412
        GByteArray *ssid_array;
 
1413
        gchar *wep_key;
 
1414
        const gchar *str_mac;
 
1415
        struct ether_addr *bin_mac;
 
1416
        GSList *connections;
 
1417
        GSList *filtered;
 
1418
        GSList *l;
 
1419
        NMClient *client;
 
1420
        NMRemoteSettings *remote_settings;
 
1421
 
 
1422
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
1423
        g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI);
 
1424
 
 
1425
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
1426
        connections = nm_remote_settings_list_connections (remote_settings);
 
1427
        filtered = nm_device_filter_connections (device, connections);
 
1428
        g_slist_free (connections);
 
1429
        c = NULL;
 
1430
        for (l = filtered; l; l = l->next) {
 
1431
                tmp = l->data;
 
1432
                if (is_hotspot_connection (tmp)) {
 
1433
                        c = tmp;
 
1434
                        break;
 
1435
                }
 
1436
        }
 
1437
        g_slist_free (filtered);
 
1438
 
 
1439
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
1440
        if (c != NULL) {
 
1441
                g_debug ("activate existing hotspot connection\n");
 
1442
                nm_client_activate_connection (client,
 
1443
                                               c,
 
1444
                                               device,
 
1445
                                               NULL,
 
1446
                                               (NMClientActivateFn)activate_cb,
 
1447
                                               device_wifi);
 
1448
                return;
 
1449
        }
 
1450
 
 
1451
        g_debug ("create new hotspot connection\n");
 
1452
        c = nm_connection_new ();
 
1453
 
 
1454
        sc = (NMSettingConnection *)nm_setting_connection_new ();
 
1455
        g_object_set (sc,
 
1456
                      "type", "802-11-wireless",
 
1457
                      "id", "Hotspot",
 
1458
                      "autoconnect", FALSE,
 
1459
                      NULL);
 
1460
        nm_connection_add_setting (c, (NMSetting *)sc);
 
1461
 
 
1462
        sw = (NMSettingWireless *)nm_setting_wireless_new ();
 
1463
        g_object_set (sw,
 
1464
                      "mode", "adhoc",
 
1465
                      "security", "802-11-wireless-security",
 
1466
                      NULL);
 
1467
 
 
1468
        str_mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device));
 
1469
        bin_mac = ether_aton (str_mac);
 
1470
        if (bin_mac) {
 
1471
                GByteArray *hw_address;
 
1472
 
 
1473
                hw_address = g_byte_array_sized_new (ETH_ALEN);
 
1474
                g_byte_array_append (hw_address, bin_mac->ether_addr_octet, ETH_ALEN);
 
1475
                g_object_set (sw,
 
1476
                              "mac-address", hw_address,
 
1477
                              NULL);
 
1478
                g_byte_array_unref (hw_address);
 
1479
        }
 
1480
        nm_connection_add_setting (c, (NMSetting *)sw);
 
1481
 
 
1482
        sip = (NMSettingIP4Config*) nm_setting_ip4_config_new ();
 
1483
        g_object_set (sip, "method", "shared", NULL);
 
1484
        nm_connection_add_setting (c, (NMSetting *)sip);
 
1485
 
 
1486
        ssid_array = generate_ssid_for_hotspot (device_wifi);
 
1487
        g_object_set (sw,
 
1488
                      "ssid", ssid_array,
 
1489
                      NULL);
 
1490
        g_byte_array_unref (ssid_array);
 
1491
 
 
1492
        sws = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new ();
 
1493
        wep_key = generate_wep_key (device_wifi);
 
1494
        g_object_set (sws,
 
1495
                      "key-mgmt", "none",
 
1496
                      "wep-key0", wep_key,
 
1497
                      "wep-key-type", NM_WEP_KEY_TYPE_KEY,
 
1498
                      NULL);
 
1499
        g_free (wep_key);
 
1500
        nm_connection_add_setting (c, (NMSetting *)sws);
 
1501
 
 
1502
        nm_client_add_and_activate_connection (client,
 
1503
                                               c,
 
1504
                                               device,
 
1505
                                               NULL,
 
1506
                                               (NMClientAddActivateFn)activate_new_cb,
 
1507
                                               device_wifi);
 
1508
 
 
1509
        g_object_unref (c);
 
1510
}
 
1511
 
 
1512
static void
 
1513
start_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi)
 
1514
{
 
1515
        if (response == GTK_RESPONSE_OK) {
 
1516
                start_shared_connection (device_wifi);
 
1517
        }
 
1518
        gtk_widget_hide (dialog);
 
1519
}
 
1520
 
 
1521
static void
 
1522
start_hotspot (GtkButton *button, NetDeviceWifi *device_wifi)
 
1523
{
 
1524
        NMDevice *device;
 
1525
        const GPtrArray *connections;
 
1526
        gchar *active_ssid;
 
1527
        NMClient *client;
 
1528
        GtkWidget *dialog;
 
1529
        GtkWidget *window;
 
1530
        GtkWidget *widget;
 
1531
        GString *str;
 
1532
 
 
1533
        active_ssid = NULL;
 
1534
 
 
1535
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
1536
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
1537
        connections = nm_client_get_active_connections (client);
 
1538
        if (connections) {
 
1539
                gint i;
 
1540
                for (i = 0; i < connections->len; i++) {
 
1541
                        NMActiveConnection *c;
 
1542
                        const GPtrArray *devices;
 
1543
                        c = (NMActiveConnection *)connections->pdata[i];
 
1544
                        devices = nm_active_connection_get_devices (c);
 
1545
                        if (devices && devices->pdata[0] == device) {
 
1546
                                NMAccessPoint *ap;
 
1547
                                ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
 
1548
                                active_ssid = nm_utils_ssid_to_utf8 (nm_access_point_get_ssid (ap));
 
1549
                                break;
 
1550
                        }
 
1551
                }
 
1552
        }
 
1553
 
 
1554
        window = gtk_widget_get_toplevel (GTK_WIDGET (button));
 
1555
 
 
1556
        dialog = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "hotspot-dialog"));
 
1557
        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
 
1558
 
 
1559
        str = g_string_new (_("If you have a connection to the Internet other than wireless, you can use it to share your internet connection with others."));
 
1560
        g_string_append (str, "\n\n");
 
1561
 
 
1562
        if (active_ssid) {
 
1563
                g_string_append_printf (str, _("Switching on the wireless hotspot will disconnect you from <b>%s</b>."), active_ssid);
 
1564
                g_string_append (str, " ");
 
1565
        }
 
1566
 
 
1567
        g_string_append (str, _("It is not possible to access the internet through your wireless while the hotspot is active."));
 
1568
 
 
1569
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "hotspot-dialog-content"));
 
1570
        gtk_label_set_markup (GTK_LABEL (widget), str->str);
 
1571
        g_string_free (str, TRUE);
 
1572
 
 
1573
        g_signal_connect (dialog, "response",
 
1574
                          G_CALLBACK (start_hotspot_response_cb), device_wifi);
 
1575
        gtk_window_present (GTK_WINDOW (dialog));
 
1576
        g_free (active_ssid);
 
1577
}
 
1578
 
 
1579
static void
 
1580
stop_shared_connection (NetDeviceWifi *device_wifi)
 
1581
{
 
1582
        const GPtrArray *connections;
 
1583
        const GPtrArray *devices;
 
1584
        NMDevice *device;
 
1585
        gint i;
 
1586
        NMActiveConnection *c;
 
1587
        NMClient *client;
 
1588
 
 
1589
        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
1590
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
1591
        connections = nm_client_get_active_connections (client);
 
1592
        for (i = 0; i < connections->len; i++) {
 
1593
                c = (NMActiveConnection *)connections->pdata[i];
 
1594
 
 
1595
                devices = nm_active_connection_get_devices (c);
 
1596
                if (devices && devices->pdata[0] == device) {
 
1597
                        nm_client_deactivate_connection (client, c);
 
1598
                        break;
 
1599
                }
 
1600
        }
 
1601
 
 
1602
        nm_device_wifi_refresh_ui (device_wifi);
 
1603
        show_wifi_list (device_wifi);
 
1604
}
 
1605
 
 
1606
static void
 
1607
stop_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *device_wifi)
 
1608
{
 
1609
        if (response == GTK_RESPONSE_OK) {
 
1610
                stop_shared_connection (device_wifi);
 
1611
        }
 
1612
        gtk_widget_destroy (dialog);
 
1613
}
 
1614
 
 
1615
static void
 
1616
switch_hotspot_changed_cb (GtkSwitch *sw,
 
1617
                           GParamSpec *pspec,
 
1618
                           NetDeviceWifi *device_wifi)
 
1619
{
 
1620
        GtkWidget *dialog;
 
1621
        GtkWidget *window;
 
1622
        CcNetworkPanel *panel;
 
1623
 
 
1624
        if (device_wifi->priv->updating_device)
 
1625
                return;
 
1626
 
 
1627
        panel = net_object_get_panel (NET_OBJECT (device_wifi));
 
1628
        window = gtk_widget_get_toplevel (GTK_WIDGET (panel));
 
1629
        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
 
1630
                                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
 
1631
                                         GTK_MESSAGE_OTHER,
 
1632
                                         GTK_BUTTONS_NONE,
 
1633
                                         _("Stop hotspot and disconnect any users?"));
 
1634
        gtk_dialog_add_buttons (GTK_DIALOG (dialog),
 
1635
                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
1636
                                _("_Stop Hotspot"), GTK_RESPONSE_OK,
 
1637
                                NULL);
 
1638
        g_signal_connect (dialog, "response",
 
1639
                          G_CALLBACK (stop_hotspot_response_cb), device_wifi);
 
1640
        gtk_window_present (GTK_WINDOW (dialog));
 
1641
}
 
1642
 
 
1643
static void
 
1644
connect_wifi_network (NetDeviceWifi *device_wifi,
 
1645
                      GtkTreeView *tv,
 
1646
                      GtkTreePath *path)
 
1647
{
 
1648
        gboolean ap_in_range;
 
1649
        gchar *ap_object_path;
 
1650
        gchar *ssid;
 
1651
        gchar *connection_id;
 
1652
        GtkTreeIter iter;
 
1653
        GtkTreeModel *model;
 
1654
        NM80211Mode mode;
 
1655
 
 
1656
        model = gtk_tree_view_get_model (tv);
 
1657
        gtk_tree_model_get_iter (model, &iter, path);
 
1658
 
 
1659
        gtk_tree_model_get (model, &iter,
 
1660
                            COLUMN_ACCESS_POINT_ID, &ap_object_path,
 
1661
                            COLUMN_CONNECTION_ID, &connection_id,
 
1662
                            COLUMN_TITLE, &ssid,
 
1663
                            COLUMN_AP_IN_RANGE, &ap_in_range,
 
1664
                            COLUMN_MODE, &mode,
 
1665
                            -1);
 
1666
        if (ap_in_range) {
 
1667
                if (connection_id)
 
1668
                        activate_connection (device_wifi, connection_id);
 
1669
                else
 
1670
                        wireless_try_to_connect (device_wifi, ssid, ap_object_path);
 
1671
        } else {
 
1672
                g_warning ("can't connect");
 
1673
        }
 
1674
 
 
1675
        g_free (ap_object_path);
 
1676
        g_free (connection_id);
 
1677
        g_free (ssid);
 
1678
}
 
1679
 
 
1680
static void
 
1681
show_wifi_details (NetDeviceWifi *device_wifi,
 
1682
                   GtkTreeView *tv,
 
1683
                   GtkTreePath *path)
 
1684
{
 
1685
        GtkWidget *widget;
 
1686
        gboolean ret;
 
1687
        gboolean in_range;
 
1688
        GtkTreeModel *model;
 
1689
        GtkTreeIter iter;
 
1690
        gchar *path_str;
 
1691
 
 
1692
        model = gtk_tree_view_get_model (tv);
 
1693
        path_str = gtk_tree_path_to_string (path);
 
1694
        ret = gtk_tree_model_get_iter_from_string (model, &iter, path_str);
 
1695
        if (!ret)
 
1696
                goto out;
 
1697
 
 
1698
        /* get parameters about the selected connection */
 
1699
        g_free (device_wifi->priv->selected_connection_id);
 
1700
        g_free (device_wifi->priv->selected_ssid_title);
 
1701
        gtk_tree_model_get (model, &iter,
 
1702
                            COLUMN_ACCESS_POINT_ID, &device_wifi->priv->selected_ap_id,
 
1703
                            COLUMN_CONNECTION_ID, &device_wifi->priv->selected_connection_id,
 
1704
                            COLUMN_TITLE, &device_wifi->priv->selected_ssid_title,
 
1705
                            COLUMN_AP_IN_RANGE, &in_range,
 
1706
                            -1);
 
1707
        g_debug ("ssid = %s, in-range = %i",
 
1708
                 device_wifi->priv->selected_ssid_title, in_range);
 
1709
 
 
1710
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
 
1711
 
 
1712
        nm_device_wifi_refresh_ui (device_wifi);
 
1713
        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1);
 
1714
 
 
1715
out:
 
1716
        g_free (path_str);
 
1717
}
 
1718
 
 
1719
static void
 
1720
show_wifi_list (NetDeviceWifi *device_wifi)
 
1721
{
 
1722
        GtkWidget *widget;
 
1723
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
 
1724
        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
 
1725
}
 
1726
 
 
1727
static gboolean
 
1728
arrow_visible (GtkTreeModel *model,
 
1729
               GtkTreeIter  *iter)
 
1730
{
 
1731
        gboolean active;
 
1732
        gboolean ap_is_saved;
 
1733
        gboolean ret;
 
1734
        gchar *sort;
 
1735
 
 
1736
        gtk_tree_model_get (model, iter,
 
1737
                            COLUMN_ACTIVE, &active,
 
1738
                            COLUMN_AP_IS_SAVED, &ap_is_saved,
 
1739
                            COLUMN_SORT, &sort,
 
1740
                            -1);
 
1741
 
 
1742
        if (active || ap_is_saved)
 
1743
                ret = TRUE;
 
1744
        else
 
1745
                ret = FALSE;
 
1746
 
 
1747
        g_free (sort);
 
1748
 
 
1749
        return ret;
 
1750
}
 
1751
 
 
1752
static void
 
1753
set_arrow_image (GtkCellLayout   *layout,
 
1754
                 GtkCellRenderer *cell,
 
1755
                 GtkTreeModel    *model,
 
1756
                 GtkTreeIter     *iter,
 
1757
                 gpointer         user_data)
 
1758
{
 
1759
        NetDeviceWifi *device = user_data;
 
1760
        const gchar *icon;
 
1761
 
 
1762
        if (arrow_visible (model, iter)) {
 
1763
                GtkWidget *widget;
 
1764
 
 
1765
                widget = GTK_WIDGET (gtk_builder_get_object (device->priv->builder,
 
1766
                                                             "treeview_list"));
 
1767
 
 
1768
                if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
 
1769
                        icon = "go-previous";
 
1770
                else
 
1771
                        icon = "go-next";
 
1772
        }
 
1773
        else {
 
1774
                icon = "";
 
1775
        }
 
1776
 
 
1777
        g_object_set (cell, "icon-name", icon, NULL);
 
1778
}
 
1779
 
 
1780
static void
 
1781
edit_connection (GtkButton *button, NetDeviceWifi *device_wifi)
 
1782
{
 
1783
        net_object_edit (NET_OBJECT (device_wifi));
 
1784
}
 
1785
 
 
1786
static void
 
1787
remote_settings_read_cb (NMRemoteSettings *remote_settings,
 
1788
                         NetDeviceWifi *device_wifi)
 
1789
{
 
1790
        gboolean is_hotspot;
 
1791
 
 
1792
        device_wifi_refresh_saved_connections (device_wifi);
 
1793
 
 
1794
        /* go straight to the hotspot UI */
 
1795
        is_hotspot = device_is_hotspot (device_wifi);
 
1796
        if (is_hotspot) {
 
1797
                nm_device_wifi_refresh_hotspot (device_wifi);
 
1798
                show_hotspot_ui (device_wifi);
 
1799
        }
 
1800
}
 
1801
 
 
1802
static gboolean
 
1803
separator_visible (GtkTreeModel *model,
 
1804
                   GtkTreeIter  *iter)
 
1805
{
 
1806
        gboolean active;
 
1807
        gboolean ap_is_saved;
 
1808
        gboolean ap_in_range;
 
1809
        gchar *sort;
 
1810
        gboolean ret;
 
1811
 
 
1812
        gtk_tree_model_get (model, iter,
 
1813
                            COLUMN_ACTIVE, &active,
 
1814
                            COLUMN_AP_IS_SAVED, &ap_is_saved,
 
1815
                            COLUMN_AP_IN_RANGE, &ap_in_range,
 
1816
                            COLUMN_SORT, &sort,
 
1817
                            -1);
 
1818
 
 
1819
        if (!active && ap_is_saved && ap_in_range)
 
1820
                ret = TRUE;
 
1821
        else
 
1822
                ret = FALSE;
 
1823
 
 
1824
        g_free (sort);
 
1825
 
 
1826
        return ret;
 
1827
 
 
1828
}
 
1829
 
 
1830
static void
 
1831
set_draw_separator (GtkCellLayout   *layout,
 
1832
                    GtkCellRenderer *cell,
 
1833
                    GtkTreeModel    *model,
 
1834
                    GtkTreeIter     *iter,
 
1835
                    gpointer         user_data)
 
1836
{
 
1837
        gboolean draw;
 
1838
 
 
1839
        draw = separator_visible (model, iter);
 
1840
 
 
1841
        g_object_set (cell, "draw", draw, NULL);
 
1842
}
 
1843
 
 
1844
static void
 
1845
switch_page_cb (GtkNotebook   *notebook,
 
1846
                GtkWidget     *page,
 
1847
                guint          page_num,
 
1848
                NetDeviceWifi *device_wifi)
 
1849
{
 
1850
        GtkWidget *widget;
 
1851
 
 
1852
        if (page_num == 1) {
 
1853
                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
1854
                                                             "button_back1"));
 
1855
                gtk_widget_grab_focus (widget);
 
1856
        }
 
1857
}
 
1858
 
 
1859
static void
 
1860
net_device_wifi_constructed (GObject *object)
 
1861
{
 
1862
        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object);
 
1863
        NMClient *client;
 
1864
        NMRemoteSettings *remote_settings;
 
1865
        NMClientPermissionResult perm;
 
1866
        GtkWidget *widget;
 
1867
 
 
1868
        G_OBJECT_CLASS (net_device_wifi_parent_class)->constructed (object);
 
1869
 
 
1870
        client = net_object_get_client (NET_OBJECT (device_wifi));
 
1871
        g_signal_connect (client, "notify::wireless-enabled",
 
1872
                          G_CALLBACK (wireless_enabled_toggled), device_wifi);
 
1873
 
 
1874
        /* only show the button if the user can create a hotspot */
 
1875
        perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN);
 
1876
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
1877
                                                     "start_hotspot_button"));
 
1878
        gtk_widget_set_sensitive (widget, perm == NM_CLIENT_PERMISSION_RESULT_YES ||
 
1879
                                          perm == NM_CLIENT_PERMISSION_RESULT_AUTH);
 
1880
 
 
1881
        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
 
1882
        g_signal_connect (remote_settings, "connections-read",
 
1883
                          G_CALLBACK (remote_settings_read_cb), device_wifi);
 
1884
 
 
1885
        nm_device_wifi_refresh_ui (device_wifi);
 
1886
}
 
1887
 
 
1888
static void
 
1889
net_device_wifi_finalize (GObject *object)
 
1890
{
 
1891
        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object);
 
1892
        NetDeviceWifiPrivate *priv = device_wifi->priv;
 
1893
 
 
1894
        g_object_unref (priv->builder);
 
1895
        g_free (priv->selected_ssid_title);
 
1896
        g_free (priv->selected_connection_id);
 
1897
        g_free (priv->selected_ap_id);
 
1898
 
 
1899
        G_OBJECT_CLASS (net_device_wifi_parent_class)->finalize (object);
 
1900
}
 
1901
 
 
1902
static void
 
1903
device_wifi_edit (NetObject *object)
 
1904
{
 
1905
        const gchar *uuid;
 
1906
        gchar *cmdline;
 
1907
        GError *error = NULL;
 
1908
        NetDeviceWifi *device = NET_DEVICE_WIFI (object);
 
1909
        NMRemoteSettings *settings;
 
1910
        NMRemoteConnection *connection;
 
1911
 
 
1912
        settings = net_object_get_remote_settings (object);
 
1913
        connection = nm_remote_settings_get_connection_by_path (settings, device->priv->selected_connection_id);
 
1914
        if (connection == NULL) {
 
1915
                g_warning ("failed to get remote connection");
 
1916
                return;
 
1917
        }
 
1918
        uuid = nm_connection_get_uuid (NM_CONNECTION (connection));
 
1919
        cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
 
1920
        g_debug ("Launching '%s'\n", cmdline);
 
1921
        if (!g_spawn_command_line_async (cmdline, &error)) {
 
1922
                g_warning ("Failed to launch nm-connection-editor: %s", error->message);
 
1923
                g_error_free (error);
 
1924
        }
 
1925
        g_free (cmdline);
 
1926
}
 
1927
 
 
1928
static void
 
1929
net_device_wifi_class_init (NetDeviceWifiClass *klass)
 
1930
{
 
1931
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
1932
        NetObjectClass *parent_class = NET_OBJECT_CLASS (klass);
 
1933
 
 
1934
        object_class->finalize = net_device_wifi_finalize;
 
1935
        object_class->constructed = net_device_wifi_constructed;
 
1936
        parent_class->add_to_notebook = device_wifi_proxy_add_to_notebook;
 
1937
        parent_class->refresh = device_wifi_refresh;
 
1938
        parent_class->edit = device_wifi_edit;
 
1939
 
 
1940
        g_type_class_add_private (klass, sizeof (NetDeviceWifiPrivate));
 
1941
}
 
1942
 
 
1943
static void
 
1944
activate_ssid_cb (PanelCellRendererText *cell,
 
1945
                  const gchar           *path,
 
1946
                  NetDeviceWifi         *device_wifi)
 
1947
{
 
1948
        GtkTreeView *tv;
 
1949
        GtkTreePath *tpath;
 
1950
 
 
1951
        g_debug ("activate ssid!\n");
 
1952
 
 
1953
        tv = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder,
 
1954
                                                    "treeview_list"));
 
1955
        tpath = gtk_tree_path_new_from_string (path);
 
1956
 
 
1957
        connect_wifi_network (device_wifi, tv, tpath);
 
1958
 
 
1959
        gtk_tree_path_free (tpath);
 
1960
}
 
1961
 
 
1962
static void
 
1963
activate_arrow_cb (PanelCellRendererText *cell,
 
1964
                  const gchar           *path,
 
1965
                  NetDeviceWifi         *device_wifi)
 
1966
{
 
1967
        GtkTreeView *tv;
 
1968
        GtkTreeModel *model;
 
1969
        GtkTreePath *tpath;
 
1970
        GtkTreeIter iter;
 
1971
 
 
1972
        g_debug ("activate arrow!\n");
 
1973
 
 
1974
        tv = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder,
 
1975
                                                    "treeview_list"));
 
1976
        model = gtk_tree_view_get_model (tv);
 
1977
        tpath = gtk_tree_path_new_from_string (path);
 
1978
        gtk_tree_model_get_iter (model, &iter, tpath);
 
1979
 
 
1980
        if (arrow_visible (model, &iter))
 
1981
                show_wifi_details (device_wifi, tv, tpath);
 
1982
        gtk_tree_path_free (tpath);
 
1983
}
 
1984
 
 
1985
static void
 
1986
net_device_wifi_init (NetDeviceWifi *device_wifi)
 
1987
{
 
1988
        GError *error = NULL;
 
1989
        GtkWidget *widget;
 
1990
        GtkCellRenderer *renderer1;
 
1991
        GtkCellRenderer *renderer2;
 
1992
        GtkCellRenderer *renderer3;
 
1993
        GtkCellRenderer *renderer4;
 
1994
        GtkCellRenderer *renderer5;
 
1995
        GtkCellRenderer *renderer6;
 
1996
        GtkCellRenderer *renderer7;
 
1997
        GtkCellRenderer *renderer8;
 
1998
        GtkTreeSortable *sortable;
 
1999
        GtkTreeViewColumn *column;
 
2000
        GtkCellArea *area;
 
2001
 
 
2002
        device_wifi->priv = NET_DEVICE_WIFI_GET_PRIVATE (device_wifi);
 
2003
 
 
2004
        device_wifi->priv->builder = gtk_builder_new ();
 
2005
        gtk_builder_add_from_file (device_wifi->priv->builder,
 
2006
                                   GNOMECC_UI_DIR "/network-wifi.ui",
 
2007
                                   &error);
 
2008
        if (error != NULL) {
 
2009
                g_warning ("Could not load interface file: %s", error->message);
 
2010
                g_error_free (error);
 
2011
                return;
 
2012
        }
 
2013
 
 
2014
        /* setup wifi views */
 
2015
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2016
                                                     "device_off_switch"));
 
2017
        g_signal_connect (widget, "notify::active",
 
2018
                          G_CALLBACK (device_off_toggled), device_wifi);
 
2019
 
 
2020
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2021
                                                     "button_options1"));
 
2022
        g_signal_connect (widget, "clicked",
 
2023
                          G_CALLBACK (edit_connection), device_wifi);
 
2024
 
 
2025
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2026
                                                     "button_forget1"));
 
2027
        g_signal_connect (widget, "clicked",
 
2028
                          G_CALLBACK (forget_button_clicked_cb), device_wifi);
 
2029
 
 
2030
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2031
                                                     "button_disconnect1"));
 
2032
        g_signal_connect (widget, "clicked",
 
2033
                          G_CALLBACK (disconnect_button_clicked_cb), device_wifi);
 
2034
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2035
                                                     "button_connect1"));
 
2036
        g_signal_connect (widget, "clicked",
 
2037
                          G_CALLBACK (connect_button_clicked_cb), device_wifi);
 
2038
 
 
2039
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2040
                                                     "treeview_list"));
 
2041
 
 
2042
        /* sort networks in drop down */
 
2043
        sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (device_wifi->priv->builder,
 
2044
                                                              "liststore_network"));
 
2045
        gtk_tree_sortable_set_sort_column_id (sortable,
 
2046
                                              COLUMN_SORT,
 
2047
                                              GTK_SORT_ASCENDING);
 
2048
        gtk_tree_sortable_set_sort_func (sortable,
 
2049
                                         COLUMN_SORT,
 
2050
                                         wireless_ap_model_sort_cb,
 
2051
                                         device_wifi,
 
2052
                                         NULL);
 
2053
 
 
2054
 
 
2055
        column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (device_wifi->priv->builder,
 
2056
                                                               "treeview_list_column"));
 
2057
        area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
 
2058
 
 
2059
        renderer1 = gtk_cell_renderer_pixbuf_new ();
 
2060
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer1, FALSE);
 
2061
        g_object_set (renderer1,
 
2062
                      "follow-state", TRUE,
 
2063
                      "icon-name", "object-select-symbolic",
 
2064
                      "xpad", 6,
 
2065
                      "ypad", 6,
 
2066
                      NULL);
 
2067
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer1,
 
2068
                                        "visible", COLUMN_ACTIVE,
 
2069
                                        NULL);
 
2070
        gtk_cell_area_cell_set (area, renderer1, "align", TRUE, NULL);
 
2071
 
 
2072
        renderer2 = panel_cell_renderer_text_new ();
 
2073
        g_object_set (renderer2,
 
2074
                      "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
 
2075
                      "ellipsize", PANGO_ELLIPSIZE_END,
 
2076
                      NULL);
 
2077
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer2, TRUE);
 
2078
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer2,
 
2079
                                        "markup", COLUMN_TITLE,
 
2080
                                        NULL);
 
2081
        gtk_cell_area_cell_set (area, renderer2,
 
2082
                                "align", TRUE,
 
2083
                                "expand", TRUE,
 
2084
                                NULL);
 
2085
        g_signal_connect (renderer2, "activate",
 
2086
                          G_CALLBACK (activate_ssid_cb), device_wifi);
 
2087
 
 
2088
        renderer3 = panel_cell_renderer_mode_new ();
 
2089
        gtk_cell_renderer_set_padding (renderer3, 4, 0);
 
2090
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column),
 
2091
                                    renderer3,
 
2092
                                    FALSE);
 
2093
        g_object_set (renderer3, "follow-state", TRUE, NULL);
 
2094
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer3,
 
2095
                                        "ap-mode", COLUMN_MODE,
 
2096
                                        NULL);
 
2097
 
 
2098
        renderer4 = gtk_cell_renderer_text_new ();
 
2099
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer4, FALSE);
 
2100
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer4,
 
2101
                                        "visible", COLUMN_AP_OUT_OF_RANGE,
 
2102
                                        NULL);
 
2103
        g_object_set (renderer4,
 
2104
                      "text", _("Out of range"),
 
2105
                      "mode", GTK_CELL_RENDERER_MODE_INERT,
 
2106
                      "xalign", 1.0,
 
2107
                      NULL);
 
2108
 
 
2109
        renderer5 = panel_cell_renderer_signal_new ();
 
2110
        gtk_cell_renderer_set_padding (renderer5, 4, 0);
 
2111
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column),
 
2112
                                    renderer5,
 
2113
                                    FALSE);
 
2114
        g_object_set (renderer5, "follow-state", TRUE, NULL);
 
2115
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer5,
 
2116
                                        "signal", COLUMN_STRENGTH,
 
2117
                                        "visible", COLUMN_AP_IN_RANGE,
 
2118
                                        NULL);
 
2119
 
 
2120
        renderer6 = panel_cell_renderer_security_new ();
 
2121
        gtk_cell_renderer_set_padding (renderer6, 4, 0);
 
2122
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column),
 
2123
                                    renderer6,
 
2124
                                    FALSE);
 
2125
        g_object_set (renderer6, "follow-state", TRUE, NULL);
 
2126
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer6,
 
2127
                                        "security", COLUMN_SECURITY,
 
2128
                                        "visible", COLUMN_AP_IN_RANGE,
 
2129
                                        NULL);
 
2130
 
 
2131
        renderer7 = panel_cell_renderer_separator_new ();
 
2132
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer7, FALSE);
 
2133
        g_object_set (renderer7,
 
2134
                      "visible", TRUE,
 
2135
                      "sensitive", FALSE,
 
2136
                      "draw", TRUE,
 
2137
                      NULL);
 
2138
        gtk_cell_renderer_set_fixed_size (renderer7, 1, -1);
 
2139
        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer7,
 
2140
                                            set_draw_separator, device_wifi, NULL);
 
2141
 
 
2142
        renderer8 = panel_cell_renderer_pixbuf_new ();
 
2143
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer8, FALSE);
 
2144
        g_object_set (renderer8,
 
2145
                      "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
 
2146
                      "follow-state", TRUE,
 
2147
                      "visible", TRUE,
 
2148
                      "xpad", 6,
 
2149
                      "ypad", 6,
 
2150
                      NULL);
 
2151
        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer8,
 
2152
                                            set_arrow_image, device_wifi, NULL);
 
2153
        g_signal_connect (renderer8, "activate",
 
2154
                          G_CALLBACK (activate_arrow_cb), device_wifi);
 
2155
 
 
2156
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2157
                                                     "button_back1"));
 
2158
        g_signal_connect_swapped (widget, "clicked",
 
2159
                                  G_CALLBACK (show_wifi_list), device_wifi);
 
2160
 
 
2161
        /* draw focus around everything but the arrow */
 
2162
        gtk_cell_area_add_focus_sibling (area, renderer2, renderer1);
 
2163
        gtk_cell_area_add_focus_sibling (area, renderer2, renderer3);
 
2164
        gtk_cell_area_add_focus_sibling (area, renderer2, renderer4);
 
2165
        gtk_cell_area_add_focus_sibling (area, renderer2, renderer5);
 
2166
        gtk_cell_area_add_focus_sibling (area, renderer2, renderer6);
 
2167
        gtk_cell_area_add_focus_sibling (area, renderer2, renderer7);
 
2168
 
 
2169
        /* setup view */
 
2170
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2171
                                                     "notebook_view"));
 
2172
        gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
 
2173
        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
 
2174
        g_signal_connect_after (widget, "switch-page",
 
2175
                                G_CALLBACK (switch_page_cb), device_wifi);
 
2176
 
 
2177
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2178
                                                     "start_hotspot_button"));
 
2179
        g_signal_connect (widget, "clicked",
 
2180
                          G_CALLBACK (start_hotspot), device_wifi);
 
2181
 
 
2182
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2183
                                                     "connect_hidden_button"));
 
2184
        g_signal_connect_swapped (widget, "clicked",
 
2185
                                  G_CALLBACK (connect_to_hidden_network), device_wifi);
 
2186
 
 
2187
        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
 
2188
                                                     "switch_hotspot_off"));
 
2189
        g_signal_connect (widget, "notify::active",
 
2190
                          G_CALLBACK (switch_hotspot_changed_cb), device_wifi);
 
2191
}