* [gentoo-commits] proj/gnome:master commit in: gnome-base/gnome-shell/, net-misc/networkmanager/, ...
@ 2011-02-23 14:40 Nirbheek Chauhan
0 siblings, 0 replies; 4+ messages in thread
From: Nirbheek Chauhan @ 2011-02-23 14:40 UTC (permalink / raw
To: gentoo-commits
commit: c4b935e51b5eb23600ff21c9407feb07f5ed06b1
Author: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 23 13:48:27 2011 +0000
Commit: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
CommitDate: Wed Feb 23 14:09:12 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gnome.git;a=commit;h=c4b935e5
gnome-base/gnome-shell: update nm-applet patch, update networkmanager-9999
* New patch added to NM, needed for gnome-shell now
---
...> gnome-shell-experimental-nm-applet-1.0.patch} | 1121 +++++++++++---------
gnome-base/gnome-shell/gnome-shell-9999.ebuild | 2 +-
.../files/networkmanager-more-gi-annotations.patch | 43 +
net-misc/networkmanager/networkmanager-9999.ebuild | 3 +
4 files changed, 663 insertions(+), 506 deletions(-)
diff --git a/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.patch b/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.0.patch
similarity index 63%
rename from gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.patch
rename to gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.0.patch
index 64aa99c..15a560b 100644
--- a/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.patch
+++ b/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.0.patch
@@ -1,4 +1,4 @@
-From 11400d81fd9775bac7db3e49e620004bb9d6fab5 Mon Sep 17 00:00:00 2001
+From f8a4fa0646aa4ab620331c0bbcae4334173b614d Mon Sep 17 00:00:00 2001
From: Giovanni Campagna <gcampagna@src.gnome.org>
Date: Tue, 25 Jan 2011 22:08:12 +0100
Subject: [PATCH] Status area: add NetworkManager indicator
@@ -10,15 +10,35 @@ dialogs.
https://bugzilla.gnome.org/show_bug.cgi?id=621707
---
+ data/theme/gnome-shell.css | 8 +
js/Makefile.am | 2 +
- js/misc/modemManager.js | 93 +++
+ js/misc/modemManager.js | 103 +++
js/ui/panel.js | 3 +-
- js/ui/status/network.js | 1656 +++++++++++++++++++++++++++++++++++++++
- tools/build/gnome-shell.modules | 19 +
- 5 files changed, 1772 insertions(+), 1 deletions(-)
+ js/ui/status/network.js | 1754 +++++++++++++++++++++++++++++++++++++++
+ tools/build/gnome-shell.modules | 17 +
+ 6 files changed, 1886 insertions(+), 1 deletions(-)
create mode 100644 js/misc/modemManager.js
create mode 100644 js/ui/status/network.js
+diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
+index 1da6619..8f0fb52 100644
+--- a/data/theme/gnome-shell.css
++++ b/data/theme/gnome-shell.css
+@@ -154,6 +154,14 @@ StTooltip StLabel {
+ spacing: .5em;
+ }
+
++.popup-inactive-menu-item {
++ font-style: italic;
++}
++
++.popup-subtitle-menu-item {
++ font-weight: bold;
++}
++
+ .popup-menu-icon {
+ icon-size: 1.14em;
+ }
diff --git a/js/Makefile.am b/js/Makefile.am
index e4a4145..53f80d4 100644
--- a/js/Makefile.am
@@ -41,10 +61,10 @@ index e4a4145..53f80d4 100644
ui/status/bluetooth.js \
diff --git a/js/misc/modemManager.js b/js/misc/modemManager.js
new file mode 100644
-index 0000000..104262b
+index 0000000..b368511
--- /dev/null
+++ b/js/misc/modemManager.js
-@@ -0,0 +1,93 @@
+@@ -0,0 +1,103 @@
+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
+const DBus = imports.dbus;
+const Lang = imports.lang;
@@ -56,15 +76,15 @@ index 0000000..104262b
+const ModemGsmNetworkInterface = {
+ name: 'org.freedesktop.ModemManager.Modem.Gsm.Network',
+ methods: [
-+ { name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
-+ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
++ { name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
++ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
+ ],
+ properties: [
-+ { name: 'AccessTechnology', signature: 'u', access: 'read' }
++ { name: 'AccessTechnology', signature: 'u', access: 'read' }
+ ],
+ signals: [
-+ { name: 'SignalQuality', inSignature: 'u' },
-+ { name: 'RegistrationInfo', inSignature: 'uss' }
++ { name: 'SignalQuality', inSignature: 'u' },
++ { name: 'RegistrationInfo', inSignature: 'uss' }
+ ]
+};
+const ModemGsmNetworkProxy = DBus.makeProxyClass(ModemGsmNetworkInterface);
@@ -72,11 +92,11 @@ index 0000000..104262b
+const ModemCdmaInterface = {
+ name: 'org.freedesktop.ModemManager.Modem.Cdma',
+ methods: [
-+ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
-+ { name: 'GetServingSystem', inSignature: '', outSignature: 'usu' },
++ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
++ { name: 'GetServingSystem', inSignature: '', outSignature: 'usu' },
+ ],
+ signals: [
-+ { name: 'SignalQuality', inSignature: 'u' }
++ { name: 'SignalQuality', inSignature: 'u' }
+ ]
+};
+const ModemCdmaProxy = DBus.makeProxyClass(ModemCdmaInterface);
@@ -88,29 +108,37 @@ index 0000000..104262b
+
+ModemGsm.prototype = {
+ _init: function(path) {
-+ this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
-+
-+ this.signal_quality = 0;
-+ this.operator_name = null;
-+ this._proxy.connect('SignalQuality', Lang.bind(this, this._qualityChanged));
-+ this._proxy.connect('RegistrationInfo', Lang.bind(this, this._registrationInfoChanged));
-+ this._proxy.GetRegistrationInfoRemote(Lang.bind(this, this._registrationInfoChanged));
-+ this._proxy.GetSignalQualityRemote(Lang.bind(this, this._qualityChanged));
-+ },
++ this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
+
-+ _registrationInfoChanged: function(status, code, name) {
-+ if (name.length > 0)
-+ this.operator_name = name;
-+ else
-+ this.operator_name = null;
-+ this.emit('notify::operator-name');
-+ },
++ this.signal_quality = 0;
++ this.operator_name = null;
+
-+ _qualityChanged: function(quality) {
-+ this.signal_quality = quality;
-+ this.emit('notify::signal-quality');
++ // Code is duplicated because the function have different signatures
++ this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
++ this.signal_quality = quality;
++ this.emit('notify::signal-quality');
++ }));
++ this._proxy.connect('RegistrationInfo', Lang.bind(this, function(proxy, status, code, name) {
++ if (name.length > 0)
++ this.operator_name = name;
++ else
++ this.operator_name = null;
++ this.emit('notify::operator-name');
++ }));
++ this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(status, code, name) {
++ if (name.length > 0)
++ this.operator_name = name;
++ else
++ this.operator_name = null;
++ this.emit('notify::operator-name');
++ }));
++ this._proxy.GetSignalQualityRemote(Lang.bind(this, function(quality) {
++ this.signal_quality = quality;
++ this.emit('notify::signal-quality');
++ }));
+ }
+}
++Signals.addSignalMethods(ModemGsm.prototype);
+
+function ModemCdma() {
+ this._init.apply(this, arguments);
@@ -122,28 +150,29 @@ index 0000000..104262b
+
+ this.signal_quality = 0;
+ this.operator_name = null;
-+ this._proxy.connect('SignalQuality', Lang.bind(this, this._qualityChanged));
-+ this._proxy.GetSignalQualityRemote(Lang.bind(this, this._qualityChanged));
-+ this._proxy.GetServingSystemRemote(Lang.bind(this, function(status, name, code) {
++ this._proxy.connect('SignalQuality', Lang.bind(this, function(quality) {
++ this.signal_quality = quality;
++ this.emit('notify::signal-quality');
++ }));
++ this._proxy.GetSignalQualityRemote(Lang.bind(this, function(proxy, quality) {
++ this.signal_quality = quality;
++ this.emit('notify::signal-quality');
++ }));
++ this._proxy.GetServingSystemRemote(Lang.bind(this, function(proxy, status, name, code) {
+ if (name.length > 0)
+ this.operator_name = name;
+ else
+ this.operator_name = null;
+ this.emit('notify::operator-name');
+ }));
-+ },
-+
-+ _qualityChanged: function(quality) {
-+ this.signal_quality = quality;
-+ this.emit('notify::signal-quality');
+ }
+};
-\ No newline at end of file
++Signals.addSignalMethods(ModemCdma.prototype);
diff --git a/js/ui/panel.js b/js/ui/panel.js
-index f1a5e90..46355c4 100644
+index 1c23ae8..ab7a656 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
-@@ -37,7 +37,8 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
+@@ -38,7 +38,8 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
'battery': imports.ui.status.power.Indicator,
@@ -155,10 +184,10 @@ index f1a5e90..46355c4 100644
if (Config.HAVE_BLUETOOTH)
diff --git a/js/ui/status/network.js b/js/ui/status/network.js
new file mode 100644
-index 0000000..a0cd576
+index 0000000..04e9c87
--- /dev/null
+++ b/js/ui/status/network.js
-@@ -0,0 +1,1656 @@
+@@ -0,0 +1,1754 @@
+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
+const ByteArray = imports.byteArray;
+const DBus = imports.dbus;
@@ -181,6 +210,13 @@ index 0000000..a0cd576
+const Gettext = imports.gettext.domain('gnome-shell');
+const _ = Gettext.gettext;
+
++const NMConnectionCategory = {
++ WIRED: 'wired',
++ WIRELESS: 'wireless',
++ WWAN: 'wwan',
++ VPN: 'vpn'
++};
++
+const NMAppletIface = {
+ name: 'org.freedesktop.NetworkManager.Applet',
+ methods: [
@@ -191,16 +227,9 @@ index 0000000..a0cd576
+const NMAppletProxy = DBus.makeProxyClass(NMAppletIface);
+
+function macToArray(string) {
-+ const regexp = /([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2})/;
-+ let match = regexp.exec(string);
-+ if (match) {
-+ // remove the global match
-+ match.splice(0, 1);
-+ return match.map(function(el) {
-+ return parseInt(el, 16);
-+ });
-+ } else
-+ return new Array(6);
++ return string.split(':').map(function(el) {
++ return parseInt(el, 16);
++ });
+}
+
+function macCompare(one, two) {
@@ -211,75 +240,101 @@ index 0000000..a0cd576
+ return true;
+}
+
-+/**
-+ * makeClassKey:
-+ * @object: any Object
-+ *
-+ * Returns a string which can be used to identify @object's [[Class]]
-+ */
-+function makeClassKey(object) {
-+ return Object.prototype.toString.call(object);
-+}
-+
-+function addChipersFromFlags(settings, flags) {
-+ // helper copied from nm-applet
-+
-+ if (flags & NetworkManager['802_11_AP_SEC_PAIR_TKIP'])
-+ settings.add_pairwise('tkip');
-+ if (flags & NetworkManager['802_11_AP_SEC_PAIR_CCMP'])
-+ settings.add_pairwise('ccmp');
-+
-+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_WEP40'])
-+ settings.add_group('wep40');
-+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_WEP104'])
-+ settings.add_group('wep104');
-+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_TKIP'])
-+ settings.add_group('tkip');
-+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_CCMP'])
-+ settings.add_group('ccmp');
++function ssidCompare(one, two) {
++ if (one.length != two.length)
++ return false;
++ for (let i = 0; i < one.length; i++) {
++ if (one[i] != two[i])
++ return false;
++ }
++ return true;
+}
+
-+// shared between NMAccessPointMenuItem and NMDeviceWWAN
++// shared between NMNetworkMenuItem and NMDeviceWWAN
+function signalToIcon(value) {
-+ if(value > 80)
++ if (value > 80)
+ return 'excellent';
-+ if(value > 55)
++ if (value > 55)
+ return 'good';
-+ if(value > 30)
++ if (value > 30)
+ return 'ok';
-+ if(value > 5)
++ if (value > 5)
+ return 'weak';
+ return 'none';
+}
+
-+function NMAccessPointMenuItem() {
++// shared between NMNetworkMenuItem and NMDeviceWireless
++function sortAccessPoints(accessPoints) {
++ return accessPoints.sort(function (one, two) {
++ return two.strength - one.strength;
++ });
++}
++
++function NMNetworkMenuItem() {
+ this._init.apply(this, arguments);
+}
+
-+NMAccessPointMenuItem.prototype = {
++NMNetworkMenuItem.prototype = {
+ __proto__: PopupMenu.PopupImageMenuItem.prototype,
+
-+ _init: function(accessPoint, title, params) {
-+ this._accessPoint = accessPoint;
-+ this._title = title || String(accessPoint.get_ssid());
++ _init: function(accessPoints, title, params) {
++ accessPoints = sortAccessPoints(accessPoints);
++ this.bestAP = accessPoints[0];
++
++ let ssid = this.bestAP.get_ssid();
++ title = title || NetworkManager.utils_ssid_to_utf8(ssid, ssid.length) || _("<unknown>");
++
++ PopupMenu.PopupImageMenuItem.prototype._init.call(this, title, this._getIcon(), params);
++
++ this._accessPoints = [ ];
++ for (let i = 0; i < accessPoints.length; i++) {
++ let ap = accessPoints[i];
++ // need a wrapper object here, because the access points can be shared
++ // between many NMNetworkMenuItems
++ let apObj = {
++ ap: ap,
++ updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
++ };
++ this._accessPoints.push(apObj);
++ }
++ },
+
-+ PopupMenu.PopupImageMenuItem.prototype._init.call(this, this._title, this._get_icon(), params);
++ _updated: function(ap, strength) {
++ if (strength > this._bestAP.strength)
++ this.bestAP = ap;
+
-+ this._updateId = this._accessPoint.connect('notify::strength', Lang.bind(this, this._updated));
++ this.setIcon(this._getIcon());
+ },
+
-+ _updated: function() {
-+ this.setIcon(this._get_icon());
++ _getIcon: function() {
++ return 'network-wireless-signal-' + signalToIcon(this.bestAP.strength);
+ },
+
-+ _get_icon: function() {
-+ return 'network-wireless-signal-' + signalToIcon(this._accessPoint.strength);
++ updateAccessPoints: function(accessPoints) {
++ for (let i = 0; i < this._accessPoints.length; i++) {
++ let apObj = this._accessPoints[i];
++ apObj.ap.disconnect(apObj.updateId);
++ apObj.updateId = 0;
++ }
++
++ accessPoints = sortAccessPoints(accessPoints);
++ this.bestAP = accessPoints[0];
++ this._accessPoints = [ ];
++ for (let i = 0; i < accessPoints; i++) {
++ let ap = accessPoints[i];
++ let apObj = {
++ ap: ap,
++ updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
++ };
++ this._accessPoints.push(apObj);
++ }
+ },
+
+ destroy: function() {
-+ if (this._updateId) {
-+ this._accessPoint.disconnect(this._updateId);
-+ this._updateId = 0;
++ for (let i = 0; i < this._accessPoints.length; i++) {
++ let apObj = this._accessPoints[i];
++ apObj.ap.disconnect(apObj.updateId);
++ apObj.updateId = 0;
+ }
+
+ PopupMenu.PopupImageMenuItem.prototype.destroy.call(this);
@@ -287,20 +342,20 @@ index 0000000..a0cd576
+};
+
+function NMDevice() {
-+ throw TypeError('Instantanting abstract class NMDevice');
++ throw new TypeError('Instantanting abstract class NMDevice');
+}
+
+NMDevice.prototype = {
+ _init: function(client, device, connections, activeConnectionPosition) {
-+ /* <protected> */
-+ this.client = client;
+ this.device = device;
+ if (device) {
+ this.device._delegate = this;
+ this.device.connect('state-changed', Lang.bind(this, this.deviceStateChanged));
+ }
+
-+ this.connections = [ ];
++ // protected
++ this._client = client;
++ this._connections = [ ];
+ for (let i = 0; i < connections.length; i++) {
+ if (!connections[i]._uuid)
+ continue;
@@ -312,42 +367,42 @@ index 0000000..a0cd576
+ name: connections[i]._name,
+ uuid: connections[i]._uuid,
+ };
-+ this.connections.push(obj);
++ this._connections.push(obj);
+ }
-+ this.activeConnection = null;
-+ this.activeConnectionItem = null;
-+ this.disconnectItem = null;
-+ this.autoConnectionItem = null;
-+ this.statusItem = null;
++ this._activeConnection = null;
++ this._activeConnectionItem = null;
++ this._disconnectItem = null;
++ this._autoConnectionItem = null;
++ this._statusItem = null;
+
-+ /* <private> */
++ // private
+ this._activeConnectionPosition = activeConnectionPosition || 0;
+
-+ /* <public> */
-+ this.titleItem = new PopupMenu.PopupMenuItem(this.device._description, { reactive: false, style_class: 'popup-subtitle-menu-item' });
++ if (this.device)
++ this.titleItem = new PopupMenu.PopupMenuItem(this.device._description, { reactive: false, style_class: 'popup-subtitle-menu-item' });
+ this.section = new PopupMenu.PopupMenuSection();
+
-+ this.createSection();
++ this._createSection();
+ },
+
+ setActiveConnection: function(activeConnection) {
-+ if (this.activeConnection && activeConnection == this.activeConnection)
++ if (activeConnection == this._activeConnection)
+ // nothing to do
+ return;
+
+ // remove any UI
-+ if (this.activeConnectionItem) {
-+ this.activeConnectionItem.destroy();
-+ this.activeConnectionItem = null;
++ if (this._activeConnectionItem) {
++ this._activeConnectionItem.destroy();
++ this._activeConnectionItem = null;
+ }
+
-+ if (this.disconnectItem) {
-+ this.disconnectItem.destroy();
-+ this.disconnectItem = null;
++ if (this._disconnectItem) {
++ this._disconnectItem.destroy();
++ this._disconnectItem = null;
+ }
+
-+ let previousActive = this.activeConnection;
-+ this.activeConnection == null;
++ let previousActive = this._activeConnection;
++ this._activeConnection == null;
+
+ if (previousActive && previousActive._connection) {
+ // add the connection back as a normal one, by removing and adding it
@@ -358,25 +413,25 @@ index 0000000..a0cd576
+ if (activeConnection) {
+ if (activeConnection._connection) {
+ // remove the connection if it was already seen
-+ let pos = this.findConnection(activeConnection._connection._uuid);
++ let pos = this._findConnection(activeConnection._connection._uuid);
+ if (pos != -1) {
-+ let obj = this.connections[pos];
++ let obj = this._connections[pos];
+ if (obj.item)
+ obj.item.destroy();
+ obj.item = null;
+ }
+ }
+
-+ this.activeConnection = activeConnection;
-+ this.createActiveConnectionItems();
-+ if (this.disconnectItem)
-+ this.section.addMenuItem(this.disconnectItem, this._activeConnectionPosition);
-+ this.section.addMenuItem(this.activeConnectionItem, this._activeConnectionPosition);
++ this._activeConnection = activeConnection;
++ this._createActiveConnectionItems();
++ if (this._disconnectItem)
++ this.section.addMenuItem(this._disconnectItem, this._activeConnectionPosition);
++ this.section.addMenuItem(this._activeConnectionItem, this._activeConnectionPosition);
+ }
+ },
+
+ addConnection: function(connection) {
-+ if (this.findConnection(connection._uuid) != -1) {
++ if (this._findConnection(connection._uuid) != -1) {
+ log('Connection already added to menu, not adding again');
+ return;
+ }
@@ -387,157 +442,139 @@ index 0000000..a0cd576
+ name: connection._name,
+ uuid: connection._uuid,
+ };
-+ this.connections.push(obj);
++ this._connections.push(obj);
+
+ if (!this.device ||
+ (this.device.state == NetworkManager.DeviceState.DISCONNECTED ||
+ this.device.state == NetworkManager.DeviceState.ACTIVATED)) {
-+ // we need to show this connection
-+ if (!this.hasAuto) {
-+ // already showing the connection list
-+ obj.item = this.createConnectionItem(obj);
++ // we're showing a connection list, so we need to append this one
++ if (this._connections.length > 1) {
++ // already showing real connections
++ obj.item = this._createConnectionItem(obj);
+ this.section.addMenuItem(obj.item);
+ } else {
-+ // First connection in the list
-+ this.clearSection();
-+ this.createSection();
++ // first connection in the list, destroy the automatic one
++ this._clearSection();
++ this._createSection();
+ }
+ }
+ },
+
+ removeConnection: function(connection, skipCreateAuto) {
-+ if (!connection._uuid)
++ if (!connection._uuid) {
++ log('Cannot remove a connection without an UUID');
+ return;
-+ let pos = this.findConnection(connection._uuid);
-+ if (pos == -1)
++ }
++ let pos = this._findConnection(connection._uuid);
++ if (pos == -1) {
++ log('Connection was never added, cannot remove');
+ return;
++ }
+
-+ let obj = this.connections[pos];
++ let obj = this._connections[pos];
+ if (obj.item)
+ obj.item.destroy();
-+ this.connections.splice(pos, 1);
++ this._connections.splice(pos, 1);
+
-+ if (this.connections.length == 0 && !skipCreateAuto) {
++ if (this._connections.length == 0 && !skipCreateAuto) {
+ // We need to show the automatic connection again
-+ this.clearSection();
-+ this.createSection();
++ this._clearSection();
++ this._createSection();
+ }
+ },
+
+ connectionValid: function(connection) {
-+ throw TypeError('Invoking pure virtual function NMDevice.connectionValid');
++ throw new TypeError('Invoking pure virtual function NMDevice.connectionValid');
+ },
+
-+ /* <protected> */
-+ createAutomaticConnection: function() {
-+ throw TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
++ // protected
++ _createAutomaticConnection: function() {
++ throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
+ },
+
-+ findConnection: function(uuid) {
-+ for (let i = 0; i < this.connections.length; i++) {
-+ let obj = this.connections[i];
++ _findConnection: function(uuid) {
++ for (let i = 0; i < this._connections.length; i++) {
++ let obj = this._connections[i];
+ if (obj.uuid == uuid)
+ return i;
+ }
+ return -1;
+ },
+
-+ clearSection: function() {
++ _clearSection: function() {
+ // Clear everything
+ this.section.removeAll();
-+ this.autoConnectionItem = null;
-+ this.activeConnectionItem = null;
-+ this.disconnectItem = null;
-+ this.statusItem = null;
-+ for (let i = 0; i < this.connections.length; i++) {
-+ this.connections[i].item = null;
++ this._autoConnectionItem = null;
++ this._activeConnectionItem = null;
++ this._disconnectItem = null;
++ this._statusItem = null;
++ for (let i = 0; i < this._connections.length; i++) {
++ this._connections[i].item = null;
+ }
+ },
+
-+ createSection: function() {
++ _createSection: function() {
+ let status;
+ if (!this.device ||
+ (this.device.state == NetworkManager.DeviceState.DISCONNECTED ||
+ this.device.state == NetworkManager.DeviceState.ACTIVATED))
-+ this.createConnectionList();
++ this._createConnectionList();
+ else if (this.device.state != NetworkManager.DeviceState.UNMANAGED) {
-+ let title = this.getStatusLabel();
-+ this.statusItem = new PopupMenu.PopupMenuItem(title, { reactive: false, style_class: 'popup-inactive-menu-item' });
-+ this.section.addMenuItem(this.statusItem);
++ let title = this._getStatusLabel();
++ this._statusItem = new PopupMenu.PopupMenuItem(title,
++ { reactive: false,
++ style_class: 'popup-inactive-menu-item'
++ });
++ this.section.addMenuItem(this._statusItem);
+ }
+ // else do nothing, the menu should remain empty
+ },
+
-+ getStatusLabel: function() {
-+ switch(this.device.state) {
-+ case NetworkManager.DeviceState.DISCONNECTED:
-+ case NetworkManager.DeviceState.ACTIVATED:
-+ log('Attempt to show status for a disconnected / activate device, should be showing connection list instead');
-+ return 'invalid';
-+ case NetworkManager.DeviceState.PREPARE:
-+ case NetworkManager.DeviceState.CONFIG:
-+ case NetworkManager.DeviceState.IP_CONFIG:
-+ return _("connecting...");
-+ case NetworkManager.DeviceState.NEED_AUTH:
-+ return _("authentication required");
-+ case NetworkManager.DeviceState.UNAVAILABLE:
-+ if ((this.device.capabilities & NetworkManager.DeviceCapabilities.CARRIER_DETECT) &&
-+ !this.device.carrier)
-+ return _("network cable unplugged");
-+ else
-+ return _("network unavailable");
-+ case NetworkManager.DeviceState.FAILED:
-+ return _("connection failed");
-+ default:
-+ log('Device state invalid, is %d'.format(this.device.state));
-+ return 'invalid';
-+ }
-+ },
-+
-+ createConnectionList: function() {
-+ if (this.activeConnection) {
-+ this.createActiveConnectionItems();
-+ this.section.addMenuItem(this.activeConnectionItem);
-+ if (this.disconnectItem)
-+ this.section.addMenuItem(this.disconnectItem);
++ _createConnectionList: function() {
++ if (this._activeConnection) {
++ this._createActiveConnectionItems();
++ this.section.addMenuItem(this._activeConnectionItem);
++ if (this._disconnectItem)
++ this.section.addMenuItem(this._disconnectItem);
+ }
-+ if (this.connections.length > 0) {
-+ for(let j = 0; j < this.connections.length; ++j) {
-+ let obj = this.connections[j];
-+ if (this.activeConnection && obj.connection == this.activeConnection._connection)
++ if (this._connections.length > 0) {
++ for(let j = 0; j < this._connections.length; ++j) {
++ let obj = this._connections[j];
++ if (this._activeConnection &&
++ obj.connection == this._activeConnection._connection)
+ continue;
-+ obj.item = this.createConnectionItem(obj);
++ obj.item = this._createConnectionItem(obj);
+ this.section.addMenuItem(obj.item);
+ }
-+ } else if (this.autoConnectionName) {
-+ this.autoConnectionItem = new PopupMenu.PopupMenuItem(this.autoConnectionName);
-+ this.autoConnectionItem.connect('activate', Lang.bind(this, function() {
-+ let connection = this.createAutomaticConnection();
-+ this.client.add_and_activate_connection(connection, this.device, null, function() { });
++ } else if (this._autoConnectionName) {
++ this._autoConnectionItem = new PopupMenu.PopupMenuItem(this._autoConnectionName);
++ this._autoConnectionItem.connect('activate', Lang.bind(this, function() {
++ let connection = this._createAutomaticConnection();
++ this._client.add_and_activate_connection(connection, this.device, null, null);
+ }));
-+ this.section.addMenuItem(this.autoConnectionItem);
++ this.section.addMenuItem(this._autoConnectionItem);
+ }
+ },
+
-+ createConnectionItem: function(obj) {
++ _createConnectionItem: function(obj) {
+ let path = obj.connection.path;
+ let item = new PopupMenu.PopupMenuItem(obj.name);
+ item.connect('activate', Lang.bind(this, function() {
-+ this.client.activate_connection(path, this.device, null, function() { });
++ this._client.activate_connection(path, this.device, null, null);
+ }));
+ return item;
+ },
+
-+ createActiveConnectionItems: function() {
++ _createActiveConnectionItems: function() {
+ let title;
-+ let active = this.activeConnection._connection;
-+ this.disconnectItem = null;
++ let active = this._activeConnection._connection;
++ this._disconnectItem = null;
+ if (active) {
+ title = active._name;
-+ this.disconnectItem = new PopupMenu.PopupMenuItem(_("Disconnect"));
-+ this.disconnectItem.connect('activate', Lang.bind(this, function() {
++ this._disconnectItem = new PopupMenu.PopupMenuItem(_("Disconnect"));
++ this._disconnectItem.connect('activate', Lang.bind(this, function() {
+ /* The correct approach would be
-+ this.client.deactivate_connection(this.activeConnection);
++ this.client.deactivate_connection(this._activeConnection);
+ but with this, NM insists in restarting the connection immediately
+ */
+ this.device.disconnect(function() { });
@@ -547,8 +584,35 @@ index 0000000..a0cd576
+ and we cannot access its settings (including the name) */
+ title = _("Connected (private)");
+ }
-+ this.activeConnectionItem = new PopupMenu.PopupMenuItem(title, { reactive: false });
-+ this.activeConnectionItem.setShowDot(true);
++ this._activeConnectionItem = new PopupMenu.PopupMenuItem(title, { reactive: false });
++ this._activeConnectionItem.setShowDot(true);
++ },
++
++ // private
++ _getStatusLabel: function() {
++ switch(this.device.state) {
++ case NetworkManager.DeviceState.DISCONNECTED:
++ case NetworkManager.DeviceState.ACTIVATED:
++ log('Attempt to show status for a disconnected / activate device, should be showing connection list instead');
++ return 'invalid';
++ case NetworkManager.DeviceState.PREPARE:
++ case NetworkManager.DeviceState.CONFIG:
++ case NetworkManager.DeviceState.IP_CONFIG:
++ return _("connecting...");
++ case NetworkManager.DeviceState.NEED_AUTH:
++ return _("authentication required");
++ case NetworkManager.DeviceState.UNAVAILABLE:
++ if ((this.device.capabilities & NetworkManager.DeviceCapabilities.CARRIER_DETECT) &&
++ !this.device.carrier)
++ return _("network cable unplugged");
++ else
++ return _("network unavailable");
++ case NetworkManager.DeviceState.FAILED:
++ return _("connection failed");
++ default:
++ log('Device state invalid, is %d'.format(this.device.state));
++ return 'invalid';
++ }
+ },
+
+ deviceStateChanged: function(device, newstate, oldstate, reason) {
@@ -564,10 +628,11 @@ index 0000000..a0cd576
+ switch(newstate) {
+ case NetworkManager.DeviceState.UNMANAGED:
+ // clear everything and be quiet
-+ this.clearSection();
++ this._clearSection();
+ return;
+ case NetworkManager.DeviceState.NEED_AUTH:
+ // FIXME: make this have a real effect
++ // (currently we rely on a running nm-applet)
+ this.emit('need-auth');
+ break;
+ case NetworkManager.DeviceState.FAILED:
@@ -581,13 +646,13 @@ index 0000000..a0cd576
+ oldstate != NetworkManager.DeviceState.ACTIVATED &&
+ oldstate != NetworkManager.DeviceState.UNMANAGED) {
+ // a transition between states that show the status label
-+ this.statusItem.label.text = this.getStatusLabel();
++ this._statusItem.label.text = this._getStatusLabel();
+ return;
+ }
+
+ // just refresh everything
-+ this.clearSection();
-+ this.createSection();
++ this._clearSection();
++ this._createSection();
+ }
+};
+Signals.addSignalMethods(NMDevice.prototype);
@@ -601,31 +666,31 @@ index 0000000..a0cd576
+ __proto__: NMDevice.prototype,
+
+ _init: function(client, device, connections) {
-+ this.autoConnectionName = _("Auto Ethernet");
-+ this.category = 'wired';
++ this._autoConnectionName = _("Auto Ethernet");
++ this.category = NMConnectionCategory.WIRED;
+
+ NMDevice.prototype._init.call(this, client, device, connections);
+ },
+
+ connectionValid: function(connection) {
-+ if (connection._type != '802-3-ethernet')
++ if (connection._type != NetworkManager.SETTING_WIRED_SETTING_NAME)
+ return false;
+
-+ let ethernetSettings = connection.get_setting_by_name('802-3-ethernet');
++ let ethernetSettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRED_SETTING_NAME);
+ let fixedMac = ethernetSettings.get_mac_address();
+ if (fixedMac)
+ return macCompare(fixedMac, macToArray(this.device.perm_hw_address));
+ return true;
+ },
+
-+ createAutomaticConnection: function() {
++ _createAutomaticConnection: function() {
+ let connection = new NetworkManager.Connection();
+ connection._uuid = NetworkManager.utils_uuid_generate();
+ connection.add_setting(new NetworkManager.SettingWired());
+ connection.add_setting(new NetworkManager.SettingConnection({
+ uuid: connection._uuid,
-+ id: this.autoConnectionName,
-+ type: '802-3-ethernet',
++ id: this._autoConnectionName,
++ type: NetworkManager.SETTING_WIRED_SETTING_NAME,
+ autoconnect: true
+ }));
+ return connection;
@@ -640,15 +705,15 @@ index 0000000..a0cd576
+ __proto__: NMDevice.prototype,
+
+ _init: function(client, device, connections) {
-+ this.autoConnectionName = _("New Mobile Broadband connection...");
-+ this.category = 'wwan';
++ this._autoConnectionName = _("New Mobile Broadband connection...");
++ this.category = NMConnectionCategory.WWAN;
+
+ if (device instanceof NMClient.GsmDevice) {
+ this.mobileDevice = new ModemManager.ModemGsm(device.udi);
-+ this._connectionType = 'gsm';
++ this._connectionType = NetworkManager.SETTING_GSM_SETTING_NAME;
+ } else if (device instanceof NMClient.CdmaDevice) {
+ this.mobileDevice = new ModemManager.ModemCdma(device.udi);
-+ this._connectionType = 'cdma';
++ this._connectionType = NetworkManager.SETTING_CDMA_SETTING_NAME;
+ }
+
+ this.mobileDevice.connect('notify::operator-name', Lang.bind(this, function() {
@@ -663,43 +728,46 @@ index 0000000..a0cd576
+ }));
+ this.mobileDevice.connect('notify::signal-quality', Lang.bind(this, function() {
+ if (this._operatorItem) {
-+ this._operatorItem.setIcon(this._get_signal_icon());
++ this._operatorItem.setIcon(this._getSignalIcon());
+ }
+ }));
+
+ NMDevice.prototype._init.call(this, client, device, connections, 1);
+ },
+
-+ _get_signal_icon: function() {
++ _getSignalIcon: function() {
+ return 'network-cellular-signal-' + signalToIcon(this.mobileDevice.signal_quality);
+ },
+
-+ createSection: function() {
-+ NMDevice.prototype.createSection.call(this);
++ _createSection: function() {
++ NMDevice.prototype._createSection.call(this);
+
-+ this._operatorItem = new PopupMenu.PopupImageMenuItem(this.mobileDevice.operator_name || '', this._get_signal_icon(), { reactive: false });
++ this._operatorItem = new PopupMenu.PopupImageMenuItem(this.mobileDevice.operator_name || '',
++ this._getSignalIcon(),
++ { reactive: false });
+ this.section.addMenuItem(this._operatorItem, 0);
+ },
+
+ clearSection: function() {
+ this._operatorItem = null;
+
-+ NMDevice.prototype.clearSection.call(this);
++ NMDevice.prototype._clearSection.call(this);
+ },
+
+ connectionValid: function(connection) {
+ return connection._type == this._connectionType;
+ },
+
-+ createAutomaticConnection: function() {
++ _createAutomaticConnection: function() {
+ // FIXME: we need to summon the mobile wizard here
+ // or NM will not have the necessary parameters to complete the connection
++ // (the same FIXME is currently in nm-applet, actually)
+
+ let connection = new NetworkManager.Connection;
+ connection._uuid = NetworkManager.utils_uuid_generate();
+ connection.add_setting(new NetworkManager.SettingConnection({
+ uuid: connection._uuid,
-+ id: this.autoConnectionName,
++ id: this._autoConnectionName,
+ type: this._connectionType,
+ autoconnect: false
+ }));
@@ -715,17 +783,17 @@ index 0000000..a0cd576
+ __proto__: NMDevice.prototype,
+
+ _init: function(client, device, connections) {
-+ this.autoConnectionName = _("New Mobile Broadband connection...");
-+ this.category = 'wwan';
++ this._autoConnectionName = _("New Mobile Broadband connection...");
++ this.category = NMConnectionCategory.WWAN;
+
+ NMDevice.prototype._init.call(this, client, device, connections);
+ },
+
+ connectionValid: function(connection) {
-+ if (connection._type != 'bluetooth')
++ if (connection._type != NetworkManager.SETTING_BLUETOOTH_SETTING_NAME)
+ return false;
+
-+ let bluetoothSettings = connection.get_setting_by_name('bluetooth');
++ let bluetoothSettings = connection.get_setting_by_name(NetworkManager.SETTING_BLUETOOTH_SETTING_NAME);
+ let fixedBdaddr = bluetoothSettings.get_bdaddr();
+ if (fixedBdaddr)
+ return macCompare(fixedBdaddr, macToArray(this.device.hw_address));
@@ -733,15 +801,16 @@ index 0000000..a0cd576
+ return true;
+ },
+
-+ createAutomaticConnection: function() {
++ _createAutomaticConnection: function() {
+ // XXX: is this enough? or do we need other stuff from bluetoothd?
+
+ let connection = new NetworkManager.Connection;
+ connection._uuid = NetworkManager.utils_uuid_generate();
++ connection.add_setting(new NetworkManager.SettingBluetooth);
+ connection.add_setting(new NetworkManager.SettingConnection({
+ uuid: connection._uuid,
-+ id: this.autoConnectionName,
-+ type: 'gsm',
++ id: this._autoConnectionName,
++ type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
+ autoconnect: false
+ }));
+ return connection;
@@ -759,14 +828,18 @@ index 0000000..a0cd576
+
+ _init: function(client) {
+ // Disable autoconnections
-+ this.autoConnectionName = null;
-+ this.category = 'vpn';
++ this._autoConnectionName = null;
++ this.category = NMConnectionCategory.VPN;
+
+ NMDevice.prototype._init.call(this, client, null, [ ]);
+ },
+
+ connectionValid: function(connection) {
-+ return connection._type == 'vpn';
++ return connection._type == NetworkManager.SETTING_VPN_SETTING_NAME;
++ },
++
++ get empty() {
++ return this._connections.length == 0;
+ }
+};
+
@@ -778,10 +851,10 @@ index 0000000..a0cd576
+ __proto__: NMDevice.prototype,
+
+ _init: function(client, device, connections) {
-+ this.category = 'wireless';
++ this.category = NMConnectionCategory.WIRELESS;
+
+ this._overflowItem = null;
-+ this._accessPoints = [ ];
++ this._networks = [ ];
+
+ // XXX: breaking the layers with this, but cannot call
+ // this.connectionValid until I have a device
@@ -794,22 +867,19 @@ index 0000000..a0cd576
+ for (let i = 0; i < accessPoints.length; i++) {
+ // Access points are grouped by network name
+ let ap = accessPoints[i];
-+ let name = String(ap.get_ssid());
-+ let pos = this._findAccessPoint(name);
++ let ssid = ap.get_ssid();
++ let pos = this._findNetwork(ssid);
+ let obj;
+ if (pos != -1) {
-+ obj = this._accessPoints[pos];
++ obj = this._networks[pos];
+ obj.accessPoints.push(ap);
-+ obj.accessPoints.sort(function(one, two) {
-+ return two.strength - one.strength;
-+ });
+ } else {
-+ obj = { name: name,
++ obj = { ssid: ssid,
+ connections: [ ],
+ item: null,
+ accessPoints: [ ap ]
+ };
-+ this._accessPoints.push(obj);
++ this._networks.push(obj);
+ }
+
+ // Check if some connection is valid for this AP
@@ -827,32 +897,28 @@ index 0000000..a0cd576
+ NMDevice.prototype._init.call(this, client, device, validConnections);
+ },
+
-+ _findAccessPoint: function(name) {
-+ for (let i = 0; i < this._accessPoints.length; i++) {
-+ if (this._accessPoints[i].name == name)
++ _findNetwork: function(ssid) {
++ for (let i = 0; i < this._networks.length; i++) {
++ if (ssidCompare(this._networks[i].ssid, ssid))
+ return i;
+ }
+ return -1;
+ },
+
+ _accessPointAdded: function(device, accessPoint) {
-+ let name = String(accessPoint.get_ssid());
-+ let pos = this._findAccessPoint(name);
++ let ssid = accessPoint.get_ssid();
++ let pos = this._findNetwork(ssid);
+ let apObj;
+ if (pos != -1) {
-+ apObj = this._accessPoints[pos];
++ apObj = this._network[pos];
+ if (apObj.accessPoints.indexOf(accessPoint) != -1) {
-+ // already seen this AP
++ log('Access point was already seen, not adding again');
+ return;
+ }
+
+ apObj.accessPoints.push(accessPoint);
-+ apObj.accessPoints.sort(function(one, two) {
-+ return two.strength - one.strength;
-+ });
-+
+ } else {
-+ apObj = { name: name,
++ apObj = { ssid: ssid,
+ connections: [ ],
+ item: null,
+ accessPoints: [ accessPoint ]
@@ -861,8 +927,8 @@ index 0000000..a0cd576
+ }
+
+ // check if this enables new connections for this group
-+ for (let i = 0; i < this.connections.length; i++) {
-+ let connection = this.connections[i].connection;
++ for (let i = 0; i < this._connections.length; i++) {
++ let connection = this._connections[i].connection;
+ if (this._connectionValidForAP(connection, accessPoint) &&
+ apObj.connections.indexOf(connection) == -1) {
+ apObj.connections.push(connection);
@@ -872,21 +938,21 @@ index 0000000..a0cd576
+ if (this.device.state == NetworkManager.DeviceState.DISCONNECTED ||
+ this.device.state == NetworkManager.DeviceState.ACTIVATED) {
+ // update everything (it would be too complicated to update just what has changed)
-+ this.clearSection();
-+ this.createConnectionList();
++ this._clearSection();
++ this._createConnectionList();
+ }
+ },
+
+ _accessPointRemoved: function(device, accessPoint) {
-+ let name = String(accessPoint.get_ssid());
-+ let pos = this._findAccessPoint(name);
++ let ssid = accessPoint.get_ssid();
++ let pos = this._findNetwork(ssid);
+
+ if (pos == -1) {
+ log('Removing an access point that was never added');
+ return;
+ }
+
-+ let apObj = this._accessPoints[pos];
++ let apObj = this._networks[pos];
+ let i = apObj.accessPoints.indexOf(accessPoint);
+
+ if (i == -1) {
@@ -899,25 +965,19 @@ index 0000000..a0cd576
+ if (apObj.accessPoints.length == 0) {
+ if (apObj.item)
+ apObj.item.destroy();
-+ this._accessPoints.splice(pos, 1);
-+ }
++ this._networks.splice(pos, 1);
++ } else if (apObj.item)
++ apObj.item.updateAccessPoints(apObj.accessPoints);
+ },
+
+ _createAPItem: function(connection, accessPointObj, useConnectionName) {
-+ accessPointObj.accessPoints.sort(function(one, two) {
-+ return two.strength - one.strength;
-+ });
-+ let item = new NMAccessPointMenuItem(accessPointObj.accessPoints[0], useConnectionName ? connection._name : undefined);
++ let item = new NMNetworkMenuItem(accessPointObj.accessPoints, useConnectionName ? connection._name : undefined);
+ item._connection = connection;
+ item.connect('activate', Lang.bind(this, function() {
-+ // always connect to the strongest access point in a group
-+ let apList = accessPointObj.accessPoints;
-+ apList.sort(function(one, two) {
-+ return two.strength - one.strength;
-+ });
-+ for (let i = 0; i < apList.length; i++) {
-+ if (this._connectionValidForAP(connection, apList[i])) {
-+ this.client.activate_connection(connection.path, this.device, apList[i].dbus_path, function() { });
++ let accessPoints = sortAccessPoints(accessPointObj.accessPoints);
++ for (let i = 0; i < accessPoints.length; i++) {
++ if (this._connectionValidForAP(connection, accessPoints[i])) {
++ this._client.activate_connection(connection.path, this.device, accessPoints[i].dbus_path, null);
+ break;
+ }
+ }
@@ -926,11 +986,11 @@ index 0000000..a0cd576
+ },
+
+ connectionValid: function(connection) {
-+ if (connection._type != '802-11-wireless')
++ if (connection._type != NetworkManager.SETTING_WIRELESS_SETTING_NAME)
+ return false;
+
-+ let wirelessSettings = connection.get_setting_by_name('802-11-wireless');
-+ let wirelessSecuritySettings = connection.get_setting_by_name('802-11-wireless-security');
++ let wirelessSettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SETTING_NAME);
++ let wirelessSecuritySettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ let fixedMac = wirelessSettings.get_mac_address();
+ if (fixedMac && !macCompare(fixedMac, macToArray(this.device.perm_hw_address)))
@@ -959,27 +1019,29 @@ index 0000000..a0cd576
+ return true;
+ },
+
-+ clearSection: function() {
-+ NMDevice.prototype.clearSection.call(this);
++ _clearSection: function() {
++ NMDevice.prototype._clearSection.call(this);
+
-+ for (let i = 0; i < this._accessPoints.length; i++)
-+ this._accessPoints[i].item = null;
++ for (let i = 0; i < this._networks.length; i++)
++ this._networks[i].item = null;
+ this._overflowItem = null;
+ },
+
+ removeConnection: function(connection, skipCreateAuto) {
+ if (!connection._uuid)
+ return;
-+ let pos = this.findConnection(connection._uuid);
-+ if (pos == -1)
++ let pos = this._findConnection(connection._uuid);
++ if (pos == -1) {
++ log('Removing connection that was never added');
+ return;
++ }
+
-+ let obj = this.connections[pos];
-+ this.connections.splice(pos, 1);
++ let obj = this._connections[pos];
++ this._connections.splice(pos, 1);
+
+ let anyauto = false, forceupdate = false;
-+ for (let i = 0; i < this._accessPoints.length; i++) {
-+ let apObj = this._accessPoints[i];
++ for (let i = 0; i < this._networks.length; i++) {
++ let apObj = this._networks[i];
+ let connections = apObj.connections;
+ for (let k = 0; k < connections.length; k++) {
+ if (connections[k]._uuid == connection._uuid) {
@@ -1010,13 +1072,13 @@ index 0000000..a0cd576
+ }
+
+ if (forceupdate || (anyauto && !skipCreateAuto)) {
-+ this.clearSection();
-+ this.createConnectionList();
++ this._clearSection();
++ this._createConnectionList();
+ }
+ },
+
+ addConnection: function(connection) {
-+ if (this.findConnection(connection._uuid) != -1) {
++ if (this._findConnection(connection._uuid) != -1) {
+ log('Connection already added to menu, not adding again');
+ return;
+ }
@@ -1027,12 +1089,12 @@ index 0000000..a0cd576
+ name: connection._name,
+ uuid: connection._uuid,
+ };
-+ this.connections.push(obj);
++ this._connections.push(obj);
+
+ // find an appropriate access point
-+ let any = false;
-+ for (let i = 0; i < this._accessPoints.length; i++) {
-+ let apObj = this._accessPoints[i];
++ let any = false, forceupdate = false;
++ for (let i = 0; i < this._networks.length; i++) {
++ let apObj = this._networks[i];
+
+ // Check if connection is valid for any of these access points
+ let any = false;
@@ -1049,7 +1111,7 @@ index 0000000..a0cd576
+ (this.device.state == NetworkManager.DeviceState.DISCONNECTED ||
+ this.device.state == NetworkManager.DeviceState.ACTIVATED)) {
+ // we need to show this connection
-+ if (apObj.item && apObj.connections.length > 2) {
++ if (apObj.item && apObj.item.menu) {
+ // We're already showing the submenu for this access point
+ apObj.item.menu.addMenuItem(this._createAPItem(connection, apObj, true));
+ } else {
@@ -1057,23 +1119,29 @@ index 0000000..a0cd576
+ apObj.item.destroy();
+ if (apObj.connections.length == 1) {
+ apObj.item = this._createAPItem(connection, apObj, false);
++ this.section.addMenuItem(apObj.item);
+ } else {
-+ apObj.item = new PopupMenu.PopupSubMenuMenuItem(apObj.name);
-+ apObj.item.menu.addMenuItem(this._createAPItem(connection, apObj, true));
++ apObj.item = null;
++ // we need to force an update to create the submenu
++ forceupdate = true;
+ }
-+ this.section.addMenuItem(apObj.item);
+ }
+ }
+ }
++
++ if (forceupdate) {
++ this._clearSection();
++ this._createSection();
++ }
+ },
+
+ _connectionValidForAP: function(connection, ap) {
+ // copied and adapted from nm-applet
-+ let wirelessSettings = connection.get_setting_by_name('802-11-wireless');
-+ if (wirelessSettings.get_ssid() != String(ap.get_ssid()))
++ let wirelessSettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SETTING_NAME);
++ if (!ssidCompare(wirelessSettings.get_ssid(), ap.get_ssid()))
+ return false;
+
-+ let wirelessSecuritySettings = connection.get_setting_by_name('802-11-wireless-security');
++ let wirelessSecuritySettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ let fixedBssid = wirelessSettings.get_bssid();
+ if (fixedBssid && !macCompare(fixedBssid, macToArray(ap.hw_address)))
@@ -1097,44 +1165,52 @@ index 0000000..a0cd576
+ return true;
+ },
+
-+ createActiveConnectionItems: function() {
++ _createActiveConnectionItems: function() {
+ let activeAp = this.device.active_access_point;
+ let icon, title;
-+ if (this.activeConnection._connection) {
-+ let connection = this.activeConnection._connection;
++ if (this._activeConnection._connection) {
++ let connection = this._activeConnection._connection;
+ if (activeAp)
-+ this.activeConnectionItem = new NMAccessPointMenuItem(activeAp, undefined, { reactive: false });
++ this._activeConnectionItem = new NMNetworkMenuItem([ activeAp ], undefined,
++ { reactive: false });
+ else
-+ this.activeConnectionItem = new PopupMenu.PopupImageMenuItem(connection._name, 'network-wireless-connected', { reactive: false });
-+ this.disconnectItem = new PopupMenu.PopupMenuItem(_("Disconnect"));
-+ this.disconnectItem.connect('activate', Lang.bind(this, function() {
++ this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(connection._name,
++ 'network-wireless-connected',
++ { reactive: false });
++ this._disconnectItem = new PopupMenu.PopupMenuItem(_("Disconnect"));
++ this._disconnectItem.connect('activate', Lang.bind(this, function() {
+ this.device.disconnect(function() { });
+ }));
+ } else {
-+ // We cannot read the connection (due to ACL, most likely), but we still show signal if we have it
++ // We cannot read the connection (due to ACL, or API incompatibility), but we still show signal if we have it
+ let menuItem;
+ if (activeAp)
-+ this.activeConnectionItem = new NMAccessPointMenuItem(activeAp, undefined, { reactive: false });
++ this._activeConnectionItem = new NMNetworkMenuItem([ activeAp ], undefined,
++ { reactive: false });
+ else
-+ this.activeConnectionItem = new PopupMenu.PopupImageMenuItem(_("Connected (private)"), 'network-wireless-connected', { reactive: false });
++ this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(_("Connected (private)"),
++ 'network-wireless-connected',
++ { reactive: false });
+ }
-+ this.activeConnectionItem.setShowDot(true);
++ this._activeConnectionItem.setShowDot(true);
+ },
+
-+ createConnectionList: function() {
-+ if(this.activeConnection) {
-+ this.createActiveConnectionItems();
-+ this.section.addMenuItem(this.activeConnectionItem);
-+ if (this.disconnectItem)
-+ this.section.addMenuItem(this.disconnectItem);
++ _createConnectionList: function() {
++ if(this._activeConnection) {
++ this._createActiveConnectionItems();
++ this.section.addMenuItem(this._activeConnectionItem);
++ if (this._disconnectItem)
++ this.section.addMenuItem(this._disconnectItem);
+ }
+
+ let activeAp = this.device.active_access_point;
-+ let activeApName = activeAp ? String(activeAp.get_ssid()) : null;
++ // Use undefined instead of null, so we're sure not to match anything
++ // that comes from NetworkManager
++ let activeApSsid = activeAp ? activeAp.get_ssid() : null;
+
-+ for(let j = 0; j < this._accessPoints.length; j++) {
-+ let apObj = this._accessPoints[j];
-+ if(apObj.name == activeApName)
++ for(let j = 0; j < this._networks.length; j++) {
++ let apObj = this._networks[j];
++ if(activeAp && ssidCompare(apObj.ssid, activeApSsid))
+ continue;
+
+ let menuItem;
@@ -1142,26 +1218,35 @@ index 0000000..a0cd576
+ if (apObj.connections.length == 1)
+ apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
+ else {
-+ apObj.item = new PopupMenu.PopupSubMenuMenuItem(apObj.name);
++ let title = NetworkManager.utils_ssid_to_utf8(apObj.ssid, apObj.ssid.length) || _("<unknown>");
++ apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
+ apObj.item._apObj = apObj;
+ for (let i = 0; i < apObj.connections.length; i++)
-+ menuItem.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
++ apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
+ }
+ } else {
-+ apObj.item = new NMAccessPointMenuItem(apObj.accessPoints[0]);
++ apObj.item = new NMNetworkMenuItem(apObj.accessPoints);
+ apObj.item._apObj = apObj;
+ apObj.item.connect('activate', Lang.bind(this, function() {
++ let name;
++ let ssid = NetworkManager.utils_ssid_to_utf8(apObj.ssid, apObj.ssid.length);
++ if (ssid) {
++ /* TRANSLATORS: this the automatic wireless connection name (including the network name) */
++ name = _("Auto %s").format(ssid);
++ } else
++ name = _("Auto wireless");
++
+ let connection = new NetworkManager.Connection();
+ connection.add_setting(new NetworkManager.SettingWireless());
+ connection.add_setting(new NetworkManager.SettingConnection({
-+ /* TRANSLATORS: this the automatic wireless connection name (including the network name) */
-+ id: _("Auto %s").format(apObj.name),
++ id: name,
+ autoconnect: true, // NetworkManager will know to ignore this if appropriate
+ uuid: NetworkManager.utils_uuid_generate(),
-+ type: '802-11-wireless'
++ type: NetworkManager.SETTING_WIRELESS_SETTING_NAME
+ }));
+
-+ this.client.add_and_activate_connection(connection, this.device, apObj.accessPoints[0].dbus_path, function() { })
++ accessPoints = sortAccessPoints(apObj.accessPoints);
++ this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null)
+ }));
+ }
+
@@ -1170,6 +1255,7 @@ index 0000000..a0cd576
+ else {
+ if (!this._overflowItem) {
+ this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More..."));
++ this.section.addMenuItem(this._overflowItem);
+ }
+ this._overflowItem.menu.addMenuItem(menuItem);
+ }
@@ -1198,16 +1284,17 @@ index 0000000..a0cd576
+ this._statusSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+ this.menu.addMenuItem(this._statusSection);
+
-+ this._allSections = [ ];
++ this._deviceSections = [ ];
+
+ this._wiredSection = new PopupMenu.PopupMenuSection();
-+ this._wiredItem = new PopupMenu.PopupMenuItem(_("Wired networks"), { style_class: 'popup-subtitle-menu-item', reactive: false });
++ this._wiredItem = new PopupMenu.PopupMenuItem(_("Wired networks"),
++ { style_class: 'popup-subtitle-menu-item', reactive: false });
+ this._wiredDevices = [ ];
+
+ this._wiredSection.addMenuItem(this._wiredItem);
+ this._wiredSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+ this._wiredSection.actor.hide();
-+ this._allSections.push(this._wiredSection);
++ this._deviceSections.push(this._wiredSection);
+ this.menu.addMenuItem(this._wiredSection);
+
+ this._wirelessSection = new PopupMenu.PopupMenuSection();
@@ -1221,7 +1308,7 @@ index 0000000..a0cd576
+ }));
+ this._wirelessSection.addMenuItem(newAdhocWireless);
+
-+ let newHiddenWireless = new PopupMenu.PopupMenuItem(_("Connect to hidden wireless network..."));
++ let newHiddenWireless = new PopupMenu.PopupMenuItem(_("Other networks..."));
+ newHiddenWireless.connect('activate', Lang.bind(this, function() {
+ this._nmApplet.ConnectToHiddenNetworkRemote();
+ }));
@@ -1229,7 +1316,7 @@ index 0000000..a0cd576
+
+ this._wirelessSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+ this._wirelessSection.actor.hide();
-+ this._allSections.push(this._wirelessSection);
++ this._deviceSections.push(this._wirelessSection);
+ this.menu.addMenuItem(this._wirelessSection);
+
+ this._wwanSection = new PopupMenu.PopupMenuSection();
@@ -1239,13 +1326,18 @@ index 0000000..a0cd576
+ this._wwanSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+
+ this._wwanSection.actor.hide();
-+ this._allSections.push(this._wwanSection);
++ this._deviceSections.push(this._wwanSection);
+ this.menu.addMenuItem(this._wwanSection);
+
-+ // this._vpnDevice = new NMDeviceVPN();
-+ // this._vpnSection = this._vpnDevice.section
-+ // this._allSections.push(this._vpnSection)
-+ // this.menu.addMenuItem(this._vpnSection);
++ this._vpnDevice = new NMDeviceVPN();
++ this._vpnItem = new PopupMenu.PopupMenuItem(_("VPN Connections"),
++ { style_class: 'popup-subtitle-menu-item', reactive: false });
++ this._vpnSection = new PopupMenu.PopupMenuSection();
++ this._vpnSection.addMenuItem(this._vpnItem);
++ this._vpnSection.addMenuItem(this._vpnDevice.section);
++ this._vpnSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
++ this._deviceSections.push(this._vpnSection);
++ this.menu.addMenuItem(this._vpnSection);
+
+ this.menu.addAction(_("Network Settings"), function() {
+ Util.spawnDesktop('gnome-network-panel');
@@ -1262,48 +1354,45 @@ index 0000000..a0cd576
+
+ // Device types
+ this._dtypes = { };
-+ this._dtypes[makeClassKey(NMClient.DeviceEthernet.prototype)] = NMDeviceWired;
-+ this._dtypes[makeClassKey(NMClient.DeviceWifi.prototype)] = NMDeviceWireless;
-+ this._dtypes[makeClassKey(NMClient.GsmDevice.prototype)] = NMDeviceWWAN;
-+ this._dtypes[makeClassKey(NMClient.CdmaDevice.prototype)] = NMDeviceWWAN;
-+ this._dtypes[makeClassKey(NMClient.DeviceBt.prototype)] = NMDeviceBluetooth;
++ this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
++ this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
++ this._dtypes[NetworkManager.DeviceType.GSM] = NMDeviceWWAN;
++ this._dtypes[NetworkManager.DeviceType.CDMA] = NMDeviceWWAN;
++ this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
+ // FIXME: WWAN support (if enabled)
+
+ // Connection types
+ this._ctypes = { };
-+ this._ctypes['802-11-wireless'] = 'wireless';
-+ this._ctypes['802-3-ethernet'] = this._ctypes['pppoe'] = 'wired';
-+ this._ctypes['bluetooth'] = this._ctypes['cdma'] = this._ctypes['gsm'] = 'wwan';
-+ this._ctypes['vpn'] = 'vpn';
++ this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] = NMConnectionCategory.WIRELESS;
++ this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] = NMConnectionCategory.WIRED;
++ this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] = NMConnectionCategory.WIRED;
++ this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
++ this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
++ this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
++ this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
+
+ this._settings = NMClient.RemoteSettings.new(null);
+ this._settings.connect('connections-read', Lang.bind(this, function() {
-+ this._read_connections();
-+ this._read_devices();
-+ this._sync_nm_state();
++ this._readConnections();
++ this._readDevices();
++ this._syncNMState();
+
+ // Connect to signals late so that early signals don't find in inconsistent state
-+ this._client.connect('notify::manager-running', Lang.bind(this, this._sync_nm_state));
-+ this._client.connect('notify::networking-enabled', Lang.bind(this, this._sync_nm_state));
-+ this._client.connect('notify::state', Lang.bind(this, this._sync_nm_state));
-+ this._client.connect('notify::active-connections', Lang.bind(this, this._update_icon));
-+ this._client.connect('device-added', Lang.bind(this, this._device_added));
-+ this._client.connect('device-removed', Lang.bind(this, this._device_removed));
-+ this._settings.connect('new-connection', Lang.bind(this, this._new_connection));
++ this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
++ this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
++ this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
++ this._client.connect('notify::active-connections', Lang.bind(this, this._updateIcon));
++ this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
++ this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
++ this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
+ }));
-+ //this._sync_nm_state();
+ },
+
+ _ensureSource: function() {
+ if (!this._source) {
-+ this._source = new MessageTray.Source(_("Network Manager"));
-+ let icon = new St.Icon({ icon_name: 'network-transmit-receive',
-+ icon_type: St.IconType.SYMBOLIC,
-+ icon_size: this._source.ICON_SIZE
-+ });
-+ this._source._setSummaryIcon(icon);
++ this._source = new NMMessageTraySource();
+ this._source._destroyId = this._source.connect('destroy', Lang.bind(this, function() {
-+ this._source.disconnect(this._source._destroyId);
++ this._source._destroyId = 0;
+ this._source = null;
+ }));
+ Main.messageTray.add(this._source);
@@ -1346,21 +1435,20 @@ index 0000000..a0cd576
+ });
+
+ this._client.connect('notify::' + type + '-enabled', handler);
-+ this._client.connect('notify::' + type + 'hardware-enabled', handler);
++ this._client.connect('notify::' + type + '-hardware-enabled', handler);
+ this['_' + type + 'Item'] = item;
+ handler();
+ },
+
-+ _read_devices: function() {
++ _readDevices: function() {
+ let devices = this._client.get_devices();
+ for (let i = 0; i < devices.length; ++i) {
-+ this._device_added(this._client, devices[i]);
++ this._deviceAdded(this._client, devices[i]);
+ }
+ },
+
-+ _device_added: function(client, device) {
-+ let objKey = makeClassKey(device);
-+ let wrapperClass = this._dtypes[objKey];
++ _deviceAdded: function(client, device) {
++ let wrapperClass = this._dtypes[device.get_device_type()];
+ if (wrapperClass) {
+ // XXX: check what nm-applet does here
+ device._description = device.get_product();
@@ -1393,6 +1481,10 @@ index 0000000..a0cd576
+ { icon: icon });
+ this._source.notify(notification);
+ }));
++ wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
++ wrapper.disconnect(wrapper._networkLostId);
++ wrapper.disconnect(wrapper._activationFailedId);
++ });
+ let section = this['_' + wrapper.category + 'Section'];
+ let devices = this['_' + wrapper.category + 'Devices'];
+
@@ -1408,10 +1500,10 @@ index 0000000..a0cd576
+ devices[i].titleItem.actor.hide();
+ }
+ } else
-+ log('Invalid network device class, is ' + objKey);
++ log('Invalid network device type, is ' + device.get_device_type());
+ },
+
-+ _device_removed: function(client, device) {
++ _deviceRemoved: function(client, device) {
+ if (!device._delegate) {
+ log('Removing a network device that was not added (race condition?)');
+ return;
@@ -1436,7 +1528,7 @@ index 0000000..a0cd576
+ }
+ },
+
-+ _sync_active_connections: function() {
++ _syncActiveConnections: function() {
+ let closedConnections = [ ];
+ let newActiveConnections = this._client.get_active_connections() || [ ];
+ for (let i = 0; i < this._activeConnections.length; i++) {
@@ -1469,10 +1561,16 @@ index 0000000..a0cd576
+ let a = this._activeConnections[i];
+
+ if (!a._inited) {
-+ a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._update_icon));
-+ a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._update_icon));
++ a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._updateIcon));
++ a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._updateIcon));
+ if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING) // prepare to notify to the user
-+ a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._notify_active_connection));
++ a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._notifyActiveConnection));
++ else {
++ // notify immediately
++ Mainloop.idle_add(Lang.bind(this, function() {
++ this._notifyActiveConnection(a);
++ }));
++ }
+
+ a._inited = true;
+ }
@@ -1486,6 +1584,7 @@ index 0000000..a0cd576
+ } else {
+ a._connection = null;
+ a._type = null;
++ a._section = null;
+ log('Cannot find connection for active (or connection cannot be read)');
+ }
+ }
@@ -1507,7 +1606,7 @@ index 0000000..a0cd576
+ }
+
+ if (!a._primaryDevice) {
-+ if (a._type != 'vpn') {
++ if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
+ // find a good device to be considered primary
+ // XXX: check what nm-applet does here
+ a._primaryDevice = null;
@@ -1527,36 +1626,32 @@ index 0000000..a0cd576
+ }
+ }
+
-+ if (activating)
-+ this._mainConnection = activating;
-+ else if (default_ip4)
-+ this._mainConnection = default_ip4;
-+ else
-+ this._mainConnection = default_ip6;
++ this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
+ },
+
-+ _notify_active_connection: function(active) {
-+ if (active.state == NetworkManager.ActiveConnectionState.ACTIVE) {
++ _notifyActiveConnection: function(active) {
++ if (active.state == NetworkManager.ActiveConnectionState.ACTIVATED) {
+ this._ensureSource();
+
+ let icon;
+ let banner;
-+ switch (active._type) {
-+ case 'gsm':
-+ case 'cdma':
-+ case 'bluetooth':
++ switch (active._section) {
++ case NMConnectionCategory.WWAN:
+ icon = 'network-cellular-signal-excellent';
+ banner = _("You're now connected to mobile broadband connection '%s'").format(active._connection._name);
+ break;
-+ case '802-11-wireless':
++ case NMConnectionCategory.WIRELESS:
+ icon = 'network-wireless-signal-excellent';
+ banner = _("You're now connected to wireless network '%s'").format(active._connection._name);
+ break;
-+ case '802-3-ethernet':
-+ case 'pppoe':
++ case NMConnectionCategory.WIRED:
+ icon = 'network-wired';
+ banner = _("You're now connected to wired network '%s'").format(active._connection._name);
+ break;
++ case NMConnectionCategory.VPN:
++ icon = 'network-vpn';
++ banner = _("You're now connected to VPN network '%s'").format(active._connection._name);
++ break;
+ default:
+ // a fallback for a generic 'connected' icon
+ icon = 'network-transmit-receive';
@@ -1564,7 +1659,7 @@ index 0000000..a0cd576
+ }
+
+ let iconActor = new St.Icon({ icon_name: icon,
-+ con_type: St.IconType.SYMBOLIC,
++ icon_type: St.IconType.SYMBOLIC,
+ icon_size: this._source.ICON_SIZE
+ });
+ let notification = new MessageTray.Notification(this._source,
@@ -1573,14 +1668,16 @@ index 0000000..a0cd576
+ { icon: iconActor });
+ this._source.notify(notification);
+
-+ active.disconnect(active._stateChangeId);
-+ active._stateChangeId = 0;
++ if (active._stateChangeId) {
++ active.disconnect(active._stateChangeId);
++ active._stateChangeId = 0;
++ }
+ }
+
-+ this._sync_nm_state();
++ this._syncNMState();
+ },
+
-+ _read_connections: function() {
++ _readConnections: function() {
+ let connections = this._settings.list_connections();
+ for (let i = 0; i < connections.length; i++) {
+ let connection = connections[i];
@@ -1588,75 +1685,77 @@ index 0000000..a0cd576
+ log('Connection was already seen, when reading the connections for the first time (race condition?)');
+ continue;
+ }
-+ connection.connect('removed', Lang.bind(this, this._connection_removed));
-+ // we don't connect to 'updated' because GJS currently cannot deliver it
-+ // (it needs to type overrides from GIR)
-+ //connection.connect('updated', Lang.bind(this, this._update_connection));
-+
-+ let connectionSettings = connection.get_setting_by_name('connection');
-+ connection._type = connectionSettings.type;
-+ connection._section = this._ctypes[connection._type];
-+ connection._name = connectionSettings.id;
-+ connection._uuid = connectionSettings.uuid;
++ connection.connect('removed', Lang.bind(this, this._connectionRemoved));
++ connection.connect('updated', Lang.bind(this, this._updateConnection));
++
++ this._updateConnection(connection);
+ this._connections.push(connection);
+ }
+ },
+
-+ _new_connection: function(settings, connection) {
++ _newConnection: function(settings, connection) {
+ if (connection._uuid) {
+ log('Connection was already seen, not adding again...');
+ return;
+ }
+
-+ connection.connect('removed', Lang.bind(this, this._connection_removed));
-+ //connection.connect('updated', Lang.bind(this, this._update_connection));
++ connection.connect('removed', Lang.bind(this, this._connectionRemoved));
++ connection.connect('updated', Lang.bind(this, this._updateConnection));
+
-+ let connectionSettings = connection.get_setting_by_name('connection');
-+ connection._type = connectionSettings.type;
-+ connection._section = this._ctypes[connection._type];
-+ connection._name = connectionSettings.id;
-+ connection._uuid = connectionSettings.uuid;
++ this._updateConnection(connection);
+ this._connections.push(connection);
+
-+ this._update_icon();
++ this._updateIcon();
+ },
+
-+ _connection_removed: function(connection) {
++ _connectionRemoved: function(connection) {
+ let pos = this._connections.indexOf(connection);
+ if (pos != -1)
+ this._connections.splice(connection);
+
-+ if (!connection._ever_added)
++ if (!connection._everAdded)
+ return;
+
+ let section = connection._section;
-+ let devices = this['_' + section + 'Devices'];
-+ for (let i = 0; i < devices.length; i++)
-+ devices[i].removeConnection(connection);
++ if (section == NMConnectionCategory.VPN) {
++ this._vpnDevice.removeConnection(connection);
++ if (this._vpnDevice.empty)
++ this._vpnSection.actor.hide();
++ } else {
++ let devices = this['_' + section + 'Devices'];
++ for (let i = 0; i < devices.length; i++)
++ devices[i].removeConnection(connection);
++ }
+ },
+
-+ _update_connection: function(connection) {
-+ this._connection_removed(connection);
++ _updateConnection: function(connection) {
++ this._connectionRemoved(connection);
+
-+ let connectionSettings = connection.get_setting_by_name('connection');
++ let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
+ connection._type = connectionSettings.type;
+ connection._section = this._ctypes[connection._type];
+ connection._name = connectionSettings.id;
+ connection._uuid = connectionSettings.uuid;
+
+ let section = connection._section;
-+ let devices = this['_' + section + 'Devices'];
-+ for (let i = 0; i < devices.length; i++) {
-+ if (devices[i].connectionValid(connection)) {
-+ devices[i].addConnection(connection);
-+ connection._ever_added = true;
++ if (section == NMConnectionCategory.VPN) {
++ this._vpnDevice.addConnection(connection);
++ this._vpnSection.actor.show();
++ connection._everAdded = true;
++ } else {
++ let devices = this['_' + section + 'Devices'];
++ for (let i = 0; i < devices.length; i++) {
++ if (devices[i].connectionValid(connection)) {
++ devices[i].addConnection(connection);
++ connection._everAdded = true;
++ }
+ }
+ }
+ },
+
-+ _hideAll: function() {
-+ for (let i = 0; i < this._allSections.length; i++) {
-+ let item = this._allSections[i];
++ _hideDevices: function() {
++ for (let i = 0; i < this._deviceSections.length; i++) {
++ let item = this._deviceSections[i];
+ item.actor.hide();
+ }
+ },
@@ -1666,17 +1765,26 @@ index 0000000..a0cd576
+
+ if (this._wiredDevices.length > 0)
+ this._wiredSection.actor.show();
++ else
++ this._wiredSection.actor.hide();
+
+ if (this._wirelessDevices.length > 0)
+ this._wirelessSection.actor.show();
++ else
++ this._wirelessSection.actor.hide();
+
+ if (this._wwanDevices.length > 0)
+ this._wwanSection.actor.show();
++ else
++ this._wwanSection.actor.hide();
+
-+ // this._vpnSection.actor.show();
++ if (!this._vpnDevice.empty)
++ this._vpnSection.actor.show();
++ else
++ this._vpnSection.actor.hide();
+ },
+
-+ _sync_nm_state: function() {
++ _syncNMState: function() {
+ if (!this._client.manager_running) {
+ log('NetworkManager is not running, hiding...');
+ this.menu.close();
@@ -1687,18 +1795,18 @@ index 0000000..a0cd576
+
+ if (!this._client.networking_enabled) {
+ this.setIcon('network-offline');
-+ this._hideAll();
++ this._hideDevices();
+ this._statusItem.label.text = _("Networking is disabled");
+ this._statusSection.actor.show();
+ return;
+ }
+
+ this._showNormal();
-+ this._update_icon();
++ this._updateIcon();
+ },
+
-+ _update_icon: function() {
-+ this._sync_active_connections();
++ _updateIcon: function() {
++ this._syncActiveConnections();
+ let mc = this._mainConnection;
+ let hasApIcon = false;
+ let hasMobileIcon = false;
@@ -1712,22 +1820,23 @@ index 0000000..a0cd576
+ log('NetworkManager is connecting, but we have no ActiveConnection activating');
+ break;
+ }
-+ switch (mc._type) {
-+ case 'gsm':
-+ case 'cdma':
-+ case 'bluetooth':
++ switch (mc._section) {
++ case NMConnectionCategory.WWAN:
+ this.setIcon('network-cellular-acquiring');
+ break;
-+ case '802-11-wireless':
++ case NMConnectionCategory.WIRELESS:
+ this.setIcon('network-wireless-acquiring');
+ break;
-+ case '802-3-ethernet':
-+ case 'pppoe':
++ case NMConnectionCategory.WIRED:
+ this.setIcon('network-wired-acquiring');
+ break;
++ case NMConnectionCategory.VPN:
++ // XXX: there is no network-vpn-acquiring
++ this.setIcon('network-vpn');
++ break;
+ default:
+ this.setIcon('network-error');
-+ log ('Invalid active connection type ' + mc._type);
++ log('Invalid active connection type ' + mc._section);
+ }
+ break;
+ case NetworkManager.State.CONNECTED_LOCAL:
@@ -1738,18 +1847,19 @@ index 0000000..a0cd576
+ break;
+ }
+ let dev;
-+ switch (mc._type) {
-+ case '802-11-wireless':
++ switch (mc._section) {
++ case NMConnectionCategory.WIRELESS:
+ dev = mc._primaryDevice;
+ if (dev) {
+ let ap = dev.device.active_access_point;
+ let mode = dev.device.mode;
+ if (!ap) {
+ if (mode != NetworkManager['80211Mode'].ADHOC) {
-+ log ('An active wireless connection, in infrastructure mode, involves no access point?');
++ log('An active wireless connection, in infrastructure mode, involves no access point?');
+ break;
+ }
-+ this.setIcon('network-wireless-connected');
++ // XXX: there is no network-wireless-connected
++ this.setIcon('network-wireless-signal-excellent');
+ } else {
+ if (this._accessPointUpdateId && this._activeAccessPoint != ap) {
+ this._activeAccessPoint.disconnect(this._accessPointUpdateId);
@@ -1763,20 +1873,19 @@ index 0000000..a0cd576
+ }
+ break;
+ } else {
-+ log ('Active connection with no primary device?');
++ log('Active connection with no primary device?');
+ break;
+ }
-+ case '802-3-ethernet':
-+ case 'pppoe':
-+ case 'serial':
++ case NMConnectionCategory.WIRED:
+ this.setIcon('network-wired-symbolic');
+ break;
-+ case 'bluetooth':
-+ // XXX: NetworkManager does not give us signal for bluetooth
-+ this.setIcon('network-cellular-signal-excellent');
-+ break;
-+ case 'cdma':
-+ case 'gsm':
++ case NMConnectionCategory.WWAN:
++ if (mc._type == NetworkManager.SETTING_BLUETOOTH_SETTING_NAME) {
++ // XXX: NetworkManager does not give us signal for bluetooth
++ this.setIcon('network-cellular-signal-excellent');
++ break;
++ }
++
+ dev = mc._primaryDevice;
+ if (this._mobileUpdateId && this._mobileUpdateDevice != dev) {
+ this._mobileUpdateDevice.disconnect(this._mobileUpdateId);
@@ -1788,11 +1897,11 @@ index 0000000..a0cd576
+ this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
+ hasMobileIcon = true;
+ break;
-+ case 'vpn':
++ case NMConnectionCategory.VPN:
+ this.setIcon('network-vpn');
+ break;
+ default:
-+ log('Invalid active connection type ' + mc._type);
++ log('Invalid active connection type ' + mc._section);
+ this.setIcon('network-error');
+ break;
+ }
@@ -1815,8 +1924,26 @@ index 0000000..a0cd576
+ }
+ }
+};
++
++function NMMessageTraySource() {
++ this._init();
++}
++
++NMMessageTraySource.prototype = {
++ __proto__: MessageTray.Source.prototype,
++
++ _init: function() {
++ MessageTray.Source.prototype._init.call(this, _("Network Manager"));
++
++ let icon = new St.Icon({ icon_name: 'network-transmit-receive',
++ icon_type: St.IconType.SYMBOLIC,
++ icon_size: this.ICON_SIZE
++ });
++ this._setSummaryIcon(icon);
++ }
++};
diff --git a/tools/build/gnome-shell.modules b/tools/build/gnome-shell.modules
-index e8b5493..b14fd53 100644
+index e8b5493..2f44c5d 100644
--- a/tools/build/gnome-shell.modules
+++ b/tools/build/gnome-shell.modules
@@ -9,6 +9,8 @@
@@ -1828,23 +1955,7 @@ index e8b5493..b14fd53 100644
<repository type="tarball" name="cairo.org"
href="http://cairographics.org/"/>
<repository type="tarball" name="0pointer.de"
-@@ -237,6 +239,7 @@
- <dep package="gnome-settings-daemon"/>
- <dep package="gnome-bluetooth"/>
- <dep package="telepathy-glib"/>
-+ <dep package="NetworkManager"/>
- </dependencies>
- </autotools>
-
-@@ -255,6 +258,7 @@
- <dep package="gnome-themes-standard"/>
- <dep package="gnome-shell"/>
- <dep package="gnome-power-manager"/>
-+ <dep package="network-manager-applet"/>
- </dependencies>
- </metamodule>
-
-@@ -315,4 +319,19 @@
+@@ -315,4 +317,19 @@
</dependencies>
</autotools>
diff --git a/gnome-base/gnome-shell/gnome-shell-9999.ebuild b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
index ef3cd5a..f3a6869 100644
--- a/gnome-base/gnome-shell/gnome-shell-9999.ebuild
+++ b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
@@ -91,7 +91,7 @@ src_prepare() {
ewarn "Adding support for the experimental NetworkManager applet."
ewarn "This needs the latest NetworkManager & nm-applet trunk."
ewarn "Report bugs about this to 'nirbheek' on #gentoo-desktop @ FreeNode."
- epatch "${FILESDIR}/${PN}-experimental-nm-applet.patch"
+ epatch "${FILESDIR}/${PN}-experimental-nm-applet-1.0.patch"
fi
gnome2_src_prepare
diff --git a/net-misc/networkmanager/files/networkmanager-more-gi-annotations.patch b/net-misc/networkmanager/files/networkmanager-more-gi-annotations.patch
new file mode 100644
index 0000000..e6bac7d
--- /dev/null
+++ b/net-misc/networkmanager/files/networkmanager-more-gi-annotations.patch
@@ -0,0 +1,43 @@
+From a420d59ea24a1eb82a7c1dc96e3cf5b38b0fd757 Mon Sep 17 00:00:00 2001
+From: Giovanni Campagna <gcampagna@src.gnome.org>
+Date: Tue, 22 Feb 2011 23:34:41 +0100
+Subject: [PATCH] libnm-util: another introspection annotation
+
+nm_utils_ssid_to_utf8 has gchar* in the signature, but it accepts
+an array of bytes, not a string. Fix with the appropriate
+annotation.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=643011
+---
+ libnm-util/nm-utils.c | 9 +++++----
+ 1 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c
+index 87c5d5f..c2134db 100644
+--- a/libnm-util/nm-utils.c
++++ b/libnm-util/nm-utils.c
+@@ -304,7 +304,8 @@ nm_utils_deinit (void)
+
+ /**
+ * nm_utils_ssid_to_utf8:
+- * @ssid: pointer to a buffer containing the SSID data
++ * @ssid: (array length=len) (element-type guint8): pointer to a buffer
++ * containing the SSID data
+ * @len: length of the SSID data in @ssid
+ *
+ * WiFi SSIDs are byte arrays, they are _not_ strings. Thus, an SSID may
+@@ -330,9 +331,9 @@ nm_utils_deinit (void)
+ * Again, this function should be used for debugging and display purposes
+ * _only_.
+ *
+- * Returns: an allocated string containing a UTF-8 representation of the
+- * SSID, which must be freed by the caller using g_free(). Returns NULL
+- * on errors.
++ * Returns: (transfer full): an allocated string containing a UTF-8 representation
++ * of the SSID, which must be freed by the caller using g_free(). Returns
++ * NULL on errors.
+ **/
+ char *
+ nm_utils_ssid_to_utf8 (const char *ssid, guint32 len)
+--
+1.7.4
\ No newline at end of file
diff --git a/net-misc/networkmanager/networkmanager-9999.ebuild b/net-misc/networkmanager/networkmanager-9999.ebuild
index d4bbdd6..686bad1 100644
--- a/net-misc/networkmanager/networkmanager-9999.ebuild
+++ b/net-misc/networkmanager/networkmanager-9999.ebuild
@@ -133,6 +133,9 @@ src_prepare() {
# FIXME: does not apply
#epatch "${FILESDIR}/${PN}-0.8.2-shared-connection.patch"
+ # https://bugzilla.gnome.org/show_bug.cgi?id=643011
+ epatch "${FILESDIR}/${PN}-more-gi-annotations.patch"
+
gnome2_src_prepare
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/gnome:master commit in: gnome-base/gnome-shell/, net-misc/networkmanager/, ...
@ 2011-04-05 0:57 Nirbheek Chauhan
0 siblings, 0 replies; 4+ messages in thread
From: Nirbheek Chauhan @ 2011-04-05 0:57 UTC (permalink / raw
To: gentoo-commits
commit: 87ab7bf424538af1114104c0800a235b60401a87
Author: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 4 22:07:03 2011 +0000
Commit: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
CommitDate: Tue Apr 5 00:29:58 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gnome.git;a=commit;h=87ab7bf4
net-misc/networkmanager: 0.8.996-r1 → 0.8.997
---
...ell-2.91.93.ebuild => gnome-shell-3.0.0.ebuild} | 6 +-
gnome-base/gnome-shell/gnome-shell-9999.ebuild | 2 +-
.../networkmanager-0.8.996-fix-introspection.patch | 51 --------------------
...996-r1.ebuild => networkmanager-0.8.997.ebuild} | 26 ++--------
4 files changed, 10 insertions(+), 75 deletions(-)
diff --git a/gnome-base/gnome-shell/gnome-shell-2.91.93.ebuild b/gnome-base/gnome-shell/gnome-shell-3.0.0.ebuild
similarity index 96%
rename from gnome-base/gnome-shell/gnome-shell-2.91.93.ebuild
rename to gnome-base/gnome-shell/gnome-shell-3.0.0.ebuild
index b31d84a..da01a14 100644
--- a/gnome-base/gnome-shell/gnome-shell-2.91.93.ebuild
+++ b/gnome-base/gnome-shell/gnome-shell-3.0.0.ebuild
@@ -40,7 +40,7 @@ COMMON_DEPEND=">=dev-libs/glib-2.25.9:2
>=net-libs/telepathy-glib-0.13.12[introspection]
>=net-wireless/gnome-bluetooth-2.90.0[introspection]
>=sys-auth/polkit-0.100[introspection]
- >=x11-wm/mutter-2.91.93[introspection]
+ >=x11-wm/mutter-3.0.0[introspection]
dev-libs/dbus-glib
dev-libs/libxml2:2
@@ -76,8 +76,8 @@ RDEPEND="${COMMON_DEPEND}
>=gnome-base/gnome-control-center-2.91.92-r1
nm-applet? (
- >=gnome-extra/nm-applet-0.8.996
- >=net-misc/networkmanager-0.8.996-r1[introspection] )"
+ >=gnome-extra/nm-applet-0.8.997
+ >=net-misc/networkmanager-0.8.997[introspection] )"
DEPEND="${COMMON_DEPEND}
sys-devel/gettext
>=dev-util/pkgconfig-0.22
diff --git a/gnome-base/gnome-shell/gnome-shell-9999.ebuild b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
index b31d84a..fa14e4b 100644
--- a/gnome-base/gnome-shell/gnome-shell-9999.ebuild
+++ b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
@@ -40,7 +40,7 @@ COMMON_DEPEND=">=dev-libs/glib-2.25.9:2
>=net-libs/telepathy-glib-0.13.12[introspection]
>=net-wireless/gnome-bluetooth-2.90.0[introspection]
>=sys-auth/polkit-0.100[introspection]
- >=x11-wm/mutter-2.91.93[introspection]
+ >=x11-wm/mutter-3.0.0[introspection]
dev-libs/dbus-glib
dev-libs/libxml2:2
diff --git a/net-misc/networkmanager/files/networkmanager-0.8.996-fix-introspection.patch b/net-misc/networkmanager/files/networkmanager-0.8.996-fix-introspection.patch
deleted file mode 100644
index 0e488c3..0000000
--- a/net-misc/networkmanager/files/networkmanager-0.8.996-fix-introspection.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 3ac6aa8008970b9cbafaa7a7134c9dc2f455d2f7 Mon Sep 17 00:00:00 2001
-From: Giovanni Campagna <gcampagna@src.gnome.org>
-Date: Tue, 15 Mar 2011 20:37:29 +0100
-Subject: [PATCH] include: mark flags as such
-
-If the /*< flags >*/ annotation is missing, enums are picked as
-enumerations, so bindings won't allow passing combinations of them.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=643011
----
- include/NetworkManager.h | 4 ++++
- 1 files changed, 4 insertions(+), 0 deletions(-)
-
-diff --git a/include/NetworkManager.h b/include/NetworkManager.h
-index d8f29c5..d421aff 100644
---- a/include/NetworkManager.h
-+++ b/include/NetworkManager.h
-@@ -138,6 +138,7 @@ typedef enum {
-
- /* 802.11 Access Point flags */
- typedef enum {
-+ /*< flags >*/
- NM_802_11_AP_FLAGS_NONE = 0x00000000,
- NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
- } NM80211ApFlags;
-@@ -150,6 +151,7 @@ typedef enum {
- * information elements.
- */
- typedef enum {
-+ /*< flags >*/
- NM_802_11_AP_SEC_NONE = 0x00000000,
- NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001,
- NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002,
-@@ -183,6 +185,7 @@ typedef enum {
- * Bluetooth device.
- */
- typedef enum {
-+ /*< flags >*/
- NM_BT_CAPABILITY_NONE = 0x00000000,
- NM_BT_CAPABILITY_DUN = 0x00000001,
- NM_BT_CAPABILITY_NAP = 0x00000002,
-@@ -205,6 +208,7 @@ typedef enum {
- * API.
- */
- typedef enum {
-+ /*< flags >*/
- NM_DEVICE_MODEM_CAPABILITY_NONE = 0x00000000,
- NM_DEVICE_MODEM_CAPABILITY_POTS = 0x00000001,
- NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO = 0x00000002,
---
-1.7.4
\ No newline at end of file
diff --git a/net-misc/networkmanager/networkmanager-0.8.996-r1.ebuild b/net-misc/networkmanager/networkmanager-0.8.997.ebuild
similarity index 84%
rename from net-misc/networkmanager/networkmanager-0.8.996-r1.ebuild
rename to net-misc/networkmanager/networkmanager-0.8.997.ebuild
index 201783c..39bd459 100644
--- a/net-misc/networkmanager/networkmanager-0.8.996-r1.ebuild
+++ b/net-misc/networkmanager/networkmanager-0.8.997.ebuild
@@ -3,17 +3,16 @@
# $Header: /var/cvsroot/gentoo-x86/net-misc/networkmanager/networkmanager-0.8.995.ebuild,v 1.1 2011/03/09 07:56:21 qiaomuf Exp $
EAPI="4"
+GNOME_ORG_MODULE="NetworkManager"
inherit autotools eutils gnome.org linux-info
# NetworkManager likes itself with capital letters
-MY_PN=${PN/networkmanager/NetworkManager}
+MY_PN=${PN/networkmanager/${GNOME_ORG_MODULE}}
MY_P=${MY_PN}-${PV}
DESCRIPTION="Network configuration and management in an easy way. Desktop environment independent."
HOMEPAGE="http://www.gnome.org/projects/NetworkManager/"
-SRC_URI="${SRC_URI//${PN}/${MY_PN}}
- http://dev.gentoo.org/~dagger/files/ifnet-0.9.tar.bz2"
LICENSE="GPL-2"
SLOT="0"
@@ -71,7 +70,7 @@ sysfs_deprecated_check() {
eend $?
}
-pkg_setup() {
+pkg_pretend() {
if use kernel_linux; then
get_version
if linux_config_exists; then
@@ -86,14 +85,8 @@ pkg_setup() {
}
src_prepare() {
- # disable tests
+ # Don't build tests
epatch "${FILESDIR}/${PN}-fix-tests.patch"
-
- # https://bugzilla.gnome.org/show_bug.cgi?id=643011
- # Merged upstream, not needed for next release
- epatch "${FILESDIR}/${P}-fix-introspection.patch"
-
- EPATCH_SOURCE="${WORKDIR}/ifnet-0.9" EPATCH_SUFFIX="diff" EPATCH_FORCE="yes" epatch
eautoreconf
default
}
@@ -131,17 +124,10 @@ src_install() {
# Need to keep the /etc/NetworkManager/dispatched.d for dispatcher scripts
keepdir /etc/NetworkManager/dispatcher.d
- dodoc AUTHORS ChangeLog NEWS README TODO || die "dodoc failed"
+ dodoc AUTHORS ChangeLog NEWS README TODO
# Add keyfile plugin support
keepdir /etc/NetworkManager/system-connections
insinto /etc/NetworkManager
- newins "${FILESDIR}/nm-system-settings.conf-ifnet" nm-system-settings.conf \
- || die "newins failed"
-}
-
-pkg_postinst() {
- elog "You will need to reload DBus if this is your first time installing"
- elog "NetworkManager, or if you're upgrading from 0.7 or older."
- elog ""
+ newins "${FILESDIR}/nm-system-settings.conf-ifnet" nm-system-settings.conf
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/gnome:master commit in: gnome-base/gnome-shell/, net-misc/networkmanager/, ...
@ 2011-03-16 20:20 Nirbheek Chauhan
0 siblings, 0 replies; 4+ messages in thread
From: Nirbheek Chauhan @ 2011-03-16 20:20 UTC (permalink / raw
To: gentoo-commits
commit: c9fdf24db6db05d9cb04e78c775faa3e5c8fd5df
Author: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 16 20:19:21 2011 +0000
Commit: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
CommitDate: Wed Mar 16 20:19:21 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gnome.git;a=commit;h=c9fdf24d
gnome-base/gnome-shell: nm-applet patch is now upstream
* Update networkmanager and gnome-shell deps
---
.../gnome-shell-experimental-nm-applet-1.5.patch | 3446 --------------------
gnome-base/gnome-shell/gnome-shell-9999.ebuild | 22 +-
.../networkmanager-0.8.996-fix-introspection.patch | 51 +
...996.ebuild => networkmanager-0.8.996-r1.ebuild} | 4 +
4 files changed, 62 insertions(+), 3461 deletions(-)
diff --git a/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.5.patch b/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.5.patch
deleted file mode 100644
index d32aca4..0000000
--- a/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.5.patch
+++ /dev/null
@@ -1,3446 +0,0 @@
-From 1bf9b9694338ba917db07d2bf75146dba6a80054 Mon Sep 17 00:00:00 2001
-From: Giovanni Campagna <gcampagna@src.gnome.org>
-Date: Tue, 25 Jan 2011 22:08:12 +0100
-Subject: [PATCH] Status area: add NetworkManager indicator
-
-Adds an implementation of nm-applet in javascript. Uses the new
-introspection from NetworkManager, and temporarily requires
-nm-applet to be running for the secret service.
-Features a renewed interface, with each device controllable through
-a switch, which if toggled off disconnects, and if toggled on
-connects to the most recently used valid connection. More esoteric
-features like creation of ad-hoc networks have been moved to the
-control center panel.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=621707
----
- data/theme/gnome-shell.css | 8 +
- js/Makefile.am | 2 +
- js/misc/modemManager.js | 219 +++++
- js/misc/util.js | 80 ++
- js/ui/panel.js | 7 +
- js/ui/status/network.js | 2048 +++++++++++++++++++++++++++++++++++++++
- src/Makefile.am | 5 +-
- src/shell-mobile-providers.c | 816 ++++++++++++++++
- src/shell-mobile-providers.h | 96 ++
- tools/build/gnome-shell.modules | 17 +
- 10 files changed, 3297 insertions(+), 1 deletions(-)
- create mode 100644 js/misc/modemManager.js
- create mode 100644 js/ui/status/network.js
- create mode 100644 src/shell-mobile-providers.c
- create mode 100644 src/shell-mobile-providers.h
-
-diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
-index 7d9f011..5d7eea2 100644
---- a/data/theme/gnome-shell.css
-+++ b/data/theme/gnome-shell.css
-@@ -160,6 +160,14 @@ StTooltip StLabel {
- spacing: .5em;
- }
-
-+.popup-inactive-menu-item {
-+ font-style: italic;
-+}
-+
-+.popup-subtitle-menu-item {
-+ font-weight: bold;
-+}
-+
- .popup-menu-icon {
- icon-size: 1.14em;
- }
-diff --git a/js/Makefile.am b/js/Makefile.am
-index 55bb111..a085bfc 100644
---- a/js/Makefile.am
-+++ b/js/Makefile.am
-@@ -8,6 +8,7 @@ nobase_dist_js_DATA = \
- misc/format.js \
- misc/gnomeSession.js \
- misc/history.js \
-+ misc/modemManager.js \
- misc/params.js \
- misc/util.js \
- perf/core.js \
-@@ -50,6 +51,7 @@ nobase_dist_js_DATA = \
- ui/statusMenu.js \
- ui/status/accessibility.js \
- ui/status/keyboard.js \
-+ ui/status/network.js \
- ui/status/power.js \
- ui/status/volume.js \
- ui/status/bluetooth.js \
-diff --git a/js/misc/modemManager.js b/js/misc/modemManager.js
-new file mode 100644
-index 0000000..5b2754b
---- /dev/null
-+++ b/js/misc/modemManager.js
-@@ -0,0 +1,219 @@
-+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
-+
-+const DBus = imports.dbus;
-+const Lang = imports.lang;
-+const Shell = imports.gi.Shell;
-+const Signals = imports.signals;
-+
-+// The following are not the complete interfaces, just the methods we need
-+// (or may need in the future)
-+
-+const ModemGsmNetworkInterface = {
-+ name: 'org.freedesktop.ModemManager.Modem.Gsm.Network',
-+ methods: [
-+ { name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' },
-+ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }
-+ ],
-+ properties: [
-+ { name: 'AccessTechnology', signature: 'u', access: 'read' }
-+ ],
-+ signals: [
-+ { name: 'SignalQuality', inSignature: 'u' },
-+ { name: 'RegistrationInfo', inSignature: 'uss' }
-+ ]
-+};
-+const ModemGsmNetworkProxy = DBus.makeProxyClass(ModemGsmNetworkInterface);
-+
-+const ModemCdmaInterface = {
-+ name: 'org.freedesktop.ModemManager.Modem.Cdma',
-+ methods: [
-+ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' },
-+ { name: 'GetServingSystem', inSignature: '', outSignature: 'usu' }
-+ ],
-+ signals: [
-+ { name: 'SignalQuality', inSignature: 'u' }
-+ ]
-+};
-+const ModemCdmaProxy = DBus.makeProxyClass(ModemCdmaInterface);
-+
-+let _providersTable;
-+function _getProvidersTable() {
-+ if (_providersTable)
-+ return _providersTable;
-+ let [providers, countryCodes] = Shell.mobile_providers_parse();
-+ return _providersTable = providers;
-+}
-+
-+function _findProviderForMCCMNC(needle) {
-+ let table = _getProvidersTable();
-+ let needlemcc = needle.substring(0, 3);
-+ let needlemnc = needle.substring(3, needle.length);
-+
-+ let name2, name3;
-+ for (let iter in table) {
-+ let providers = table[value];
-+
-+ /* Search through each country's providers */
-+ for (let i = 0; i < providers.length; i++) {
-+ let provider = providers[i];
-+
-+ /* Search through MCC/MNC list */
-+ let list = provider.get_gsm_mcc_mnc();
-+ for (let j = 0; j < list.length; j++) {
-+ let mccmnc = list[j];
-+
-+ /* Match both 2-digit and 3-digit MNC; prefer a
-+ * 3-digit match if found, otherwise a 2-digit one.
-+ */
-+ if (mccmnc.mcc != needlemcc)
-+ continue; /* MCC was wrong */
-+
-+ if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
-+ name3 = provider.name;
-+
-+ if (!name2 && needlemnc.substring(0, 2) == mcc.mnc.substring(0, 2))
-+ name2 = provider.name;
-+
-+ if (name2 && name3)
-+ break;
-+ }
-+ }
-+ }
-+
-+ return name3 || name2 || null;
-+}
-+
-+function _findProviderForSid(sid) {
-+ if (sid == 0)
-+ return null;
-+
-+ let table = _getProvidersTable();
-+
-+ /* Search through each country */
-+ for (let iter in table) {
-+ let providers = table[iter];
-+
-+ /* Search through each country's providers */
-+ for (let i = 0; i < providers.length; i++) {
-+ let provider = providers[i];
-+ let cdma_sid = provider.get_cdma_sid();
-+
-+ /* Search through CDMA SID list */
-+ for (let j = 0; j < cdma_sid.length; j++) {
-+ if (cmda_sid[j] == sid)
-+ return provider.name;
-+ }
-+ }
-+ }
-+
-+ return null;
-+}
-+
-+function ModemGsm() {
-+ this._init.apply(this, arguments);
-+}
-+
-+ModemGsm.prototype = {
-+ _init: function(path) {
-+ this._proxy = new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop.ModemManager', path);
-+
-+ this.signal_quality = 0;
-+ this.operator_name = null;
-+
-+ // Code is duplicated because the function have different signatures
-+ this._proxy.connect('SignalQuality', Lang.bind(this, function(proxy, quality) {
-+ this.signal_quality = quality;
-+ this.emit('notify::signal-quality');
-+ }));
-+ this._proxy.connect('RegistrationInfo', Lang.bind(this, function(proxy, status, code, name) {
-+ this.operator_name = this._findOperatorName(name, code);
-+ this.emit('notify::operator-name');
-+ }));
-+ this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(result, err) {
-+ if (err) {
-+ log(err);
-+ return;
-+ }
-+
-+ let [status, code, name] = result;
-+ this.operator_name = this._findOperatorName(name, code);
-+ this.emit('notify::operator-name');
-+ }));
-+ this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
-+ if (err) {
-+ // it will return an error if the device is not connected
-+ this.signal_quality = 0;
-+ } else {
-+ let [quality] = result;
-+ this.signal_quality = quality;
-+ }
-+ this.emit('notify::signal-quality');
-+ }));
-+ },
-+
-+ _findOperatorName: function(name, opCode) {
-+ if (name.length != 0 && (name.length > 6 || name.length < 5)) {
-+ // this looks like a valid name, i.e. not an MCCMNC (that some
-+ // devices return when not yet connected
-+ return name;
-+ }
-+ let needle;
-+ if (name.length == 0 && opCode)
-+ needle = opCode;
-+ else if (name.length == 6 || name.length == 5)
-+ needle = name;
-+ else // nothing to search
-+ return null;
-+
-+ return _findProviderForMCCMNC(needle);
-+ }
-+}
-+Signals.addSignalMethods(ModemGsm.prototype);
-+
-+function ModemCdma() {
-+ this._init.apply(this, arguments);
-+}
-+
-+ModemCdma.prototype = {
-+ _init: function(path) {
-+ this._proxy = new ModemCdmaProxy(DBus.system, 'org.freedesktop.ModemManager', path);
-+
-+ this.signal_quality = 0;
-+ this.operator_name = null;
-+ this._proxy.connect('SignalQuality', Lang.bind(this, function(quality) {
-+ this.signal_quality = quality;
-+ this.emit('notify::signal-quality');
-+
-+ // receiving this signal means the device got activated
-+ // and we can finally call GetServingSystem
-+ if (this.operator_name == null)
-+ this._refreshServingSystem();
-+ }));
-+ this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
-+ if (err) {
-+ // it will return an error if the device is not connected
-+ this.signal_quality = 0;
-+ } else {
-+ let [quality] = result;
-+ this.signal_quality = quality;
-+ }
-+ this.emit('notify::signal-quality');
-+ }));
-+ },
-+ _refreshServingSystem: function() {
-+ this._proxy.GetServingSystemRemote(Lang.bind(this, function(result, err) {
-+ if (err) {
-+ // it will return an error if the device is not connected
-+ this.operator_name = null;
-+ } else {
-+ let [bandClass, band, id] = result;
-+ if (name.length > 0)
-+ this.operator_name = _findProviderForSid(id);
-+ else
-+ this.operator_name = null;
-+ }
-+ this.emit('notify::operator-name');
-+ }));
-+ }
-+};
-+Signals.addSignalMethods(ModemCdma.prototype);
-diff --git a/js/misc/util.js b/js/misc/util.js
-index e2ec2c1..ab430c8 100644
---- a/js/misc/util.js
-+++ b/js/misc/util.js
-@@ -178,3 +178,83 @@ function killall(processName) {
- logError(e, 'Failed to kill ' + processName);
- }
- }
-+
-+// This was ported from network-manager-applet
-+// Copyright 2007 - 2011 Red Hat, Inc.
-+// Author: Dan Williams <dcbw@redhat.com>
-+
-+const _IGNORED_WORDS = [
-+ 'Semiconductor',
-+ 'Components',
-+ 'Corporation',
-+ 'Communications',
-+ 'Company',
-+ 'Corp.',
-+ 'Corp',
-+ 'Co.',
-+ 'Inc.',
-+ 'Inc',
-+ 'Incorporated',
-+ 'Ltd.',
-+ 'Limited.',
-+ 'Intel?',
-+ 'chipset',
-+ 'adapter',
-+ '[hex]',
-+ 'NDIS',
-+ 'Module'
-+];
-+
-+const _IGNORED_PHRASES = [
-+ 'Multiprotocol MAC/baseband processor',
-+ 'Wireless LAN Controller',
-+ 'Wireless LAN Adapter',
-+ 'Wireless Adapter',
-+ 'Network Connection',
-+ 'Wireless Cardbus Adapter',
-+ 'Wireless CardBus Adapter',
-+ '54 Mbps Wireless PC Card',
-+ 'Wireless PC Card',
-+ 'Wireless PC',
-+ 'PC Card with XJACK(r) Antenna',
-+ 'Wireless cardbus',
-+ 'Wireless LAN PC Card',
-+ 'Technology Group Ltd.',
-+ 'Communication S.p.A.',
-+ 'Business Mobile Networks BV',
-+ 'Mobile Broadband Minicard Composite Device',
-+ 'Mobile Communications AB',
-+ '(PC-Suite Mode)'
-+];
-+
-+function fixupPCIDescription(desc) {
-+ desc.replace('[_,]', ' ');
-+
-+ /* Attempt to shorten ID by ignoring certain phrases */
-+ for (let i = 0; i < _IGNORED_PHRASES.length; i++) {
-+ let item = _IGNORED_PHRASES[i];
-+ let pos = desc.indexOf(item);
-+ if (pos != -1) {
-+ let before = desc.substring(0, pos);
-+ let after = desc.substring(pos + item.length, desc.length);
-+ desc = before + after;
-+ }
-+ }
-+
-+ /* Attmept to shorten ID by ignoring certain individual words */
-+ let words = desc.split(' ');
-+ let out = '';
-+ for (let i = 0; i < words; i++) {
-+ let item = words[i];
-+
-+ // skip empty items (that come out from consecutive spaces)
-+ if (item.length == 0)
-+ continue;
-+
-+ if (_IGNORED_WORDS.indexOf(item) == -1) {
-+ out += ' ' + item;
-+ }
-+ }
-+
-+ return out;
-+}
-\ No newline at end of file
-diff --git a/js/ui/panel.js b/js/ui/panel.js
-index c08c3e8..adcd148 100644
---- a/js/ui/panel.js
-+++ b/js/ui/panel.js
-@@ -47,6 +47,13 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
- if (Config.HAVE_BLUETOOTH)
- STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
-
-+try {
-+ STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
-+} catch(e) {
-+ STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = undefined;
-+ log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
-+}
-+
- // To make sure the panel corners blend nicely with the panel,
- // we draw background and borders the same way, e.g. drawing
- // them as filled shapes from the outside inwards instead of
-diff --git a/js/ui/status/network.js b/js/ui/status/network.js
-new file mode 100644
-index 0000000..ac8e3d0
---- /dev/null
-+++ b/js/ui/status/network.js
-@@ -0,0 +1,2048 @@
-+// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
-+const ByteArray = imports.byteArray;
-+const DBus = imports.dbus;
-+const GLib = imports.gi.GLib;
-+const GObject = imports.gi.GObject;
-+const Lang = imports.lang;
-+const Mainloop = imports.mainloop;
-+const NetworkManager = imports.gi.NetworkManager;
-+const NMClient = imports.gi.NMClient;
-+const Shell = imports.gi.Shell;
-+const Signals = imports.signals;
-+const St = imports.gi.St;
-+
-+const Main = imports.ui.main;
-+const PanelMenu = imports.ui.panelMenu;
-+const PopupMenu = imports.ui.popupMenu;
-+const MessageTray = imports.ui.messageTray;
-+const ModemManager = imports.misc.modemManager;
-+const Util = imports.misc.util;
-+
-+const Gettext = imports.gettext.domain('gnome-shell');
-+const _ = Gettext.gettext;
-+
-+const NMConnectionCategory = {
-+ WIRED: 'wired',
-+ WIRELESS: 'wireless',
-+ WWAN: 'wwan',
-+ VPN: 'vpn'
-+};
-+
-+// small optimization, to avoid using [] all the time
-+const NM80211Mode = NetworkManager['80211Mode'];
-+const NM80211ApFlags = NetworkManager['80211ApFlags'];
-+
-+function macToArray(string) {
-+ return string.split(':').map(function(el) {
-+ return parseInt(el, 16);
-+ });
-+}
-+
-+function macCompare(one, two) {
-+ for (let i = 0; i < 6; i++) {
-+ if (one[i] != two[i])
-+ return false;
-+ }
-+ return true;
-+}
-+
-+function ssidCompare(one, two) {
-+ if (!one || !two)
-+ return false;
-+ if (one.length != two.length)
-+ return false;
-+ for (let i = 0; i < one.length; i++) {
-+ if (one[i] != two[i])
-+ return false;
-+ }
-+ return true;
-+}
-+
-+// shared between NMNetworkMenuItem and NMDeviceWWAN
-+function signalToIcon(value) {
-+ if (value > 80)
-+ return 'excellent';
-+ if (value > 55)
-+ return 'good';
-+ if (value > 30)
-+ return 'ok';
-+ if (value > 5)
-+ return 'weak';
-+ return 'none';
-+}
-+
-+// shared between NMNetworkMenuItem and NMDeviceWireless
-+function getApSecurityType(accessPoint) {
-+ // XXX: have this checked by someone familiar with IEEE 802.1x
-+
-+ let flags = accessPoint.flags;
-+ let wpa_flags = accessPoint.wpa_flags;
-+ let rsn_flags = accessPoint.rsn_flags;
-+ if ( !(flags & NM80211ApFlags.PRIVACY)
-+ && (wpa_flags == NM80211ApSecurityFlags.NONE)
-+ && (rsn_flags == NM80211ApSecurityFlags.NONE))
-+ return 0;
-+ else if ( (flags & NM80211ApFlags.PRIVACY)
-+ && (wpa_flags == NM80211ApSecurityFlags.NONE)
-+ && (rsn_flags == NM80211ApSecurityFlags.NONE))
-+ return 1;
-+ else if ( !(flags & NM80211ApFlags.PRIVACY)
-+ && (wpa_flags != NM80211ApSecurity.NONE)
-+ && (rsn_flags != NM80211ApSecurity.NONE))
-+ return 2;
-+ else
-+ return 3;
-+}
-+
-+function sortAccessPoints(accessPoints) {
-+ return accessPoints.sort(function (one, two) {
-+ return two.strength - one.strength;
-+ });
-+}
-+
-+function getDeviceDescription(device) {
-+ let dev_product = device.get_product();
-+ let dev_vendor = device.get_vendor();
-+ if (!dev_product || !dev_vendor)
-+ return null;
-+
-+ let product = Util.fixupPCIDescription(dev_product);
-+ let vendor = Util.fixupPCIDescription(dev_vendor);
-+ let out = '';
-+
-+ /* Another quick hack; if all of the fixed up vendor string
-+ * is found in product, ignore the vendor.
-+ */
-+ if (product.indexOf(vendor) == -1)
-+ out += vendor + ' ';
-+ out += product;
-+
-+ return out;
-+}
-+
-+function NMNetworkMenuItem() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMNetworkMenuItem.prototype = {
-+ __proto__: PopupMenu.PopupImageMenuItem.prototype,
-+
-+ _init: function(accessPoints, title, params) {
-+ accessPoints = sortAccessPoints(accessPoints);
-+ this.bestAP = accessPoints[0];
-+
-+ let ssid = this.bestAP.get_ssid();
-+ title = title || NetworkManager.utils_ssid_to_utf8(ssid) || _("<unknown>");
-+
-+ PopupMenu.PopupImageMenuItem.prototype._init.call(this, title, this._getIcon(), params);
-+
-+ this._accessPoints = [ ];
-+ for (let i = 0; i < accessPoints.length; i++) {
-+ let ap = accessPoints[i];
-+ // need a wrapper object here, because the access points can be shared
-+ // between many NMNetworkMenuItems
-+ let apObj = {
-+ ap: ap,
-+ updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
-+ };
-+ this._accessPoints.push(apObj);
-+ }
-+ },
-+
-+ _updated: function(ap, strength) {
-+ if (strength > this.bestAP.strength)
-+ this.bestAP = ap;
-+
-+ this.setIcon(this._getIcon());
-+ },
-+
-+ _getIcon: function() {
-+ return 'network-wireless-signal-' + signalToIcon(this.bestAP.strength);
-+ },
-+
-+ updateAccessPoints: function(accessPoints) {
-+ for (let i = 0; i < this._accessPoints.length; i++) {
-+ let apObj = this._accessPoints[i];
-+ apObj.ap.disconnect(apObj.updateId);
-+ apObj.updateId = 0;
-+ }
-+
-+ accessPoints = sortAccessPoints(accessPoints);
-+ this.bestAP = accessPoints[0];
-+ this._accessPoints = [ ];
-+ for (let i = 0; i < accessPoints; i++) {
-+ let ap = accessPoints[i];
-+ let apObj = {
-+ ap: ap,
-+ updateId: ap.connect('notify::strength', Lang.bind(this, this._updated))
-+ };
-+ this._accessPoints.push(apObj);
-+ }
-+ },
-+
-+ destroy: function() {
-+ for (let i = 0; i < this._accessPoints.length; i++) {
-+ let apObj = this._accessPoints[i];
-+ apObj.ap.disconnect(apObj.updateId);
-+ apObj.updateId = 0;
-+ }
-+
-+ PopupMenu.PopupImageMenuItem.prototype.destroy.call(this);
-+ }
-+};
-+
-+function NMDeviceTitleMenuItem() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMDeviceTitleMenuItem.prototype = {
-+ __proto__: PopupMenu.PopupBaseMenuItem.prototype,
-+
-+ _init: function(description, params) {
-+ PopupMenu.PopupBaseMenuItem.prototype._init.call(this, params);
-+
-+ this._descriptionLabel = new St.Label({ text: description,
-+ style_class: 'popup-subtitle-menu-item'
-+ });
-+ this.addActor(this._descriptionLabel);
-+
-+ this._statusBin = new St.Bin({ x_align: St.Align.END });
-+ this.addActor(this._statusBin, { align: St.Align.END });
-+
-+ this._statusLabel = new St.Label({ text: '',
-+ style_class: 'popup-inactive-menu-item'
-+ });
-+ this._switch = new PopupMenu.Switch(false);
-+ this._statusBin.child = this._switch.actor;
-+ },
-+
-+ setStatus: function(text) {
-+ if (text) {
-+ this._statusLabel.text = text;
-+ this._statusBin.child = this._statusLabel;
-+ this.actor.reactive = false;
-+ this.actor.can_focus = false;
-+ } else {
-+ this._statusBin.child = this._switch.actor;
-+ this.actor.reactive = true;
-+ this.actor.can_focus = true;
-+ }
-+ },
-+
-+ activate: function(event) {
-+ if (this._switch.actor.mapped) {
-+ this._switch.toggle();
-+ this.emit('toggled', this._switch.state);
-+ }
-+
-+ PopupMenu.PopupBaseMenuItem.prototype.activate.call(this, event);
-+ },
-+
-+ get state() {
-+ return this._switch.state;
-+ },
-+
-+ setToggleState: function(newval) {
-+ this._switch.setToggleState(newval);
-+ }
-+};
-+
-+function NMWiredSectionTitleMenuItem() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMWiredSectionTitleMenuItem.prototype = {
-+ __proto__: NMDeviceTitleMenuItem.prototype,
-+
-+ updateForDevice: function(device) {
-+ if (device) {
-+ this._device = device;
-+ this.setStatus(device.getStatusLabel());
-+ this.setToggleState(device.connected);
-+ } else
-+ this.setStatus('');
-+ },
-+
-+ activate: function(event) {
-+ NMDeviceTitleMenuItem.prototype.activate.call(this, event);
-+
-+ if (!this._device) {
-+ log('Section title activated when there is more than one device, should be non reactive');
-+ return;
-+ }
-+
-+ if (this._switch.state)
-+ this._device.activate();
-+ else
-+ this._device.deactivate();
-+ }
-+};
-+
-+function NMWirelessSectionTitleMenuItem() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMWirelessSectionTitleMenuItem.prototype = {
-+ __proto__: NMDeviceTitleMenuItem.prototype,
-+
-+ _init: function(client, property, title, params) {
-+ NMDeviceTitleMenuItem.prototype._init.call(this, title, params);
-+
-+ this._client = client;
-+ this._property = property + '_enabled';
-+ this._propertyHardware = property + '_hardware_enabled';
-+ this._setEnabledFunc = property + '_set_enabled';
-+
-+ this._client.connect('notify::' + property + '-enabled', Lang.bind(this, this._propertyChanged));
-+ this._client.connect('notify::' + property + '-hardware-enabled', Lang.bind(this, this._propertyChanged));
-+
-+ this._propertyChanged();
-+ },
-+
-+ updateForDevice: function(device) {
-+ // we show the switch
-+ // - if there not just one device
-+ // - if the switch is off
-+ // - if the device is activated or disconnected
-+ if (device && this._softwareEnabled && this._hardwareEnabled) {
-+ let text = device.getStatusLabel();
-+ this.setStatus(text);
-+ } else
-+ this.setStatus(null);
-+ },
-+
-+ activate: function(event) {
-+ NMDeviceTitleMenuItem.prototype.activate.call(this, event);
-+
-+ this._client[this._setEnabledFunc](this._switch.state);
-+ },
-+
-+ _propertyChanged: function() {
-+ this._softwareEnabled = this._client[this._property];
-+ this._hardwareEnabled = this._client[this._propertyHardware];
-+
-+ let enabled = this._softwareEnabled && this._hardwareEnabled;
-+ this.setToggleState(enabled);
-+ if (!this._hardwareEnabled)
-+ /* Translators: this indicates that wireless or wwan is disabled by hardware killswitch */
-+ this.setStatus(_("disabled"));
-+
-+ this.emit('enabled-changed', enabled);
-+ }
-+};
-+
-+function NMDevice() {
-+ throw new TypeError('Instantanting abstract class NMDevice');
-+}
-+
-+NMDevice.prototype = {
-+ _init: function(client, device, connections) {
-+ this.device = device;
-+ if (device) {
-+ this.device._delegate = this;
-+ this._stateChangedId = this.device.connect('state-changed', Lang.bind(this, this.deviceStateChanged));
-+ } else
-+ this._stateChangedId = 0;
-+
-+ // protected
-+ this._client = client;
-+ this._connections = [ ];
-+ for (let i = 0; i < connections.length; i++) {
-+ if (!connections[i]._uuid)
-+ continue;
-+ if (!this.connectionValid(connections[i]))
-+ continue;
-+ // record the connection
-+ let obj = {
-+ connection: connections[i],
-+ name: connections[i]._name,
-+ uuid: connections[i]._uuid,
-+ timestamp: connections[i]._timestamp,
-+ };
-+ this._connections.push(obj);
-+ }
-+ this._connections.sort(function(one, two) {
-+ return two.timestamp - one.timestamp;
-+ });
-+ this._activeConnection = null;
-+ this._activeConnectionItem = null;
-+ this._autoConnectionItem = null;
-+ this._onlyOfCategory = false;
-+
-+ if (this.device) {
-+ this.statusItem = new NMDeviceTitleMenuItem(this.device._description);
-+ this._statusChanged = this.statusItem.connect('toggled', Lang.bind(this, function(item, state) {
-+ if (state)
-+ this.activate();
-+ else
-+ this.deactivate();
-+ this.emit('enabled-changed');
-+ }));
-+ }
-+ this.section = new PopupMenu.PopupMenuSection();
-+
-+ this._createSection();
-+ },
-+
-+ destroy: function() {
-+ if (this.device)
-+ this.device._delegate = null;
-+
-+ if (this._stateChangedId) {
-+ // Need to go through GObject.Object.prototype because
-+ // nm_device_disconnect conflicts with g_signal_disconnect
-+ GObject.Object.prototype.disconnect.call(this.device, this._stateChangedId);
-+ this._stateChangedId = 0;
-+ }
-+
-+ this._clearSection();
-+ if (this.titleItem)
-+ this.titleItem.destroy();
-+ this.section.destroy();
-+ },
-+
-+ deactivate: function() {
-+ this.device.disconnect(null);
-+ },
-+
-+ activate: function() {
-+ if (this._activeConnection)
-+ // nothing to do
-+ return;
-+
-+ // pick the most recently used connection and connect to that
-+ // or if no connections ever set, create an automatic one
-+ if (this._connections.length > 0) {
-+ this._client.activate_connection(this._connections[0].connection.path, this.device, null, null);
-+ } else if (this._autoConnectionName) {
-+ let connection = this._createAutomaticConnection();
-+ this._client.add_and_activate_connection(connection, this.device, null, null);
-+ }
-+ },
-+
-+ get connected() {
-+ return this.device.state == NetworkManager.DeviceState.ACTIVATED;
-+ },
-+
-+ setActiveConnection: function(activeConnection) {
-+ if (activeConnection == this._activeConnection)
-+ // nothing to do
-+ return;
-+
-+ // remove any UI
-+ if (this._activeConnectionItem) {
-+ this._activeConnectionItem.destroy();
-+ this._activeConnectionItem = null;
-+ }
-+
-+ this._activeConnection = activeConnection;
-+
-+ this._clearSection();
-+ this._createSection();
-+ },
-+
-+ checkConnection: function(connection) {
-+ let exists = this._findConnection(connection) != -1;
-+ let valid = this.connectionValid(connection);
-+ if (exists && !valid)
-+ this.removeConnection(connection);
-+ else if (!exists && valid)
-+ this.addConnection(connection);
-+ },
-+
-+ addConnection: function(connection) {
-+ // record the connection
-+ let obj = {
-+ connection: connection,
-+ name: connection._name,
-+ uuid: connection._uuid,
-+ timestamp: connection._timestamp,
-+ };
-+ this._connections.push(obj);
-+ this._connections.sort(function(one, two) {
-+ return two.timestamp - one.timestamp;
-+ });
-+
-+ this._clearSection();
-+ this._createSection();
-+ },
-+
-+ removeConnection: function(connection) {
-+ if (!connection._uuid) {
-+ log('Cannot remove a connection without an UUID');
-+ return;
-+ }
-+ let pos = this._findConnection(connection._uuid);
-+ if (pos == -1) {
-+ // this connection was never added, nothing to do here
-+ return;
-+ }
-+
-+ let obj = this._connections[pos];
-+ if (obj.item)
-+ obj.item.destroy();
-+ this._connections.splice(pos, 1);
-+
-+ if (this._connections.length == 0) {
-+ // We need to show the automatic connection again
-+ this._clearSection();
-+ this._createSection();
-+ }
-+ },
-+
-+ connectionValid: function(connection) {
-+ throw new TypeError('Invoking pure virtual function NMDevice.connectionValid');
-+ },
-+
-+ setEnabled: function(enabled) {
-+ // do nothing by default, we want to keep the conneciton list visible
-+ // in the majority of cases (wired, wwan, vpn)
-+ },
-+
-+ getStatusLabel: function() {
-+ switch(this.device.state) {
-+ case NetworkManager.DeviceState.DISCONNECTED:
-+ case NetworkManager.DeviceState.ACTIVATED:
-+ return null;
-+ case NetworkManager.DeviceState.PREPARE:
-+ case NetworkManager.DeviceState.CONFIG:
-+ case NetworkManager.DeviceState.IP_CONFIG:
-+ return _("connecting...");
-+ case NetworkManager.DeviceState.NEED_AUTH:
-+ /* Translators: this is for network connections that require some kind of key or password */
-+ return _("authentication required");
-+ case NetworkManager.DeviceState.UNAVAILABLE:
-+ // we don't check if the carrier property is actually false, as that causes race
-+ // conditions if state is changed before the new carrier value is picked by libnm-glib
-+ if (this.device.capabilities & NetworkManager.DeviceCapabilities.CARRIER_DETECT)
-+ /* Translators: this is for wired network devices that are physically disconnected */
-+ return _("cable unplugged");
-+ else
-+ /* Translators: this is for a network device that cannot be activated (for example it
-+ is disabled by rfkill, or it has no coverage */
-+ return _("unavailable");
-+ case NetworkManager.DeviceState.FAILED:
-+ return _("connection failed");
-+ default:
-+ log('Device state invalid, is %d'.format(this.device.state));
-+ return 'invalid';
-+ }
-+ },
-+
-+ // protected
-+ _createAutomaticConnection: function() {
-+ throw new TypeError('Invoking pure virtual function NMDevice.createAutomaticConnection');
-+ },
-+
-+ _findConnection: function(uuid) {
-+ for (let i = 0; i < this._connections.length; i++) {
-+ let obj = this._connections[i];
-+ if (obj.uuid == uuid)
-+ return i;
-+ }
-+ return -1;
-+ },
-+
-+ _clearSection: function() {
-+ // Clear everything
-+ this.section.removeAll();
-+ this._autoConnectionItem = null;
-+ this._activeConnectionItem = null;
-+ for (let i = 0; i < this._connections.length; i++) {
-+ this._connections[i].item = null;
-+ }
-+ },
-+
-+ _shouldShowConnectionList: function() {
-+ return (this.device.state == NetworkManager.DeviceState.DISCONNECTED ||
-+ this.device.state == NetworkManager.DeviceState.ACTIVATED);
-+ },
-+
-+ _createSection: function() {
-+ if (!this._shouldShowConnectionList())
-+ return;
-+
-+ if (this._activeConnection) {
-+ this._createActiveConnectionItem();
-+ this.section.addMenuItem(this._activeConnectionItem);
-+ }
-+ if (this._connections.length > 0) {
-+ for(let j = 0; j < this._connections.length; ++j) {
-+ let obj = this._connections[j];
-+ if (this._activeConnection &&
-+ obj.connection == this._activeConnection._connection)
-+ continue;
-+ obj.item = this._createConnectionItem(obj);
-+ this.section.addMenuItem(obj.item);
-+ }
-+ } else if (this._autoConnectionName) {
-+ this._autoConnectionItem = new PopupMenu.PopupMenuItem(this._autoConnectionName);
-+ this._autoConnectionItem.connect('activate', Lang.bind(this, function() {
-+ let connection = this._createAutomaticConnection();
-+ this._client.add_and_activate_connection(connection, this.device, null, null);
-+ }));
-+ this.section.addMenuItem(this._autoConnectionItem);
-+ }
-+ },
-+
-+ _createConnectionItem: function(obj) {
-+ let path = obj.connection.path;
-+ let item = new PopupMenu.PopupMenuItem(obj.name);
-+ item.connect('activate', Lang.bind(this, function() {
-+ this._client.activate_connection(path, this.device, null, null);
-+ }));
-+ return item;
-+ },
-+
-+ _createActiveConnectionItem: function() {
-+ let title;
-+ let active = this._activeConnection._connection;
-+ if (active) {
-+ title = active._name;
-+ } else {
-+ /* TRANSLATORS: this is the indication that a connection for another logged in user is active,
-+ and we cannot access its settings (including the name) */
-+ title = _("Connected (private)");
-+ }
-+ this._activeConnectionItem = new PopupMenu.PopupMenuItem(title, { reactive: false });
-+ this._activeConnectionItem.setShowDot(true);
-+ },
-+
-+ deviceStateChanged: function(device, newstate, oldstate, reason) {
-+ if (newstate == oldstate) {
-+ log('device emitted state-changed without actually changing state');
-+ return;
-+ }
-+
-+ if (oldstate == NetworkManager.DeviceState.ACTIVATED) {
-+ this.emit('network-lost');
-+ }
-+
-+ switch(newstate) {
-+ case NetworkManager.DeviceState.NEED_AUTH:
-+ // FIXME: make this have a real effect
-+ // (currently we rely on a running nm-applet)
-+ this.emit('need-auth');
-+ break;
-+ case NetworkManager.DeviceState.FAILED:
-+ this.emit('activation-failed', reason);
-+ break;
-+ }
-+
-+ this.statusItem.setStatus(this.getStatusLabel());
-+ this.statusItem.setToggleState(this.connected);
-+
-+ this._clearSection();
-+ this._createSection();
-+ this.emit('state-changed');
-+ }
-+};
-+Signals.addSignalMethods(NMDevice.prototype);
-+
-+
-+function NMDeviceWired() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMDeviceWired.prototype = {
-+ __proto__: NMDevice.prototype,
-+
-+ _init: function(client, device, connections) {
-+ this._autoConnectionName = _("Auto Ethernet");
-+ this.category = NMConnectionCategory.WIRED;
-+
-+ NMDevice.prototype._init.call(this, client, device, connections);
-+ },
-+
-+ connectionValid: function(connection) {
-+ if (connection._type != NetworkManager.SETTING_WIRED_SETTING_NAME)
-+ return false;
-+
-+ let ethernetSettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRED_SETTING_NAME);
-+ let fixedMac = ethernetSettings.get_mac_address();
-+ if (fixedMac)
-+ return macCompare(fixedMac, macToArray(this.device.perm_hw_address));
-+ return true;
-+ },
-+
-+ _createAutomaticConnection: function() {
-+ let connection = new NetworkManager.Connection();
-+ connection._uuid = NetworkManager.utils_uuid_generate();
-+ connection.add_setting(new NetworkManager.SettingWired());
-+ connection.add_setting(new NetworkManager.SettingConnection({
-+ uuid: connection._uuid,
-+ id: this._autoConnectionName,
-+ type: NetworkManager.SETTING_WIRED_SETTING_NAME,
-+ autoconnect: true
-+ }));
-+ return connection;
-+ }
-+};
-+
-+function NMDeviceModem() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMDeviceModem.prototype = {
-+ __proto__: NMDevice.prototype,
-+
-+ _init: function(client, device, connections) {
-+ let is_wwan = false;
-+
-+ this._enabled = true;
-+ this.mobileDevice = null;
-+ this._connectionType = 'ppp';
-+
-+ this._capabilities = device.current_capabilities;
-+ if (this._capabilities & NetworkManager.DeviceModemCapabilities.GSM_UMTS) {
-+ is_wwan = true;
-+ this.mobileDevice = new ModemManager.ModemGsm(device.udi);
-+ this._connectionType = NetworkManager.SETTING_GSM_SETTING_NAME;
-+ } else if (this._capabilities & NetworkManager.DeviceModemCapabilities.CDMA_EVDO) {
-+ is_wwan = true;
-+ this.mobileDevice = new ModemManager.ModemCdma(device.udi);
-+ this._connectionType = NetworkManager.SETTING_CDMA_SETTING_NAME;
-+ } else if (this._capabilities & NetworkManager.DeviceModemCapabilities.LTE) {
-+ is_wwan = true;
-+ // FIXME: support signal quality
-+ }
-+
-+ if (is_wwan) {
-+ this.category = NMConnectionCategory.WWAN;
-+ this._autoConnectionName = _("Auto broadband");
-+ } else {
-+ this.category = NMConnectionCategory.WIRED;
-+ this._autoConnectionName = _("Auto dial-up");
-+ }
-+
-+ if (this.mobileDevice) {
-+ this._operatorNameId = this.mobileDevice.connect('notify::operator-name', Lang.bind(this, function() {
-+ if (this._operatorItem) {
-+ let name = this.mobileDevice.operator_name;
-+ if (name) {
-+ this._operatorItem.label.text = name;
-+ this._operatorItem.actor.show();
-+ } else
-+ this._operatorItem.actor.hide();
-+ }
-+ }));
-+ this._signalQualityId = this.mobileDevice.connect('notify::signal-quality', Lang.bind(this, function() {
-+ if (this._operatorItem) {
-+ this._operatorItem.setIcon(this._getSignalIcon());
-+ }
-+ }));
-+ }
-+
-+ NMDevice.prototype._init.call(this, client, device, connections, 1);
-+ },
-+
-+ setEnabled: function(enabled) {
-+ this._enabled = enabled;
-+ if (this.category == NMConnectionCategory.WWAN) {
-+ if (enabled) {
-+ // prevent "network unavailable" statuses
-+ this.statusItem.setStatus(null);
-+ } else
-+ this.statusItem.setStatus(this.getStatusLabel());
-+ }
-+
-+ NMDevice.prototype.setEnabled.call(this, enabled);
-+ },
-+
-+ get connected() {
-+ return this._enabled && this.device.state == NetworkManager.DeviceState.CONNECTED;
-+ },
-+
-+ destroy: function() {
-+ if (this._operatorNameId) {
-+ this.mobileDevice.disconnect(this._operatorNameId);
-+ this._operatorNameId = 0;
-+ }
-+ if (this._signalQualityId) {
-+ this.mobileDevice.disconnect(this._signalQualityId);
-+ this._signalQualityId = 0;
-+ }
-+
-+ NMDevice.prototype.destroy.call(this);
-+ },
-+
-+ _getSignalIcon: function() {
-+ return 'network-cellular-signal-' + signalToIcon(this.mobileDevice.signal_quality);
-+ },
-+
-+ _createSection: function() {
-+ if (this.mobileDevice) {
-+ // If operator_name is null, just pass the empty string, as the item is hidden anyway
-+ this._operatorItem = new PopupMenu.PopupImageMenuItem(this.mobileDevice.operator_name || '',
-+ this._getSignalIcon(),
-+ { reactive: false });
-+ if (this.mobileDevice.operator_name)
-+ this._operatorItem.actor.hide();
-+ this.section.addMenuItem(this._operatorItem);
-+ }
-+
-+ NMDevice.prototype._createSection.call(this);
-+ },
-+
-+ clearSection: function() {
-+ this._operatorItem = null;
-+
-+ NMDevice.prototype._clearSection.call(this);
-+ },
-+
-+ connectionValid: function(connection) {
-+ return connection._type == this._connectionType;
-+ },
-+
-+ _createAutomaticConnection: function() {
-+ // FIXME: we need to summon the mobile wizard here
-+ // or NM will not have the necessary parameters to complete the connection
-+ // pending a DBus method on nm-applet
-+
-+ let connection = new NetworkManager.Connection;
-+ connection._uuid = NetworkManager.utils_uuid_generate();
-+ connection.add_setting(new NetworkManager.SettingConnection({
-+ uuid: connection._uuid,
-+ id: this._autoConnectionName,
-+ type: this._connectionType,
-+ autoconnect: false
-+ }));
-+ return connection;
-+ }
-+};
-+
-+function NMDeviceBluetooth() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMDeviceBluetooth.prototype = {
-+ __proto__: NMDevice.prototype,
-+
-+ _init: function(client, device, connections) {
-+ this._autoConnectionName = this._makeConnectionName(device);
-+ device.connect('notify::name', Lang.bind(this, this._updateAutoConnectionName));
-+
-+ this.category = NMConnectionCategory.WWAN;
-+
-+ NMDevice.prototype._init.call(this, client, device, connections);
-+ },
-+
-+ connectionValid: function(connection) {
-+ if (connection._type != NetworkManager.SETTING_BLUETOOTH_SETTING_NAME)
-+ return false;
-+
-+ let bluetoothSettings = connection.get_setting_by_name(NetworkManager.SETTING_BLUETOOTH_SETTING_NAME);
-+ let fixedBdaddr = bluetoothSettings.get_bdaddr();
-+ if (fixedBdaddr)
-+ return macCompare(fixedBdaddr, macToArray(this.device.hw_address));
-+
-+ return true;
-+ },
-+
-+ _createAutomaticConnection: function() {
-+ let connection = new NetworkManager.Connection;
-+ connection._uuid = NetworkManager.utils_uuid_generate();
-+ connection.add_setting(new NetworkManager.SettingBluetooth);
-+ connection.add_setting(new NetworkManager.SettingConnection({
-+ uuid: connection._uuid,
-+ id: this._autoConnectionName,
-+ type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME,
-+ autoconnect: false
-+ }));
-+ return connection;
-+ },
-+
-+ _makeConnectionName: function(device) {
-+ let name = device.name;
-+ if (name)
-+ return _("Auto %s").format(name);
-+ else
-+ return _("Auto bluetooth");
-+ },
-+
-+ _updateAutoConnectionName: function() {
-+ this._autoConnectionName = this._makeConnectioName(this.device);
-+
-+ this._clearSection();
-+ this._createSection();
-+ }
-+};
-+
-+
-+// Not a real device, but I save a lot code this way
-+function NMDeviceVPN() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMDeviceVPN.prototype = {
-+ __proto__: NMDevice.prototype,
-+
-+ _init: function(client) {
-+ // Disable autoconnections
-+ this._autoConnectionName = null;
-+ this.category = NMConnectionCategory.VPN;
-+
-+ NMDevice.prototype._init.call(this, client, null, [ ]);
-+ },
-+
-+ connectionValid: function(connection) {
-+ return connection._type == NetworkManager.SETTING_VPN_SETTING_NAME;
-+ },
-+
-+ get empty() {
-+ return this._connections.length == 0;
-+ },
-+
-+ get connected() {
-+ return true;
-+ },
-+
-+ _shouldShowConnectionList: function() {
-+ return true;
-+ },
-+
-+ deactivate: function() {
-+ if (this._activeConnection)
-+ this._client.deactivate_connection(this._activeConnection);
-+ },
-+
-+ getStatusLabel: function() {
-+ return null;
-+ }
-+};
-+
-+function NMDeviceWireless() {
-+ this._init.apply(this, arguments);
-+}
-+
-+NMDeviceWireless.prototype = {
-+ __proto__: NMDevice.prototype,
-+
-+ _init: function(client, device, connections) {
-+ this.category = NMConnectionCategory.WIRELESS;
-+
-+ this._overflowItem = null;
-+ this._networks = [ ];
-+
-+ // XXX: breaking the layers with this, but cannot call
-+ // this.connectionValid until I have a device
-+ this.device = device;
-+
-+ let validConnections = connections.filter(Lang.bind(this, function(connection) {
-+ return this.connectionValid(connection);
-+ }));
-+ let accessPoints = device.get_access_points() || [ ];
-+ for (let i = 0; i < accessPoints.length; i++) {
-+ // Access points are grouped by network
-+ let ap = accessPoints[i];
-+ let pos = this._findNetwork(ap);
-+ let obj;
-+ if (pos != -1) {
-+ obj = this._networks[pos];
-+ obj.accessPoints.push(ap);
-+ } else {
-+ obj = { ssid: ssid,
-+ mode: ap.mode,
-+ security: getApSecurityType(ap),
-+ connections: [ ],
-+ item: null,
-+ accessPoints: [ ap ]
-+ };
-+ this._networks.push(obj);
-+ }
-+
-+ // Check if some connection is valid for this AP
-+ for (let j = 0; j < validConnections.length; j++) {
-+ let connection = validConnections[j];
-+ if (this._connectionValidForAP(connection, ap) &&
-+ obj.connections.indexOf(connection) == -1) {
-+ obj.connections.push(connection);
-+ }
-+ }
-+ }
-+ this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded));
-+ this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved));
-+
-+ NMDevice.prototype._init.call(this, client, device, validConnections);
-+ },
-+
-+ destroy: function() {
-+ if (this._apAddedId) {
-+ // see above for this HACK
-+ GObject.Object.prototype.disconnect.call(this.device, this._apAddedId);
-+ this._apAddedId = 0;
-+ }
-+
-+ if (this._apRemovedId) {
-+ GObject.Object.prototype.disconnect.call(this.device, this._apRemovedId);
-+ this._apRemovedId = 0;
-+ }
-+
-+ NMDevice.prototype.destroy.call(this);
-+ },
-+
-+ setEnabled: function(enabled) {
-+ if (enabled) {
-+ this.statusItem.actor.show();
-+ this.section.actor.show();
-+ } else {
-+ this.statusItem.actor.hide();
-+ this.section.actor.hide();
-+ }
-+ },
-+
-+ activate: function() {
-+ if (this._activeConnection)
-+ // nothing to do
-+ return;
-+
-+ // among all visible networks, pick the last recently used connection
-+ let best = null;
-+ let bestApObj = null;
-+ let bestTime = 0;
-+ for (let i = 0; i < this._networks.length; i++) {
-+ let apObj = this._networks[i];
-+ for (let j = 0; j < apObj.connections.length; j++) {
-+ let connection = apObj.connections[j];
-+ if (connection._timestamp > bestTime) {
-+ best = connection;
-+ bestTime = connection._timestamp;
-+ bestApObj = apObj;
-+ }
-+ }
-+ }
-+
-+ if (best) {
-+ for (let i = 0; i < bestApObj.accessPoints.length; i++) {
-+ let ap = bestApObj.accessPoints[i];
-+ if (this._connectionValidForAP(best, ap)) {
-+ this._client.activate_connection(best.path, this.device, ap.dbus_path, null);
-+ break;
-+ }
-+ }
-+ return;
-+ }
-+
-+ // XXX: what else to do?
-+ // for now, just pick a random network
-+ // (this function is called in a corner case anyway, that is, only when
-+ // the user toggles the switch and has more than one wireless device)
-+ if (this._networks.length > 0) {
-+ let connection = this._createAutomaticConnection(this._networks[0]);
-+ let accessPoints = sortAccessPoints(this._networks[0].accessPoints);
-+ this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null);
-+ }
-+ },
-+
-+ _networkCompare: function(network, accessPoint) {
-+ if (!ssidCompare(network.ssid, accessPoint.get_ssid()))
-+ return false;
-+ if (network.mode != accessPoint.mode)
-+ return false;
-+ if (network.security != getApSecurityType(accessPoint))
-+ return false;
-+
-+ return true;
-+ },
-+
-+ _findNetwork: function(accessPoint) {
-+ for (let i = 0; i < this._networks.length; i++) {
-+ if (this._networkCompare(this._networks[i], accessPoint))
-+ return i;
-+ }
-+ return -1;
-+ },
-+
-+ _accessPointAdded: function(device, accessPoint) {
-+ let pos = this._findNetwork(accessPoint);
-+ let apObj;
-+ if (pos != -1) {
-+ apObj = this._networks[pos];
-+ if (apObj.accessPoints.indexOf(accessPoint) != -1) {
-+ log('Access point was already seen, not adding again');
-+ return;
-+ }
-+
-+ apObj.accessPoints.push(accessPoint);
-+ } else {
-+ apObj = { ssid: ssid,
-+ mode: accessPoint.mode,
-+ security: getApSecurityType(accessPoint),
-+ connections: [ ],
-+ item: null,
-+ accessPoints: [ accessPoint ]
-+ };
-+ this._networks.push(apObj);
-+ }
-+
-+ // check if this enables new connections for this group
-+ for (let i = 0; i < this._connections.length; i++) {
-+ let connection = this._connections[i].connection;
-+ if (this._connectionValidForAP(connection, accessPoint) &&
-+ apObj.connections.indexOf(connection) == -1) {
-+ apObj.connections.push(connection);
-+ }
-+ }
-+
-+ // update everything
-+ this._clearSection();
-+ this._createSection();
-+ },
-+
-+ _accessPointRemoved: function(device, accessPoint) {
-+ let pos = this._findNetwork(accessPoint);
-+
-+ if (pos == -1) {
-+ log('Removing an access point that was never added');
-+ return;
-+ }
-+
-+ let apObj = this._networks[pos];
-+ let i = apObj.accessPoints.indexOf(accessPoint);
-+
-+ if (i == -1) {
-+ log('Removing an access point that was never added');
-+ return;
-+ }
-+
-+ apObj.accessPoints.splice(i, 1);
-+
-+ if (apObj.accessPoints.length == 0) {
-+ if (apObj.item)
-+ apObj.item.destroy();
-+ this._networks.splice(pos, 1);
-+ } else if (apObj.item)
-+ apObj.item.updateAccessPoints(apObj.accessPoints);
-+ },
-+
-+ _createAPItem: function(connection, accessPointObj, useConnectionName) {
-+ let item = new NMNetworkMenuItem(accessPointObj.accessPoints, useConnectionName ? connection._name : undefined);
-+ item._connection = connection;
-+ item.connect('activate', Lang.bind(this, function() {
-+ let accessPoints = sortAccessPoints(accessPointObj.accessPoints);
-+ for (let i = 0; i < accessPoints.length; i++) {
-+ if (this._connectionValidForAP(connection, accessPoints[i])) {
-+ this._client.activate_connection(connection.path, this.device, accessPoints[i].dbus_path, null);
-+ break;
-+ }
-+ }
-+ }));
-+ return item;
-+ },
-+
-+ connectionValid: function(connection) {
-+ if (connection._type != NetworkManager.SETTING_WIRELESS_SETTING_NAME)
-+ return false;
-+
-+ let wirelessSettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SETTING_NAME);
-+ let wirelessSecuritySettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SECURITY_SETTING_NAME);
-+
-+ let fixedMac = wirelessSettings.get_mac_address();
-+ if (fixedMac && !macCompare(fixedMac, macToArray(this.device.perm_hw_address)))
-+ return false;
-+
-+ if (wirelessSecuritySettings &&
-+ wirelessSecuritySettings.key_mgmt != 'none' &&
-+ wirelessSecuritySettings.key_mgmt != 'ieee8021x') {
-+ let capabilities = this.device.wireless_capabilities;
-+ if (!(capabilities & NetworkManager.DeviceWifiCapabilities.WPA) ||
-+ !(capabilities & NetworkManager.DeviceWifiCapabilities.CIPHER_TKIP))
-+ return false;
-+ if (wirelessSecuritySettings.get_num_protos() == 1 &&
-+ wirelessSecuritySettings.get_proto(0) == 'rsn' &&
-+ !(capabilities & NetworkManager.DeviceWifiCapabilities.RSN))
-+ return false;
-+ if (wirelessSecuritySettings.get_num_pairwise() == 1 &&
-+ wirelessSecuritySettings.get_pairwise(0) == 'ccmp' &&
-+ !(capabilities & NetworkManager.DeviceWifiCapabilities.CIPHER_CCMP))
-+ return false;
-+ if (wirelessSecuritySettings.get_num_groups() == 1 &&
-+ wirelessSecuritySettings.get_group(0) == 'ccmp' &&
-+ !(capabilities & NetworkManager.DeviceWifiCapabilities.CIPHER_CCMP))
-+ return false;
-+ }
-+ return true;
-+ },
-+
-+ _clearSection: function() {
-+ NMDevice.prototype._clearSection.call(this);
-+
-+ for (let i = 0; i < this._networks.length; i++)
-+ this._networks[i].item = null;
-+ this._overflowItem = null;
-+ },
-+
-+ removeConnection: function(connection) {
-+ if (!connection._uuid)
-+ return;
-+ let pos = this._findConnection(connection._uuid);
-+ if (pos == -1) {
-+ // removing connection that was never added
-+ return;
-+ }
-+
-+ let obj = this._connections[pos];
-+ this._connections.splice(pos, 1);
-+
-+ let anyauto = false, forceupdate = false;
-+ for (let i = 0; i < this._networks.length; i++) {
-+ let apObj = this._networks[i];
-+ let connections = apObj.connections;
-+ for (let k = 0; k < connections.length; k++) {
-+ if (connections[k]._uuid == connection._uuid) {
-+ // remove the connection from the access point group
-+ connections.splice(k);
-+ anyauto = connections.length == 0;
-+ if (apObj.item) {
-+ if (apObj.item instanceof PopupMenu.PopupSubMenuMenuItem) {
-+ let items = apObj.item.menu.getMenuItems();
-+ if (items.length == 2) {
-+ // we need to update the connection list to convert this to a normal item
-+ forceupdate = true;
-+ } else {
-+ for (let j = 0; j < items.length; j++) {
-+ if (items[j]._connection._uuid == connection._uuid) {
-+ items[j].destroy();
-+ break;
-+ }
-+ }
-+ }
-+ } else {
-+ apObj.item.destroy();
-+ apObj.item = null;
-+ }
-+ }
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (forceupdate || anyauto) {
-+ this._clearSection();
-+ this._createSection();
-+ }
-+ },
-+
-+ addConnection: function(connection) {
-+ // record the connection
-+ let obj = {
-+ connection: connection,
-+ name: connection._name,
-+ uuid: connection._uuid,
-+ };
-+ this._connections.push(obj);
-+
-+ // find an appropriate access point
-+ let any = false, forceupdate = false;
-+ for (let i = 0; i < this._networks.length; i++) {
-+ let apObj = this._networks[i];
-+
-+ // Check if connection is valid for any of these access points
-+ let any = false;
-+ for (let k = 0; k < apObj.accessPoints.length; k++) {
-+ let ap = apObj.accessPoints[k];
-+ if (this._connectionValidForAP(connection, ap)) {
-+ apObj.connections.push(connection);
-+ any = true;
-+ break;
-+ }
-+ }
-+
-+ if (any && this._shouldShowConnectionList() && !skipCreateMenu) {
-+ // we need to show this connection
-+ if (apObj.item && apObj.item.menu) {
-+ // We're already showing the submenu for this access point
-+ apObj.item.menu.addMenuItem(this._createAPItem(connection, apObj, true));
-+ } else {
-+ if (apObj.item)
-+ apObj.item.destroy();
-+ if (apObj.connections.length == 1) {
-+ apObj.item = this._createAPItem(connection, apObj, false);
-+ this.section.addMenuItem(apObj.item);
-+ } else {
-+ apObj.item = null;
-+ // we need to force an update to create the submenu
-+ forceupdate = true;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (forceupdate) {
-+ this._clearSection();
-+ this._createSection();
-+ }
-+ },
-+
-+ _connectionValidForAP: function(connection, ap) {
-+ // copied and adapted from nm-applet
-+ let wirelessSettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SETTING_NAME);
-+ if (!ssidCompare(wirelessSettings.get_ssid(), ap.get_ssid()))
-+ return false;
-+
-+ let wirelessSecuritySettings = connection.get_setting_by_name(NetworkManager.SETTING_WIRELESS_SECURITY_SETTING_NAME);
-+
-+ let fixedBssid = wirelessSettings.get_bssid();
-+ if (fixedBssid && !macCompare(fixedBssid, macToArray(ap.hw_address)))
-+ return false;
-+
-+ let fixedBand = wirelessSettings.band;
-+ if (fixedBand) {
-+ let freq = ap.frequency;
-+ if (fixedBand == 'a' && (freq < 4915 || freq > 5825))
-+ return false;
-+ if (fixedBand == 'bg' && (freq < 2412 || freq > 2484))
-+ return false;
-+ }
-+
-+ let fixedChannel = wirelessSettings.channel;
-+ if (fixedChannel && fixedChannel != NetworkManager.utils_wifi_freq_to_channel(ap.frequency))
-+ return false;
-+
-+ if (!wirelessSecuritySettings)
-+ return true;
-+
-+ return wirelessSettings.ap_security_compatible(wirelessSecuritySettings, ap.flags, ap.wpa_flags, ap.rsn_flags, ap.mode);
-+ },
-+
-+ _createActiveConnectionItem: function() {
-+ let activeAp = this.device.active_access_point;
-+ let icon, title;
-+ if (this._activeConnection._connection) {
-+ let connection = this._activeConnection._connection;
-+ if (activeAp)
-+ this._activeConnectionItem = new NMNetworkMenuItem([ activeAp ], undefined,
-+ { reactive: false });
-+ else
-+ this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(connection._name,
-+ 'network-wireless-connected',
-+ { reactive: false });
-+ } else {
-+ // We cannot read the connection (due to ACL, or API incompatibility), but we still show signal if we have it
-+ let menuItem;
-+ if (activeAp)
-+ this._activeConnectionItem = new NMNetworkMenuItem([ activeAp ], undefined,
-+ { reactive: false });
-+ else
-+ this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(_("Connected (private)"),
-+ 'network-wireless-connected',
-+ { reactive: false });
-+ }
-+ this._activeConnectionItem.setShowDot(true);
-+ },
-+
-+ _createAutomaticConnection: function(apObj) {
-+ let name;
-+ let ssid = NetworkManager.utils_ssid_to_utf8(apObj.ssid);
-+ if (ssid) {
-+ /* TRANSLATORS: this the automatic wireless connection name (including the network name) */
-+ name = _("Auto %s").format(ssid);
-+ } else
-+ name = _("Auto wireless");
-+
-+ let connection = new NetworkManager.Connection();
-+ connection.add_setting(new NetworkManager.SettingWireless());
-+ connection.add_setting(new NetworkManager.SettingConnection({
-+ id: name,
-+ autoconnect: true, // NetworkManager will know to ignore this if appropriate
-+ uuid: NetworkManager.utils_uuid_generate(),
-+ type: NetworkManager.SETTING_WIRELESS_SETTING_NAME
-+ }));
-+ return connection;
-+ },
-+
-+ _createSection: function() {
-+ if (!this._shouldShowConnectionList())
-+ return;
-+
-+ if(this._activeConnection) {
-+ this._createActiveConnectionItem();
-+ this.section.addMenuItem(this._activeConnectionItem);
-+ }
-+
-+ let activeAp = this.device.active_access_point;
-+ let activeApSsid = activeAp ? activeAp.get_ssid() : null;
-+
-+ // we want five access points in the menu, including the active one
-+ let numItems = this._activeConnection ? 4 : 5;
-+
-+ for(let j = 0; j < this._networks.length; j++) {
-+ let apObj = this._networks[j];
-+ if(activeAp && ssidCompare(apObj.ssid, activeApSsid))
-+ continue;
-+
-+ let menuItem;
-+ if(apObj.connections.length > 0) {
-+ if (apObj.connections.length == 1)
-+ apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
-+ else {
-+ let title = NetworkManager.utils_ssid_to_utf8(apObj.ssid) || _("<unknown>");
-+ apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
-+ apObj.item._apObj = apObj;
-+ for (let i = 0; i < apObj.connections.length; i++)
-+ apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
-+ }
-+ } else {
-+ apObj.item = new NMNetworkMenuItem(apObj.accessPoints);
-+ apObj.item._apObj = apObj;
-+ apObj.item.connect('activate', Lang.bind(this, function() {
-+ let connection = this._createAutomaticConnection(apObj);
-+ let accessPoints = sortAccessPoints(apObj.accessPoints);
-+ this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null)
-+ }));
-+ }
-+
-+ if (j < numItems)
-+ this.section.addMenuItem(apObj.item);
-+ else {
-+ if (!this._overflowItem) {
-+ this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More..."));
-+ this.section.addMenuItem(this._overflowItem);
-+ }
-+ this._overflowItem.menu.addMenuItem(apObj.item);
-+ }
-+ }
-+ },
-+};
-+
-+function NMApplet() {
-+ this._init.apply(this, arguments);
-+}
-+NMApplet.prototype = {
-+ __proto__: PanelMenu.SystemStatusButton.prototype,
-+
-+ _init: function() {
-+ PanelMenu.SystemStatusButton.prototype._init.call(this, 'network-error');
-+
-+ this._client = NMClient.Client.new();
-+
-+ this._statusSection = new PopupMenu.PopupMenuSection();
-+ this._statusItem = new PopupMenu.PopupMenuItem('', { style_class: 'popup-inactive-menu-item', reactive: false });
-+ this._statusSection.addMenuItem(this._statusItem);
-+ this._statusSection.addAction(_("Enable networking"), Lang.bind(this, function() {
-+ this._client.networking_enabled = true;
-+ }));
-+ this._statusSection.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
-+ this._statusSection.actor.hide();
-+ this.menu.addMenuItem(this._statusSection);
-+
-+ this._devices = { };
-+
-+ this._devices.wired = {
-+ section: new PopupMenu.PopupMenuSection(),
-+ devices: [ ],
-+ item: new NMWiredSectionTitleMenuItem(_("Wired"))
-+ };
-+
-+ this._devices.wired.section.addMenuItem(this._devices.wired.item);
-+ this._devices.wired.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
-+ this._devices.wired.section.actor.hide();
-+ this.menu.addMenuItem(this._devices.wired.section);
-+
-+ this._devices.wireless = {
-+ section: new PopupMenu.PopupMenuSection(),
-+ devices: [ ],
-+ item: this._makeToggleItem('wireless', _("Wireless"))
-+ };
-+ this._devices.wireless.section.addMenuItem(this._devices.wireless.item);
-+ this._devices.wireless.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
-+ this._devices.wireless.section.actor.hide();
-+ this.menu.addMenuItem(this._devices.wireless.section);
-+
-+ this._devices.wwan = {
-+ section: new PopupMenu.PopupMenuSection(),
-+ devices: [ ],
-+ item: this._makeToggleItem('wwan', _("Mobile broadband"))
-+ };
-+ this._devices.wwan.section.addMenuItem(this._devices.wwan.item);
-+ this._devices.wwan.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
-+ this._devices.wwan.section.actor.hide();
-+ this.menu.addMenuItem(this._devices.wwan.section);
-+
-+ this._devices.vpn = {
-+ section: new PopupMenu.PopupMenuSection(),
-+ device: new NMDeviceVPN(this._client),
-+ item: new NMWiredSectionTitleMenuItem(_("VPN Connections"))
-+ };
-+ this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
-+ this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
-+ this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
-+ this._devices.vpn.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
-+ this._devices.vpn.section.actor.hide();
-+ this.menu.addMenuItem(this._devices.vpn.section);
-+
-+ this.menu.addAction(_("Network Settings"), function() {
-+ Util.spawnDesktop('gnome-network-panel');
-+ });
-+
-+ this._activeConnections = [ ];
-+ this._connections = [ ];
-+
-+ this._mainConnection = null;
-+ this._activeAccessPointUpdateId = 0;
-+ this._activeAccessPoint = null;
-+ this._mobileUpdateId = 0;
-+ this._mobileUpdateDevice = null;
-+
-+ // Device types
-+ this._dtypes = { };
-+ this._dtypes[NetworkManager.DeviceType.ETHERNET] = NMDeviceWired;
-+ this._dtypes[NetworkManager.DeviceType.WIFI] = NMDeviceWireless;
-+ this._dtypes[NetworkManager.DeviceType.MODEM] = NMDeviceModem;
-+ this._dtypes[NetworkManager.DeviceType.BT] = NMDeviceBluetooth;
-+ // TODO: WiMax support
-+
-+ // Connection types
-+ this._ctypes = { };
-+ this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] = NMConnectionCategory.WIRELESS;
-+ this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] = NMConnectionCategory.WIRED;
-+ this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] = NMConnectionCategory.WIRED;
-+ this._ctypes[NetworkManager.SETTING_PPP_SETTING_NAME] = NMConnectionCategory.WIRED;
-+ this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] = NMConnectionCategory.WWAN;
-+ this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] = NMConnectionCategory.WWAN;
-+ this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] = NMConnectionCategory.WWAN;
-+ this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] = NMConnectionCategory.VPN;
-+
-+ this._settings = NMClient.RemoteSettings.new(null);
-+ this._connectionsReadId = this._settings.connect('connections-read', Lang.bind(this, function() {
-+ this._readConnections();
-+ this._readDevices();
-+ this._syncNMState();
-+
-+ // Connect to signals late so that early signals don't find in inconsistent state
-+ // and connect only once (this signal handler can be called again if NetworkManager goes up and down)
-+ if (!this._inited) {
-+ this._inited = true;
-+ this._client.connect('notify::manager-running', Lang.bind(this, this._syncNMState));
-+ this._client.connect('notify::networking-enabled', Lang.bind(this, this._syncNMState));
-+ this._client.connect('notify::state', Lang.bind(this, this._syncNMState));
-+ this._client.connect('notify::active-connections', Lang.bind(this, this._updateIcon));
-+ this._client.connect('device-added', Lang.bind(this, this._deviceAdded));
-+ this._client.connect('device-removed', Lang.bind(this, this._deviceRemoved));
-+ this._settings.connect('new-connection', Lang.bind(this, this._newConnection));
-+ }
-+ }));
-+ },
-+
-+ _ensureSource: function() {
-+ if (!this._source) {
-+ this._source = new NMMessageTraySource();
-+ this._source._destroyId = this._source.connect('destroy', Lang.bind(this, function() {
-+ this._source._destroyId = 0;
-+ this._source = null;
-+ }));
-+ Main.messageTray.add(this._source);
-+ }
-+ },
-+
-+ _makeToggleItem: function(type, title) {
-+ let item = new NMWirelessSectionTitleMenuItem(this._client, type, title);
-+ item.connect('enabled-changed', Lang.bind(this, function(item, enabled) {
-+ let devices = this._devices[type].devices;
-+ devices.forEach(function(dev) {
-+ dev.setEnabled(enabled);
-+ });
-+ this._syncSectionTitle(type);
-+ }));
-+ return item;
-+ },
-+
-+ _syncSectionTitle: function(category) {
-+ let devices = this._devices[category].devices;
-+ let managedDevices = devices.filter(function(dev) {
-+ return dev.device.state != NetworkManager.DeviceState.UNMANAGED;
-+ });
-+ let item = this._devices[category].item;
-+ let section = this._devices[category].section;
-+ if (managedDevices.length == 0)
-+ section.actor.hide();
-+ else {
-+ section.actor.show();
-+ if (managedDevices.length == 1) {
-+ let dev = managedDevices[0];
-+ dev.statusItem.actor.hide();
-+ item.updateForDevice(dev);
-+ } else {
-+ managedDevices.forEach(function(dev) {
-+ dev.statusItem.actor.show();
-+ });
-+ }
-+ }
-+ },
-+
-+ _readDevices: function() {
-+ let devices = this._client.get_devices() || [ ];
-+ for (let i = 0; i < devices.length; ++i) {
-+ this._deviceAdded(this._client, devices[i]);
-+ }
-+ },
-+
-+ _deviceAdded: function(client, device) {
-+ if (device._delegate) {
-+ // already seen, not adding again
-+ return;
-+ }
-+ let wrapperClass = this._dtypes[device.get_device_type()];
-+ if (wrapperClass) {
-+ device._description = getDeviceDescription(device);
-+
-+ let wrapper = new wrapperClass(this._client, device, this._connections);
-+ // FIXME: these notifications are duplicate with those exposed by nm-applet
-+ // uncomment this code in 3.2, when we'll conflict with and kill nm-applet
-+ /* wrapper._networkLostId = wrapper.connect('network-lost', Lang.bind(this, function(emitter) {
-+ this._ensureSource();
-+ let icon = new St.Icon({ icon_name: 'network-offline',
-+ icon_type: St.IconType.SYMBOLIC,
-+ icon_size: this._source.ICON_SIZE
-+ });
-+ let notification = new MessageTray.Notification(this._source,
-+ _("Connectivity lost"),
-+ _("You're no longer connected to the network"),
-+ { icon: icon });
-+ this._source.notify(notification);
-+ }));
-+ wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(wrapper, reason) {
-+ this._ensureSource();
-+ let icon = new St.Icon({ icon_name: 'network-error',
-+ icon_type: St.IconType.SYMBOLIC,
-+ icon_size: this._source.ICON_SIZE,
-+ });
-+ let banner;
-+ // XXX: nm-applet has no special text depending on reason
-+ // but I'm not sure of this generic message
-+ let notification = new MessageTray.Notification(this._source,
-+ _("Connection failed"),
-+ _("Activation of network connection failed"),
-+ { icon: icon });
-+ this._source.notify(notification);
-+ })); */
-+ wrapper._stateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
-+ this._syncSectionTitle(dev.category);
-+ }));
-+ wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
-+ //wrapper.disconnect(wrapper._networkLostId);
-+ //wrapper.disconnect(wrapper._activationFailedId);
-+ wrapper.disconnect(wrapper._stateChangedId);
-+ });
-+ let section = this._devices[wrapper.category].section;
-+ let devices = this._devices[wrapper.category].devices;
-+
-+ section.addMenuItem(wrapper.section, 1);
-+ section.addMenuItem(wrapper.statusItem, 1);
-+ devices.push(wrapper);
-+
-+ this._syncSectionTitle(wrapper.category);
-+ } else
-+ log('Invalid network device type, is ' + device.get_device_type());
-+ },
-+
-+ _deviceRemoved: function(client, device) {
-+ if (!device._delegate) {
-+ log('Removing a network device that was not added');
-+ return;
-+ }
-+
-+ let wrapper = device._delegate;
-+ wrapper.destroy();
-+
-+ let devices = this._devices[wrapper.category].devices;
-+ let pos = devices.indexOf(wrapper);
-+ devices.splice(pos, 1);
-+
-+ this._syncSectionTitle(wrapper.category)
-+ },
-+
-+ _syncActiveConnections: function() {
-+ let closedConnections = [ ];
-+ let newActiveConnections = this._client.get_active_connections() || [ ];
-+ for (let i = 0; i < this._activeConnections.length; i++) {
-+ let a = this._activeConnections[i];
-+ if (newActiveConnections.indexOf(a) == -1) // connection is removed
-+ closedConnections.push(a);
-+ }
-+
-+ for (let i = 0; i < closedConnections.length; i++) {
-+ let active = closedConnections[i];
-+ if (active._primaryDevice)
-+ active._primaryDevice.setActiveConnection(null);
-+ if (active._notifyStateId)
-+ active.disconnect(active._notifyStateId);
-+ if (active._inited) {
-+ active.disconnect(active._notifyDefaultId);
-+ active.disconnect(active._notifyDefault6Id);
-+ active._inited = false;
-+ }
-+ }
-+
-+ this._activeConnections = newActiveConnections;
-+ this._mainConnection = null;
-+ let activating = null;
-+ let default_ip4 = null;
-+ let default_ip6 = null;
-+ for (let i = 0; i < this._activeConnections.length; i++) {
-+ let a = this._activeConnections[i];
-+
-+ if (!a._inited) {
-+ a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._updateIcon));
-+ a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._updateIcon));
-+ if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING) // prepare to notify to the user
-+ a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._notifyActiveConnection));
-+ else {
-+ // notify as soon as possible
-+ Mainloop.idle_add(Lang.bind(this, function() {
-+ this._notifyActiveConnection(a);
-+ }));
-+ }
-+
-+ a._inited = true;
-+ }
-+
-+ if (!a._connection) {
-+ a._connection = this._settings.get_connection_by_path(a.connection);
-+
-+ if (a._connection) {
-+ a._type = a._connection._type;
-+ a._section = this._ctypes[a._type];
-+ } else {
-+ a._connection = null;
-+ a._type = null;
-+ a._section = null;
-+ log('Cannot find connection for active (or connection cannot be read)');
-+ }
-+ }
-+
-+ if (a['default'])
-+ default_ip4 = a;
-+ if (a.default6)
-+ default_ip6 = a;
-+
-+ if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING) {
-+ activating = a;
-+
-+ // don't set activating connections to devices, NMDevice:state-changed
-+ // should take care of rebuilding the menu
-+ continue;
-+ }
-+
-+ if (!a._primaryDevice) {
-+ if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
-+ // find a good device to be considered primary
-+ a._primaryDevice = null;
-+ let devices = a.get_devices();
-+ for (let j = 0; j < devices.length; j++) {
-+ let d = devices[j];
-+ if (d._delegate) {
-+ a._primaryDevice = d._delegate;
-+ break;
-+ }
-+ }
-+ } else
-+ a._primaryDevice = this._vpnDevice;
-+
-+ if (a._primaryDevice)
-+ a._primaryDevice.setActiveConnection(a);
-+ }
-+ }
-+
-+ this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
-+ },
-+
-+ _notifyActiveConnection: function(active) {
-+ // FIXME: duplicate notifications when nm-applet is running
-+ // This code will come back when nm-applet is killed
-+ this._syncNMState();
-+ return;
-+
-+ if (active.state == NetworkManager.ActiveConnectionState.ACTIVATED) {
-+
-+ // notify only connections that are visible
-+ if (active._connection) {
-+ this._ensureSource();
-+
-+ let icon;
-+ let banner;
-+ switch (active._section) {
-+ case NMConnectionCategory.WWAN:
-+ icon = 'network-cellular-signal-excellent';
-+ banner = _("You're now connected to mobile broadband connection '%s'").format(active._connection._name);
-+ break;
-+ case NMConnectionCategory.WIRELESS:
-+ icon = 'network-wireless-signal-excellent';
-+ banner = _("You're now connected to wireless network '%s'").format(active._connection._name);
-+ break;
-+ case NMConnectionCategory.WIRED:
-+ icon = 'network-wired';
-+ banner = _("You're now connected to wired network '%s'").format(active._connection._name);
-+ break;
-+ case NMConnectionCategory.VPN:
-+ icon = 'network-vpn';
-+ banner = _("You're now connected to VPN network '%s'").format(active._connection._name);
-+ break;
-+ default:
-+ // a fallback for a generic 'connected' icon
-+ icon = 'network-transmit-receive';
-+ banner = _("You're now connected to '%s'").format(active._connection._name);
-+ }
-+
-+ let iconActor = new St.Icon({ icon_name: icon,
-+ icon_type: St.IconType.SYMBOLIC,
-+ icon_size: this._source.ICON_SIZE
-+ });
-+ let notification = new MessageTray.Notification(this._source,
-+ _("Connection estabilished"),
-+ banner,
-+ { icon: iconActor });
-+ this._source.notify(notification);
-+ }
-+
-+ if (active._stateChangeId) {
-+ active.disconnect(active._stateChangeId);
-+ active._stateChangeId = 0;
-+ }
-+ }
-+
-+ this._syncNMState();
-+ },
-+
-+ _readConnections: function() {
-+ let connections = this._settings.list_connections();
-+ for (let i = 0; i < connections.length; i++) {
-+ let connection = connections[i];
-+ if (connection._uuid) {
-+ // connection was already seen (for example because NetworkManager was restarted)
-+ continue;
-+ }
-+ connection._removedId = connection.connect('removed', Lang.bind(this, this._connectionRemoved));
-+ connection._updatedId = connection.connect('updated', Lang.bind(this, this._updateConnection));
-+
-+ this._updateConnection(connection);
-+ this._connections.push(connection);
-+ }
-+ },
-+
-+ _newConnection: function(settings, connection) {
-+ if (connection._uuid) {
-+ // connection was already seen
-+ return;
-+ }
-+
-+ connection._removedId = connection.connect('removed', Lang.bind(this, this._connectionRemoved));
-+ connection._updatedId = connection.connect('updated', Lang.bind(this, this._updateConnection));
-+
-+ this._updateConnection(connection);
-+ this._connections.push(connection);
-+
-+ this._updateIcon();
-+ },
-+
-+ _connectionRemoved: function(connection) {
-+ let pos = this._connections.indexOf(connection);
-+ if (pos != -1)
-+ this._connections.splice(connection);
-+
-+ let section = connection._section;
-+ if (section == NMConnectionCategory.VPN) {
-+ this._devices.vpn.device.removeConnection(connection);
-+ if (this._devices.vpn.device.empty)
-+ this._devices.vpn.section.actor.hide();
-+ } else {
-+ let devices = this._devices[section].devices;
-+ for (let i = 0; i < devices.length; i++)
-+ devices[i].removeConnection(connection);
-+ }
-+
-+ connection._uuid = null;
-+ connection.disconnect(connection._removedId);
-+ connection.disconnect(connection._updatedId);
-+ },
-+
-+ _updateConnection: function(connection) {
-+ let connectionSettings = connection.get_setting_by_name(NetworkManager.SETTING_CONNECTION_SETTING_NAME);
-+ connection._type = connectionSettings.type;
-+ connection._section = this._ctypes[connection._type];
-+ connection._name = connectionSettings.id;
-+ connection._uuid = connectionSettings.uuid;
-+ connection._timestamp = connectionSettings.timestamp;
-+
-+ let section = connection._section;
-+ if (section == NMConnectionCategory.VPN) {
-+ this._devices.vpn.device.checkConnection(connection);
-+ this._devices.vpn.section.actor.show();
-+ connection._everAdded = true;
-+ } else {
-+ let devices = this._devices[section].devices;
-+ for (let i = 0; i < devices.length; i++) {
-+ devices[i].checkConnection(connection);
-+ }
-+ }
-+ },
-+
-+ _hideDevices: function() {
-+ this._devicesHidden = true;
-+
-+ for (let category in this._devices)
-+ this._devices[category].section.actor.hide();
-+ },
-+
-+ _showNormal: function() {
-+ if (!this._devicesHidden) // nothing to do
-+ return;
-+ this._devicesHidden = false;
-+
-+ this._statusSection.actor.hide();
-+
-+ this._syncSectionTitle('wired');
-+ this._syncSectionTitle('wireless');
-+ this._syncSectionTitle('wwan');
-+
-+ if (!this._devices.vpn.device.empty)
-+ this._devices.vpn.section.actor.show();
-+ },
-+
-+ _syncNMState: function() {
-+ if (!this._client.manager_running) {
-+ log('NetworkManager is not running, hiding...');
-+ this.menu.close();
-+ this.actor.hide();
-+ return;
-+ } else
-+ this.actor.show();
-+
-+ if (!this._client.networking_enabled) {
-+ this.setIcon('network-offline');
-+ this._hideDevices();
-+ this._statusItem.label.text = _("Networking is disabled");
-+ this._statusSection.actor.show();
-+ return;
-+ }
-+
-+ this._showNormal();
-+ this._updateIcon();
-+ },
-+
-+ _updateIcon: function() {
-+ this._syncActiveConnections();
-+ let mc = this._mainConnection;
-+ let hasApIcon = false;
-+ let hasMobileIcon = false;
-+
-+ if (!mc) {
-+ this.setIcon('network-offline');
-+ } else if (mc.state == NetworkManager.ActiveConnectionState.ACTIVATING) {
-+ switch (mc._section) {
-+ case NMConnectionCategory.WWAN:
-+ this.setIcon('network-cellular-acquiring');
-+ break;
-+ case NMConnectionCategory.WIRELESS:
-+ this.setIcon('network-wireless-acquiring');
-+ break;
-+ case NMConnectionCategory.WIRED:
-+ this.setIcon('network-wired-acquiring');
-+ break;
-+ case NMConnectionCategory.VPN:
-+ // XXX: there is no network-vpn-acquiring
-+ this.setIcon('network-vpn');
-+ break;
-+ default:
-+ this.setIcon('network-error');
-+ log('Invalid active connection type ' + mc._section);
-+ }
-+ } else {
-+ let dev;
-+ switch (mc._section) {
-+ case NMConnectionCategory.WIRELESS:
-+ dev = mc._primaryDevice;
-+ if (dev) {
-+ let ap = dev.device.active_access_point;
-+ let mode = dev.device.mode;
-+ if (!ap) {
-+ if (mode != NetworkManager['80211Mode'].ADHOC) {
-+ log('An active wireless connection, in infrastructure mode, involves no access point?');
-+ break;
-+ }
-+ // XXX: there is no network-wireless-connected
-+ this.setIcon('network-wireless-signal-excellent');
-+ } else {
-+ if (this._accessPointUpdateId && this._activeAccessPoint != ap) {
-+ this._activeAccessPoint.disconnect(this._accessPointUpdateId);
-+ this._activeAccessPoint = ap;
-+ this._activeAccessPointUpdateId = ap.connect('notify::strength', Lang.bind(function() {
-+ this.setIcon('network-wireless-signal-' + signalToIcon(ap.strength));
-+ }));
-+ }
-+ this.setIcon('network-wireless-signal-' + signalToIcon(ap.strength));
-+ hasApIcon = true;
-+ }
-+ break;
-+ } else {
-+ log('Active connection with no primary device?');
-+ break;
-+ }
-+ case NMConnectionCategory.WIRED:
-+ this.setIcon('network-wired');
-+ break;
-+ case NMConnectionCategory.WWAN:
-+ dev = mc._primaryDevice;
-+ if (!dev) {
-+ log('Active connection with no primary device?');
-+ break;
-+ }
-+ if (!dev.mobileDevice) {
-+ // this can happen for bluetooth in PAN mode
-+ // XXX: need network-cellular-connected icon
-+ this.setIcon('network-cellular-signal-excellent');
-+ break;
-+ }
-+
-+ if (this._mobileUpdateId && this._mobileUpdateDevice != dev) {
-+ this._mobileUpdateDevice.disconnect(this._mobileUpdateId);
-+ this._mobileUpdateDevice = dev.mobileDevice;
-+ this._mobileUpdateId = dev.mobileDevice.connect('notify::signal-quality', Lang.bind(this, function() {
-+ this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
-+ }));
-+ }
-+ this.setIcon('network-cellular-signal-' + signalToIcon(dev.mobileDevice.signal_quality));
-+ hasMobileIcon = true;
-+ break;
-+ case NMConnectionCategory.VPN:
-+ this.setIcon('network-vpn');
-+ break;
-+ default:
-+ log('Invalid active connection type ' + mc._section);
-+ this.setIcon('network-error');
-+ break;
-+ }
-+ }
-+
-+ // cleanup stale signal connections
-+
-+ if (!hasApIcon && this._activeAccessPointUpdateId) {
-+ this._activeAccessPoint.disconnect(this._activeAccessPointUpdateId);
-+ this._activeAccessPoint = null;
-+ this._activeAccessPointUpdateId = 0;
-+ }
-+ if (!hasMobileIcon && this._mobileUpdateId) {
-+ this._mobileUpdateDevice.disconnect(this._mobileUpdateId);
-+ this._mobileUpdateDevice = null;
-+ this._mobileUpdateId = 0;
-+ }
-+ }
-+};
-+
-+function NMMessageTraySource() {
-+ this._init();
-+}
-+
-+NMMessageTraySource.prototype = {
-+ __proto__: MessageTray.Source.prototype,
-+
-+ _init: function() {
-+ MessageTray.Source.prototype._init.call(this, _("Network Manager"));
-+
-+ let icon = new St.Icon({ icon_name: 'network-transmit-receive',
-+ icon_type: St.IconType.SYMBOLIC,
-+ icon_size: this.ICON_SIZE
-+ });
-+ this._setSummaryIcon(icon);
-+ }
-+};
-diff --git a/src/Makefile.am b/src/Makefile.am
-index 7c251de..0c440ae 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -62,7 +62,8 @@ gnome_shell_cflags = \
- $(GNOME_SHELL_CFLAGS) \
- -I$(srcdir)/tray \
- -DVERSION=\"$(VERSION)\" \
-- -DLOCALEDIR=\"$(datadir)/locale\" \
-+ -DLOCALEDIR=\"$(datadir)/locale\" \
-+ -DDATADIR=\"$(datadir)\" \
- -DGNOME_SHELL_LIBEXECDIR=\"$(libexecdir)\" \
- -DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
- -DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
-@@ -90,6 +91,7 @@ shell_public_headers_h = \
- shell-generic-container.h \
- shell-gtk-embed.h \
- shell-global.h \
-+ shell-mobile-providers.h \
- shell-perf-log.h \
- shell-slicer.h \
- shell-stack.h \
-@@ -121,6 +123,7 @@ libgnome_shell_la_SOURCES = \
- shell-generic-container.c \
- shell-gtk-embed.c \
- shell-global.c \
-+ shell-mobile-providers.c \
- shell-perf-log.c \
- shell-polkit-authentication-agent.h \
- shell-polkit-authentication-agent.c \
-diff --git a/src/shell-mobile-providers.c b/src/shell-mobile-providers.c
-new file mode 100644
-index 0000000..ca6a41f
---- /dev/null
-+++ b/src/shell-mobile-providers.c
-@@ -0,0 +1,816 @@
-+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/*
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-+ * Boston, MA 02110-1301 USA.
-+ *
-+ * Copyright (C) 2009 Novell, Inc.
-+ * Author: Tambet Ingo (tambet@gmail.com).
-+ *
-+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
-+ */
-+
-+#include "config.h"
-+
-+#include <string.h>
-+#include <errno.h>
-+#include <stdlib.h>
-+
-+#include <glib/gi18n.h>
-+
-+#include "shell-mobile-providers.h"
-+
-+#ifndef MOBILE_BROADBAND_PROVIDER_INFO
-+#define MOBILE_BROADBAND_PROVIDER_INFO DATADIR "/mobile-broadband-provider-info/serviceproviders.xml"
-+#endif
-+
-+#define ISO_3166_COUNTRY_CODES DATADIR "/zoneinfo/iso3166.tab"
-+
-+
-+
-+static GHashTable *
-+read_country_codes (void)
-+{
-+ GHashTable *table;
-+ GIOChannel *channel;
-+ GString *buffer;
-+ GError *error = NULL;
-+ GIOStatus status;
-+
-+ channel = g_io_channel_new_file (ISO_3166_COUNTRY_CODES, "r", &error);
-+ if (!channel) {
-+ if (error) {
-+ g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": %s", error->message);
-+ g_error_free (error);
-+ } else
-+ g_warning ("Could not read " ISO_3166_COUNTRY_CODES ": Unknown error");
-+
-+ return NULL;
-+ }
-+
-+ table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-+ buffer = g_string_sized_new (32);
-+
-+ status = G_IO_STATUS_NORMAL;
-+ while (status == G_IO_STATUS_NORMAL) {
-+ status = g_io_channel_read_line_string (channel, buffer, NULL, &error);
-+
-+ switch (status) {
-+ case G_IO_STATUS_NORMAL:
-+ if (buffer->str[0] != '#') {
-+ char **pieces;
-+
-+ pieces = g_strsplit (buffer->str, "\t", 2);
-+
-+ /* Hack for rh#556292; iso3166.tab is just wrong */
-+ pieces[1] = pieces[1] ? g_strchomp (pieces[1]) : NULL;
-+ if (pieces[1] && !strcmp (pieces[1], "Britain (UK)")) {
-+ g_free (pieces[1]);
-+ pieces[1] = g_strdup (_("United Kingdom"));
-+ }
-+
-+ g_hash_table_insert (table, pieces[0], pieces[1]);
-+ g_free (pieces);
-+ }
-+
-+ g_string_truncate (buffer, 0);
-+ break;
-+ case G_IO_STATUS_EOF:
-+ break;
-+ case G_IO_STATUS_ERROR:
-+ g_warning ("Error while reading: %s", error->message);
-+ g_error_free (error);
-+ break;
-+ case G_IO_STATUS_AGAIN:
-+ /* FIXME: Try again a few times, but really, it never happes, right? */
-+ break;
-+ }
-+ }
-+
-+ g_string_free (buffer, TRUE);
-+ g_io_channel_unref (channel);
-+
-+ return table;
-+}
-+
-+/* XML Parser */
-+
-+typedef enum {
-+ PARSER_TOPLEVEL = 0,
-+ PARSER_COUNTRY,
-+ PARSER_PROVIDER,
-+ PARSER_METHOD_GSM,
-+ PARSER_METHOD_GSM_APN,
-+ PARSER_METHOD_CDMA,
-+ PARSER_ERROR
-+} MobileContextState;
-+
-+typedef struct {
-+ GHashTable *country_codes;
-+ GHashTable *table;
-+
-+ char *current_country;
-+ GSList *current_providers;
-+ ShellMobileProvider *current_provider;
-+ ShellMobileAccessMethod *current_method;
-+
-+ char *text_buffer;
-+ MobileContextState state;
-+} MobileParser;
-+
-+static ShellGsmMccMnc *
-+mcc_mnc_new (const char *mcc, const char *mnc)
-+{
-+ ShellGsmMccMnc *m;
-+
-+ m = g_slice_new (ShellGsmMccMnc);
-+ m->mcc = g_strstrip (g_strdup (mcc));
-+ m->mnc = g_strstrip (g_strdup (mnc));
-+ return m;
-+}
-+
-+/* added in porting */
-+static ShellGsmMccMnc *
-+mcc_mnc_copy (const ShellGsmMccMnc *other) {
-+ ShellGsmMccMnc *ret;
-+
-+ ret = g_slice_new (ShellGsmMccMnc);
-+ ret->mcc = g_strdup (other->mcc);
-+ ret->mnc = g_strdup (other->mnc);
-+ return ret;
-+}
-+
-+static void
-+mcc_mnc_free (ShellGsmMccMnc *m)
-+{
-+ g_return_if_fail (m != NULL);
-+ g_free (m->mcc);
-+ g_free (m->mnc);
-+ g_slice_free (ShellGsmMccMnc, m);
-+}
-+
-+/* added in porting */
-+G_DEFINE_BOXED_TYPE (ShellGsmMccMnc, shell_gsm_mcc_mnc, mcc_mnc_copy, mcc_mnc_free)
-+
-+static ShellMobileAccessMethod *
-+access_method_new (void)
-+{
-+ ShellMobileAccessMethod *method;
-+
-+ method = g_slice_new0 (ShellMobileAccessMethod);
-+ method->refs = 1;
-+ method->lcl_names = g_hash_table_new_full (g_str_hash, g_str_equal,
-+ (GDestroyNotify) g_free,
-+ (GDestroyNotify) g_free);
-+
-+ return method;
-+}
-+
-+ShellMobileAccessMethod *
-+shell_mobile_access_method_ref (ShellMobileAccessMethod *method)
-+{
-+ g_return_val_if_fail (method != NULL, NULL);
-+ g_return_val_if_fail (method->refs > 0, NULL);
-+
-+ method->refs++;
-+
-+ return method;
-+}
-+
-+void
-+shell_mobile_access_method_unref (ShellMobileAccessMethod *method)
-+{
-+ g_return_if_fail (method != NULL);
-+ g_return_if_fail (method->refs > 0);
-+
-+ if (--method->refs == 0) {
-+ g_free (method->name);
-+ g_hash_table_destroy (method->lcl_names);
-+ g_free (method->username);
-+ g_free (method->password);
-+ g_free (method->gateway);
-+ g_free (method->gsm_apn);
-+ g_slist_foreach (method->dns, (GFunc) g_free, NULL);
-+ g_slist_free (method->dns);
-+
-+ g_slice_free (ShellMobileAccessMethod, method);
-+ }
-+}
-+
-+GType
-+shell_mobile_access_method_get_type (void)
-+{
-+ static GType type = 0;
-+
-+ if (G_UNLIKELY (type == 0)) {
-+ type = g_boxed_type_register_static ("ShellMobileAccessMethod",
-+ (GBoxedCopyFunc) shell_mobile_access_method_ref,
-+ (GBoxedFreeFunc) shell_mobile_access_method_unref);
-+ }
-+ return type;
-+}
-+
-+
-+static ShellMobileProvider *
-+provider_new (void)
-+{
-+ ShellMobileProvider *provider;
-+
-+ provider = g_slice_new0 (ShellMobileProvider);
-+ provider->refs = 1;
-+ provider->lcl_names = g_hash_table_new_full (g_str_hash, g_str_equal,
-+ (GDestroyNotify) g_free,
-+ (GDestroyNotify) g_free);
-+
-+ return provider;
-+}
-+
-+ShellMobileProvider *
-+shell_mobile_provider_ref (ShellMobileProvider *provider)
-+{
-+ provider->refs++;
-+
-+ return provider;
-+}
-+
-+void
-+shell_mobile_provider_unref (ShellMobileProvider *provider)
-+{
-+ if (--provider->refs == 0) {
-+ g_free (provider->name);
-+ g_hash_table_destroy (provider->lcl_names);
-+
-+ g_slist_foreach (provider->methods, (GFunc) shell_mobile_access_method_unref, NULL);
-+ g_slist_free (provider->methods);
-+
-+ g_slist_foreach (provider->gsm_mcc_mnc, (GFunc) mcc_mnc_free, NULL);
-+ g_slist_free (provider->gsm_mcc_mnc);
-+
-+ g_slist_free (provider->cdma_sid);
-+
-+ g_slice_free (ShellMobileProvider, provider);
-+ }
-+}
-+
-+GType
-+shell_mobile_provider_get_type (void)
-+{
-+ static GType type = 0;
-+
-+ if (G_UNLIKELY (type == 0)) {
-+ type = g_boxed_type_register_static ("ShellMobileProvider",
-+ (GBoxedCopyFunc) shell_mobile_provider_ref,
-+ (GBoxedFreeFunc) shell_mobile_provider_unref);
-+ }
-+ return type;
-+}
-+
-+static void
-+provider_list_free (gpointer data)
-+{
-+ GSList *list = (GSList *) data;
-+
-+ while (list) {
-+ shell_mobile_provider_unref ((ShellMobileProvider *) list->data);
-+ list = g_slist_delete_link (list, list);
-+ }
-+}
-+
-+static void
-+parser_toplevel_start (MobileParser *parser,
-+ const char *name,
-+ const char **attribute_names,
-+ const char **attribute_values)
-+{
-+ int i;
-+
-+ if (!strcmp (name, "serviceproviders")) {
-+ for (i = 0; attribute_names && attribute_names[i]; i++) {
-+ if (!strcmp (attribute_names[i], "format")) {
-+ if (strcmp (attribute_values[i], "2.0")) {
-+ g_warning ("%s: mobile broadband provider database format '%s'"
-+ " not supported.", __func__, attribute_values[i]);
-+ parser->state = PARSER_ERROR;
-+ break;
-+ }
-+ }
-+ }
-+ } else if (!strcmp (name, "country")) {
-+ for (i = 0; attribute_names && attribute_names[i]; i++) {
-+ if (!strcmp (attribute_names[i], "code")) {
-+ char *country_code;
-+ char *country;
-+
-+ country_code = g_ascii_strup (attribute_values[i], -1);
-+ country = g_hash_table_lookup (parser->country_codes, country_code);
-+ if (country) {
-+ parser->current_country = g_strdup (country);
-+ g_free (country_code);
-+ } else
-+ parser->current_country = country_code;
-+
-+ parser->state = PARSER_COUNTRY;
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+static void
-+parser_country_start (MobileParser *parser,
-+ const char *name,
-+ const char **attribute_names,
-+ const char **attribute_values)
-+{
-+ if (!strcmp (name, "provider")) {
-+ parser->state = PARSER_PROVIDER;
-+ parser->current_provider = provider_new ();
-+ }
-+}
-+
-+static void
-+parser_provider_start (MobileParser *parser,
-+ const char *name,
-+ const char **attribute_names,
-+ const char **attribute_values)
-+{
-+ if (!strcmp (name, "gsm"))
-+ parser->state = PARSER_METHOD_GSM;
-+ else if (!strcmp (name, "cdma")) {
-+ parser->state = PARSER_METHOD_CDMA;
-+ parser->current_method = access_method_new ();
-+ }
-+}
-+
-+static void
-+parser_gsm_start (MobileParser *parser,
-+ const char *name,
-+ const char **attribute_names,
-+ const char **attribute_values)
-+{
-+ if (!strcmp (name, "network-id")) {
-+ const char *mcc = NULL, *mnc = NULL;
-+ int i;
-+
-+ for (i = 0; attribute_names && attribute_names[i]; i++) {
-+ if (!strcmp (attribute_names[i], "mcc"))
-+ mcc = attribute_values[i];
-+ else if (!strcmp (attribute_names[i], "mnc"))
-+ mnc = attribute_values[i];
-+
-+ if (mcc && strlen (mcc) && mnc && strlen (mnc)) {
-+ parser->current_provider->gsm_mcc_mnc = g_slist_prepend (parser->current_provider->gsm_mcc_mnc,
-+ mcc_mnc_new (mcc, mnc));
-+ break;
-+ }
-+ }
-+ } else if (!strcmp (name, "apn")) {
-+ int i;
-+
-+ for (i = 0; attribute_names && attribute_names[i]; i++) {
-+ if (!strcmp (attribute_names[i], "value")) {
-+
-+ parser->state = PARSER_METHOD_GSM_APN;
-+ parser->current_method = access_method_new ();
-+ parser->current_method->gsm_apn = g_strstrip (g_strdup (attribute_values[i]));
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+static void
-+parser_cdma_start (MobileParser *parser,
-+ const char *name,
-+ const char **attribute_names,
-+ const char **attribute_values)
-+{
-+ if (!strcmp (name, "sid")) {
-+ int i;
-+
-+ for (i = 0; attribute_names && attribute_names[i]; i++) {
-+ if (!strcmp (attribute_names[i], "value")) {
-+ unsigned long tmp;
-+
-+ errno = 0;
-+ tmp = strtoul (attribute_values[i], NULL, 10);
-+ if (errno == 0 && tmp > 0)
-+ parser->current_provider->cdma_sid = g_slist_prepend (parser->current_provider->cdma_sid,
-+ GUINT_TO_POINTER ((guint32) tmp));
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+static void
-+mobile_parser_start_element (GMarkupParseContext *context,
-+ const gchar *element_name,
-+ const gchar **attribute_names,
-+ const gchar **attribute_values,
-+ gpointer data,
-+ GError **error)
-+{
-+ MobileParser *parser = (MobileParser *) data;
-+
-+ if (parser->text_buffer) {
-+ g_free (parser->text_buffer);
-+ parser->text_buffer = NULL;
-+ }
-+
-+ switch (parser->state) {
-+ case PARSER_TOPLEVEL:
-+ parser_toplevel_start (parser, element_name, attribute_names, attribute_values);
-+ break;
-+ case PARSER_COUNTRY:
-+ parser_country_start (parser, element_name, attribute_names, attribute_values);
-+ break;
-+ case PARSER_PROVIDER:
-+ parser_provider_start (parser, element_name, attribute_names, attribute_values);
-+ break;
-+ case PARSER_METHOD_GSM:
-+ parser_gsm_start (parser, element_name, attribute_names, attribute_values);
-+ break;
-+ case PARSER_METHOD_CDMA:
-+ parser_cdma_start (parser, element_name, attribute_names, attribute_values);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static void
-+parser_country_end (MobileParser *parser,
-+ const char *name)
-+{
-+ if (!strcmp (name, "country")) {
-+ g_hash_table_insert (parser->table, parser->current_country, parser->current_providers);
-+ parser->current_country = NULL;
-+ parser->current_providers = NULL;
-+ parser->text_buffer = NULL;
-+ parser->state = PARSER_TOPLEVEL;
-+ }
-+}
-+
-+static void
-+parser_provider_end (MobileParser *parser,
-+ const char *name)
-+{
-+ if (!strcmp (name, "name")) {
-+ if (!parser->current_provider->name) {
-+ /* Use the first one. */
-+ parser->current_provider->name = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ }
-+ } else if (!strcmp (name, "provider")) {
-+ parser->current_provider->methods = g_slist_reverse (parser->current_provider->methods);
-+
-+ parser->current_provider->gsm_mcc_mnc = g_slist_reverse (parser->current_provider->gsm_mcc_mnc);
-+ parser->current_provider->cdma_sid = g_slist_reverse (parser->current_provider->cdma_sid);
-+
-+ parser->current_providers = g_slist_prepend (parser->current_providers, parser->current_provider);
-+ parser->current_provider = NULL;
-+ parser->text_buffer = NULL;
-+ parser->state = PARSER_COUNTRY;
-+ }
-+}
-+
-+static void
-+parser_gsm_end (MobileParser *parser,
-+ const char *name)
-+{
-+ if (!strcmp (name, "gsm")) {
-+ parser->text_buffer = NULL;
-+ parser->state = PARSER_PROVIDER;
-+ }
-+}
-+
-+static void
-+parser_gsm_apn_end (MobileParser *parser,
-+ const char *name)
-+{
-+ if (!strcmp (name, "name")) {
-+ if (!parser->current_method->name) {
-+ /* Use the first one. */
-+ parser->current_method->name = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ }
-+ } else if (!strcmp (name, "username")) {
-+ parser->current_method->username = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "password")) {
-+ parser->current_method->password = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "dns")) {
-+ parser->current_method->dns = g_slist_prepend (parser->current_method->dns, parser->text_buffer);
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "gateway")) {
-+ parser->current_method->gateway = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "apn")) {
-+ parser->current_method->type = SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM;
-+ parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
-+
-+ if (!parser->current_method->name)
-+ parser->current_method->name = g_strdup (_("Default"));
-+
-+ parser->current_provider->methods = g_slist_prepend (parser->current_provider->methods,
-+ parser->current_method);
-+ parser->current_method = NULL;
-+ parser->text_buffer = NULL;
-+ parser->state = PARSER_METHOD_GSM;
-+ }
-+}
-+
-+static void
-+parser_cdma_end (MobileParser *parser,
-+ const char *name)
-+{
-+ if (!strcmp (name, "username")) {
-+ parser->current_method->username = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "password")) {
-+ parser->current_method->password = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "dns")) {
-+ parser->current_method->dns = g_slist_prepend (parser->current_method->dns, parser->text_buffer);
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "gateway")) {
-+ parser->current_method->gateway = parser->text_buffer;
-+ parser->text_buffer = NULL;
-+ } else if (!strcmp (name, "cdma")) {
-+ parser->current_method->type = SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA;
-+ parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
-+
-+ if (!parser->current_method->name)
-+ parser->current_method->name = g_strdup (parser->current_provider->name);
-+
-+ parser->current_provider->methods = g_slist_prepend (parser->current_provider->methods,
-+ parser->current_method);
-+ parser->current_method = NULL;
-+ parser->text_buffer = NULL;
-+ parser->state = PARSER_PROVIDER;
-+ }
-+}
-+
-+static void
-+mobile_parser_end_element (GMarkupParseContext *context,
-+ const gchar *element_name,
-+ gpointer data,
-+ GError **error)
-+{
-+ MobileParser *parser = (MobileParser *) data;
-+
-+ switch (parser->state) {
-+ case PARSER_COUNTRY:
-+ parser_country_end (parser, element_name);
-+ break;
-+ case PARSER_PROVIDER:
-+ parser_provider_end (parser, element_name);
-+ break;
-+ case PARSER_METHOD_GSM:
-+ parser_gsm_end (parser, element_name);
-+ break;
-+ case PARSER_METHOD_GSM_APN:
-+ parser_gsm_apn_end (parser, element_name);
-+ break;
-+ case PARSER_METHOD_CDMA:
-+ parser_cdma_end (parser, element_name);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static void
-+mobile_parser_characters (GMarkupParseContext *context,
-+ const gchar *text,
-+ gsize text_len,
-+ gpointer data,
-+ GError **error)
-+{
-+ MobileParser *parser = (MobileParser *) data;
-+
-+ g_free (parser->text_buffer);
-+ parser->text_buffer = g_strdup (text);
-+}
-+
-+static const GMarkupParser mobile_parser = {
-+ mobile_parser_start_element,
-+ mobile_parser_end_element,
-+ mobile_parser_characters,
-+ NULL, /* passthrough */
-+ NULL /* error */
-+};
-+
-+/**
-+ * shell_mobile_providers_parse:
-+ * @out_ccs: (out) (allow-none): (element-type utf8 utf8): a #GHashTable containing
-+ * country codes
-+ *
-+ * Returns: (element-type utf8 GList<Shell.MobileProvider>) (transfer container): a
-+ * hash table where keys are country names 'char *', values are a 'GSList *'
-+ * of 'ShellMobileProvider *'. Everything is destroyed with g_hash_table_destroy ().
-+*/
-+GHashTable *
-+shell_mobile_providers_parse (GHashTable **out_ccs)
-+{
-+ GMarkupParseContext *ctx;
-+ GIOChannel *channel;
-+ MobileParser parser;
-+ GError *error = NULL;
-+ char buffer[4096];
-+ GIOStatus status;
-+ gsize len = 0;
-+
-+ memset (&parser, 0, sizeof (MobileParser));
-+
-+ parser.country_codes = read_country_codes ();
-+ if (!parser.country_codes)
-+ goto out;
-+
-+ channel = g_io_channel_new_file (MOBILE_BROADBAND_PROVIDER_INFO, "r", &error);
-+ if (!channel) {
-+ if (error) {
-+ g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": %s", error->message);
-+ g_error_free (error);
-+ } else
-+ g_warning ("Could not read " MOBILE_BROADBAND_PROVIDER_INFO ": Unknown error");
-+
-+ goto out;
-+ }
-+
-+ parser.table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, provider_list_free);
-+ parser.state = PARSER_TOPLEVEL;
-+
-+ ctx = g_markup_parse_context_new (&mobile_parser, 0, &parser, NULL);
-+
-+ status = G_IO_STATUS_NORMAL;
-+ while (status == G_IO_STATUS_NORMAL) {
-+ status = g_io_channel_read_chars (channel, buffer, sizeof (buffer), &len, &error);
-+
-+ switch (status) {
-+ case G_IO_STATUS_NORMAL:
-+ if (!g_markup_parse_context_parse (ctx, buffer, len, &error)) {
-+ status = G_IO_STATUS_ERROR;
-+ g_warning ("Error while parsing XML: %s", error->message);
-+ g_error_free (error);;
-+ }
-+ break;
-+ case G_IO_STATUS_EOF:
-+ break;
-+ case G_IO_STATUS_ERROR:
-+ g_warning ("Error while reading: %s", error->message);
-+ g_error_free (error);
-+ break;
-+ case G_IO_STATUS_AGAIN:
-+ /* FIXME: Try again a few times, but really, it never happes, right? */
-+ break;
-+ }
-+ }
-+
-+ g_io_channel_unref (channel);
-+ g_markup_parse_context_free (ctx);
-+
-+ if (parser.current_provider) {
-+ g_warning ("pending current provider");
-+ shell_mobile_provider_unref (parser.current_provider);
-+ }
-+
-+ if (parser.current_providers) {
-+ g_warning ("pending current providers");
-+ provider_list_free (parser.current_providers);
-+ }
-+
-+ g_free (parser.current_country);
-+ g_free (parser.text_buffer);
-+
-+ out:
-+ if (parser.country_codes) {
-+ if (out_ccs)
-+ *out_ccs = parser.country_codes;
-+ else
-+ g_hash_table_destroy (parser.country_codes);
-+ }
-+
-+ return parser.table;
-+}
-+
-+static void
-+dump_generic (ShellMobileAccessMethod *method)
-+{
-+ GSList *iter;
-+ GString *dns;
-+
-+ g_print (" username: %s\n", method->username ? method->username : "");
-+ g_print (" password: %s\n", method->password ? method->password : "");
-+
-+ dns = g_string_new (NULL);
-+ for (iter = method->dns; iter; iter = g_slist_next (iter))
-+ g_string_append_printf (dns, "%s%s", dns->len ? ", " : "", (char *) iter->data);
-+ g_print (" dns : %s\n", dns->str);
-+ g_string_free (dns, TRUE);
-+
-+ g_print (" gateway : %s\n", method->gateway ? method->gateway : "");
-+}
-+
-+static void
-+dump_cdma (ShellMobileAccessMethod *method)
-+{
-+ g_print (" CDMA: %s\n", method->name);
-+
-+ dump_generic (method);
-+}
-+
-+static void
-+dump_gsm (ShellMobileAccessMethod *method)
-+{
-+ g_print (" APN: %s (%s)\n", method->name, method->gsm_apn);
-+
-+ dump_generic (method);
-+}
-+
-+static void
-+dump_country (gpointer key, gpointer value, gpointer user_data)
-+{
-+ GSList *citer, *miter;
-+
-+ for (citer = value; citer; citer = g_slist_next (citer)) {
-+ ShellMobileProvider *provider = citer->data;
-+
-+ g_print ("Provider: %s (%s)\n", provider->name, (const char *) key);
-+ for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
-+ ShellMobileAccessMethod *method = miter->data;
-+ GSList *liter;
-+
-+
-+ for (liter = provider->gsm_mcc_mnc; liter; liter = g_slist_next (liter)) {
-+ ShellGsmMccMnc *m = liter->data;
-+ g_print (" MCC/MNC: %s-%s\n", m->mcc, m->mnc);
-+ }
-+
-+ for (liter = provider->cdma_sid; liter; liter = g_slist_next (liter))
-+ g_print (" SID: %d\n", GPOINTER_TO_UINT (liter->data));
-+
-+ switch (method->type) {
-+ case SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA:
-+ dump_cdma (method);
-+ break;
-+ case SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM:
-+ dump_gsm (method);
-+ break;
-+ default:
-+ break;
-+ }
-+ g_print ("\n");
-+ }
-+ }
-+}
-+
-+void
-+shell_mobile_providers_dump (GHashTable *providers)
-+{
-+ g_return_if_fail (providers != NULL);
-+ g_hash_table_foreach (providers, dump_country, NULL);
-+}
-+
-+/* All the following don't exist in nm-applet, because C doesn't need
-+ those. They're only needed for the introspection annotations
-+*/
-+
-+/**
-+ * shell_mobile_provider_get_gsm_mcc_mnc:
-+ * @provider: a #ShellMobileProvider
-+ *
-+ * Returns: (element-type Shell.GsmMccMnc) (transfer none): the
-+ * list of #ShellGsmMccMnc this provider exposes
-+ */
-+GSList *
-+shell_mobile_provider_get_gsm_mcc_mnc (ShellMobileProvider *provider)
-+{
-+ return provider->gsm_mcc_mnc;
-+}
-+
-+/**
-+ * shell_mobile_provider_get_cdma_sid:
-+ * @provider: a #ShellMobileProvider
-+ *
-+ * Returns: (element-type guint32) (transfer none): the
-+ * list of CDMA sids this provider exposes
-+ */
-+GSList *
-+shell_mobile_provider_get_cdma_sid (ShellMobileProvider *provider)
-+{
-+ return provider->cdma_sid;
-+}
-diff --git a/src/shell-mobile-providers.h b/src/shell-mobile-providers.h
-new file mode 100644
-index 0000000..d70b8e2
---- /dev/null
-+++ b/src/shell-mobile-providers.h
-@@ -0,0 +1,96 @@
-+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-+/*
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General Public
-+ * License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-+ * Boston, MA 02110-1301 USA.
-+ *
-+ * Copyright (C) 2009 Novell, Inc.
-+ * Author: Tambet Ingo (tambet@gmail.com).
-+ *
-+ * Copyright (C) 2009 - 2010 Red Hat, Inc.
-+ *
-+ * Ported to GNOME Shell by Giovanni Campagna <scampa.giovanni@gmail.com>
-+ * Porting consisted only in replacing nmn with shell, to be compatible with
-+ * GObject Introspection namespacing
-+ */
-+
-+#ifndef SHELL_MOBILE_PROVIDERS_H
-+#define SHELL_MOBILE_PROVIDERS_H
-+
-+#include <glib.h>
-+#include <glib-object.h>
-+
-+#define SHELL_TYPE_MOBILE_PROVIDER (shell_mobile_provider_get_type ())
-+#define SHELL_TYPE_MOBILE_ACCESS_METHOD (shell_mobile_access_method_get_type ())
-+
-+typedef enum {
-+ SHELL_MOBILE_ACCESS_METHOD_TYPE_UNKNOWN = 0,
-+ SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM,
-+ SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA
-+} ShellMobileAccessMethodType;
-+
-+typedef struct {
-+ char *mcc;
-+ char *mnc;
-+} ShellGsmMccMnc;
-+
-+typedef struct {
-+ char *name;
-+ /* maps lang (char *) -> name (char *) */
-+ GHashTable *lcl_names;
-+
-+ char *username;
-+ char *password;
-+ char *gateway;
-+ GSList *dns; /* GSList of 'char *' */
-+
-+ /* Only used with SHELL_PROVIDER_TYPE_GSM */
-+ char *gsm_apn;
-+
-+ ShellMobileAccessMethodType type;
-+
-+ gint refs;
-+} ShellMobileAccessMethod;
-+
-+typedef struct {
-+ char *name;
-+ /* maps lang (char *) -> name (char *) */
-+ GHashTable *lcl_names;
-+
-+ GSList *methods; /* GSList of ShellMobileAccessMethod */
-+
-+ GSList *gsm_mcc_mnc; /* GSList of ShellGsmMccMnc */
-+ GSList *cdma_sid; /* GSList of guint32 */
-+
-+ gint refs;
-+} ShellMobileProvider;
-+
-+
-+GType shell_gsm_mcc_mnc_get_type (void); /* added in porting */
-+GType shell_mobile_provider_get_type (void);
-+GType shell_mobile_access_method_get_type (void);
-+
-+ShellMobileProvider *shell_mobile_provider_ref (ShellMobileProvider *provider);
-+void shell_mobile_provider_unref (ShellMobileProvider *provider);
-+GSList * shell_mobile_provider_get_gsm_mcc_mnc (ShellMobileProvider *provider);
-+GSList * shell_mobile_provider_get_cdma_sid (ShellMobileProvider *provider);
-+
-+ShellMobileAccessMethod *shell_mobile_access_method_ref (ShellMobileAccessMethod *method);
-+void shell_mobile_access_method_unref (ShellMobileAccessMethod *method);
-+
-+GHashTable *shell_mobile_providers_parse (GHashTable **out_ccs);
-+
-+void shell_mobile_providers_dump (GHashTable *providers);
-+
-+#endif /* SHELL_MOBILE_PROVIDERS_H */
-diff --git a/tools/build/gnome-shell.modules b/tools/build/gnome-shell.modules
-index 6c8db09..837cb22 100644
---- a/tools/build/gnome-shell.modules
-+++ b/tools/build/gnome-shell.modules
-@@ -9,6 +9,8 @@
- href="git://git.gnome.org/"/>
- <repository type="git" name="git.moblin.org"
- href="git://git.moblin.org"/>
-+ <repository type="git" name="anongit.freedesktop.org"
-+ href="git://anongit.freedesktop.org"/>
- <repository type="tarball" name="cairo.org"
- href="http://cairographics.org/"/>
- <repository type="tarball" name="0pointer.de"
-@@ -369,4 +371,19 @@
- </dependencies>
- </autotools>
-
-+ <autotools id="NetworkManager" autogenargs="--enable-introspection">
-+ <branch repo="anongit.freedesktop.org" module="NetworkManager/NetworkManager.git" checkoutdir="NetworkManager" />
-+ <dependencies>
-+ <dep package="glib"/>
-+ </dependencies>
-+ </autotools>
-+
-+ <autotools id="network-manager-applet">
-+ <branch repo="git.gnome.org" module="network-manager-applet" />
-+ <dependencies>
-+ <dep package="glib"/>
-+ <dep package="gtk3"/>
-+ <dep package="libnotify"/>
-+ </dependencies>
-+ </autotools>
- </moduleset>
---
-1.7.4
\ No newline at end of file
diff --git a/gnome-base/gnome-shell/gnome-shell-9999.ebuild b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
index 17a9912..bc58dac 100644
--- a/gnome-base/gnome-shell/gnome-shell-9999.ebuild
+++ b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
@@ -13,7 +13,7 @@ HOMEPAGE="http://live.gnome.org/GnomeShell"
LICENSE="GPL-2"
SLOT="0"
-IUSE="nm-applet"
+IUSE="+nm-applet"
if [[ ${PV} = 9999 ]]; then
inherit gnome2-live
KEYWORDS=""
@@ -23,7 +23,7 @@ fi
# gnome-desktop-2.91.2 is needed due to header changes, db82a33 in gnome-desktop
# FIXME: Automagic gnome-bluetooth[introspection] support.
-# latest mutter is needed due to commit 474ff2e997
+# latest mutter is needed due to commit 474ff2e9 and commit 079953c3
# latest gsettings-desktop-schemas is needed due to commit 602fa1c6
COMMON_DEPEND=">=dev-libs/glib-2.25.9:2
>=dev-libs/gjs-0.7.11
@@ -40,7 +40,7 @@ COMMON_DEPEND=">=dev-libs/glib-2.25.9:2
>=net-libs/telepathy-glib-0.13.12[introspection]
>=net-wireless/gnome-bluetooth-2.90.0[introspection]
>=sys-auth/polkit-0.100[introspection]
- >=x11-wm/mutter-2.91.91[introspection]
+ >=x11-wm/mutter-2.91.91.1[introspection]
dev-libs/dbus-glib
dev-libs/libxml2:2
@@ -55,9 +55,7 @@ COMMON_DEPEND=">=dev-libs/glib-2.25.9:2
x11-libs/startup-notification
x11-libs/libXfixes
- x11-apps/mesa-progs
-
- nm-applet? ( >=net-misc/networkmanager-0.8.996[introspection] )"
+ x11-apps/mesa-progs"
# Runtime-only deps are probably incomplete and approximate.
# Each block:
# 1. Pull in polkit-0.101 for pretty authorization dialogs
@@ -77,7 +75,9 @@ RDEPEND="${COMMON_DEPEND}
>=gnome-base/gnome-settings-daemon-2.91
>=gnome-base/gnome-control-center-2.91
- nm-applet? ( >=gnome-extra/nm-applet-0.8.996 )"
+ nm-applet? (
+ >=gnome-extra/nm-applet-0.8.996
+ >=net-misc/networkmanager-0.8.996-r1[introspection] )"
DEPEND="${COMMON_DEPEND}
sys-devel/gettext
>=dev-util/pkgconfig-0.22
@@ -90,14 +90,6 @@ G2CONF="--enable-compile-warnings=maximum
--disable-jhbuild-wrapper-script"
src_prepare() {
- if use nm-applet; then
- # See https://bugzilla.gnome.org/show_bug.cgi?id=621707"
- ewarn "Adding support for the experimental NetworkManager applet."
- ewarn "This needs the latest NetworkManager & nm-applet trunk."
- ewarn "Report bugs about this to 'nirbheek' on #gentoo-desktop @ FreeNode."
- epatch "${FILESDIR}/${PN}-experimental-nm-applet-1.5.patch"
- fi
-
epatch "${FILESDIR}/${PN}-fix-gnome-bluetooth.patch"
gnome2_src_prepare
diff --git a/net-misc/networkmanager/files/networkmanager-0.8.996-fix-introspection.patch b/net-misc/networkmanager/files/networkmanager-0.8.996-fix-introspection.patch
new file mode 100644
index 0000000..0e488c3
--- /dev/null
+++ b/net-misc/networkmanager/files/networkmanager-0.8.996-fix-introspection.patch
@@ -0,0 +1,51 @@
+From 3ac6aa8008970b9cbafaa7a7134c9dc2f455d2f7 Mon Sep 17 00:00:00 2001
+From: Giovanni Campagna <gcampagna@src.gnome.org>
+Date: Tue, 15 Mar 2011 20:37:29 +0100
+Subject: [PATCH] include: mark flags as such
+
+If the /*< flags >*/ annotation is missing, enums are picked as
+enumerations, so bindings won't allow passing combinations of them.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=643011
+---
+ include/NetworkManager.h | 4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/include/NetworkManager.h b/include/NetworkManager.h
+index d8f29c5..d421aff 100644
+--- a/include/NetworkManager.h
++++ b/include/NetworkManager.h
+@@ -138,6 +138,7 @@ typedef enum {
+
+ /* 802.11 Access Point flags */
+ typedef enum {
++ /*< flags >*/
+ NM_802_11_AP_FLAGS_NONE = 0x00000000,
+ NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
+ } NM80211ApFlags;
+@@ -150,6 +151,7 @@ typedef enum {
+ * information elements.
+ */
+ typedef enum {
++ /*< flags >*/
+ NM_802_11_AP_SEC_NONE = 0x00000000,
+ NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001,
+ NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002,
+@@ -183,6 +185,7 @@ typedef enum {
+ * Bluetooth device.
+ */
+ typedef enum {
++ /*< flags >*/
+ NM_BT_CAPABILITY_NONE = 0x00000000,
+ NM_BT_CAPABILITY_DUN = 0x00000001,
+ NM_BT_CAPABILITY_NAP = 0x00000002,
+@@ -205,6 +208,7 @@ typedef enum {
+ * API.
+ */
+ typedef enum {
++ /*< flags >*/
+ NM_DEVICE_MODEM_CAPABILITY_NONE = 0x00000000,
+ NM_DEVICE_MODEM_CAPABILITY_POTS = 0x00000001,
+ NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO = 0x00000002,
+--
+1.7.4
\ No newline at end of file
diff --git a/net-misc/networkmanager/networkmanager-0.8.996.ebuild b/net-misc/networkmanager/networkmanager-0.8.996-r1.ebuild
similarity index 96%
rename from net-misc/networkmanager/networkmanager-0.8.996.ebuild
rename to net-misc/networkmanager/networkmanager-0.8.996-r1.ebuild
index a5a6587..f384197 100644
--- a/net-misc/networkmanager/networkmanager-0.8.996.ebuild
+++ b/net-misc/networkmanager/networkmanager-0.8.996-r1.ebuild
@@ -88,6 +88,10 @@ src_prepare() {
# disable tests
epatch "${FILESDIR}/${PN}-fix-tests.patch"
+ # https://bugzilla.gnome.org/show_bug.cgi?id=643011
+ # Merged upstream, not needed for next release
+ epatch "${FILESDIR}/${P}-fix-introspection.patch"
+
EPATCH_SOURCE="${WORKDIR}/ifnet-0.9" EPATCH_SUFFIX="diff" EPATCH_FORCE="yes" epatch
eautoreconf
default
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/gnome:master commit in: gnome-base/gnome-shell/, net-misc/networkmanager/, ...
@ 2011-02-22 2:57 Nirbheek Chauhan
0 siblings, 0 replies; 4+ messages in thread
From: Nirbheek Chauhan @ 2011-02-22 2:57 UTC (permalink / raw
To: gentoo-commits
commit: 6b8f3033e43c505b73270f90b7248b82e6aa38d0
Author: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 22 01:11:42 2011 +0000
Commit: Nirbheek Chauhan <nirbheek <AT> gentoo <DOT> org>
CommitDate: Tue Feb 22 01:13:59 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/gnome.git;a=commit;h=6b8f3033
gnome-base/gnome-shell, net-misc/networkmanager: update live ebuild
* Patches were pushed to trunk
---
...ch => gnome-shell-experimental-nm-applet.patch} | 0
.../gnome-shell/files/gnome-shell-nm-1.patch | 124 ------------
.../gnome-shell/files/gnome-shell-nm-2.patch | 165 ----------------
gnome-base/gnome-shell/gnome-shell-9999.ebuild | 4 +-
.../files/networkmanager-introspection-fixes.patch | 206 --------------------
net-misc/networkmanager/networkmanager-9999.ebuild | 3 -
6 files changed, 1 insertions(+), 501 deletions(-)
diff --git a/gnome-base/gnome-shell/files/gnome-shell-nm-3.patch b/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.patch
similarity index 100%
rename from gnome-base/gnome-shell/files/gnome-shell-nm-3.patch
rename to gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.patch
diff --git a/gnome-base/gnome-shell/files/gnome-shell-nm-1.patch b/gnome-base/gnome-shell/files/gnome-shell-nm-1.patch
deleted file mode 100644
index 4a7580d..0000000
--- a/gnome-base/gnome-shell/files/gnome-shell-nm-1.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 25884b4b480c18dae05f45e6739241d3e11cd12f Mon Sep 17 00:00:00 2001
-From: Giovanni Campagna <gcampagna@src.gnome.org>
-Date: Tue, 25 Jan 2011 22:06:40 +0100
-Subject: [PATCH] PopupMenu: make parameters overridable in items
-
-Make all subclasses of PopupMenuBase accept a params argument, which
-can be used to make the item non reactive, not responsive to hover
-and, as a new feature, with a different style class.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=621707
----
- data/theme/gnome-shell.css | 4 ++++
- js/ui/popupMenu.js | 28 +++++++++++++++++++---------
- js/ui/statusMenu.js | 4 ++--
- 3 files changed, 25 insertions(+), 11 deletions(-)
-
-diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
-index ba931ad..7bf17d4 100644
---- a/data/theme/gnome-shell.css
-+++ b/data/theme/gnome-shell.css
-@@ -178,6 +178,10 @@ StTooltip StLabel {
- background-image: url("toggle-on-intl.svg");
- }
-
-+.popup-inactive-menu-item {
-+ font-style: italic;
-+}
-+
- /* Panel */
-
- #panel {
-diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js
-index 30f353e..4e88a2a 100644
---- a/js/ui/popupMenu.js
-+++ b/js/ui/popupMenu.js
-@@ -55,7 +55,9 @@ PopupBaseMenuItem.prototype = {
- _init: function (params) {
- params = Params.parse (params, { reactive: true,
- activate: true,
-- hover: true });
-+ hover: true,
-+ style_class: null
-+ });
- this.actor = new Shell.GenericContainer({ style_class: 'popup-menu-item',
- reactive: params.reactive,
- track_hover: params.reactive,
-@@ -72,6 +74,9 @@ PopupBaseMenuItem.prototype = {
- this._spacing = 0;
- this.active = false;
-
-+ if (params.style_class)
-+ this.actor.add_style_class_name(params.style_class);
-+
- if (params.reactive && params.activate) {
- this.actor.connect('button-release-event', Lang.bind(this, this._onButtonReleaseEvent));
- this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
-@@ -533,8 +538,8 @@ function PopupSwitchMenuItem() {
- PopupSwitchMenuItem.prototype = {
- __proto__: PopupBaseMenuItem.prototype,
-
-- _init: function(text, active) {
-- PopupBaseMenuItem.prototype._init.call(this);
-+ _init: function(text, active, params) {
-+ PopupBaseMenuItem.prototype._init.call(this, params);
-
- this.label = new St.Label({ text: text });
- this._switch = new Switch(active);
-@@ -562,15 +567,15 @@ PopupSwitchMenuItem.prototype = {
- }
-
-
--function PopupImageMenuItem(text, iconName) {
-- this._init(text, iconName);
-+function PopupImageMenuItem() {
-+ this._init.apply(this, arguments);
- }
-
- PopupImageMenuItem.prototype = {
- __proto__: PopupBaseMenuItem.prototype,
-
-- _init: function (text, iconName) {
-- PopupBaseMenuItem.prototype._init.call(this);
-+ _init: function (text, iconName, params) {
-+ PopupBaseMenuItem.prototype._init.call(this, params);
-
- this.label = new St.Label({ text: text });
- this.addActor(this.label);
-@@ -615,8 +620,13 @@ PopupMenuBase.prototype = {
- _init: function(sourceActor, styleClass) {
- this.sourceActor = sourceActor;
-
-- this.box = new St.BoxLayout({ style_class: styleClass,
-- vertical: true });
-+ // GJS bug: it complains when an optional property is undefined
-+ if (styleClass !== undefined) {
-+ this.box = new St.BoxLayout({ style_class: styleClass,
-+ vertical: true });
-+ } else {
-+ this.box = new St.BoxLayout({ vertical: true });
-+ }
-
- this.isOpen = false;
- this._activeMenuItem = null;
-diff --git a/js/ui/statusMenu.js b/js/ui/statusMenu.js
-index f834aad..9ca5692 100644
---- a/js/ui/statusMenu.js
-+++ b/js/ui/statusMenu.js
-@@ -99,12 +99,12 @@ StatusMenuButton.prototype = {
- _createSubMenu: function() {
- let item;
-
-- item = new PopupMenu.PopupImageMenuItem(_("Available"), 'user-available', true);
-+ item = new PopupMenu.PopupImageMenuItem(_("Available"), 'user-available');
- item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.AVAILABLE));
- this.menu.addMenuItem(item);
- this._presenceItems[GnomeSession.PresenceStatus.AVAILABLE] = item;
-
-- item = new PopupMenu.PopupImageMenuItem(_("Busy"), 'user-busy', true);
-+ item = new PopupMenu.PopupImageMenuItem(_("Busy"), 'user-busy');
- item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.BUSY));
- this.menu.addMenuItem(item);
- this._presenceItems[GnomeSession.PresenceStatus.BUSY] = item;
---
-1.7.3.5
\ No newline at end of file
diff --git a/gnome-base/gnome-shell/files/gnome-shell-nm-2.patch b/gnome-base/gnome-shell/files/gnome-shell-nm-2.patch
deleted file mode 100644
index e711763..0000000
--- a/gnome-base/gnome-shell/files/gnome-shell-nm-2.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From fa144c1aa5126097f28d54b91edf488b74b68f79 Mon Sep 17 00:00:00 2001
-From: Giovanni Campagna <gcampagna@src.gnome.org>
-Date: Tue, 25 Jan 2011 22:04:57 +0100
-Subject: [PATCH] PopupMenu: introduce PopupMenuSection
-
-Complex popup menus require the ability to manager sequences of items
-as "sections", to which you can add and and remove items, as well
-as hide and show.
-PopupMenuSection does exactly that, leveraging the existing machinery
-for submenus, but without being exposed as a submenu to the user.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=621707
----
- js/ui/popupMenu.js | 115 +++++++++++++++++++++++++++++++++++++---------------
- 1 files changed, 82 insertions(+), 33 deletions(-)
-
-diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js
-index 4e88a2a..8615c87 100644
---- a/js/ui/popupMenu.js
-+++ b/js/ui/popupMenu.js
-@@ -640,38 +640,20 @@ PopupMenuBase.prototype = {
- }));
- },
-
-- addMenuItem: function(menuItem, position) {
-- let before_item = null;
-- if (position == undefined) {
-- this.box.add(menuItem.actor);
-- } else {
-- let items = this.getMenuItems();
-- if (position < items.length) {
-- before_item = items[position].actor;
-- this.box.insert_before(menuItem.actor, before_item);
-- } else
-- this.box.add(menuItem.actor);
-- }
-- if (menuItem instanceof PopupSubMenuMenuItem) {
-- if (before_item == null)
-- this.box.add(menuItem.menu.actor);
-- else
-- this.box.insert_before(menuItem.menu.actor, before_item);
-- menuItem._subMenuActivateId = menuItem.menu.connect('activate', Lang.bind(this, function() {
-- this.emit('activate');
-- this.close(true);
-- }));
-- menuItem._subMenuActiveChangeId = menuItem.menu.connect('active-changed', Lang.bind(this, function(submenu, submenuItem) {
-- if (this._activeMenuItem && this._activeMenuItem != submenuItem)
-- this._activeMenuItem.setActive(false);
-- this._activeMenuItem = submenuItem;
-- this.emit('active-changed', submenuItem);
-- }));
-- menuItem._closingId = this.connect('open-state-changed', function(self, open) {
-- if (!open)
-- menuItem.menu.close(false);
-- });
-- }
-+ _connectSubMenuSignals: function(object, menu) {
-+ object._subMenuActivateId = menu.connect('activate', Lang.bind(this, function() {
-+ this.emit('activate');
-+ this.close(true);
-+ }));
-+ object._subMenuActiveChangeId = menu.connect('active-changed', Lang.bind(this, function(submenu, submenuItem) {
-+ if (this._activeMenuItem && this._activeMenuItem != submenuItem)
-+ this._activeMenuItem.setActive(false);
-+ this._activeMenuItem = submenuItem;
-+ this.emit('active-changed', submenuItem);
-+ }));
-+ },
-+
-+ _connectItemSignals: function(menuItem) {
- menuItem._activeChangeId = menuItem.connect('active-changed', Lang.bind(this, function (menuItem, active) {
- if (active && this._activeMenuItem != menuItem) {
- if (this._activeMenuItem)
-@@ -700,6 +682,41 @@ PopupMenuBase.prototype = {
- }));
- },
-
-+ addMenuItem: function(menuItem, position) {
-+ let before_item = null;
-+ if (position == undefined) {
-+ this.box.add(menuItem.actor);
-+ } else {
-+ let items = this.getMenuItems();
-+ if (position < items.length) {
-+ before_item = items[position].actor;
-+ this.box.insert_before(menuItem.actor, before_item);
-+ } else
-+ this.box.add(menuItem.actor);
-+ }
-+ if (menuItem instanceof PopupMenuSection) {
-+ this._connectSubMenuSignals(menuItem, menuItem);
-+ menuItem.connect('destroy', Lang.bind(this, function() {
-+ menuItem.disconnect(menuItem._subMenuActivateId);
-+ menuItem.disconnect(menuItem._subMenuActiveChangeId);
-+ }));
-+ } else if (menuItem instanceof PopupSubMenuMenuItem) {
-+ if (before_item == null)
-+ this.box.add(menuItem.menu.actor);
-+ else
-+ this.box.insert_before(menuItem.menu.actor, before_item);
-+ this._connectSubMenuSignals(menuItem, menuItem.menu);
-+ this._connectItemSignals(menuItem);
-+ menuItem._closingId = this.connect('open-state-changed', function(self, open) {
-+ if (!open)
-+ menuItem.menu.close(false);
-+ });
-+ } else if (menuItem instanceof PopupBaseMenuItem)
-+ this._connectItemSignals(menuItem);
-+ else
-+ throw TypeError("Invalid argument to PopupMenuBase.addMenuItem()");
-+ },
-+
- getColumnWidths: function() {
- let columnWidths = [];
- let items = this.box.get_children();
-@@ -728,7 +745,11 @@ PopupMenuBase.prototype = {
- },
-
- getMenuItems: function() {
-- return this.box.get_children().map(function (actor) { return actor._delegate; }).filter(function(item) { return item instanceof PopupBaseMenuItem; });
-+ return this.box.get_children().map(function (actor) {
-+ return actor._delegate;
-+ }).filter(function(item) {
-+ return item instanceof PopupBaseMenuItem || item instanceof PopupMenuSection;
-+ });
- },
-
- removeAll: function() {
-@@ -943,6 +964,34 @@ PopupSubMenu.prototype = {
- }
- };
-
-+/**
-+ * PopupMenuSection:
-+ *
-+ * A section of a PopupMenu which is handled like a submenu
-+ * (you can add and remove items, you can destroy it, you
-+ * can add it to another menu), but is completely transparent
-+ * to the user
-+ */
-+function PopupMenuSection() {
-+ this._init.apply(this, arguments);
-+}
-+
-+PopupMenuSection.prototype = {
-+ __proto__: PopupMenuBase.prototype,
-+
-+ _init: function() {
-+ PopupMenuBase.prototype._init.call(this);
-+
-+ this.actor = this.box;
-+ this.actor._delegate = this;
-+ this.isOpen = true;
-+ },
-+
-+ // deliberately ignore any attempt to open() or close()
-+ open: function(animate) { },
-+ close: function() { },
-+}
-+
- function PopupSubMenuMenuItem() {
- this._init.apply(this, arguments);
- }
---
-1.7.3.5
\ No newline at end of file
diff --git a/gnome-base/gnome-shell/gnome-shell-9999.ebuild b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
index 82a86b4..c90dc8e 100644
--- a/gnome-base/gnome-shell/gnome-shell-9999.ebuild
+++ b/gnome-base/gnome-shell/gnome-shell-9999.ebuild
@@ -85,9 +85,7 @@ src_prepare() {
ewarn "Adding support for the experimental NetworkManager applet."
ewarn "This needs the latest NetworkManager & nm-applet trunk."
ewarn "Report bugs about this to 'nirbheek' on #gentoo-desktop @ FreeNode."
- epatch "${FILESDIR}/${PN}-nm-1.patch"
- epatch "${FILESDIR}/${PN}-nm-2.patch"
- epatch "${FILESDIR}/${PN}-nm-3.patch"
+ epatch "${FILESDIR}/${PN}-experimental-nm-applet.patch"
fi
gnome2_src_prepare
diff --git a/net-misc/networkmanager/files/networkmanager-introspection-fixes.patch b/net-misc/networkmanager/files/networkmanager-introspection-fixes.patch
deleted file mode 100644
index 2c5befc..0000000
--- a/net-misc/networkmanager/files/networkmanager-introspection-fixes.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From dbd3c269d04413deb79a72f688af77ea299d2205 Mon Sep 17 00:00:00 2001
-From: Giovanni Campagna <gcampagna@src.gnome.org>
-Date: Sat, 11 Dec 2010 18:05:30 +0100
-Subject: [PATCH] More GObjectIntrospection fixes
-
-Fix some annotations and add the necessary ones for new functions.
-
-https://bugzilla.gnome.org/show_bug.cgi?id=637032
----
- libnm-glib/nm-client.c | 5 +++--
- libnm-glib/nm-dhcp4-config.c | 2 ++
- libnm-glib/nm-dhcp6-config.c | 2 ++
- libnm-glib/nm-remote-connection.c | 9 +++++++++
- libnm-glib/nm-secret-agent.c | 37 +++++++++++++++++++++++++++++++++++++
- libnm-util/nm-connection.c | 17 +++++++++--------
- libnm-util/nm-setting-vpn.h | 2 --
- 7 files changed, 62 insertions(+), 12 deletions(-)
-
-diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c
-index 4e725cf..bab86a9 100644
---- a/libnm-glib/nm-client.c
-+++ b/libnm-glib/nm-client.c
-@@ -1152,8 +1152,9 @@ activate_cb (DBusGProxy *proxy,
- * @client: a #NMClient
- * @connection_path: the connection's DBus path
- * @device: the #NMDevice
-- * @specific_object: the device specific object (currently used only for
-- * activating wireless devices and should be the #NMAccessPoint<!-- -->'s path.
-+ * @specific_object: (allow-none): the device specific object (currently
-+ * used only for activating wireless devices and should be the
-+ * #NMAccessPoint<!-- -->'s path).
- * @callback: (scope async): the function to call when the call is done
- * @user_data: user data to pass to the callback function
- *
-diff --git a/libnm-glib/nm-dhcp4-config.c b/libnm-glib/nm-dhcp4-config.c
-index d17578a..31dfe25 100644
---- a/libnm-glib/nm-dhcp4-config.c
-+++ b/libnm-glib/nm-dhcp4-config.c
-@@ -169,6 +169,8 @@ nm_dhcp4_config_class_init (NMDHCP4ConfigClass *config_class)
- * NMDHCP4Config:options:
- *
- * The #GHashTable containing options of the configuration.
-+ *
-+ * Type: GHashTable<utf8,GValue>
- **/
- g_object_class_install_property
- (object_class, PROP_OPTIONS,
-diff --git a/libnm-glib/nm-dhcp6-config.c b/libnm-glib/nm-dhcp6-config.c
-index 8b85595..7e6e4f8 100644
---- a/libnm-glib/nm-dhcp6-config.c
-+++ b/libnm-glib/nm-dhcp6-config.c
-@@ -169,6 +169,8 @@ nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class)
- * NMDHCP6Config:options:
- *
- * The #GHashTable containing options of the configuration.
-+ *
-+ * Type: GHashTable<utf8,GValue>
- **/
- g_object_class_install_property
- (object_class, PROP_OPTIONS,
-diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c
-index 09c7112..1869a3a 100644
---- a/libnm-glib/nm-remote-connection.c
-+++ b/libnm-glib/nm-remote-connection.c
-@@ -480,6 +480,15 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
- G_PARAM_READABLE));
-
- /* Signals */
-+ /**
-+ * NMRemoteConnection::updated:
-+ * @connection: a #NMConnection
-+ * @new_settings: (type GHashTable<utf8,GHashTable<utf8,GValue>>):
-+ * the updated settings
-+ *
-+ * This signal is emitted when a connection changes, and it is
-+ * still visible to the user.
-+ */
- signals[UPDATED] =
- g_signal_new (NM_REMOTE_CONNECTION_UPDATED,
- G_TYPE_FROM_CLASS (remote_class),
-diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c
-index 72431e2..9cc2440 100644
---- a/libnm-glib/nm-secret-agent.c
-+++ b/libnm-glib/nm-secret-agent.c
-@@ -567,6 +567,20 @@ auto_register_cb (gpointer user_data)
-
- /**************************************************************/
-
-+/**
-+ * nm_secret_agent_get_secrets:
-+ * @self: a #NMSecretAgent
-+ * @connection: the #NMConnection for which we're asked secrets
-+ * @setting_name: the name of the secret setting
-+ * @hints: (array zero-terminated=1): hints to the agent
-+ * @flags:
-+ * @callback: (scope async): a callback, invoked when the operation is done
-+ * @callback_data: (closure):
-+ *
-+ * Asyncronously retrieve @setting_name from @connection
-+ *
-+ * VFunc: get_secrets
-+ */
- void
- nm_secret_agent_get_secrets (NMSecretAgent *self,
- NMConnection *connection,
-@@ -595,6 +609,18 @@ nm_secret_agent_get_secrets (NMSecretAgent *self,
- callback_data);
- }
-
-+/**
-+ * nm_secret_agent_save_secrets:
-+ * @self: a #NMSecretAgent
-+ * @connection: a #NMConnection
-+ * @callback: (scope async): a callback, invoked when the operation is done
-+ * @callback_data: (closure):
-+ *
-+ * Asyncronously ensure that all secrets inside @connection
-+ * are stored to disk.
-+ *
-+ * VFunc: save_secrets
-+ */
- void
- nm_secret_agent_save_secrets (NMSecretAgent *self,
- NMConnection *connection,
-@@ -614,6 +640,17 @@ nm_secret_agent_save_secrets (NMSecretAgent *self,
- callback_data);
- }
-
-+/**
-+ * nm_secret_agent_delete_secrets:
-+ * @self: a #NMSecretAgent
-+ * @connection: a #NMConnection
-+ * @callback: (scope async): a callback, invoked when the operation is done
-+ * @callback_data: (closure):
-+ *
-+ * Asyncronously remove all secret settings from @connection
-+ *
-+ * VFunc: delete_secrets
-+ */
- void
- nm_secret_agent_delete_secrets (NMSecretAgent *self,
- NMConnection *connection,
-diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
-index ec33907..aef1cc0 100644
---- a/libnm-util/nm-connection.c
-+++ b/libnm-util/nm-connection.c
-@@ -493,7 +493,7 @@ validate_permissions_type (GHashTable *hash, GError **error)
- /**
- * nm_connection_replace_settings:
- * @connection: a #NMConnection
-- * @new_settings: (element-type utf8 GLib.HashTable): a #GHashTable of settings
-+ * @new_settings: (element-type utf8 GHashTable<utf8,GValue>): a #GHashTable of settings
- * @error: location to store error, or %NULL
- *
- * Returns: %TRUE if the settings were valid and added to the connection, %FALSE
-@@ -728,11 +728,12 @@ add_setting_to_list (gpointer key, gpointer data, gpointer user_data)
- /**
- * nm_connection_need_secrets:
- * @connection: the #NMConnection
-- * @hints: the address of a pointer to a #GPtrArray, initialized to NULL, which
-- * on return points to an allocated #GPtrArray containing the property names of
-- * secrets of the #NMSetting which may be required; the caller owns the array
-- * and must free the each array element with g_free(), as well as the array
-- * itself with g_ptr_array_free()
-+ * @hints: (out callee-allocates) (element-type utf8) (allow-none) (transfer full):
-+ * the address of a pointer to a #GPtrArray, initialized to NULL, which on
-+ * return points to an allocated #GPtrArray containing the property names of
-+ * secrets of the #NMSetting which may be required; the caller owns the array
-+ * and must free the each array element with g_free(), as well as the array
-+ * itself with g_ptr_array_free()
- *
- * Returns the name of the first setting object in the connection which would
- * need secrets to make a successful connection. The returned hints are only
-@@ -741,7 +742,7 @@ add_setting_to_list (gpointer key, gpointer data, gpointer user_data)
- * secrets are needed.
- *
- * Returns: the setting name of the #NMSetting object which has invalid or
-- * missing secrets
-+ * missing secrets
- **/
- const char *
- nm_connection_need_secrets (NMConnection *connection,
-@@ -821,7 +822,7 @@ nm_connection_clear_secrets (NMConnection *connection)
- * are #GHashTables mapping string:GValue, each of which represents the
- * properties of the #NMSetting object.
- *
-- * Returns: (transfer full) (element-type utf8 GLib.HashTable): a new
-+ * Returns: (transfer full) (element-type utf8 GHashTable<utf8,GValue>): a new
- * #GHashTable describing the connection, its settings, and each setting's
- * properties. The caller owns the hash table and must unref the hash table
- * with g_hash_table_unref() when it is no longer needed.
-diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h
-index bb20356..6ff1928 100644
---- a/libnm-util/nm-setting-vpn.h
-+++ b/libnm-util/nm-setting-vpn.h
-@@ -72,8 +72,6 @@ typedef struct {
- } NMSettingVPNClass;
-
- typedef void (*NMVPNIterFunc) (const char *key, const char *value, gpointer user_data);
--/* For backward compatibility */
--typedef NMVPNIterFunc VPNIterFunc;
-
- GType nm_setting_vpn_get_type (void);
-
---
-1.7.4
\ No newline at end of file
diff --git a/net-misc/networkmanager/networkmanager-9999.ebuild b/net-misc/networkmanager/networkmanager-9999.ebuild
index f0f5095..d4bbdd6 100644
--- a/net-misc/networkmanager/networkmanager-9999.ebuild
+++ b/net-misc/networkmanager/networkmanager-9999.ebuild
@@ -133,9 +133,6 @@ src_prepare() {
# FIXME: does not apply
#epatch "${FILESDIR}/${PN}-0.8.2-shared-connection.patch"
- # https://bugzilla.gnome.org/show_bug.cgi?id=637032
- epatch "${FILESDIR}/${PN}-introspection-fixes.patch"
-
gnome2_src_prepare
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-04-05 1:03 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-23 14:40 [gentoo-commits] proj/gnome:master commit in: gnome-base/gnome-shell/, net-misc/networkmanager/, Nirbheek Chauhan
-- strict thread matches above, loose matches on Subject: below --
2011-04-05 0:57 Nirbheek Chauhan
2011-03-16 20:20 Nirbheek Chauhan
2011-02-22 2:57 Nirbheek Chauhan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox