Blame src/ap-menu-item.c

Packit Service d328f3
// SPDX-License-Identifier: GPL-2.0+
Packit Service d328f3
/* ap-menu-item.c - Class to represent a Wifi access point 
Packit Service d328f3
 *
Packit Service d328f3
 * Jonathan Blandford <jrb@redhat.com>
Packit Service d328f3
 * Dan Williams <dcbw@redhat.com>
Packit Service d328f3
 *
Packit Service d328f3
 * Copyright 2005 - 2014 Red Hat, Inc.
Packit Service d328f3
 */
Packit Service d328f3
Packit Service d328f3
#include "nm-default.h"
Packit Service d328f3
Packit Service d328f3
#include <stdio.h>
Packit Service d328f3
#include <string.h>
Packit Service d328f3
Packit Service d328f3
#include <NetworkManager.h>
Packit Service d328f3
Packit Service d328f3
#include "ap-menu-item.h"
Packit Service d328f3
#include "nm-access-point.h"
Packit Service d328f3
#include "mobile-helpers.h"
Packit Service d328f3
Packit Service d328f3
/* Only to get the NMU_SEC_SAE compat constant. */
Packit Service d328f3
#include "wireless-security.h"
Packit Service d328f3
Packit Service d328f3
G_DEFINE_TYPE (NMNetworkMenuItem, nm_network_menu_item, GTK_TYPE_MENU_ITEM);
Packit Service d328f3
Packit Service d328f3
#define NM_NETWORK_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_NETWORK_MENU_ITEM, NMNetworkMenuItemPrivate))
Packit Service d328f3
Packit Service d328f3
typedef struct {
Packit Service d328f3
	GtkWidget * ssid;
Packit Service d328f3
	GtkWidget * strength;
Packit Service d328f3
	GtkWidget * hbox;
Packit Service d328f3
Packit Service d328f3
	char *      ssid_string;
Packit Service d328f3
	guint32     int_strength;
Packit Service d328f3
	gchar *     hash;
Packit Service d328f3
	GSList *    dupes;
Packit Service d328f3
	gboolean    has_connections;
Packit Service d328f3
	gboolean    is_adhoc;
Packit Service d328f3
	gboolean    is_encrypted;
Packit Service d328f3
} NMNetworkMenuItemPrivate;
Packit Service d328f3
Packit Service d328f3
/******************************************************************/
Packit Service d328f3
Packit Service d328f3
const char *
Packit Service d328f3
nm_network_menu_item_get_ssid (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), NULL);
Packit Service d328f3
Packit Service d328f3
	return NM_NETWORK_MENU_ITEM_GET_PRIVATE (item)->ssid_string;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
guint32
Packit Service d328f3
nm_network_menu_item_get_strength (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), 0);
Packit Service d328f3
Packit Service d328f3
	return NM_NETWORK_MENU_ITEM_GET_PRIVATE (item)->int_strength;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static void
Packit Service d328f3
update_atk_desc (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
	GString *desc = NULL;
Packit Service d328f3
Packit Service d328f3
	desc = g_string_new ("");
Packit Service d328f3
	g_string_append_printf (desc, "%s: ", priv->ssid_string);
Packit Service d328f3
Packit Service d328f3
	if (priv->is_adhoc)
Packit Service d328f3
		g_string_append (desc, _("ad-hoc"));
Packit Service d328f3
	else {
Packit Service d328f3
		g_string_append_printf (desc, "%d%%", priv->int_strength);
Packit Service d328f3
		if (priv->is_encrypted) {
Packit Service d328f3
			g_string_append (desc, ", ");
Packit Service d328f3
			g_string_append (desc, _("secure."));
Packit Service d328f3
		}
Packit Service d328f3
	}
Packit Service d328f3
Packit Service d328f3
	atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (item)), desc->str);
Packit Service d328f3
	g_string_free (desc, TRUE);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static void
Packit Service d328f3
update_icon (NMNetworkMenuItem *item, NMApplet *applet)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
	gs_unref_object GdkPixbuf *icon_free = NULL, *icon_free2 = NULL;
Packit Service d328f3
	GdkPixbuf *icon;
Packit Service d328f3
	int icon_size, scale;
Packit Service d328f3
	const char *icon_name = NULL;
Packit Service d328f3
Packit Service d328f3
	if (priv->is_adhoc)
