Logo Search packages:      
Sourcecode: cairo-dock-plugins version File versions  Download package

applet-menu.c

/**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail    : see the 'copyright' file.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#define _BSD_SOURCE

#include <unistd.h>
#include <string.h>

#include "applet-struct.h"
#include "applet-connections.h"
#include "applet-menu.h"

static GList *cd_NetworkMonitor_get_connections_for_access_point (const gchar *cAccessPoint, const gchar *cDevice, const gchar *cSsid, const gchar *cHwAddress, int iMode, int iWirelessCapabilities, GPtrArray *paConnections, GPtrArray *paSettings)
{
      GList *pConnList = NULL;
      gchar *cConnection;
      GHashTable *pSettings, *pSubSettings;
      GValue *v;
      int i;
      for (i = 0; i < paConnections->len; i++)
      {
            cConnection = (gchar *)g_ptr_array_index(paConnections, i);
            g_print (" Connection path : %s\n", cConnection);
            
            pSettings = g_ptr_array_index (paSettings, i);
            
            pSubSettings = g_hash_table_lookup (pSettings, "connection");
            if (pSubSettings == NULL)
                  continue;
            
            const gchar *cType = NULL;
            v = g_hash_table_lookup (pSubSettings, "type");
            if (v && G_VALUE_HOLDS_STRING (v))
            {
                  cType = g_value_get_string (v);
                  g_print (" type : %s\n", cType);
            }
            if (cType == NULL || strcmp (cType, "802-11-wireless") != 0)  // on veut du wifi.
                  continue;
            
            const gchar *cID = NULL;
            v = g_hash_table_lookup (pSubSettings, "id");
            if (v && G_VALUE_HOLDS_STRING (v))
            {
                  cID = g_value_get_string (v);
                  g_print (" id : %s\n", cID);
            }
            
            pSubSettings = g_hash_table_lookup (pSettings, "802-11-wireless");
            if (pSubSettings == NULL)
                  continue;
            const gchar *cMode = NULL;
            v = g_hash_table_lookup (pSubSettings, "mode");
            if (v && G_VALUE_HOLDS_STRING (v))
            {
                  cMode = g_value_get_string (v);
                  g_print (" mode : %s\n", cMode);
            }
            if (iMode && cMode)
            {
                  if (iMode == 1 && strcmp (cMode, "ad-hoc") != 0)
                        continue;
                  if (iMode == 2 && strcmp (cMode, "infrastructure") != 0)
                        continue;
            }
            
            gchar *cAPSsid = NULL;
            v = g_hash_table_lookup (pSubSettings, "ssid");
            if (v && G_VALUE_HOLDS_BOXED (v))
            {
                  GByteArray *a = g_value_get_boxed (v);
                  cAPSsid = g_strndup (a->data, a->len);
                  g_print (" ssid : %s\n", cSsid);
            }
            if (cSsid == NULL || (cAPSsid != NULL && strcmp (cAPSsid, cSsid) != 0))  // le SSID est necessaire.
                  continue;
            
            const gchar *cMacAddress = NULL;
            v = g_hash_table_lookup (pSubSettings, "mac-address");
            if (v && G_VALUE_HOLDS_STRING (v))
            {
                  cMacAddress = g_value_get_string (v);
                  g_print (" mac address : %s\n", cMacAddress);
            }
            if (cHwAddress != NULL && cMacAddress != NULL && strcmp (cMacAddress, cHwAddress) != 0)
                  continue;
            
            pSubSettings = g_hash_table_lookup (pSettings, "802-11-wireless-security");
            if (pSubSettings)
            {
                  /// on verra plus tard ...
                  
            }
            
            pConnList = g_list_prepend (pConnList, GINT_TO_POINTER (i));
      }
      
      return pConnList;
}

static GList *cd_NetworkMonitor_get_connections_for_wired_device (const gchar *cDevice, const gchar *cHwAddress, GPtrArray *paConnections)
{
      GList *pConnList = NULL;
      //\_____________ On cherche une connection qui ait le meme type (wifi ou filaire), et soit le meme SSID, soit la meme interface.
      gchar *cConnection;
      int i;
      for (i = 0; i < paConnections->len; i++)
      {
            cConnection = (gchar *)g_ptr_array_index(paConnections, i);
            g_print (" Connection path : %s\n", cConnection);
            
      }
      
      return pConnList;
}


static void _on_select_access_point (GtkMenuItem *menu_item, CDMenuItemData *pItemData)
{
      if (pItemData == NULL || pItemData->cConnection == NULL)
      {
            /// il faut creer une connection ...
            g_print ("aucune des connexions existantes ne convient pour ce point d'acces\n");
            
            GHashTable *pSettings = g_hash_table_new_full (g_str_hash,
                  g_str_equal,
                  g_free,
                  g_hash_table_destroy);
            
            GHashTable *pSubSettings = g_hash_table_new_full (g_str_hash,
                  g_str_equal,
                  g_free,
                  g_free);
            g_hash_table_insert (pSettings, "connection", pSubSettings);
            g_hash_table_insert (pSubSettings, "type", g_strdup ("802-11-wireless"));
            g_hash_table_insert (pSettings, "id", g_strdup_printf ("CD - %s", pItemData->cSsid));
            
            pSubSettings = g_hash_table_new_full (g_str_hash,
                  g_str_equal,
                  g_free,
                  g_free);
            g_hash_table_insert (pSubSettings, "ssid", g_strdup (pItemData->cSsid));
            g_hash_table_insert (pSubSettings, "mode", g_strdup ("infrastructure"));
            
            // AddConnection
            DBusGProxy *dbus_proxy_Settings = cairo_dock_create_new_system_proxy (
                  myData.cServiceName,
                  "/org/freedesktop/NetworkManagerSettings",
                  "org.freedesktop.NetworkManagerSettings");
            
            GError *erreur = NULL;
            dbus_g_proxy_call (dbus_proxy_Settings, "AddConnection", &erreur,
                  CD_DBUS_TYPE_HASH_TABLE_OF_HASH_TABLE, pSettings,
                  G_TYPE_INVALID,
                  G_TYPE_INVALID);
            if (erreur != NULL)
            {
                  cd_warning (erreur->message);
                  g_error_free (erreur);
                  return ;
            }
            
            /// on attend le signal NewConnection ...
            
            
            
            /// on active la connexion...
            
            
            
      }
      else
      {
            g_print ("on a choisit (%s; %s; %s)\n", pItemData->cAccessPoint, pItemData->cDevice, pItemData->cConnection);
            
            //ActivateConnection ( s: service_name, o: connection, o: device, o: specific_object )o
            GError *erreur = NULL;
            GValue active_connection_path = {0};
            g_value_init (&active_connection_path, DBUS_TYPE_G_OBJECT_PATH);
            
            gchar *cNewActiveConnectionPath = NULL;
            dbus_g_proxy_call (myData.dbus_proxy_NM, "ActivateConnection", &erreur,
                  G_TYPE_STRING, myData.cServiceName,
                  DBUS_TYPE_G_OBJECT_PATH, pItemData->cConnection,
                  DBUS_TYPE_G_OBJECT_PATH, pItemData->cDevice,
                  DBUS_TYPE_G_OBJECT_PATH, pItemData->cAccessPoint,
                  G_TYPE_INVALID,
                  DBUS_TYPE_G_OBJECT_PATH, &cNewActiveConnectionPath,
                  G_TYPE_INVALID);
            if (erreur != NULL)
            {
                  cd_warning (erreur->message);
                  g_error_free (erreur);
                  return ;
            }
            g_print (" => new active connection path : %s\n", cNewActiveConnectionPath);
      }
}

GtkWidget * cd_NetworkMonitor_build_menu_with_access_points (void)
{
      //\_____________ On recupere les connections existantes, ainsi que leur settings.
      DBusGProxy *dbus_proxy_Settings = cairo_dock_create_new_system_proxy (
            myData.cServiceName,
            "/org/freedesktop/NetworkManagerSettings",
            "org.freedesktop.NetworkManagerSettings");
      GPtrArray *paConnections = cairo_dock_dbus_get_array (dbus_proxy_Settings, "ListConnections");
      g_print ("%d connection(s)\n", paConnections ? paConnections->len : 0);
      g_object_unref (dbus_proxy_Settings);
      
      GPtrArray *paSettings = NULL;
      gchar *cConnection;
      if (paConnections != NULL && paConnections->len > 0)
      {
            paSettings = g_ptr_array_sized_new (paConnections->len);
            g_ptr_array_set_size (paSettings, paConnections->len);
            DBusGProxy *dbus_proxy_ConnectionSettings;
            GError *erreur = NULL;
            GHashTable *pSettingsTable;
            int i;
            for (i = 0; i < paConnections->len; i++)
            {
                  cConnection = (gchar *)g_ptr_array_index(paConnections, i);
                  g_print (" Connection path : %s\n", cConnection);
                  
                  dbus_proxy_ConnectionSettings = cairo_dock_create_new_system_proxy (
                        "org.freedesktop.NetworkManagerUserSettings",
                        cConnection,
                        "org.freedesktop.NetworkManagerSettings.Connection");
                  erreur = NULL;
                  pSettingsTable = NULL;
                  dbus_g_proxy_call (dbus_proxy_ConnectionSettings, "GetSettings", &erreur,
                        G_TYPE_INVALID,
                        CD_DBUS_TYPE_HASH_TABLE_OF_HASH_TABLE, &pSettingsTable,
                        G_TYPE_INVALID);
                  if (erreur != NULL)
                  {
                        cd_warning (erreur->message);
                        g_error_free (erreur);
                        erreur = NULL;
                  }
                  paSettings->pdata[i] = pSettingsTable;
                  
                  g_object_unref (dbus_proxy_ConnectionSettings);
            }
      }
      
      //\_____________ On recupere la liste des devices.
      GPtrArray *paDevices = cairo_dock_dbus_get_array (myData.dbus_proxy_NM, "GetDevices");
      g_return_val_if_fail (paDevices != NULL, FALSE);
      g_print ("%d device(s)\n", paDevices->len);
      
      GtkWidget *pMenu = gtk_menu_new ();
      
      //\_____________ On parcourt tous les devices.
      GHashTable *pSsidTable = g_hash_table_new_full (g_str_hash,
            g_str_equal,
            g_free,
            NULL);
      gchar *cDevice;
      DBusGProxy *dbus_proxy_Device_prop;
      guint iDeviceType;
      DBusGProxy *dbus_proxy_WirelessDevice, *dbus_proxy_WiredDevice;
      DBusGProxy *dbus_proxy_AccessPoint_prop;
      gchar *cAccessPointPath;
      GHashTable *hProperties;
      GValue *v;
      guint iPercent;
      gchar *cSsid;
      const gchar *cHwAddress;
      int iMode, iWirelessCapabilities;
      CDMenuItemData *pItemData;
      GtkWidget *pHBox;
      int i, j;
      for (i = 0; i < paDevices->len; i++)
      {
            // on recupere le device.
            cDevice = (gchar *)g_ptr_array_index(paDevices, i);
            dbus_proxy_Device_prop = cairo_dock_create_new_system_proxy (
                  "org.freedesktop.NetworkManager",
                  cDevice,
                  "org.freedesktop.DBus.Properties");
            if (!DBUS_IS_G_PROXY (dbus_proxy_Device_prop))
                  continue;
            g_print (" device %s\n", cDevice);
            
            // on regarde son type.
            iDeviceType = cairo_dock_dbus_get_property_as_uint (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device", "DeviceType");  // 1 : ethernet, 2 : wifi
            g_print (" device type : %d\n", iDeviceType);
            if (iDeviceType != 1 && iDeviceType != 2)  // ne nous insteresse pas.
            {
                  g_print (" useless device type\n");
                  g_object_unref (dbus_proxy_Device_prop);
                  continue;
            }
            
            if (iDeviceType == 2)
            {
                  // On recupere ses proprietes.
                  hProperties = cairo_dock_dbus_get_all_properties (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device.Wireless");
                  
                  const gchar *cAccessPointHwAdress = NULL;
                  v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
                  if (v && G_VALUE_HOLDS_STRING (v))
                  {
                        cAccessPointHwAdress = g_value_get_string (v);
                  }
                  
                  int iMode = 0;
                  v = (GValue *)g_hash_table_lookup (hProperties, "Mode");
                  if (v && G_VALUE_HOLDS_UINT (v))
                  {
                        iMode = g_value_get_uint (v);
                  }
                  
                  int iWirelessCapabilities = 0;
                  v = (GValue *)g_hash_table_lookup (hProperties, "WirelessCapabilities");
                  if (v && G_VALUE_HOLDS_UINT (v))
                  {
                        iWirelessCapabilities = g_value_get_uint (v);
                  }
                  
                  // On recupere la liste des points d'acces.
                  dbus_proxy_WirelessDevice = cairo_dock_create_new_system_proxy (
                  "org.freedesktop.NetworkManager",
                        cDevice,
                        "org.freedesktop.NetworkManager.Device.Wireless");
                  GError *erreur = NULL;
                  GPtrArray *pAccessPoints = NULL;
                  dbus_g_proxy_call (dbus_proxy_WirelessDevice, "GetAccessPoints", &erreur,
                        G_TYPE_INVALID,
                        dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &pAccessPoints,
                        G_TYPE_INVALID);
                  g_object_unref (dbus_proxy_WirelessDevice);
                  if (erreur != NULL)
                  {
                        cd_warning (erreur->message);
                        g_error_free (erreur);
                        erreur = NULL;
                        g_object_unref (dbus_proxy_Device_prop);
                        continue;
                  }
                  if (!pAccessPoints || pAccessPoints->len == 0)
                  {
                        g_print ("  aucun point d'acces\n");
                        g_object_unref (dbus_proxy_Device_prop);
                        /// ajouter une entree pour dire si le wifi est desactive ...
                        
                        continue;
                  }
                  
                  // on insere chaque point d'acces dans le menu.
                  for (j = 0; j < pAccessPoints->len; j ++)
                  {
                        // on recupere le point d'acces.
                        cAccessPointPath = (gchar *)g_ptr_array_index (pAccessPoints, j);
                        dbus_proxy_AccessPoint_prop = cairo_dock_create_new_system_proxy (
                        "org.freedesktop.NetworkManager",
                              cAccessPointPath,
                              "org.freedesktop.DBus.Properties");
                        
                        // on recupere ses proprietes.
                        hProperties = cairo_dock_dbus_get_all_properties (dbus_proxy_AccessPoint_prop, "org.freedesktop.NetworkManager.AccessPoint");
                        if (hProperties == NULL)
                        {
                              g_object_unref (dbus_proxy_AccessPoint_prop);
                              continue;
                        }
                        
                        iPercent = 0;
                        v = (GValue *)g_hash_table_lookup (hProperties, "Strength");
                        if (v != NULL && G_VALUE_HOLDS_UCHAR (v))
                        {
                              iPercent = (gint) g_value_get_uchar (v);
                        }
                        
                        v = (GValue *)g_hash_table_lookup (hProperties, "Ssid");
                        if (v != NULL && G_VALUE_HOLDS_BOXED (v))
                        {
                              GByteArray *a = g_value_get_boxed (v);
                              cSsid = g_strndup (a->data, a->len);
                        }
                        
                        // on empeche les doublons.
                        pItemData = g_hash_table_lookup (pSsidTable, cSsid);
                        if (pItemData != NULL)
                        {
                              if (pItemData->iPercent > iPercent)
                              {
                                    g_free (cSsid);
                                    g_object_unref (dbus_proxy_AccessPoint_prop);
                              }
                              else
                              {
                                    g_free (pItemData->cAccessPoint);
                                    pItemData->cAccessPoint = g_strdup (cAccessPointPath);
                              }
                              continue;
                        }
                        
                        cHwAddress = NULL;
                        v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
                        if (v != NULL && G_VALUE_HOLDS_STRING (v))
                        {
                              cHwAddress = g_value_get_string (v);
                        }
                        
                        iMode = 0;
                        v = (GValue *)g_hash_table_lookup (hProperties, "Mode");
                        if (v != NULL && G_VALUE_HOLDS_UINT (v))
                        {
                              iMode = g_value_get_uint (v);
                        }
                        
                        iWirelessCapabilities = 0;
                        v = (GValue *)g_hash_table_lookup (hProperties, "WpaFlags");
                        if (v != NULL && G_VALUE_HOLDS_UINT (v))
                        {
                              iWirelessCapabilities = g_value_get_uint (v);
                        }
                        
                        g_print ("%d) %s : %s (%s, %d%%)\n", j, cSsid, cAccessPointPath, cHwAddress, iPercent);
                        
                        gchar *cImage = NULL;
                        if (iPercent > 80)
                              cImage = MY_APPLET_SHARE_DATA_DIR"/link-5.svg";
                        else if (iPercent > 60)
                              cImage = MY_APPLET_SHARE_DATA_DIR"/link-4.svg";
                        else if (iPercent > 40)
                              cImage = MY_APPLET_SHARE_DATA_DIR"/link-3.svg";
                        else if (iPercent > 20)
                              cImage = MY_APPLET_SHARE_DATA_DIR"/link-2.svg";
                        else if (iPercent > 0)
                              cImage = MY_APPLET_SHARE_DATA_DIR"/link-1.svg";
                        else
                              cImage = MY_APPLET_SHARE_DATA_DIR"/link-0.svg";
                        
                        /// recuperer les flags, wpa flags, et rsn flags -> encrypted.
                        /// et le mode -> ad_hoc
                        /// et mettre une icone asociee dans une hbox...
                        
                        // on cherche une connection qui convienne.
                        GList *pConnList = cd_NetworkMonitor_get_connections_for_access_point (cAccessPointPath, cDevice, cSsid, cHwAddress, iMode, iWirelessCapabilities, paConnections, paSettings);
                        
                        g_print ("%d connexion(s) satisfont a ce point d'acces\n", g_list_length (pConnList));
                        
                        if (pConnList == NULL || pConnList->next == NULL)
                        {
                              if (pItemData == NULL)
                              {
                                    pItemData = g_new0 (CDMenuItemData, 1);
                                    g_hash_table_insert (pSsidTable, g_strdup (cSsid), pItemData);
                              }
                              else
                              {
                                    g_free (pItemData->cAccessPoint);
                              }
                              pItemData->cDevice = g_strdup (cDevice);
                              pItemData->iPercent = iPercent;
                              pItemData->cAccessPoint = g_strdup (cAccessPointPath);
                              pItemData->cSsid = g_strdup (cSsid);
                              if (pConnList)
                              {
                                    int n = GPOINTER_TO_INT (pConnList->data);
                                    pItemData->cConnection = g_strdup (g_ptr_array_index (paConnections, n));
                              }
                              cairo_dock_add_in_menu_with_stock_and_data (cSsid, cImage, _on_select_access_point, pMenu, pItemData);
                        }
                        else
                        {
                              GtkWidget *pSubMenu = cairo_dock_create_sub_menu (cSsid, pMenu, cImage);
                              GList *c;
                              for (c = pConnList; c != NULL; c = c->next)
                              {
                                    int n = GPOINTER_TO_INT (c->data);
                                    GHashTable *h = g_ptr_array_index (paSettings, n);
                                    if (!h)
                                          continue;
                                    GHashTable *hh = g_hash_table_lookup (h, "connection");
                                    if (!hh)
                                          continue;
                                    v = g_hash_table_lookup (hh, "id");
                                    if (v && G_VALUE_HOLDS_STRING (v))
                                    {
                                          const gchar *cID = g_value_get_string (v);
                                          
                                          pItemData = g_new0 (CDMenuItemData, 1);
                                          pItemData->cConnection = g_strdup (g_ptr_array_index (paConnections, n));
                                          pItemData->cDevice = g_strdup (cDevice);
                                          pItemData->cAccessPoint = g_strdup (cAccessPointPath);
                                          
                                          cairo_dock_add_in_menu_with_stock_and_data (cID, NULL, _on_select_access_point, pSubMenu, GINT_TO_POINTER (n));
                                    }
                              }
                        }
                        g_list_free (pConnList);
                        
                        g_object_unref (dbus_proxy_AccessPoint_prop);
                  }
                  g_ptr_array_free (pAccessPoints, TRUE);
            }
            else
            {
                  /// si non connecte : ajouter une entree grisee.
                  
                  /// sinon ajouter une entree pour (des)activer ce device.
                  
            }
      }
      g_ptr_array_free (paDevices, TRUE);
      g_ptr_array_free (paConnections, TRUE);
      g_hash_table_destroy (pSsidTable);
      
      return pMenu;
}

Generated by  Doxygen 1.6.0   Back to index