merge_all_tap_menus() has been moved to menus.c.
[obnox/wireshark/wip.git] / gtk / about_dlg.c
index baa874fb568a18d9b0dc29ba17cc30c93844ea38..a41fa8c4053344714aedb6937855aa304ecb2b05 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
- * Copyright 2000 Gerald Combs
+ * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -20,7 +20,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include <gtk/gtk.h>
 
+#include <string.h>
+
 #include <epan/filesystem.h>
 #include <epan/plugins.h>
-#include "about_dlg.h"
-#include "gui_utils.h"
-#include "dlg_utils.h"
-#include "file_dlg.h"
-#include "compat_macros.h"
-#include "globals.h"
-#if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
-#include "text_page.h"
+#ifdef HAVE_LIBSMI
+#include <epan/oids.h>
+#endif
+#ifdef HAVE_GEOIP
+#include <epan/geoip_db.h>
 #endif
 
-#include "../image/eicon3d64.xpm"
-#include "gtkglobals.h"
-#include "version_info.h"
-#include "main.h"
-#include "plugins_dlg.h"
+#include "../log.h"
+#include "../version_info.h"
+
+#include "gtk/about_dlg.h"
+#include "gtk/gui_utils.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/file_dlg.h"
+#include "gtk/text_page_utils.h"
+#include "gtk/gtkglobals.h"
+#include "gtk/main.h"
+#include "gtk/plugins_dlg.h"
+
+#include "../image/wssplash-dev.xpm"
+#include "webbrowser.h"
+
+/*
+ * Update frequence for the splash screen, given in milliseconds.
+ */
+int info_update_freq = 100;
 
 static void about_wireshark_destroy_cb(GtkWidget *, gpointer);
 
@@ -60,33 +73,49 @@ static GtkWidget *about_wireshark_w;
 
 
 static void
-about_wireshark(GtkWidget *parent, GtkWidget *main_vb, const char *title)
+about_wireshark(GtkWidget *parent _U_, GtkWidget *main_vb)
 {
   GtkWidget   *msg_label, *icon;
-#if GTK_MAJOR_VERSION >= 2
   gchar       *message;
-#endif
+  const char  *title = "Network Protocol Analyzer";
+
+  /*icon = xpm_to_widget_from_parent(parent, wssplash_xpm);*/
+  icon = xpm_to_widget(wssplash_xpm);
 
-  icon = xpm_to_widget_from_parent(parent, eicon3d64_xpm);
   gtk_container_add(GTK_CONTAINER(main_vb), icon);
 
   msg_label = gtk_label_new(title);
-#if GTK_MAJOR_VERSION >= 2
   message = g_strdup_printf("<span size=\"x-large\" weight=\"bold\">%s</span>", title);
   gtk_label_set_markup(GTK_LABEL(msg_label), message);
   g_free(message);
-#endif
   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
 }
 
+static void
+splash_update_label(GtkWidget *win, const char *message)
+{
+    GtkWidget *main_lb;
+
+    if (win == NULL) return;
+
+    main_lb = g_object_get_data(G_OBJECT(win), "splash_label");
+    gtk_label_set_text(GTK_LABEL(main_lb), message);
+
+    /* Process all pending GUI events before continuing, so that
+       the splash screen window gets updated. */
+    while (gtk_events_pending()) gtk_main_iteration();
+}
 