Packit Service d328f3
		icon_name = "nm-adhoc";
Packit Service d328f3
	else
Packit Service d328f3
		icon_name = mobile_helper_get_quality_icon_name (priv->int_strength);
Packit Service d328f3
Packit Service d328f3
	scale = gtk_widget_get_scale_factor (GTK_WIDGET (item));
Packit Service d328f3
	icon_size = 24;
Packit Service d328f3
	if (INDICATOR_ENABLED (applet)) {
Packit Service d328f3
		/* Since app_indicator relies on GdkPixbuf, we should not scale it */
Packit Service d328f3
	} else
Packit Service d328f3
		icon_size *= scale;
Packit Service d328f3
Packit Service d328f3
	icon = nma_icon_check_and_load (icon_name, applet);
Packit Service d328f3
	if (icon) {
Packit Service d328f3
		if (priv->is_encrypted) {
Packit Service d328f3
			GdkPixbuf *encrypted = nma_icon_check_and_load ("nm-secure-lock", applet);
Packit Service d328f3
Packit Service d328f3
			if (encrypted) {
Packit Service d328f3
				icon = icon_free = gdk_pixbuf_copy (icon);
Packit Service d328f3
Packit Service d328f3
				gdk_pixbuf_composite (encrypted, icon, 0, 0,
Packit Service d328f3
				                      gdk_pixbuf_get_width (encrypted),
Packit Service d328f3
				                      gdk_pixbuf_get_height (encrypted),
Packit Service d328f3
				                      0, 0, 1.0, 1.0,
Packit Service d328f3
				                      GDK_INTERP_NEAREST, 255);
Packit Service d328f3
			}
Packit Service d328f3
		}
Packit Service d328f3
Packit Service d328f3
		/* Scale to menu size if larger so the menu doesn't look awful */
Packit Service d328f3
		if (gdk_pixbuf_get_height (icon) > icon_size || gdk_pixbuf_get_width (icon) > icon_size)
Packit Service d328f3
			icon = icon_free2 = gdk_pixbuf_scale_simple (icon, icon_size, icon_size, GDK_INTERP_BILINEAR);
Packit Service d328f3
	}
Packit Service d328f3
Packit Service d328f3
	if (INDICATOR_ENABLED (applet)) {
Packit Service d328f3
		/* app_indicator only uses GdkPixbuf */
Packit Service d328f3
		gtk_image_set_from_pixbuf (GTK_IMAGE (priv->strength), icon);
Packit Service d328f3
	} else {
Packit Service d328f3
		cairo_surface_t *surface;
Packit Service d328f3
Packit Service d328f3
		surface = gdk_cairo_surface_create_from_pixbuf (icon, scale, NULL);
Packit Service d328f3
		gtk_image_set_from_surface (GTK_IMAGE (priv->strength), surface);
Packit Service d328f3
		cairo_surface_destroy (surface);
Packit Service d328f3
	}
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
void
Packit Service d328f3
nm_network_menu_item_set_strength (NMNetworkMenuItem *item,
Packit Service d328f3
                                   guint8 strength,
Packit Service d328f3
                                   NMApplet *applet)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv;
Packit Service d328f3
Packit Service d328f3
	g_return_if_fail (NM_IS_NETWORK_MENU_ITEM (item));
Packit Service d328f3
Packit Service d328f3
	priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
Packit Service d328f3
	strength = MIN (strength, 100);
Packit Service d328f3
	if (strength > priv->int_strength) {
Packit Service d328f3
		priv->int_strength = strength;
Packit Service d328f3
		update_icon (item, applet);
Packit Service d328f3
		update_atk_desc (item);
Packit Service d328f3
	}
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
const char *
Packit Service d328f3
nm_network_menu_item_get_hash (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), NULL);
Packit Service d328f3
Packit Service d328f3
	return NM_NETWORK_MENU_ITEM_GET_PRIVATE (item)->hash;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
gboolean
Packit Service d328f3
nm_network_menu_item_find_dupe (NMNetworkMenuItem *item, NMAccessPoint *ap)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv;
Packit Service d328f3
	const char *path;
Packit Service d328f3
	GSList *iter;
Packit Service d328f3
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), FALSE);
Packit Service d328f3
	g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), FALSE);
