Turn the code of "colorize_packet()" into a static routine that is given
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 9 Jul 2000 03:29:42 +0000 (03:29 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 9 Jul 2000 03:29:42 +0000 (03:29 +0000)
a word to use in the progress dialog, and a flag indicating whether the
display filter is to be reevaluated or not, and:

have "colorize_packet()" call that routine with "Colorizing" and
FALSE as those arguments;

have the filtering code call that routine with "Filtering" and
TRUE as those arguments;

add an exported routine to call that routine with "Reprocessing"
and TRUE as those arguments, to use to re-generate the packet
list and to re-filter the packets if a protocol preference has
been changed.

Keep track of whether preferences are changed from their initial value
by a preferences file or a command-line option, or from their previous
value by the "Preferences" dialog box; have "prefs_apply_all()" only
call the "apply" callback for a module if they have.

Call "prefs_apply_all()" after the command-line arguments have been
parsed and after "OK" has been clicked in the "Preferences" dialog box,
to notify modules of preference changes if they've registered a callback
for that.

After "OK" has been clicked in the "Preferences" dialog box, if any
preferences have changed, call the reprocessing routine, as the summary
line for some frames and/or the current display filter's value when
applied to some frames may have changed as a result of a preference
change.  Do the same after "OK" or "Apply" has been clicked in the
"Display Options" dialog box (as it controls a protocol preferences
item.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@2126 f5534014-38df-0310-8fa8-9805f1628bb7

file.c
file.h
gtk/display_opts.c
gtk/main.c
gtk/prefs_dlg.c
prefs-int.h
prefs.c
prefs.h
tethereal.c

diff --git a/file.c b/file.c
index f1595d0737bab894c0e132c2813d2cb34cff6e5f..f9c895e0e72446993773c5847424f60bf32486b0 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.196 2000/07/07 23:09:03 guy Exp $
+ * $Id: file.c,v 1.197 2000/07/09 03:29:26 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -95,6 +95,9 @@ static guint32 prevsec, prevusec;
 
 static void read_packet(capture_file *cf, int offset);
 
+static void rescan_packets(capture_file *cf, const char *action,
+       gboolean refilter);
+
 static void set_selected_row(int row);
 
 static void freeze_clist(capture_file *cf);
@@ -589,7 +592,8 @@ apply_color_filter(gpointer filter_arg, gpointer argp)
 
 static int
 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
-       union wtap_pseudo_header *pseudo_header, const u_char *buf)
+       union wtap_pseudo_header *pseudo_header, const u_char *buf,
+       gboolean refilter)
 {
   apply_color_filter_args args;
   gint          i, row;
@@ -620,37 +624,57 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
     fdata->cinfo->col_data[i][0] = '\0';
   }
 
-  /* Apply the filters */
-  if (cf->dfcode != NULL || filter_list != NULL) {
+  /* If either
+
+       we have a display filter and are re-applying it;
+
+       we have a list of color filters;
+
+       we have plugins to apply;
+
+     allocate a protocol tree root node, so that we'll construct
+     a protocol tree against which a filter expression can be
+     evaluated. */
+  if ((cf->dfcode != NULL && refilter) || filter_list != NULL
+#ifdef HAVE_PLUGINS
+       || enabled_plugins_number > 0
+#endif
+       )
     protocol_tree = proto_tree_create_root();
-    dissect_packet(pseudo_header, buf, fdata, protocol_tree);
-    if (cf->dfcode != NULL)
-      fdata->flags.passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, buf, fdata->cap_len) ? 1 : 0;
-    else
-      fdata->flags.passed_dfilter = 1;
 
-    /* Apply color filters, if we have any. */
+  /* Dissect the frame. */
+  dissect_packet(pseudo_header, buf, fdata, protocol_tree);
+
+  /* If we have a display filter, apply it if we're refiltering, otherwise
+     leave the "passed_dfilter" flag alone.
+
+     If we don't have a display filter, set "passed_dfilter" to 1. */
+  if (cf->dfcode != NULL) {
+    if (refilter) {
+      if (cf->dfcode != NULL)
+        fdata->flags.passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, buf, fdata->cap_len) ? 1 : 0;
+      else
+        fdata->flags.passed_dfilter = 1;
+    }
+  } else
+    fdata->flags.passed_dfilter = 1;
+
+  /* If we have color filters, and the frame is to be displayed, apply
+     the color filters. */
+  if (fdata->flags.passed_dfilter) {
     if (filter_list != NULL) {
       args.protocol_tree = protocol_tree;
       args.pd = buf;
       args.fdata = fdata;
       g_slist_foreach(filter_list, apply_color_filter, &args);
     }
-    proto_tree_free(protocol_tree);
-  }
-  else {
-#ifdef HAVE_PLUGINS
-       if (enabled_plugins_number > 0)
-           protocol_tree = proto_tree_create_root();
-#endif
-       dissect_packet(pseudo_header, buf, fdata, protocol_tree);
-       fdata->flags.passed_dfilter = 1;
-#ifdef HAVE_PLUGINS
-       if (protocol_tree)
-           proto_tree_free(protocol_tree);
-#endif
   }
 
+  /* There are no more filters to apply, so we don't need any protocol
+     tree; free it if we created it. */
+  if (protocol_tree != NULL)
+    proto_tree_free(protocol_tree);
+
   if (fdata->flags.passed_dfilter) {
     /* This frame passed the display filter, so add it to the clist. */
 
@@ -766,7 +790,7 @@ read_packet(capture_file *cf, int offset)
 
     cf->count++;
     fdata->num = cf->count;
-    add_packet_to_packet_list(fdata, cf, pseudo_header, buf);
+    add_packet_to_packet_list(fdata, cf, pseudo_header, buf, TRUE);
   } else {
     /* XXX - if we didn't have read filters, or if we could avoid
        allocating the "frame_data" structure until we knew whether
@@ -814,17 +838,31 @@ filter_packets(capture_file *cf, gchar *dftext)
     dfilter_destroy(cf->dfcode);
   cf->dfcode = dfcode;
 
-  /* Now go through the list of packets we've read from the capture file,
-     applying the current display filter, and, if the packet passes the
-     display filter, add it to the summary display, appropriately
-     colored.  (That's how we colorize the display - it's like filtering
-     the display, only we don't install a new filter.) */
-  colorize_packets(cf);
+  /* Now rescan the packet list, applying the new filter. */
+  rescan_packets(cf, "Filtering", TRUE);
   return 1;
 }
 
 void
 colorize_packets(capture_file *cf)
+{
+  rescan_packets(cf, "Colorizing", FALSE);
+}
+
+void
+redissect_packets(capture_file *cf)
+{
+  rescan_packets(cf, "Reprocessing", TRUE);
+}
+
+/* Rescan the list of packets, reconstructing the CList.
+
+   "action" describes why we're doing this; it's used in the progress
+   dialog box.
+
+   "refilter" is TRUE if we need to re-evaluate the filter expression. */
+static void
+rescan_packets(capture_file *cf, const char *action, gboolean refilter)
 {
   frame_data *fdata;
   progdlg_t *progbar;
@@ -866,9 +904,9 @@ colorize_packets(capture_file *cf)
   cf->first_displayed = NULL;
   cf->last_displayed = NULL;
 
-  /* Iterate through the list of packets, calling a routine
-     to run the filter on the packet, see if it matches, and
-     put it in the display list if so.  */
+  /* Iterate through the list of frames.  Call a routine for each frame
+     to check whether it should be displayed and, if so, add it to
+     the display list. */
   firstsec = 0;
   firstusec = 0;
   prevsec = 0;
@@ -883,7 +921,7 @@ colorize_packets(capture_file *cf)
   count = 0;
 
   stop_flag = FALSE;
-  progbar = create_progress_dlg("Filtering", "Stop", &stop_flag);
+  progbar = create_progress_dlg(action, "Stop", &stop_flag);
 
   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
@@ -923,7 +961,8 @@ colorize_packets(capture_file *cf)
     wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
        cf->pd, fdata->cap_len);
 
-    row = add_packet_to_packet_list(fdata, cf, &cf->pseudo_header, cf->pd);
+    row = add_packet_to_packet_list(fdata, cf, &cf->pseudo_header, cf->pd,
+                                       refilter);
     if (fdata == selected_frame)
       selected_row = row;
   }