-GtkWidget *
-splash_new(char *message)
+GtkWidget*
+splash_new(const char *message)
 {
     GtkWidget *win;
     GtkWidget *main_lb;
 
     GtkWidget *main_vb;
+    GtkWidget *percentage_hb;
+    GtkWidget *prog_bar;
+    GtkWidget *percentage_lb;
 
     win = splash_window_new();
 
@@ -97,58 +126,171 @@ splash_new(char *message)
     gtk_widget_realize(win);
 
     main_vb = gtk_vbox_new(FALSE, 6);
-    gtk_container_border_width(GTK_CONTAINER(main_vb), 24);
+    gtk_container_set_border_width(GTK_CONTAINER(main_vb), 24);
     gtk_container_add(GTK_CONTAINER(win), main_vb);
 
-    about_wireshark(win, main_vb, "Wireshark - Network Protocol Analyzer");
+    about_wireshark(win, main_vb);
 
     main_lb = gtk_label_new(message);
     gtk_container_add(GTK_CONTAINER(main_vb), main_lb);
-    OBJECT_SET_DATA(win, "splash_label", main_lb);
-    
+    g_object_set_data(G_OBJECT(win), "splash_label", main_lb);
+
+    main_lb = gtk_label_new("");
+    gtk_container_add(GTK_CONTAINER(main_vb), main_lb);
+    g_object_set_data(G_OBJECT(win), "protocol_label", main_lb);
+
+    percentage_hb = gtk_hbox_new(FALSE, 1);
+    gtk_box_pack_start(GTK_BOX(main_vb), percentage_hb, TRUE, TRUE, 3);
+
+    prog_bar = gtk_progress_bar_new();
+    gtk_box_pack_start(GTK_BOX(percentage_hb), prog_bar, TRUE, TRUE, 3);
+    g_object_set_data(G_OBJECT(win), "progress_bar", prog_bar);
+
+    percentage_lb = gtk_label_new("  0%");
+    gtk_misc_set_alignment(GTK_MISC(percentage_lb), 0.0f, 0.0f);
+    gtk_box_pack_start(GTK_BOX(percentage_hb), percentage_lb, FALSE, TRUE, 3);
+    g_object_set_data(G_OBJECT(win), "percentage_label", percentage_lb);
+
     gtk_widget_show_all(win);
 
-    splash_update(win, message);
+    splash_update_label(win, message);
 
     return win;
 }
 
 void
-splash_update(GtkWidget *win, char *message)
+splash_update(register_action_e action, const char *message, gpointer client_data)
 {
-    GtkWidget *main_lb;
+    GtkWidget  *win;
+    GtkWidget  *main_lb;
+    GtkWidget  *prog_bar;
+    GtkWidget  *percentage_lb;
+    gfloat     percentage;
+    gulong     ul_percentage;
+    gchar      tmp[100];
+    const char *action_msg;
+
+    static gulong ul_sofar = 0;
+    static gulong ul_count = 0;
+
+    static register_action_e last_action = RA_NONE;
+
+    static GTimeVal cur_tv;
+    static GTimeVal next_tv = {0, 0};
+
+    win = (GtkWidget *)client_data;
 
     if (win == NULL) return;
 
-    main_lb = OBJECT_GET_DATA(win, "splash_label");
-    gtk_label_set_text(GTK_LABEL(main_lb), message);
+    g_get_current_time(&cur_tv);
+    if (cur_tv.tv_sec <= next_tv.tv_sec && cur_tv.tv_usec <= next_tv.tv_usec && ul_sofar < ul_count - 1) {
+      /* Only update every splash_register_freq milliseconds */
+      ul_sofar++;
+      return;
+    }
+    memcpy(&next_tv, &cur_tv, sizeof(next_tv));
+    next_tv.tv_usec += info_update_freq * 1000;
+    if (next_tv.tv_usec >= 1000000) {
+        next_tv.tv_sec++;
+        next_tv.tv_usec -= 1000000;
+    }
+
+    if(last_action != action) {
+      /* the action has changed */
+      switch(action) {
+      case RA_DISSECTORS:
+       action_msg = "Initializing dissectors ...";
+       break;
+      case RA_LISTENERS:
+       action_msg = "Initializing tap listeners ...";
+       break;
+      case RA_REGISTER:
+       action_msg = "Registering dissector ...";
+       break;
+      case RA_PLUGIN_REGISTER:
+       action_msg = "Registering plugins ...";
+       break;
+      case RA_HANDOFF:
+       action_msg = "Handing off dissector ...";
+       break;
+      case RA_PLUGIN_HANDOFF:
+       action_msg = "Handing off plugins ...";
+       break;
+      case RA_PREFERENCES:
+       action_msg = "Loading module preferences ...";
+       break;
+      case RA_CONFIGURATION:
+       action_msg = "Loading configuration files ...";
+       break;
+      default:
+       action_msg = "(Unknown action)";;
+       break;
+      }
+      splash_update_label(win, action_msg);
+      last_action = action;
+    }
+
+    if(ul_count == 0) /* get the count of dissectors */
+      ul_count = register_count() + 6; /* additional 6 for:
+                                         dissectors, listeners,
+                                         registering plugins, handingoff plugins,
+                                         preferences and configuration */
+
+    main_lb = g_object_get_data(G_OBJECT(win), "protocol_label");
+    /* make_dissector_reg.py changed -
+       so we need to strip off the leading elements to get back to the protocol */
+    if(message) {
+      if(!strncmp(message, "proto_register_", 15))
+       message += 15;
+      else if(!strncmp(message, "proto_reg_handoff_", 18))
+       message += 18;
+    }
+    gtk_label_set_text(GTK_LABEL(main_lb), message ? message : "");
+
+    ul_sofar++;
+
+    g_assert (ul_sofar <= ul_count);
+
+    percentage = (gfloat)ul_sofar/(gfloat)ul_count;
+    ul_percentage = (gulong)(percentage * 100);
+
+    /* update progress bar */
+    prog_bar = g_object_get_data(G_OBJECT(win), "progress_bar");
+    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prog_bar), percentage);
+
+    percentage_lb = g_object_get_data(G_OBJECT(win), "percentage_label");
+    g_snprintf(tmp, sizeof(tmp), "%lu%%", ul_percentage);
+    gtk_label_set_text((GtkLabel*)percentage_lb, tmp);
 
     /* Process all pending GUI events before continuing, so that
        the splash screen window gets updated. */
     while (gtk_events_pending()) gtk_main_iteration();
