"Fossies" - the Fresh Open Source Software Archive

Member "etherape-0.9.18/src/menus.c" (3 Jun 2018, 17337 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 "menus.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) 2001 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 <string.h>
   23 #include <gtk/gtk.h>
   24 #include <glib.h>
   25 #include "menus.h"
   26 #include "ui_utils.h"
   27 #include "diagram.h"
   28 #include "stats/decode_proto.h"
   29 #include "info_windows.h"
   30 #include "capture/capctl.h"
   31 #include "preferences.h"
   32 #include "export.h"
   33 
   34 
   35 static gboolean in_start_capture = FALSE;
   36 
   37 static void set_active_interface(void);
   38 
   39 void init_menus(void)
   40 {
   41   GtkWidget *widget = NULL, *item = NULL;
   42   GList *interfaces;
   43   GList *iface;
   44   GSList *group = NULL;
   45   GString *info_string = NULL;
   46   GString *err_str = g_string_new ("");
   47 
   48   interfaces = get_capture_interfaces(err_str);
   49   if (err_str)
   50      g_my_info (_("get_interface result: '%s'"), err_str->str);
   51   if (!interfaces)
   52     {
   53       g_my_info (_("No suitables interfaces for capture have been found"));
   54       if (err_str)
   55          g_string_free(err_str, TRUE);
   56       return;
   57     }
   58   if (err_str)
   59     g_string_free(err_str, TRUE);
   60 
   61   widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "interfaces_menu"));
   62 
   63   info_string = g_string_new (_("Available interfaces for capture:"));
   64 
   65   /* Set up a hidden dummy interface to set when there is no active
   66    * interface */
   67   item = gtk_radio_menu_item_new_with_label (group, "apedummy");
   68   group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
   69   gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
   70 
   71   /* Set up the real interfaces menu entries */
   72   for (iface = interfaces; iface; iface = iface->next)
   73     {
   74       item = gtk_radio_menu_item_new_with_label(group,
   75                                                 (gchar *) (iface->data));
   76       group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
   77       gtk_menu_shell_append(GTK_MENU_SHELL(widget), item);
   78       gtk_widget_show(item);
   79       g_signal_connect_swapped(G_OBJECT(item), "activate",
   80                                G_CALLBACK(on_interface_radio_activate),
   81                                (gpointer) g_strdup(iface->data));
   82       g_string_append(info_string, " ");
   83       g_string_append(info_string, (gchar *) (iface->data));
   84     }
   85 
   86   if (info_string) {
   87      g_my_info ("%s", info_string->str);
   88      g_string_free(info_string, TRUE);
   89   }
   90 
   91   free_capture_interfaces(interfaces);
   92 }
   93 
   94 /* FILE MENU */
   95 
   96 void on_open_activate(GtkMenuItem * menuitem, gpointer user_data)
   97 {
   98   GtkWidget *dialog;
   99 
  100   if (!gui_stop_capture ())
  101     return;
  102 
  103   dialog = gtk_file_chooser_dialog_new ("Open Capture File",
  104                       NULL,
  105                       GTK_FILE_CHOOSER_ACTION_OPEN,
  106                       _("_Cancel"), GTK_RESPONSE_CANCEL,
  107                       _("_Open"), GTK_RESPONSE_ACCEPT,
  108                       NULL);
  109   if (appdata.source.type == ST_FILE && appdata.source.file)
  110     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), appdata.source.file);
  111 
  112   if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
  113     {
  114       GtkRecentManager *manager;
  115       manager = gtk_recent_manager_get_default ();
  116       gtk_recent_manager_add_item (manager, gtk_file_chooser_get_uri(GTK_FILE_CHOOSER (dialog)));
  117 
  118       appdata_clear_source(&appdata);
  119       appdata.source.type = ST_FILE;
  120       appdata.source.file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
  121       gtk_widget_destroy (dialog);
  122 
  123       gui_start_capture ();
  124     }
  125   else
  126     gtk_widget_destroy (dialog);
  127 }
  128 
  129 void on_export_activate (GtkMenuItem * menuitem, gpointer user_data)
  130 {
  131   GtkWidget *dialog;
  132 
  133   dialog = gtk_file_chooser_dialog_new ("Export to XML File",
  134                       NULL,
  135                       GTK_FILE_CHOOSER_ACTION_SAVE,
  136                       _("_Cancel"), GTK_RESPONSE_CANCEL,
  137                       _("_Save"), GTK_RESPONSE_ACCEPT,
  138                       NULL);
  139   gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
  140 
  141   if (appdata.export_file)
  142     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), appdata.export_file);
  143 
  144   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
  145     {
  146       GtkRecentManager *manager;
  147       manager = gtk_recent_manager_get_default ();
  148       gtk_recent_manager_add_item (manager, gtk_file_chooser_get_uri(GTK_FILE_CHOOSER (dialog)));
  149 
  150       g_free(appdata.export_file);
  151       appdata.export_file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
  152       gtk_widget_destroy (dialog);
  153 
  154       dump_xml(appdata.export_file);
  155     }
  156   else
  157     gtk_widget_destroy (dialog);
  158 }
  159 
  160 /* Capture menu */
  161 
  162 void on_interface_radio_activate(gchar * gui_device)
  163 {
  164   g_assert (gui_device != NULL);
  165 
  166   if (appdata.source.type == ST_LIVE && appdata.source.interface
  167       && !strcmp(gui_device, appdata.source.interface))
  168     return;
  169 
  170   if (in_start_capture)
  171     return;         /* Disregard when called because
  172                  * of interface look change from
  173                  * start_capture */
  174 
  175   if (!gui_stop_capture ())
  176      return;
  177 
  178   appdata_clear_source(&appdata);
  179   appdata.source.type = ST_LIVE;
  180   appdata.source.interface = g_strdup(gui_device);
  181 
  182   gui_start_capture ();
  183 
  184   g_my_info (_("Capture interface set to %s in GUI"), gui_device);
  185 }
  186 
  187 void on_mode_radio_activate(GtkRadioMenuItem * menuitem, gpointer user_data)
  188 {
  189   apemode_t new_mode = APEMODE_DEFAULT;
  190   const gchar *menuname = NULL;
  191   gchar *filter;
  192 
  193   if (in_start_capture)
  194     return;         /* Disregard when called because
  195                  * of interface look change from
  196                  * start_capture */
  197 
  198   menuname = gtk_widget_get_name(GTK_WIDGET (menuitem));
  199   g_assert (menuname);
  200   g_my_debug ("Initial mode in on_mode_radio_activate %s",
  201           (gchar *) menuname);
  202 
  203   if (!strcmp ("link_radio", menuname))
  204     new_mode = LINK6;
  205   else if (!strcmp ("ip_radio", menuname))
  206     new_mode = IP;
  207   else if (!strcmp ("tcp_radio", menuname))
  208     new_mode = TCP;
  209   else
  210     {
  211       g_my_critical ("Unsopported mode in on_mode_radio_activate");
  212       exit (1);
  213     }
  214 
  215   if (new_mode == appdata.mode)
  216     return;
  217 
  218   /* I don't know why, but this menu item is called twice, instead
  219    * of once. This forces me to make sure we are not trying to set
  220    * anything impossible */
  221 
  222   g_my_debug("Mode menuitem active: %d",
  223          gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)));
  224 
  225   if (!has_linklevel() && new_mode == LINK6)
  226     return;
  227 
  228   if (!gui_stop_capture ())
  229      return;
  230 
  231   /* if old filter was still default, we can change to default of new mode */
  232   filter = get_default_filter(appdata.mode);
  233   if (!strcmp(pref.filter, filter))
  234     {
  235       g_free(pref.filter);
  236       pref.filter = get_default_filter(new_mode);
  237     }
  238   appdata.mode = new_mode;
  239   g_my_info (_("Mode set to %s in GUI"), (gchar *) menuitem);
  240   gui_start_capture ();
  241 
  242 }               /* on_mode_radio_activate */
  243 
  244 void on_start_menuitem_activate (GtkMenuItem * menuitem, gpointer user_data)
  245 {
  246   g_my_debug ("on_start_menuitem_activate called");
  247   gui_start_capture ();
  248 }               /* on_start_menuitem_activate */
  249 
  250 void on_pause_menuitem_activate(GtkMenuItem * menuitem, gpointer user_data)
  251 {
  252   g_my_debug ("on_pause_menuitem_activate called");
  253   gui_pause_capture ();
  254 
  255 }               /* on_pause_menuitem_activate */
  256 
  257 void on_next_menuitem_activate(GtkMenuItem * menuitem, gpointer user_data)
  258 {
  259   g_my_debug ("on_next_menuitem_activate called");
  260   force_next_packet();
  261 }
  262 
  263 void on_stop_menuitem_activate(GtkMenuItem * menuitem, gpointer user_data)
  264 {
  265   g_my_debug ("on_stop_menuitem_activate called");
  266   gui_stop_capture ();
  267 }               /* on_stop_menuitem_activate */
  268 
  269 
  270 
  271 /* View menu */
  272 
  273 void on_full_screen_activate(GtkCheckMenuItem * menuitem, gpointer user_data)
  274 {
  275   if (gtk_check_menu_item_get_active(menuitem))
  276     gtk_window_fullscreen((GtkWindow *)appdata.app1);
  277   else
  278     gtk_window_unfullscreen((GtkWindow *)appdata.app1);
  279 }
  280 
  281 void edit_prefs_show_toolbar(struct pref_struct *p, void *data)
  282 {
  283   p->show_toolbar = *(gboolean*)data;
  284 }
  285 
  286 void on_toolbar_check_activate(GtkCheckMenuItem * menuitem, gpointer user_data)
  287 {
  288   GtkWidget *widget;
  289   gboolean active = gtk_check_menu_item_get_active(menuitem);
  290 
  291   widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "toolbar"));
  292   if (active)
  293     gtk_widget_show(widget);
  294   else
  295     gtk_widget_hide(widget);
  296 
  297   pref.show_toolbar = active;
  298   mutate_saved_config(edit_prefs_show_toolbar, &active);
  299 }
  300 
  301 void edit_prefs_show_legend(struct pref_struct *p, void *data)
  302 {
  303   p->show_legend = *(gboolean*)data;
  304 }
  305 
  306 void on_legend_check_activate(GtkCheckMenuItem * menuitem, gpointer user_data)
  307 {
  308   GtkWidget *widget;
  309   gboolean active = gtk_check_menu_item_get_active(menuitem);
  310 
  311   widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "legend_frame"));
  312   if (active)
  313     gtk_widget_show(widget);
  314   else
  315     gtk_widget_hide(widget);
  316 
  317   pref.show_legend = active;
  318   mutate_saved_config(edit_prefs_show_legend, &active);
  319 }
  320 
  321 void edit_prefs_show_statusbar(struct pref_struct *p, void *data)
  322 {
  323   p->show_statusbar = *(gboolean*)data;
  324 }
  325 
  326 void on_status_bar_check_activate(GtkCheckMenuItem * menuitem, gpointer user_data)
  327 {
  328   gboolean active = gtk_check_menu_item_get_active(menuitem);
  329 
  330   if (active)
  331     gtk_widget_show(GTK_WIDGET(appdata.statusbar));
  332   else
  333     gtk_widget_hide(GTK_WIDGET(appdata.statusbar));
  334 
  335   pref.show_statusbar = active;
  336   mutate_saved_config(edit_prefs_show_statusbar, &active);
  337 }
  338 
  339 
  340 /* Help menu */
  341 
  342 
  343 
  344 void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
  345 {
  346   GtkWidget *about;
  347   about = GTK_WIDGET(gtk_builder_get_object (appdata.xml, "about1"));
  348 
  349   gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION);
  350 #ifdef PACKAGE_SCM_REV
  351   msg = g_strdup_printf("HG revision: %s",
  352                         (*PACKAGE_SCM_REV) ? PACKAGE_SCM_REV : _("-unknown-"));
  353   gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about), msg);
  354   g_free(msg);
  355 #endif
  356   gtk_widget_show (about);
  357 }               /* on_about1_activate */
  358 
  359 
  360 void on_help_activate(GtkMenuItem * menuitem, gpointer user_data)
  361 {
  362   GError *err = NULL;
  363 #if GTK_CHECK_VERSION(3,22,0)  
  364   gtk_show_uri_on_window(NULL, "help:" PACKAGE_NAME, GDK_CURRENT_TIME, &err);
  365 #else
  366   gtk_show_uri (NULL, "help:" PACKAGE_NAME, GDK_CURRENT_TIME, &err);
  367 #endif
  368 }
  369 
  370 /* Helper functions */
  371 
  372 #define EN_PLAY 1
  373 #define EN_PAUSE 2
  374 #define EN_NEXT 4
  375 #define EN_STOP 8
  376 
  377 static inline void set_widget_enabled_by_id(const gchar *id, gboolean onoff)
  378 {
  379   GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(appdata.xml, id));
  380   gtk_widget_set_sensitive(w, onoff);
  381 }
  382 
  383 static void set_ctrl_enablestate(guint32 flags)
  384 {
  385   set_widget_enabled_by_id("start_button", !!(flags & EN_PLAY));
  386   set_widget_enabled_by_id("start_menuitem", !!(flags & EN_PLAY));
  387   set_widget_enabled_by_id("pause_button", !!(flags & EN_PAUSE));
  388   set_widget_enabled_by_id("pause_menuitem", !!(flags & EN_PAUSE));
  389   set_widget_enabled_by_id("next_button", !!(flags & EN_NEXT));
  390   set_widget_enabled_by_id("next_menuitem", !!(flags & EN_NEXT));
  391   set_widget_enabled_by_id("stop_button", !!(flags & EN_STOP));
  392   set_widget_enabled_by_id("stop_menuitem", !!(flags & EN_STOP));
  393 }
  394 
  395 /* Sets up the GUI to reflect changes and calls start_capture() */
  396 void gui_start_capture (void)
  397 {
  398   GtkWidget *widget;
  399   gchar *errorbuf = NULL;
  400   GString *status_string = NULL;
  401 
  402   if (get_capture_status() == CAP_EOF)
  403     if (!gui_stop_capture ())
  404       return;
  405 
  406   if (get_capture_status() == STOP)
  407     {
  408       if ((errorbuf = start_capture()) != NULL)
  409         {
  410           fatal_error_dialog (errorbuf);
  411           return;
  412         }
  413     }
  414   else if (get_capture_status() == PLAY)
  415     {
  416       g_warning (_("Status already PLAY at gui_start_capture"));
  417       return;
  418     }
  419   else if (get_capture_status() == PAUSE)
  420     {
  421       errorbuf = unpause_capture();
  422       if (errorbuf)
  423         {
  424           fatal_error_dialog(errorbuf);
  425           return;
  426         }
  427     }
  428 
  429   in_start_capture = TRUE;
  430 
  431   /* Enable and disable control buttons */
  432   set_ctrl_enablestate(EN_STOP|EN_PAUSE|(appdata.source.type == ST_FILE ? EN_NEXT : 0));
  433 
  434   /* Enable and disable link layer menu */
  435   set_widget_enabled_by_id("link_radio", has_linklevel());
  436 
  437   /* Set active mode in GUI */
  438   switch (appdata.mode)
  439     {
  440     case LINK6:
  441       widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "link_radio"));
  442       break;
  443     case IP:
  444       widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "ip_radio"));
  445       break;
  446     case TCP:
  447       widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "tcp_radio"));
  448       break;
  449     default:
  450       g_warning (_("Invalid mode: %d"), appdata.mode);
  451       return;
  452     }
  453   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE);
  454 
  455   /* Set the interface in GUI */
  456   set_active_interface ();
  457 
  458   /* Sets the statusbar */
  459   status_string = g_string_new (_("Reading data from "));
  460 
  461   if (appdata.source.type == ST_FILE && appdata.source.file)
  462     g_string_append (status_string, appdata.source.file);
  463   else if (appdata.source.interface)
  464     g_string_append (status_string, appdata.source.interface);
  465   else
  466     g_string_append (status_string, _("default interface"));
  467 
  468   switch (appdata.mode)
  469     {
  470     case LINK6:
  471       g_string_append (status_string, _(" in Data Link mode"));
  472       break;
  473     case IP:
  474       g_string_append (status_string, _(" in IP mode"));
  475       break;
  476     case TCP:
  477       g_string_append (status_string, _(" in TCP mode"));
  478       break;
  479     default:
  480       g_critical (_("Invalid mode: %d"), appdata.mode);
  481       return;
  482     }
  483 
  484   set_statusbar_msg (status_string->str);
  485   g_string_free (status_string, TRUE);
  486 
  487   in_start_capture = FALSE;
  488 
  489   g_my_info (_("Diagram started"));
  490 }               /* gui_start_capture */
  491 
  492 void
  493 gui_pause_capture (void)
  494 {
  495   gchar *err;
  496 
  497   /*
  498    * Make sure the data in the info windows is updated
  499    * so that it is consistent
  500    */
  501   update_info_windows(NULL);
  502 
  503   err = pause_capture();
  504   if (err)
  505     {
  506       g_error("Error pausing capture: %s", err);
  507       g_free(err);
  508       return;
  509     }
  510 
  511   set_ctrl_enablestate(EN_PLAY|EN_STOP);
  512 
  513   set_statusbar_msg (_("Paused"));
  514 
  515   g_my_info (_("Diagram paused"));
  516   dump_stats(0);
  517 }               /* gui_pause_capture */
  518 
  519 /* reached eof on a file replay */
  520 void gui_eof_capture(void)
  521 {
  522   GString *status_string = NULL;
  523 
  524   if (get_capture_status() == STOP)
  525     return;
  526 
  527   set_ctrl_enablestate(EN_PLAY);
  528 
  529   /* Sets the statusbar */
  530   status_string = g_string_new ("");
  531   g_string_printf(status_string, _("Replay from file '%s' completed."), appdata.source.file);
  532   set_statusbar_msg (status_string->str);
  533   g_string_free (status_string, TRUE);
  534 }               /* gui_stop_capture */
  535 
  536 
  537 /* Sets up the GUI to reflect changes and calls stop_capture() */
  538 gboolean gui_stop_capture (void)
  539 {
  540   GString *status_string = NULL;
  541   gchar *err;
  542 
  543   stop_requested = FALSE;
  544   if (get_capture_status() == STOP)
  545     return TRUE;
  546 
  547   /*
  548    * gui_stop_capture needs to call update_diagram in order to
  549    * delete all canvas_nodes and nodes. But since a slow running
  550    * update_diagram will yield to pending events, gui_stop_capture
  551    * might end up being called below another update_diagram. We can't
  552    * allow two simultaneous calls, so we fail
  553    */
  554   if (already_updating)
  555     {
  556       stop_requested = TRUE;
  557       return FALSE;
  558     }
  559 
  560   err = stop_capture();
  561   if (err)
  562     {
  563       g_error("Failed to stop capture: %s", err);
  564       g_free(err);
  565       return FALSE;
  566     }
  567 
  568   set_ctrl_enablestate(EN_PLAY);
  569 
  570   /* Delete and free protocol information */
  571   delete_gui_protocols ();
  572 
  573   /* final diagram update */
  574   update_diagram_callback(NULL);
  575 
  576   /* Sets the statusbar */
  577   status_string = g_string_new (_("Ready to capture from "));
  578 
  579   if (appdata.source.type == ST_FILE && appdata.source.file)
  580     g_string_append (status_string, appdata.source.file);
  581   else if (appdata.source.interface)
  582     g_string_append (status_string, appdata.source.interface);
  583   else
  584     g_string_append (status_string, _("default interface"));
  585 
  586   set_statusbar_msg (status_string->str);
  587   g_string_free (status_string, TRUE);
  588 
  589   g_my_info (_("Diagram stopped"));
  590   dump_stats(0);
  591   return TRUE;
  592 }               /* gui_stop_capture */
  593 
  594 void fatal_error_dialog(const gchar * message)
  595 {
  596   GtkWidget *error_messagebox;
  597 
  598   error_messagebox = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
  599                          GTK_MESSAGE_ERROR,
  600                          GTK_BUTTONS_OK, "%s", message);
  601   gtk_dialog_run (GTK_DIALOG (error_messagebox));
  602   gtk_widget_destroy (error_messagebox);
  603 
  604 }
  605 
  606 void setmenus(GtkWidget *widget, gpointer data)
  607 {
  608   const gchar *label;
  609 
  610   if (appdata.source.type == ST_FILE)
  611     {
  612       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), TRUE);
  613       return;
  614     }
  615 
  616   label = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(widget))));
  617 
  618   if (appdata.source.type == ST_LIVE && !strcmp(label, appdata.source.interface))
  619     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(widget), TRUE);
  620 }
  621 
  622 void set_active_interface()
  623 {
  624   GtkWidget *widget;
  625 
  626   widget = GTK_WIDGET(gtk_builder_get_object(appdata.xml, "interfaces_menu"));
  627   gtk_container_foreach(GTK_CONTAINER(widget), setmenus, (gpointer)NULL);
  628 }
  629