Packit Service d328f3
Packit Service d328f3
	priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
Packit Service d328f3
	path = nm_object_get_path (NM_OBJECT (ap));
Packit Service d328f3
	for (iter = priv->dupes; iter; iter = g_slist_next (iter)) {
Packit Service d328f3
		if (!strcmp (path, iter->data))
Packit Service d328f3
			return TRUE;
Packit Service d328f3
	}
Packit Service d328f3
	return FALSE;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static void
Packit Service d328f3
update_label (NMNetworkMenuItem *item, gboolean use_bold)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
Packit Service d328f3
	if (use_bold) {
Packit Service d328f3
		char *markup = g_markup_printf_escaped ("%s", priv->ssid_string);
Packit Service d328f3
Packit Service d328f3
		gtk_label_set_markup (GTK_LABEL (priv->ssid), markup);
Packit Service d328f3
		g_free (markup);
Packit Service d328f3
	} else {
Packit Service d328f3
		gtk_label_set_use_markup (GTK_LABEL (priv->ssid), FALSE);
Packit Service d328f3
		gtk_label_set_text (GTK_LABEL (priv->ssid), priv->ssid_string);
Packit Service d328f3
	}
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
void
Packit Service d328f3
nm_network_menu_item_set_active (NMNetworkMenuItem *item, gboolean active)
Packit Service d328f3
{
Packit Service d328f3
	g_return_if_fail (NM_IS_NETWORK_MENU_ITEM (item));
Packit Service d328f3
Packit Service d328f3
	update_label (item, active);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
void
Packit Service d328f3
nm_network_menu_item_add_dupe (NMNetworkMenuItem *item, NMAccessPoint *ap)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv;
Packit Service d328f3
	const char *path;
Packit Service d328f3
Packit Service d328f3
	g_return_if_fail (NM_IS_NETWORK_MENU_ITEM (item));
Packit Service d328f3
	g_return_if_fail (NM_IS_ACCESS_POINT (ap));
Packit Service d328f3
Packit Service d328f3
	priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
	path = nm_object_get_path (NM_OBJECT (ap));
Packit Service d328f3
	priv->dupes = g_slist_prepend (priv->dupes, g_strdup (path));
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
gboolean
Packit Service d328f3
nm_network_menu_item_get_has_connections (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), FALSE);
Packit Service d328f3
Packit Service d328f3
	return NM_NETWORK_MENU_ITEM_GET_PRIVATE (item)->has_connections;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
gboolean
Packit Service d328f3
nm_network_menu_item_get_is_adhoc (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), FALSE);
Packit Service d328f3
Packit Service d328f3
	return NM_NETWORK_MENU_ITEM_GET_PRIVATE (item)->is_adhoc;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
gboolean
Packit Service d328f3
nm_network_menu_item_get_is_encrypted (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	g_return_val_if_fail (NM_IS_NETWORK_MENU_ITEM (item), FALSE);
Packit Service d328f3
Packit Service d328f3
	return NM_NETWORK_MENU_ITEM_GET_PRIVATE (item)->is_encrypted;
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
/******************************************************************/
Packit Service d328f3
Packit Service d328f3
GtkWidget *
Packit Service d328f3
nm_network_menu_item_new (NMAccessPoint *ap,
Packit Service d328f3
                          guint32 dev_caps,
Packit Service d328f3
                          const char *hash,
Packit Service d328f3
                          gboolean has_connections,
Packit Service d328f3
                          NMApplet *applet)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItem *item;
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv;
Packit Service d328f3
	guint32 ap_flags, ap_wpa, ap_rsn;
Packit Service d328f3
	GBytes *ssid;
Packit Service d328f3
Packit Service d328f3
	item = g_object_new (NM_TYPE_NETWORK_MENU_ITEM, NULL);
Packit Service d328f3
	g_assert (item);
Packit Service d328f3
Packit Service d328f3
	priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
Packit Service d328f3
	nm_network_menu_item_add_dupe (item, ap);
Packit Service d328f3
Packit Service d328f3
	ssid = nm_access_point_get_ssid (ap);
Packit Service d328f3
	if (ssid) {
Packit Service d328f3
		priv->ssid_string = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL),
Packit Service d328f3
		                                           g_bytes_get_size (ssid));
Packit Service d328f3
	}
Packit Service d328f3
	if (!priv->ssid_string)