diff --git a/file.h b/file.h
index b91cfbba68f52377cd2924bdb0fa22da4b7fdfa4..72b6c87bd26fd93536d751f6ba3dab946610445e 100644 (file)
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
 /* file.h
  * Definitions for file structures and routines
  *
- * $Id: file.h,v 1.70 2000/07/03 08:35:41 guy Exp $
+ * $Id: file.h,v 1.71 2000/07/09 03:29:27 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -140,6 +140,7 @@ int  save_cap_file(char *, capture_file *, gboolean, guint);
 
 int filter_packets(capture_file *cf, gchar *dfilter);
 void colorize_packets(capture_file *);
+void redissect_packets(capture_file *cf);
 int print_packets(capture_file *cf, print_args_t *print_args);
 void change_time_formats(capture_file *);
 gboolean find_packet(capture_file *cf, dfilter *sfcode);
index 8ae7224da371a3ea67944c089c1e51cb279e4595..6f8f398ad8d20966320ff1da0a1dd038ce3b4747 100644 (file)
@@ -1,7 +1,7 @@
 /* display_opts.c
  * Routines for packet display windows
  *
- * $Id: display_opts.c,v 1.10 2000/07/05 02:45:39 guy Exp $
+ * $Id: display_opts.c,v 1.11 2000/07/09 03:29:40 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -241,6 +241,7 @@ static void
 get_display_options(GtkWidget *parent_w)
 {
   GtkWidget *button;
+  gboolean bval;
 
   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
                                               E_DISPLAY_TIME_ABS_KEY);
@@ -267,7 +268,20 @@ get_display_options(GtkWidget *parent_w)
 
   button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
                                             E_DISPLAY_IP_DSCP_KEY);
-  g_ip_dscp_actif = (GTK_TOGGLE_BUTTON (button)->active);
+  bval = (GTK_TOGGLE_BUTTON (button)->active);
+  if (g_ip_dscp_actif != bval) {
+    g_ip_dscp_actif = bval;
+
+    /* XXX - we "know" here that the IP dissector doesn't need to be
+       notified if this preference changed.
+
+       Ultimately, we should probably remove this item from the
+       "Display options" dialog box, as it can be changed from the
+       "IP" tab in the "Preferences" dialog box. */
+
+    /* Redissect all the packets, and re-evaluate the display filter. */
+    redissect_packets(&cfile);
+  }
 }
 
 static void
index f76a91ecd4f37705239f97cc54634edbcc1e7f94..5f4fca2b5d5e2d05bbc9729c059907d1f91a3065 100644 (file)
@@ -1,6 +1,6 @@
 /* main.c
  *
- * $Id: main.c,v 1.128 2000/07/05 09:41:04 guy Exp $
+ * $Id: main.c,v 1.129 2000/07/09 03:29:40 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -1485,6 +1485,11 @@ main(int argc, char *argv[])
     }
   }
 
+  /* Notify all registered modules that have had any of their preferences
+     changed either from one of the preferences file or from the command
+     line that its preferences have changed. */
+  prefs_apply_all();
+
 #ifndef HAVE_LIBPCAP
   if (capture_option_specified)
     fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n");
index a107816ac532b7c1ceca194893fde180459ca0a6..7af69af96b0831c4a7dab413f64fc02cba6f31a3 100644 (file)
@@ -1,7 +1,7 @@
 /* prefs_dlg.c
  * Routines for handling preferences
  *
- * $Id: prefs_dlg.c,v 1.14 2000/07/05 09:41:07 guy Exp $
+ * $Id: prefs_dlg.c,v 1.15 2000/07/09 03:29:42 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -334,8 +334,11 @@ pref_fetch(pref_t *pref, gpointer user_data)
   char *str_val;
   char *p;
   guint uval;
+  gboolean bval;
   GSList *rb_entry;
   GtkWidget *button;
+  gint enumval;
+  gboolean *pref_changed_p = user_data;
 
   /* Fetch the value of the preference, and set the appropriate variable
      to it. */
@@ -348,11 +351,18 @@ pref_fetch(pref_t *pref, gpointer user_data)
     if (p == value || *p != '\0')
       return PREFS_SET_SYNTAX_ERR;     /* number was bad */
 #endif
-    *pref->varp.uint = uval;
+    if (*pref->varp.uint != uval) {
+      *pref_changed_p = TRUE;
+      *pref->varp.uint = uval;
+    }
     break;
 
   case PREF_BOOL:
-    *pref->varp.bool = GTK_TOGGLE_BUTTON(pref->control)->active;
+    bval = GTK_TOGGLE_BUTTON(pref->control)->active;
+    if (*pref->varp.bool != bval) {
+      *pref_changed_p = TRUE;
+      *pref->varp.bool = bval;
+    }
     break;
 
   case PREF_ENUM:
@@ -377,15 +387,22 @@ pref_fetch(pref_t *pref, gpointer user_data)
 
     /* Get the label, and translate it to a value. */
     gtk_label_get(GTK_LABEL(label), &label_string);
-    *pref->varp.enump = find_val_for_string(label_string,
+    enumval = find_val_for_string(label_string,
                                        pref->info.enum_info.enumvals, 1);
+    if (*pref->varp.enump != enumval) {
+      *pref_changed_p = TRUE;
+      *pref->varp.enump = enumval;
+    }
     break;
 
   case PREF_STRING:
     str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
-    if (*pref->varp.string != NULL)
-      g_free(*pref->varp.string);
-    *pref->varp.string = g_strdup(str_val);
+    if (*pref->varp.string == NULL || strcmp(*pref->varp.string, str_val) != 0) {
+      *pref_changed_p = TRUE;
+      if (*pref->varp.string != NULL)
+        g_free(*pref->varp.string);
+      *pref->varp.string = g_strdup(str_val);
+    }
     break;
   }
 }
@@ -393,9 +410,18 @@ pref_fetch(pref_t *pref, gpointer user_data)
 static void
 module_prefs_fetch(module_t *module, gpointer user_data)
 {
+  gboolean *must_redissect_p = user_data;
+
   /* For all preferences in this module, fetch its value from this
-     module's notebook page. */
-  prefs_pref_foreach(module, pref_fetch, NULL);
+     module's notebook page.  Find out whether any of them changed. */
+  module->prefs_changed = FALSE;       /* assume none of them changed */
+  prefs_pref_foreach(module, pref_fetch, &module->prefs_changed);
+
+  /* If any of them changed, indicate that we must redissect and refilter
+     the current capture (if we have one), as the preference change
+     could cause packets to be dissected differently. */
+  if (module->prefs_changed)
+    *must_redissect_p = TRUE;
 }
 
 static void
@@ -432,13 +458,21 @@ module_prefs_clean(module_t *module, gpointer user_data)
 static void
 prefs_main_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
 {
+  gboolean must_redissect = FALSE;
+
   printer_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
   column_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
   stream_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
   gui_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
-  prefs_module_foreach(module_prefs_fetch, NULL);
+  prefs_module_foreach(module_prefs_fetch, &must_redissect);
+  prefs_apply_all();
   prefs_module_foreach(module_prefs_clean, NULL);
   gtk_widget_destroy(GTK_WIDGET(parent_w));
+
+  if (must_redissect) {
+    /* Redissect all the packets, and re-evaluate the display filter. */
+    redissect_packets(&cfile);
+  }
 }
 
 static void
index 0e96f5ff39a3c9f12ed0491405f4c53a37021f11..3df04f88b69d6533d96c4e33ea1c94f81a634fd1 100644 (file)
@@ -2,7 +2,7 @@
  * Definitions for implementation of preference handling routines;
  * used by "friends" of the preferences type.
  *
