285 lines
9.0 KiB
C
285 lines
9.0 KiB
C
#include <gtk/gtk.h>
|
|
|
|
#include <linux/if_arp.h>
|
|
|
|
#include "ni-client.h"
|
|
#include "ni-interface.h"
|
|
#include "ni-window-interface.h"
|
|
#include "../src/link-types.h"
|
|
|
|
enum {
|
|
COL_IFACE_OBJECT,
|
|
|
|
COL_IFACE_INDEX,
|
|
COL_IFACE_NAME,
|
|
|
|
COL_IFACE_ICON,
|
|
|
|
COL_IFACE_WINDOW,
|
|
|
|
NUM_COLS_IFACE,
|
|
};
|
|
|
|
enum {
|
|
INTERFACES_GROUP_ETHERNET,
|
|
INTERFACES_GROUP_WIFI,
|
|
INTERFACES_GROUP_BRIDGES,
|
|
INTERFACES_GROUP_OTHER,
|
|
INTERFACES_GROUP_LOOP_DUMMY,
|
|
NUM_INTERFACES_GROUP
|
|
};
|
|
|
|
typedef struct {
|
|
int group_type;
|
|
|
|
GtkWidget *vbox;
|
|
GtkWidget *label;
|
|
GtkWidget *iconview;
|
|
GtkWidget *scrolled;
|
|
GtkTreeModel *model_filter;
|
|
} UINetworkType;
|
|
|
|
const char *group_names[NUM_INTERFACES_GROUP] = {
|
|
"Redes cableadas",
|
|
"Redes inalámbricas",
|
|
"Puentes",
|
|
"Otros",
|
|
"Loopback y otros tipos"
|
|
};
|
|
|
|
GtkListStore *interfaces_store;
|
|
NIClient *ni_client;
|
|
GtkWidget *ventana;
|
|
GtkWidget *vbox;
|
|
GtkWidget *empty_label = NULL;
|
|
GHashTable *network_blocks_list;
|
|
|
|
static void click_interface_cb (GtkIconView *iconview, GtkTreePath *path, gpointer data) {
|
|
UINetworkType *network_block = (UINetworkType *) data;
|
|
GtkTreeIter iter, real_iter;
|
|
GtkWidget *ventana;
|
|
NIInterface *ni_interface;
|
|
|
|
gtk_tree_model_get_iter (GTK_TREE_MODEL (network_block->model_filter), &iter, path);
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (network_block->model_filter), &iter, COL_IFACE_OBJECT, &ni_interface, COL_IFACE_WINDOW, &ventana, -1);
|
|
|
|
if (ventana == NULL) {
|
|
ventana = ni_window_interface_new (ni_interface);
|
|
|
|
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (network_block->model_filter), &real_iter, &iter);
|
|
gtk_list_store_set (interfaces_store, &real_iter, COL_IFACE_WINDOW, ventana, -1);
|
|
}
|
|
gtk_widget_show (ventana);
|
|
}
|
|
|
|
int guess_interface_type (NIInterface *ni_interface) {
|
|
guint type;
|
|
|
|
type = ni_interface_get_iface_type (ni_interface);
|
|
if (type == NI_LINK_TYPE_ETHERNET) {
|
|
return INTERFACES_GROUP_ETHERNET;
|
|
} else if (type == NI_LINK_TYPE_WIFI) {
|
|
return INTERFACES_GROUP_WIFI;
|
|
} else if (type == NI_LINK_TYPE_DUMMY || type == NI_LINK_TYPE_LOOPBACK) {
|
|
return INTERFACES_GROUP_LOOP_DUMMY;
|
|
} else if (type == NI_LINK_TYPE_BRIDGE) {
|
|
return INTERFACES_GROUP_BRIDGES;
|
|
}
|
|
|
|
return INTERFACES_GROUP_OTHER;
|
|
}
|
|
|
|
gboolean network_block_model_filter_by_type (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
|
|
NIInterface *ni_interface;
|
|
const gchar *iface_type;
|
|
UINetworkType *network_block = (UINetworkType *) data;
|
|
|
|
gtk_tree_model_get (model, iter, COL_IFACE_OBJECT, &ni_interface, -1);
|
|
if (ni_interface == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
//iface_type = ni_interface_get_iface_type (ni_interface);
|
|
if (guess_interface_type (ni_interface) == network_block->group_type) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
UINetworkType * create_block_list (int type) {
|
|
UINetworkType *network_block;
|
|
int g, pos;
|
|
|
|
if (g_hash_table_size (network_blocks_list) == 0) {
|
|
/* Eliminar la etiqueta */
|
|
gtk_widget_destroy (empty_label);
|
|
}
|
|
|
|
network_block = g_new0 (UINetworkType, 1);
|
|
|
|
network_block->group_type = type;
|
|
|
|
network_block->model_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (interfaces_store), NULL);
|
|
printf ("Para el group type: %i, el model_filter: %p\n", type, network_block->model_filter);
|
|
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (network_block->model_filter), network_block_model_filter_by_type, network_block, NULL);
|
|
|
|
network_block->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (vbox), network_block->vbox, FALSE, FALSE, 5);
|
|
/* Reordenar los grupos presentes, dentro del vbox */
|
|
pos = 0;
|
|
for (g = 0; g < NUM_INTERFACES_GROUP && g < type; g++) {
|
|
if (g_hash_table_lookup (network_blocks_list, GINT_TO_POINTER (g)) != NULL) {
|
|
pos++;
|
|
}
|
|
}
|
|
gtk_box_reorder_child (GTK_BOX (vbox), network_block->vbox, pos);
|
|
|
|
network_block->label = gtk_label_new (group_names [type]);
|
|
gtk_box_pack_start (GTK_BOX (network_block->vbox), network_block->label, FALSE, FALSE, 0);
|
|
|
|
network_block->iconview = gtk_icon_view_new_with_model (network_block->model_filter);
|
|
g_signal_connect (network_block->iconview, "item-activated", G_CALLBACK (click_interface_cb), network_block);
|
|
|
|
gtk_icon_view_set_text_column (GTK_ICON_VIEW (network_block->iconview), COL_IFACE_NAME);
|
|
gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (network_block->iconview), COL_IFACE_ICON);
|
|
//gtk_icon_view_set_columns (GTK_ICON_VIEW (network_block->iconview), 1000);
|
|
gtk_icon_view_set_reorderable (GTK_ICON_VIEW (network_block->iconview), FALSE);
|
|
|
|
network_block->scrolled = gtk_scrolled_window_new (
|
|
gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (network_block->iconview)),
|
|
gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (network_block->iconview)));
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (network_block->scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
|
|
|
gtk_container_add (GTK_CONTAINER (network_block->scrolled), network_block->iconview);
|
|
gtk_box_pack_start (GTK_BOX (network_block->vbox), network_block->scrolled, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show_all (network_block->vbox);
|
|
|
|
return network_block;
|
|
}
|
|
|
|
gboolean locate_interface_from_store (GtkListStore *store, GtkTreeIter *iter, guint index) {
|
|
gboolean has;
|
|
guint index_data;
|
|
|
|
has = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), iter);
|
|
while (has) {
|
|
gtk_tree_model_get (GTK_TREE_MODEL (interfaces_store), iter, COL_IFACE_INDEX, &index_data, -1);
|
|
|
|
if (index == index_data) {
|
|
return TRUE;
|
|
}
|
|
has = gtk_tree_model_iter_next (GTK_TREE_MODEL (interfaces_store), iter);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void interface_changed_name_cb (GObject *object, GParamSpec *sp, gpointer data) {
|
|
NIInterface *ni_interface = NI_INTERFACE (object);
|
|
guint index;
|
|
GtkTreeIter iter;
|
|
|
|
index = ni_interface_get_index (ni_interface);
|
|
|
|
if (locate_interface_from_store (interfaces_store, &iter, index)) {
|
|
gtk_list_store_set (interfaces_store, &iter, COL_IFACE_NAME, ni_interface_get_name (ni_interface), -1);
|
|
}
|
|
}
|
|
|
|
void new_interface_cb (NIClient *ni_client, NIInterface *ni_interface, gpointer data) {
|
|
guint index;
|
|
UINetworkType *network_block;
|
|
int type;
|
|
GdkPixbuf *icon;
|
|
GtkTreeIter iter;
|
|
|
|
type = guess_interface_type (ni_interface);
|
|
network_block = g_hash_table_lookup (network_blocks_list, GINT_TO_POINTER (type));
|
|
|
|
if (network_block == NULL) {
|
|
/* El bloque está vacio, pedir crearlo */
|
|
network_block = create_block_list (type);
|
|
|
|
g_hash_table_insert (network_blocks_list, GINT_TO_POINTER (type), network_block);
|
|
}
|
|
|
|
if (type == INTERFACES_GROUP_ETHERNET) {
|
|
icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "network-wired", 32, 0, NULL);
|
|
} else {
|
|
icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "network-wired", 32, 0, NULL);
|
|
}
|
|
|
|
gtk_list_store_insert (interfaces_store, &iter, -1);
|
|
gtk_list_store_set (interfaces_store, &iter, COL_IFACE_OBJECT, ni_interface, COL_IFACE_INDEX, ni_interface_get_index (ni_interface), COL_IFACE_NAME, ni_interface_get_name (ni_interface), COL_IFACE_ICON, icon, COL_IFACE_WINDOW, NULL, -1);
|
|
|
|
g_signal_connect (ni_interface, "notify::name", G_CALLBACK (interface_changed_name_cb), NULL);
|
|
|
|
g_object_unref (icon);
|
|
}
|
|
|
|
void delete_interface_cb (NIClient *ni_client, NIInterface *ni_interface, gpointer data) {
|
|
GtkWidget *ventana;
|
|
GtkTreeIter iter;
|
|
|
|
if (locate_interface_from_store (interfaces_store, &iter, ni_interface_get_index (ni_interface))) {
|
|
gtk_tree_model_get (GTK_TREE_MODEL (interfaces_store), &iter, COL_IFACE_WINDOW, &ventana, -1);
|
|
/* Eliminar este objeto */
|
|
if (ventana != NULL) {
|
|
gtk_widget_destroy (ventana);
|
|
}
|
|
gtk_list_store_remove (interfaces_store, &iter);
|
|
}
|
|
}
|
|
|
|
void cerrar_ventana_cb (GtkWidget *ventana, gpointer data) {
|
|
g_object_unref (ni_client);
|
|
gtk_main_quit ();
|
|
}
|
|
|
|
int main (int argc, char *argv[]) {
|
|
gboolean connected;
|
|
GtkWidget *label, *scrolled;
|
|
|
|
gtk_init (&argc, &argv);
|
|
|
|
ni_client = ni_client_new ();
|
|
|
|
connected = ni_client_connect (ni_client);
|
|
g_signal_connect (ni_client, "new-interface", G_CALLBACK (new_interface_cb), NULL);
|
|
g_signal_connect (ni_client, "delete-interface", G_CALLBACK (delete_interface_cb), NULL);
|
|
|
|
interfaces_store = gtk_list_store_new (NUM_COLS_IFACE, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER);
|
|
|
|
network_blocks_list = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
|
|
ventana = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
gtk_window_set_title (GTK_WINDOW (ventana), "Interfaces");
|
|
gtk_window_set_default_size (GTK_WINDOW (ventana), 640, 480);
|
|
g_signal_connect (ventana, "destroy", G_CALLBACK (cerrar_ventana_cb), NULL);
|
|
|
|
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
|
|
|
|
gtk_container_add (GTK_CONTAINER (ventana), scrolled);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
|
gtk_widget_set_size_request (vbox, 260, -1);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled), vbox);
|
|
|
|
if (connected == FALSE) {
|
|
empty_label = gtk_label_new ("El servicio del network inador no está corriendo\n");
|
|
} else {
|
|
empty_label = gtk_label_new ("Recuperando información...\n");
|
|
}
|
|
gtk_box_pack_start (GTK_BOX (vbox), empty_label, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show_all (ventana);
|
|
|
|
gtk_main ();
|
|
|
|
return 0;
|
|
}
|