+
 }
 
-guint
+gboolean
 splash_destroy(GtkWidget *win)
 {
-    if (win == NULL) return FALSE;
+    if (win == NULL)
+        return FALSE;
 
     gtk_widget_destroy(win);
     return FALSE;
 }
 
-
 static GtkWidget *
 about_wireshark_page_new(void)
 {
   GtkWidget   *main_vb, *msg_label /*, *icon*/;
   gchar       *message;
-  const char   title[] = "Wireshark - Network Protocol Analyzer";
 
   main_vb = gtk_vbox_new(FALSE, 6);
-  gtk_container_border_width(GTK_CONTAINER(main_vb), 12);
+  gtk_container_set_border_width(GTK_CONTAINER(main_vb), 12);
+
+  g_object_set(gtk_widget_get_settings(main_vb),
+    "gtk-label-select-on-focus", FALSE, NULL);
 
-  about_wireshark(top_level, main_vb, title);
+  about_wireshark(top_level, main_vb);
 
   /* Construct the message string */
   message = g_strdup_printf(
@@ -163,21 +305,18 @@ about_wireshark_page_new(void)
        "Wireshark is Open Source Software released under the GNU General Public License.\n"
        "\n"
        "Check the man page and http://www.wireshark.org for more information.",
-       svnversion, get_copyright_info(), comp_info_str->str,
+       wireshark_svnversion, get_copyright_info(), comp_info_str->str,
        runtime_info_str->str);
 
   msg_label = gtk_label_new(message);
   g_free(message);
   gtk_label_set_justify(GTK_LABEL(msg_label), GTK_JUSTIFY_FILL);
-#if GTK_MAJOR_VERSION >= 2
   gtk_label_set_selectable(GTK_LABEL(msg_label), TRUE);
-#endif
   gtk_container_add(GTK_CONTAINER(main_vb), msg_label);
 
   return main_vb;
 }
 
-#if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
 static GtkWidget *
 about_authors_page_new(void)
 {
@@ -189,7 +328,31 @@ about_authors_page_new(void)
 
   return page;
 }
-#endif
+
+static gboolean about_folders_callback(GtkWidget *widget, GdkEventButton *event, gint id _U_)
+{
+  GtkTreeSelection *tree_selection;
+  GtkTreeModel *model;
+  GtkTreeIter  iter;
+  gchar        *path;
+
+  tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+
+  if(gtk_tree_selection_count_selected_rows(tree_selection) == 0)
+    return FALSE;
+
+  if(event->type != GDK_2BUTTON_PRESS)
+    /* not a double click */
+    return FALSE;
+
+  if(gtk_tree_selection_get_selected (tree_selection, &model, &iter)) {
+    gtk_tree_model_get(model, &iter, 1, &path, -1);
+    filemanager_open_directory(path);
+    g_free(path);
+  }
+
+  return TRUE;
+}
 
 static void
 about_folders_row(GtkWidget *table, const char *label, const char *dir, const char *tip)
