"Fossies" - the Fresh Open Source Software Archive

Member "etherape-0.9.18/src/node_windows.c" (14 Apr 2018, 13890 Bytes) of package /linux/privat/etherape-0.9.18.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "node_windows.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.9.17_vs_0.9.18.

    1 /* EtherApe
    2  * Copyright (C) 2009 Juan Toledo, Riccardo Ghetta
    3  *
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation; either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, see <http://www.gnu.org/licenses/>.
   16  */
   17 
   18 #ifdef HAVE_CONFIG_H
   19 #include <config.h>
   20 #endif
   21 
   22 #include <math.h>
   23 #include "node_windows.h"
   24 #include "info_windows.h"
   25 #include "ui_utils.h"
   26 #include "stats/util.h"
   27 #include "stats/node.h"
   28 
   29 typedef enum 
   30 {
   31   NODES_COLUMN_NAME = 0,
   32   NODES_COLUMN_NUMERIC,
   33   NODES_COLUMN_INSTANTANEOUS,
   34   NODES_COLUMN_ACCUMULATED,
   35   NODES_COLUMN_AVGSIZE,
   36   NODES_COLUMN_LASTHEARD,
   37   NODES_COLUMN_PACKETS,
   38   NODES_COLUMN_N        /* must be the last entry */
   39 } NODES_COLUMN;
   40 
   41 
   42 static GtkWidget *nodes_wnd = NULL;        /* Ptr to nodes window */
   43 static GtkCheckMenuItem *nodes_check = NULL;   /* Ptr to nodes menu */
   44 
   45 /* private functions */
   46 static void nodes_table_clear(GtkWidget *window);
   47 static void nodes_table_update(GtkWidget *window);
   48 
   49 void nodes_wnd_show(void)
   50 {
   51   nodes_wnd = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "nodes_wnd"));
   52   nodes_check = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(appdata.xml, "nodes_check"));
   53 
   54   if (DEBUG_ENABLED)
   55     {
   56       gchar *nodemsg = nodes_catalog_dump();
   57       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_MESSAGE, "%s", nodemsg);
   58       g_free(nodemsg);
   59     }
   60   
   61   if (!nodes_wnd || gtk_widget_get_visible(nodes_wnd))
   62     return;
   63 
   64   gtk_widget_show(nodes_wnd);
   65   gdk_window_raise(gtk_widget_get_window(nodes_wnd));
   66   if (nodes_check && !gtk_check_menu_item_get_active(nodes_check))
   67     gtk_check_menu_item_set_active(nodes_check, TRUE);
   68   nodes_wnd_update();
   69 }
   70 
   71 void nodes_wnd_hide(void)
   72 {
   73   if (!nodes_wnd || !gtk_widget_get_visible(nodes_wnd))
   74     return;
   75 
   76   gtk_widget_hide (nodes_wnd);
   77   nodes_table_clear(nodes_wnd);
   78   if (nodes_check && gtk_check_menu_item_get_active(nodes_check))
   79     gtk_check_menu_item_set_active(nodes_check, FALSE);
   80 }
   81 
   82 void nodes_wnd_update(void)
   83 {
   84   if (!nodes_wnd || !gtk_widget_get_visible(nodes_wnd))
   85     return;
   86 
   87   nodes_table_update(nodes_wnd);
   88 
   89   /* with viewport, no need to resize 
   90    gtk_widget_queue_resize (GTK_WIDGET (nodes_wnd)); */
   91 }               /* update_nodes_wnd */
   92 
   93 /***************************************************************
   94  *
   95  * node table handling functions 
   96  *
   97  ***************************************************************/
   98 
   99 /* Comparison functions used to sort the clist */
  100 static gint
  101 nodes_table_compare (GtkTreeModel * gls, GtkTreeIter * a, GtkTreeIter * b, 
  102                      gpointer data)
  103 {
  104   gint ret = 0;
  105   gdouble t1, t2;
  106   double diffms;
  107   const node_id_t *nodeid1, *nodeid2;
  108   const node_t *node1, *node2;
  109 
  110   gtk_tree_model_get (gls, a, NODES_COLUMN_N, &nodeid1, -1);
  111   gtk_tree_model_get (gls, b, NODES_COLUMN_N, &nodeid2, -1);
  112   if (!nodeid1 || !nodeid2)
  113     return 0;           /* error */ 
  114   
  115   /* retrieve nodes. One or more might be expired */
  116   node1 = nodes_catalog_find(nodeid1);
  117   node2 = nodes_catalog_find(nodeid2);
  118   if (!node1 && !node2)
  119     return 0;           
  120   else if (!node1)      
  121     return -1;          
  122   else if (!node2)
  123     return 1;
  124   
  125   /* gets sort info */
  126   switch (GPOINTER_TO_INT(data))
  127     {
  128     case NODES_COLUMN_NAME: /* name */
  129     default:
  130       ret = strcmp (node1->name->str, node2->name->str);
  131       break;
  132     case NODES_COLUMN_NUMERIC: /* id */
  133       ret = node_id_compare(&(node1->node_id), &(node2->node_id));
  134       break;
  135     case NODES_COLUMN_INSTANTANEOUS:
  136       t1 = node1->node_stats.stats.average;
  137       t2 = node2->node_stats.stats.average;
  138       if (t1 == t2)
  139     ret = 0;
  140       else if (t1 < t2)
  141     ret = -1;
  142       else
  143     ret = 1;
  144       break;
  145     case NODES_COLUMN_ACCUMULATED:
  146       t1 = node1->node_stats.stats.accumulated;
  147       t2 = node2->node_stats.stats.accumulated;
  148       if (t1 == t2)
  149     ret = 0;
  150       else if (t1 < t2)
  151     ret = -1;
  152       else
  153     ret = 1;
  154       break;
  155     case NODES_COLUMN_AVGSIZE:
  156       t1 = node1->node_stats.stats.avg_size;
  157       t2 = node2->node_stats.stats.avg_size;
  158       if (t1 == t2)
  159     ret = 0;
  160       else if (t1 < t2)
  161     ret = -1;
  162       else
  163     ret = 1;
  164       break;
  165     case NODES_COLUMN_LASTHEARD:
  166       diffms = subtract_times_ms(&node1->node_stats.stats.last_time,
  167                                   &node2->node_stats.stats.last_time);
  168       if (diffms == 0)
  169     ret = 0;
  170       else if (diffms < 0)
  171     ret = -1;
  172       else
  173     ret = 1;
  174       break;
  175     case NODES_COLUMN_PACKETS:
  176       if (node1->node_stats.stats.accu_packets == node2->node_stats.stats.accu_packets)
  177     ret = 0;
  178       else if (node1->node_stats.stats.accu_packets < node2->node_stats.stats.accu_packets)
  179     ret = -1;
  180       else
  181     ret = 1;
  182       break;
  183     }
  184 
  185   return ret;
  186 }
  187 
  188 /* retrieves the data store creating if needed */
  189 static GtkListStore *nodes_table_create(GtkWidget *window)
  190 {
  191   GtkTreeView *gv;
  192   GtkListStore *gls;
  193   GtkTreeModel *sort_model;
  194   int i;
  195 
  196   /* get the treeview */
  197   gv = retrieve_treeview(window);
  198   if (!gv)
  199     {
  200       gv = GTK_TREE_VIEW (gtk_builder_get_object (appdata.xml, "nodes_table"));
  201       if (!gv)
  202         {
  203           g_critical("can't find nodes_table");
  204           return NULL;
  205         }
  206       register_treeview(window, gv);
  207     }
  208 
  209   sort_model = gtk_tree_view_get_model(gv);
  210   if (sort_model)
  211     {
  212       gls = GTK_LIST_STORE(gtk_tree_model_sort_get_model
  213                             (GTK_TREE_MODEL_SORT(sort_model)));
  214       if (gls)
  215         return gls; 
  216     }
  217   
  218   /* create the store. it uses 8 values, 7 displayable and the data pointer */
  219   gls = gtk_list_store_new (8, G_TYPE_STRING, G_TYPE_STRING,
  220                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, 
  221                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
  222 
  223   /* to update successfully, the list store must be unsorted. So we wrap it */
  224   sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(gls));
  225   gtk_tree_view_set_model (gv, GTK_TREE_MODEL (sort_model));
  226 
  227   create_add_text_column(gv, "Name", NODES_COLUMN_NAME, FALSE);
  228   create_add_text_column(gv, "Address", NODES_COLUMN_NUMERIC, TRUE);
  229   create_add_text_column(gv, "Inst Traffic", NODES_COLUMN_INSTANTANEOUS, FALSE);
  230   create_add_text_column(gv, "Accum Traffic", NODES_COLUMN_ACCUMULATED, FALSE);
  231   create_add_text_column(gv, "Avg Size", NODES_COLUMN_AVGSIZE, FALSE);
  232   create_add_text_column(gv, "Last Heard", NODES_COLUMN_LASTHEARD, FALSE);
  233   create_add_text_column(gv, "Packets", NODES_COLUMN_PACKETS, FALSE);
  234 
  235   /* the sort functions ... */
  236   for (i = 0 ; i < NODES_COLUMN_N ; ++i)
  237     gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sort_model), i,
  238                                      nodes_table_compare, 
  239                                      GINT_TO_POINTER(i), NULL);
  240 
  241   /* initial sort order is by name */
  242   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), 
  243                                         NODES_COLUMN_NAME,
  244                                         GTK_SORT_ASCENDING);
  245 
  246   return gls;
  247 }
  248 
  249 static void nodes_table_clear(GtkWidget *window)
  250 {
  251   /* releases the datastore */
  252   GtkTreeView *gv;
  253   GtkTreeModel *sort_model;
  254   GtkTreeModel *gls;
  255   GtkTreeIter it;
  256   gboolean res;
  257 
  258   gv = retrieve_treeview(window);
  259   if (!gv)
  260     return; /* gv not registered, store doesn't exists */
  261   
  262   /* parameters came from sorted model; we need to convert to liststore*/
  263   sort_model = gtk_tree_view_get_model(gv);
  264   if (!sort_model)
  265     return;
  266 
  267   /* liststore from sorted model */
  268   gls = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(sort_model));
  269   if (!gls)
  270     return; 
  271 
  272   res = gtk_tree_model_get_iter_first (gls, &it);
  273   while (res)
  274     {
  275       node_id_t *rowitem = NULL;
  276       gtk_tree_model_get (gls, &it, 
  277                           NODES_COLUMN_N, &rowitem, -1);
  278       g_free(rowitem);
  279       res = gtk_list_store_remove (GTK_LIST_STORE(gls), &it);
  280     }
  281 }
  282 
  283 static void nodes_table_update_row(GtkListStore *gs, GtkTreeIter *it, 
  284                                    const node_t * node)
  285 {
  286   gchar *sa, *sb, *sc, *sd, *se;
  287   const basic_stats_t *stats = (const basic_stats_t *) &(node->node_stats.stats);
  288   
  289   sa = traffic_to_str (stats->average, TRUE);
  290   sb = traffic_to_str (stats->accumulated, FALSE);
  291   sc = g_strdup_printf ("%lu", stats->accu_packets);
  292   sd = timeval_to_str(stats->last_time);
  293   se = traffic_to_str (stats->avg_size, FALSE);
  294 
  295   gtk_list_store_set (gs, it, 
  296                       NODES_COLUMN_NAME, node->name->str, 
  297                       NODES_COLUMN_NUMERIC, node->numeric_name->str, 
  298                       NODES_COLUMN_INSTANTANEOUS, sa,
  299                       NODES_COLUMN_ACCUMULATED, sb,
  300                       NODES_COLUMN_AVGSIZE, se,
  301                       NODES_COLUMN_PACKETS, sc,
  302                       NODES_COLUMN_LASTHEARD, sd,
  303                       -1);
  304   g_free (sa);
  305   g_free (sb);
  306   g_free (sc);
  307   g_free (sd);
  308   g_free (se);
  309 }
  310 
  311 struct NTTraverse
  312 {
  313   GtkListStore *gs;
  314   GtkTreeIter it;
  315   gboolean res;
  316 };
  317 
  318 static gboolean nodes_table_iterate(gpointer key, gpointer value, gpointer data)
  319 {
  320   const node_t *node = (const node_t *)value;
  321   struct NTTraverse *tt = (struct NTTraverse *)data;
  322   node_id_t *rowitem;
  323  
  324   while (tt->res)
  325     {
  326       gtk_tree_model_get (GTK_TREE_MODEL (tt->gs), &(tt->it), 
  327                           NODES_COLUMN_N, &rowitem, -1);
  328 
  329       switch (node_id_compare(&(node->node_id), rowitem))
  330         {
  331         case 0:
  332             /* curnode==cur row, update results and go next */
  333             nodes_table_update_row(tt->gs, &(tt->it), node);
  334             tt->res = gtk_tree_model_iter_next (GTK_TREE_MODEL (tt->gs), 
  335                                                 &(tt->it));
  336             return FALSE; /* continue with next node */
  337         case -1:
  338             /* current node name less than current row means node is new.
  339                Insert a new node in store before current (it moves to new node),
  340                fill it and move next */
  341             gtk_list_store_insert_before(tt->gs, &(tt->it), &(tt->it));
  342             rowitem = g_malloc(sizeof(node_id_t));
  343             g_assert(rowitem);
  344             
  345             *rowitem = node->node_id;
  346             gtk_list_store_set (tt->gs, &(tt->it), NODES_COLUMN_N, rowitem, -1);
  347             nodes_table_update_row(tt->gs, &(tt->it), node);
  348             tt->res = gtk_tree_model_iter_next (GTK_TREE_MODEL (tt->gs), 
  349                                                 &(tt->it));
  350             return FALSE; /* continue with next node */
  351         case 1:
  352             /* current node name greater than current row means deleted row.
  353              * remove row and loop */
  354             g_free(rowitem);
  355             tt->res = gtk_list_store_remove (tt->gs, &(tt->it));
  356             break;
  357         }
  358     }  /* end while */
  359 
  360   /* coming here means node is new - append and move next */
  361   gtk_list_store_prepend(tt->gs, &(tt->it));
  362   rowitem = g_malloc(sizeof(node_id_t));
  363   g_assert(rowitem);
  364   *rowitem = node->node_id;
  365   gtk_list_store_set (tt->gs, &(tt->it), NODES_COLUMN_N, rowitem, -1);
  366   nodes_table_update_row(tt->gs, &(tt->it), node);
  367   return FALSE;
  368 }
  369 
  370 static void nodes_table_update(GtkWidget *window)
  371 {
  372   GtkListStore *gs;
  373   struct NTTraverse tt;
  374 
  375   gs = nodes_table_create(window);
  376   if (!gs)
  377     return; /* no datastore, exit */
  378 
  379   /* traverse both the full list and the treestore, comparing entries */
  380   tt.gs = gs;
  381   tt.res = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tt.gs), &(tt.it));
  382   nodes_catalog_foreach(nodes_table_iterate, &tt);
  383 
  384   /* if the iterator is still active, remaining rows must be removed */
  385   while (tt.res)
  386     {
  387       node_id_t *rowitem;
  388       gtk_tree_model_get (GTK_TREE_MODEL (tt.gs), &(tt.it), 
  389                           NODES_COLUMN_N, &rowitem, -1);
  390       g_free(rowitem);
  391       tt.res = gtk_list_store_remove (tt.gs, &(tt.it));
  392     }
  393 }
  394 
  395 /* ----------------------------------------------------------
  396    Events
  397    ---------------------------------------------------------- */
  398 
  399 gboolean on_nodes_wnd_delete_event(GtkWidget * wdg, GdkEvent * evt, gpointer ud)
  400 {
  401   nodes_wnd_hide();
  402   return TRUE;          /* ignore signal */
  403 }
  404 
  405 void on_nodes_check_toggled(GtkCheckMenuItem *checkmenuitem,  gpointer data)
  406 {
  407   if (gtk_check_menu_item_get_active(checkmenuitem))
  408     nodes_wnd_show();
  409   else
  410     nodes_wnd_hide();
  411 }
  412 
  413 void on_nodes_toolbar_button_clicked(void)
  414 {
  415   GtkWidget *nodes_check = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "nodes_check"));
  416   if (!nodes_check)
  417     return;
  418   gtk_menu_item_activate(GTK_MENU_ITEM (nodes_check));
  419 }
  420 
  421 /* double click on row */
  422 void on_nodes_table_row_activated(GtkTreeView *gv,
  423                                   GtkTreePath *sorted_path,
  424                                   GtkTreeViewColumn *column,
  425                                   gpointer data)
  426 {
  427   GtkTreeModel *sort_model;
  428   GtkTreeModel *gls;
  429   GtkTreePath *path;
  430   GtkTreeIter it;
  431 
  432   /* parameters came from sorted model; we need to convert to liststore*/
  433   sort_model = gtk_tree_view_get_model(gv);
  434   if (!sort_model)
  435     return;
  436 
  437   /* liststore from sorted model */
  438   gls = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(sort_model));
  439   if (!gls)
  440     return; 
  441 
  442   /* liststore path from sorted path */
  443   path = gtk_tree_model_sort_convert_path_to_child_path
  444             (GTK_TREE_MODEL_SORT(sort_model), sorted_path);
  445   if (!path)
  446     return;
  447 
  448   /* iterator from path */
  449   if (gtk_tree_model_get_iter (gls, &it, path))
  450     {
  451       /* and last, value */
  452       node_id_t *rowitem;
  453       gtk_tree_model_get (gls, &it, NODES_COLUMN_N, &rowitem, -1);
  454       node_protocols_window_create(rowitem);
  455     }
  456   
  457   gtk_tree_path_free(path);
  458 }
  459 
  460