Packit Service d328f3
		priv->ssid_string = g_strdup ("<unknown>");
Packit Service d328f3
Packit Service d328f3
	priv->has_connections = has_connections;
Packit Service d328f3
	priv->hash = g_strdup (hash);
Packit Service d328f3
	priv->int_strength = nm_access_point_get_strength (ap);
Packit Service d328f3
Packit Service d328f3
	if (nm_access_point_get_mode (ap) == NM_802_11_MODE_ADHOC)
Packit Service d328f3
		priv->is_adhoc = TRUE;
Packit Service d328f3
Packit Service d328f3
	ap_flags = nm_access_point_get_flags (ap);
Packit Service d328f3
	ap_wpa = nm_access_point_get_wpa_flags (ap);
Packit Service d328f3
	ap_rsn = nm_access_point_get_rsn_flags (ap);
Packit Service d328f3
	if ((ap_flags & NM_802_11_AP_FLAGS_PRIVACY) || ap_wpa || ap_rsn)
Packit Service d328f3
		priv->is_encrypted = TRUE;
Packit Service d328f3
Packit Service d328f3
	/* Don't enable the menu item the device can't even connect to the AP */
Packit Service d328f3
	if (   !nm_utils_security_valid (NMU_SEC_NONE, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
#if NM_CHECK_VERSION(1,24,0)
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_OWE, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)
Packit Service d328f3
#endif
Packit Service d328f3
	    && !nm_utils_security_valid (NMU_SEC_SAE, dev_caps, TRUE, priv->is_adhoc, ap_flags, ap_wpa, ap_rsn)) {
Packit Service d328f3
		gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
Packit Service d328f3
	}
Packit Service d328f3
Packit Service d328f3
	update_label (item, FALSE);
Packit Service d328f3
	update_icon (item, applet);
Packit Service d328f3
	update_atk_desc (item);
Packit Service d328f3
Packit Service d328f3
	return GTK_WIDGET (item);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static void
Packit Service d328f3
nm_network_menu_item_init (NMNetworkMenuItem *item)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (item);
Packit Service d328f3
Packit Service d328f3
	priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
Packit Service d328f3
	priv->ssid = gtk_label_new (NULL);
Packit Service d328f3
	gtk_misc_set_alignment (GTK_MISC (priv->ssid), 0.0, 0.5);
Packit Service d328f3
Packit Service d328f3
	gtk_container_add (GTK_CONTAINER (item), priv->hbox);
Packit Service d328f3
	gtk_box_pack_start (GTK_BOX (priv->hbox), priv->ssid, TRUE, TRUE, 0);
Packit Service d328f3
Packit Service d328f3
	priv->strength = gtk_image_new ();
Packit Service d328f3
	gtk_box_pack_end (GTK_BOX (priv->hbox), priv->strength, FALSE, TRUE, 0);
Packit Service d328f3
	gtk_widget_show (priv->strength);
Packit Service d328f3
Packit Service d328f3
	gtk_widget_show (priv->ssid);
Packit Service d328f3
	gtk_widget_show (priv->hbox);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static void
Packit Service d328f3
finalize (GObject *object)
Packit Service d328f3
{
Packit Service d328f3
	NMNetworkMenuItemPrivate *priv = NM_NETWORK_MENU_ITEM_GET_PRIVATE (object);
Packit Service d328f3
Packit Service d328f3
	g_free (priv->hash);
Packit Service d328f3
	g_free (priv->ssid_string);
Packit Service d328f3
Packit Service d328f3
	g_slist_free_full (priv->dupes, g_free);
Packit Service d328f3
Packit Service d328f3
	G_OBJECT_CLASS (nm_network_menu_item_parent_class)->finalize (object);
Packit Service d328f3
}
Packit Service d328f3
Packit Service d328f3
static void
Packit Service d328f3
nm_network_menu_item_class_init (NMNetworkMenuItemClass * klass)
Packit Service d328f3
{
Packit Service d328f3
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service d328f3
Packit Service d328f3
	g_type_class_add_private (klass, sizeof (NMNetworkMenuItemPrivate));
Packit Service d328f3
Packit Service d328f3
	/* virtual methods */
Packit Service d328f3
	object_class->finalize = finalize;
Packit Service d328f3
}
Packit Service d328f3