@@ -197,7 +360,6 @@ about_folders_row(GtkWidget *table, const char *label, const char *dir, const ch
   simple_list_append(table, 0, label, 1, dir, 2, tip, -1);
 }
 
-
 static GtkWidget *
 about_folders_page_new(void)
 {
@@ -206,16 +368,24 @@ about_folders_page_new(void)
   char *path;
   const gchar *titles[] = { "Name", "Folder", "Typical Files"};
   GtkWidget *scrolledwindow;
+#if defined (HAVE_LIBSMI) || defined (HAVE_GEOIP)
+  gint i;
+  gchar **resultArray;
+#endif
 
   scrolledwindow = scrolled_window_new(NULL, NULL);
-#if GTK_MAJOR_VERSION >= 2
-  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), 
+  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow),
                                    GTK_SHADOW_IN);
-#endif
 
   /* Container for our data */
   table = simple_list_new(3, titles);
 
+  /* connect a callback so we can spot a double-click */
+  g_signal_connect(table, "button_press_event",
+                    G_CALLBACK(about_folders_callback), NULL);
+
+  simple_list_url_col(table, 1);
+
   /* "file open" */
   about_folders_row(table, "\"File\" dialogs", get_last_open_dir(),
       "capture files");
@@ -224,13 +394,13 @@ about_folders_page_new(void)
   path = get_tempfile_path("");
   about_folders_row(table, "Temp", path,
       "untitled capture files");
-  g_free((void *) path);
+  g_free(path);
 
   /* pers conf */
-  path = get_persconffile_path("", FALSE);
-  about_folders_row(table, "Personal configuration", path, 
+  path = get_persconffile_path("", FALSE, FALSE);
+  about_folders_row(table, "Personal configuration", path,
       "\"dfilters\", \"preferences\", \"ethers\", ...");
-  g_free((void *) path);
+  g_free(path);
 
   /* global conf */
   constpath = get_datafile_dir();
@@ -249,18 +419,48 @@ about_folders_page_new(void)
   about_folders_row(table, "Program", constpath,
       "program files");
 
-#ifdef HAVE_PLUGINS
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
   /* pers plugins */
   path = get_plugins_pers_dir();
   about_folders_row(table, "Personal Plugins", path,
       "dissector plugins");
-  g_free((void *) path);
+  g_free(path);
 
   /* global plugins */
-  path = get_plugins_global_dir(PLUGIN_DIR);
-  about_folders_row(table, "Global Plugins", path,
+  about_folders_row(table, "Global Plugins", get_plugin_dir(),
       "dissector plugins");
-  g_free((void *) path);
+#endif
+
+#ifdef HAVE_PYTHON
+  /* global python bindings */
+  about_folders_row(table, "Python Bindings", get_wspython_dir(),
+      "python bindings");
+#endif
+
+#ifdef HAVE_GEOIP
+  /* GeoIP */
+  path = geoip_db_get_paths();
+
+  resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
+
+  for(i = 0; resultArray[i]; i++)
+    about_folders_row(table, "GeoIP path", g_strstrip(resultArray[i]),
+                     "GeoIP database search path");
+  g_strfreev(resultArray);
+  g_free(path);
+#endif
+
+#ifdef HAVE_LIBSMI
+  /* SMI MIBs/PIBs */
+  path = oid_get_default_mib_path();
+
+  resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
+
+  for(i = 0; resultArray[i]; i++)
+    about_folders_row(table, "MIB/PIB path", g_strstrip(resultArray[i]),
+                     "SMI MIB/PIB search path");
+  g_strfreev(resultArray);
+  g_free(path);
 #endif
 
   gtk_container_add(GTK_CONTAINER(scrolledwindow), table);
@@ -268,17 +468,34 @@ about_folders_page_new(void)
   return scrolledwindow;
 }
 
+static GtkWidget *
+about_license_page_new(void)
+{
+  GtkWidget   *page;
+  char *absolute_path;
+
+#if defined(_WIN32)
+  absolute_path = get_datafile_path("COPYING.txt");
+#else
+  absolute_path = get_datafile_path("COPYING");
+#endif
+  page = text_page_new(absolute_path);
+
+  return page;
+}
 
 void
 about_wireshark_cb( GtkWidget *w _U_, gpointer data _U_ )
 {
   GtkWidget   *main_vb, *main_nb, *bbox, *ok_btn;
+  GtkWidget   *page_lb, *about_page, *folders_page;
 
-  GtkWidget   *page_lb, *about_page, *folders_page, *plugins_page;
-#if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
-  GtkWidget   *authors_page;
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
+  GtkWidget   *plugins_page;
 #endif
 
+  GtkWidget   *authors_page, *license_page;
+
   if (about_wireshark_w != NULL) {
     /* There's already an "About Wireshark" dialog box; reactivate it. */
     reactivate_window(about_wireshark_w);
@@ -294,18 +511,12 @@ about_wireshark_cb( GtkWidget *w _U_, gpointer data _U_ )
   about_wireshark_w = dlg_window_new("About Wireshark");
   /* set the initial position (must be done, before show is called!) */
   /* default position is not appropriate for the about dialog */
-#if GTK_MAJOR_VERSION >= 2
   gtk_window_set_position(GTK_WINDOW(about_wireshark_w), GTK_WIN_POS_CENTER_ON_PARENT);
-#else
-  gtk_window_set_position(GTK_WINDOW(about_wireshark_w), GTK_WIN_POS_CENTER);
-#endif
-  /* setting the size is dangerous here, as making it too short will 
-   * clip content on GTK1, so simply use the natural size */
-  /*gtk_window_set_default_size(GTK_WINDOW(about_wireshark_w), 600, 400);*/
-  gtk_container_border_width(GTK_CONTAINER(about_wireshark_w), 6);
+  gtk_window_set_default_size(GTK_WINDOW(about_wireshark_w), 600, 400);
+  gtk_container_set_border_width(GTK_CONTAINER(about_wireshark_w), 6);
 
   main_vb = gtk_vbox_new(FALSE, 12);
-  gtk_container_border_width(GTK_CONTAINER(main_vb), 6);
+  gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
   gtk_container_add(GTK_CONTAINER(about_wireshark_w), main_vb);
 
   main_nb = gtk_notebook_new();
@@ -315,31 +526,37 @@ about_wireshark_cb( GtkWidget *w _U_, gpointer data _U_ )
   page_lb = gtk_label_new("Wireshark");
   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), about_page, page_lb);
 
-#if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3
   authors_page = about_authors_page_new();
   page_lb = gtk_label_new("Authors");
   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), authors_page, page_lb);