- * $Id: prefs-int.h,v 1.1 2000/07/05 09:40:40 guy Exp $
+ * $Id: prefs-int.h,v 1.2 2000/07/09 03:29:27 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -33,6 +33,7 @@ struct pref_module {
        void (*apply_cb)(void); /* routine to call when preferences applied */
        GList   *prefs;         /* list of its preferences */
        int     numprefs;       /* number of preferences */
+       gboolean prefs_changed; /* if TRUE, a preference has changed since we last checked */
 };
 
 typedef enum {
diff --git a/prefs.c b/prefs.c
index e4b2e18829b2dc4502ed0ff7215c9fb27d2c1ebd..77f99d04940c07ef68b2fa659e08f0501c6c319a 100644 (file)
--- a/prefs.c
+++ b/prefs.c
@@ -1,7 +1,7 @@
 /* prefs.c
  * Routines for handling preferences
  *
- * $Id: prefs.c,v 1.31 2000/07/05 09:40:41 guy Exp $
+ * $Id: prefs.c,v 1.32 2000/07/09 03:29:28 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -100,6 +100,7 @@ prefs_register_module(const char *name, const char *title,
        module->apply_cb = apply_cb;
        module->prefs = NULL;   /* no preferences, to start */
        module->numprefs = 0;
+       module->prefs_changed = FALSE;
 
        modules = g_list_append(modules, module);
 
@@ -161,11 +162,18 @@ call_apply_cb(gpointer data, gpointer user_data)
 {
        module_t *module = data;
 
-       (*module->apply_cb)();
+       if (module->prefs_changed) {
+               if (module->apply_cb != NULL)
+                       (*module->apply_cb)();
+               module->prefs_changed = FALSE;
+       }
 }
 
 /*
- * Call the "apply" callback function for each module.
+ * Call the "apply" callback function for each module if any of its
+ * preferences have changed, and then clear the flag saying its
+ * preferences have changed, as the module has been notified of that
+ * fact.
  */
 void
 prefs_apply_all(void)
@@ -714,6 +722,8 @@ set_pref(gchar *pref_name, gchar *value)
   fmt_data *cfmt;
   unsigned long int cval;
   guint    uval;
+  gboolean bval;
+  gint     enum_val;
   char     *p;
   gchar    *dotp;
   module_t *module;
@@ -836,27 +846,41 @@ set_pref(gchar *pref_name, gchar *value)
       uval = strtoul(value, &p, pref->info.base);
       if (p == value || *p != '\0')
         return PREFS_SET_SYNTAX_ERR;   /* number was bad */
-      *pref->varp.uint = uval;
+      if (*pref->varp.uint != uval) {
+        module->prefs_changed = TRUE;
+        *pref->varp.uint = uval;
+      }
       break;
 
     case PREF_BOOL:
       /* XXX - give an error if it's neither "true" nor "false"? */
       if (strcasecmp(value, "true") == 0)
-        *pref->varp.bool = TRUE;
+        bval = TRUE;
       else
-        *pref->varp.bool = FALSE;
+        bval = FALSE;
+      if (*pref->varp.bool != bval) {
+       module->prefs_changed = TRUE;
+       *pref->varp.bool = bval;
+      }
       break;
 
     case PREF_ENUM:
       /* XXX - give an error if it doesn't match? */
-      *pref->varp.enump = find_val_for_string(value,
+      enum_val = find_val_for_string(value,
                                        pref->info.enum_info.enumvals, 1);
+      if (*pref->varp.enump != enum_val) {
+       module->prefs_changed = TRUE;
+       *pref->varp.enump = enum_val;
+      }
       break;
 
     case PREF_STRING:
-      if (*pref->varp.string != NULL)
-        g_free(*pref->varp.string);
-      *pref->varp.string = g_strdup(value);
+      if (*pref->varp.string == NULL || strcmp(*pref->varp.string, value) != 0) {
+        module->prefs_changed = TRUE;
+        if (*pref->varp.string != NULL)
+          g_free(*pref->varp.string);
+        *pref->varp.string = g_strdup(value);
+      }
       break;
     }
   }
diff --git a/prefs.h b/prefs.h
index ab628c0eb56af3f48211c16ce511ee1d2be9d911..c53410ab82ae72d4c5d201172f4cebb2ffcabe29 100644 (file)
--- a/prefs.h
+++ b/prefs.h
@@ -1,7 +1,7 @@
 /* prefs.h
  * Definitions for preference handling routines
  *
- * $Id: prefs.h,v 1.16 2000/07/05 09:40:42 guy Exp $
+ * $Id: prefs.h,v 1.17 2000/07/09 03:29:28 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -76,7 +76,10 @@ typedef void (*module_cb)(module_t *module, gpointer user_data);
 void prefs_module_foreach(module_cb callback, gpointer user_data);
 
 /*
- * Call the "apply" callback function for each module.
+ * Call the "apply" callback function for each module if any of its
+ * preferences have changed, and then clear the flag saying its
+ * preferences have changed, as the module has been notified of that
+ * fact.
  */
 void prefs_apply_all(void);
 
index bc98efed2bf119f0cc90ddd2ec6203425a447ccb..47fa116c2dd6b9f2314dec5b066af9340847923e 100644 (file)
@@ -1,6 +1,6 @@
 /* tethereal.c
  *
- * $Id: tethereal.c,v 1.34 2000/07/05 09:40:43 guy Exp $
+ * $Id: tethereal.c,v 1.35 2000/07/09 03:29:29 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -411,6 +411,11 @@ main(int argc, char *argv[])
     }
   }
 
+  /* Notify all registered modules that have had any of their preferences
+     changed either from one of the preferences file or from the command
+     line that its preferences have changed. */
+  prefs_apply_all();
+
 #ifndef HAVE_LIBPCAP
   if (capture_option_specified)
     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");