-#endif
 
   folders_page = about_folders_page_new();
   page_lb = gtk_label_new("Folders");
   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), folders_page, page_lb);
 
-#ifdef HAVE_PLUGINS
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
   plugins_page = about_plugins_page_new();
   page_lb = gtk_label_new("Plugins");
   gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), plugins_page, page_lb);
 #endif
 
+  license_page = about_license_page_new();
+  page_lb = gtk_label_new("License");
+  /* set a minmum width to avoid a lot of line breaks at the wrong places */
+  gtk_widget_set_size_request(license_page, 600, -1);
+  gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), license_page, page_lb);
+
   /* Button row */
   bbox = dlg_button_row_new(GTK_STOCK_OK, NULL);
   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
 
-  ok_btn = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
+  ok_btn = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
+  gtk_widget_grab_focus(ok_btn);
+  gtk_widget_grab_default(ok_btn);
   window_set_cancel_button(about_wireshark_w, ok_btn, window_cancel_button_cb);
 
-  SIGNAL_CONNECT(about_wireshark_w, "delete_event", window_delete_event_cb, NULL);
-  SIGNAL_CONNECT(about_wireshark_w, "destroy", about_wireshark_destroy_cb, NULL);
+  g_signal_connect(about_wireshark_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+  g_signal_connect(about_wireshark_w, "destroy", G_CALLBACK(about_wireshark_destroy_cb), NULL);
 
   gtk_widget_show_all(about_wireshark_w);
   window_present(about_wireshark_w);
@@ -351,5 +568,3 @@ about_wireshark_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
   /* Note that we no longer have an "About Wireshark" dialog box. */
   about_wireshark_w = NULL;
 }
-
-