summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-09-19 07:24:39 +0000
committerGuy Harris <guy@alum.mit.edu>2003-09-19 07:24:39 +0000
commite8e9f1bdfe5b7bc189e104387d3b075a81ee81d2 (patch)
tree957dddbd7b2e0e8bd9c3349b089ada57a31bba13
parentf051c17afbe3ffc628ac72f6c3fd7c42a20e255d (diff)
downloadwireshark-e8e9f1bdfe5b7bc189e104387d3b075a81ee81d2.tar.gz
Provide a mechanism by which a tap can arrange to have its menu enabled
or disabled based on a currently-selected packet (or lack of same) or a currently-selected protocol tree item (or lack of same). Not currently used, but necessary if we ever make the TCP graph stuff a tap. API is tentative and subject to change. Also, enable and disable taps based on whether we have any packets to process. svn path=/trunk/; revision=8498
-rw-r--r--gtk/bootp_stat.c5
-rw-r--r--gtk/dcerpc_stat.c5
-rw-r--r--gtk/endpoint_talkers_eth.c5
-rw-r--r--gtk/endpoint_talkers_fc.c5
-rw-r--r--gtk/endpoint_talkers_fddi.c5
-rw-r--r--gtk/endpoint_talkers_ip.c5
-rw-r--r--gtk/endpoint_talkers_ipx.c5
-rw-r--r--gtk/endpoint_talkers_tcpip.c5
-rw-r--r--gtk/endpoint_talkers_tr.c5
-rw-r--r--gtk/endpoint_talkers_udpip.c5
-rw-r--r--gtk/fc_stat.c5
-rw-r--r--gtk/http_stat.c5
-rw-r--r--gtk/io_stat.c5
-rw-r--r--gtk/menu.c273
-rw-r--r--gtk/menu.h27
-rw-r--r--gtk/mgcp_stat.c5
-rw-r--r--gtk/rpc_progs.c5
-rw-r--r--gtk/rpc_stat.c5
-rw-r--r--gtk/smb_stat.c5
-rw-r--r--gtk/tap_rtp.c5
-rw-r--r--gtk/wsp_stat.c5
21 files changed, 336 insertions, 59 deletions
diff --git a/gtk/bootp_stat.c b/gtk/bootp_stat.c
index f13864083f..c10f72dbbe 100644
--- a/gtk/bootp_stat.c
+++ b/gtk/bootp_stat.c
@@ -1,7 +1,7 @@
/* bootp_stat.c
* boop_stat 2003 Jean-Michel FAYARD
*
- * $Id: bootp_stat.c,v 1.2 2003/09/17 19:39:31 guy Exp $
+ * $Id: bootp_stat.c,v 1.3 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -331,5 +331,6 @@ register_tap_listener_gtkdhcpstat(void)
void
register_tap_menu_gtkdhcpstat(void)
{
- register_tap_menu_item("Statistics/Watch protocol/BOOTP-DHCP", gtk_dhcpstat_cb);
+ register_tap_menu_item("Statistics/Watch protocol/BOOTP-DHCP",
+ gtk_dhcpstat_cb, NULL, NULL);
}
diff --git a/gtk/dcerpc_stat.c b/gtk/dcerpc_stat.c
index 603f9eeb46..d949db5756 100644
--- a/gtk/dcerpc_stat.c
+++ b/gtk/dcerpc_stat.c
@@ -1,7 +1,7 @@
/* dcerpc_stat.c
* dcerpc_stat 2002 Ronnie Sahlberg
*
- * $Id: dcerpc_stat.c,v 1.21 2003/09/17 19:39:31 guy Exp $
+ * $Id: dcerpc_stat.c,v 1.22 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -579,5 +579,6 @@ register_tap_listener_gtkdcerpcstat(void)
void
register_tap_menu_gtkdcerpcstat(void)
{
- register_tap_menu_item("Statistics/Service Response Time/DCE-RPC", gtk_dcerpcstat_cb);
+ register_tap_menu_item("Statistics/Service Response Time/DCE-RPC",
+ gtk_dcerpcstat_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_eth.c b/gtk/endpoint_talkers_eth.c
index 1b09631299..2bef0e0b35 100644
--- a/gtk/endpoint_talkers_eth.c
+++ b/gtk/endpoint_talkers_eth.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_eth.c
* endpoint_talkers_eth 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_eth.c,v 1.16 2003/09/17 19:39:31 guy Exp $
+ * $Id: endpoint_talkers_eth.c,v 1.17 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -81,7 +81,8 @@ gtk_eth_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_eth_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/Ethernet", gtk_eth_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/Ethernet",
+ gtk_eth_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_fc.c b/gtk/endpoint_talkers_fc.c
index f103eee51a..3d3559bf84 100644
--- a/gtk/endpoint_talkers_fc.c
+++ b/gtk/endpoint_talkers_fc.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_fc.c
* endpoint_talkers_fc 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_fc.c,v 1.16 2003/09/17 19:39:31 guy Exp $
+ * $Id: endpoint_talkers_fc.c,v 1.17 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -82,7 +82,8 @@ gtk_fc_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_fc_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/Fibre Channel", gtk_fc_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/Fibre Channel",
+ gtk_fc_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_fddi.c b/gtk/endpoint_talkers_fddi.c
index e02ca96d10..73fa81600a 100644
--- a/gtk/endpoint_talkers_fddi.c
+++ b/gtk/endpoint_talkers_fddi.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_fddi.c
* endpoint_talkers_fddi 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_fddi.c,v 1.11 2003/09/17 19:39:32 guy Exp $
+ * $Id: endpoint_talkers_fddi.c,v 1.12 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -81,7 +81,8 @@ gtk_fddi_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_fddi_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/FDDI", gtk_fddi_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/FDDI",
+ gtk_fddi_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_ip.c b/gtk/endpoint_talkers_ip.c
index e1bd3ea8d5..09f6aed9c2 100644
--- a/gtk/endpoint_talkers_ip.c
+++ b/gtk/endpoint_talkers_ip.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_ip.c
* endpoint_talkers_ip 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_ip.c,v 1.17 2003/09/17 19:39:32 guy Exp $
+ * $Id: endpoint_talkers_ip.c,v 1.18 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -79,7 +79,8 @@ gtk_ip_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_ip_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/IPv4", gtk_ip_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/IPv4",
+ gtk_ip_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_ipx.c b/gtk/endpoint_talkers_ipx.c
index 596d24036c..d1ed463d71 100644
--- a/gtk/endpoint_talkers_ipx.c
+++ b/gtk/endpoint_talkers_ipx.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_ipx.c
* endpoint_talkers_ipx 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_ipx.c,v 1.15 2003/09/17 19:39:32 guy Exp $
+ * $Id: endpoint_talkers_ipx.c,v 1.16 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -81,7 +81,8 @@ gtk_ipx_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_ipx_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/IPX", gtk_ipx_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/IPX",
+ gtk_ipx_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_tcpip.c b/gtk/endpoint_talkers_tcpip.c
index a4c2f2f5b4..c17b38bb56 100644
--- a/gtk/endpoint_talkers_tcpip.c
+++ b/gtk/endpoint_talkers_tcpip.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_tcpip.c
* endpoint_talkers_tcpip 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_tcpip.c,v 1.18 2003/09/17 19:39:32 guy Exp $
+ * $Id: endpoint_talkers_tcpip.c,v 1.19 2003/09/19 07:24:37 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -81,7 +81,8 @@ gtk_tcpip_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_tcpip_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/TCP (IPv4 IPv6)", gtk_tcpip_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/TCP (IPv4 IPv6)",
+ gtk_tcpip_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_tr.c b/gtk/endpoint_talkers_tr.c
index 9a393ab355..c126634bc9 100644
--- a/gtk/endpoint_talkers_tr.c
+++ b/gtk/endpoint_talkers_tr.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_tr.c
* endpoint_talkers_tr 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_tr.c,v 1.17 2003/09/17 19:39:32 guy Exp $
+ * $Id: endpoint_talkers_tr.c,v 1.18 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -81,7 +81,8 @@ gtk_tr_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_tr_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/Token Ring", gtk_tr_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/Token Ring",
+ gtk_tr_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/endpoint_talkers_udpip.c b/gtk/endpoint_talkers_udpip.c
index 30c6803cbf..39ccc61499 100644
--- a/gtk/endpoint_talkers_udpip.c
+++ b/gtk/endpoint_talkers_udpip.c
@@ -1,7 +1,7 @@
/* endpoint_talkers_udpip.c
* endpoint_talkers_udpip 2003 Ronnie Sahlberg
*
- * $Id: endpoint_talkers_udpip.c,v 1.18 2003/09/17 19:39:32 guy Exp $
+ * $Id: endpoint_talkers_udpip.c,v 1.19 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -81,7 +81,8 @@ gtk_udpip_endpoints_cb(GtkWidget *w _U_, gpointer d _U_)
void
register_tap_menu_udpip_talkers(void)
{
- register_tap_menu_item("Statistics/Conversation List/UDP (IPv4 IPv6)", gtk_udpip_endpoints_cb);
+ register_tap_menu_item("Statistics/Conversation List/UDP (IPv4 IPv6)",
+ gtk_udpip_endpoints_cb, NULL, NULL);
}
diff --git a/gtk/fc_stat.c b/gtk/fc_stat.c
index 7067400062..3fa13e158b 100644
--- a/gtk/fc_stat.c
+++ b/gtk/fc_stat.c
@@ -1,7 +1,7 @@
/* fc_stat.c
* fc_stat 2003 Ronnie Sahlberg
*
- * $Id: fc_stat.c,v 1.9 2003/09/17 19:39:33 guy Exp $
+ * $Id: fc_stat.c,v 1.10 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -267,5 +267,6 @@ register_tap_listener_gtkfcstat(void)
void
register_tap_menu_gtkfcstat(void)
{
- register_tap_menu_item("Statistics/Service Response Time/Fibre Channel", gtk_fcstat_cb);
+ register_tap_menu_item("Statistics/Service Response Time/Fibre Channel",
+ gtk_fcstat_cb, NULL, NULL);
}
diff --git a/gtk/http_stat.c b/gtk/http_stat.c
index f03f8c9b88..c578c27e00 100644
--- a/gtk/http_stat.c
+++ b/gtk/http_stat.c
@@ -1,7 +1,7 @@
/* http_stat.c
* http_stat 2003 Jean-Michel FAYARD
*
- * $Id: http_stat.c,v 1.3 2003/09/17 19:39:33 guy Exp $
+ * $Id: http_stat.c,v 1.4 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -576,5 +576,6 @@ register_tap_listener_gtkhttpstat(void)
void
register_tap_menu_gtkhttpstat(void)
{
- register_tap_menu_item("Statistics/Watch protocol/HTTP", gtk_httpstat_cb);
+ register_tap_menu_item("Statistics/Watch protocol/HTTP",
+ gtk_httpstat_cb, NULL, NULL);
}
diff --git a/gtk/io_stat.c b/gtk/io_stat.c
index 1668bf5c81..6e0cafa9c1 100644
--- a/gtk/io_stat.c
+++ b/gtk/io_stat.c
@@ -1,7 +1,7 @@
/* io_stat.c
* io_stat 2002 Ronnie Sahlberg
*
- * $Id: io_stat.c,v 1.27 2003/09/17 19:39:33 guy Exp $
+ * $Id: io_stat.c,v 1.28 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -1667,5 +1667,6 @@ register_tap_listener_gtk_iostat(void)
void
register_tap_menu_gtkiostat(void)
{
- register_tap_menu_item("Statistics/IO/IO-Stat", gtk_iostat_cb);
+ register_tap_menu_item("Statistics/IO/IO-Stat", gtk_iostat_cb, NULL,
+ NULL);
}
diff --git a/gtk/menu.c b/gtk/menu.c
index 7d6edb7908..a2079c8848 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
- * $Id: menu.c,v 1.96 2003/09/17 19:39:33 guy Exp $
+ * $Id: menu.c,v 1.97 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -232,7 +232,6 @@ static GtkItemFactoryEntry menu_items[] =
ITEM_FACTORY_ENTRY("/Tools/_Summary", NULL, summary_open_cb, 0, NULL, NULL),
ITEM_FACTORY_ENTRY("/Tools/Protocol Hierarchy Statistics", NULL,
proto_hier_stats_cb, 0, NULL, NULL),
- ITEM_FACTORY_ENTRY("/Tools/Statistics", NULL, NULL, 0, "<Branch>", NULL),
ITEM_FACTORY_ENTRY("/_Help", NULL, NULL, 0, "<Branch>", NULL),
ITEM_FACTORY_STOCK_ENTRY("/Help/_Help", NULL, help_cb, 0, GTK_STOCK_HELP),
ITEM_FACTORY_ENTRY("/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL),
@@ -414,21 +413,50 @@ menus_init(void) {
}
}
+typedef struct _menu_item {
+ char *name;
+ gboolean enabled;
+ gboolean (*selected_packet_enabled)(gboolean);
+ gboolean (*selected_tree_row_enabled)(gboolean);
+ struct _menu_item *parent;
+ struct _menu_item *children;
+ struct _menu_item *next;
+} menu_item_t;
+
+static menu_item_t tap_menu_tree_root;
+
/*
- * Add a new menu item for a statistical tap.
+ * Add a new menu item for a tap.
* This must be called after we've created the main menu, so it can't
* be called from the routine that registers taps - we have to introduce
* another per-tap registration routine.
+ *
+ * "callback" gets called when the menu item is selected; it should do
+ * the work of creating the tap window.
+ *
+ * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
+ * it's passed a Boolean that's TRUE if a packet is selected and FALSE
+ * otherwise, and should return TRUE if the tap will work now (which
+ * might depend on whether a packet is selected and, if one is, on the
+ * packet) and FALSE if not.
+ *
+ * "selected_tree_row_enabled" gets called by
+ * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
+ * a protocol tree row is selected and FALSE otherwise, and should return
+ * TRUE if the tap will work now (which might depend on whether a tree row
+ * is selected and, if one is, on the tree row) and FALSE if not.
*/
void
-register_tap_menu_item(char *name, GtkItemFactoryCallback callback)
+register_tap_menu_item(char *name, GtkItemFactoryCallback callback,
+ gboolean (*selected_packet_enabled)(gboolean),
+ gboolean (*selected_tree_row_enabled)(gboolean))
{
static const char toolspath[] = "/Tools/";
char *p;
char *menupath;
size_t menupathlen;
- GtkWidget *w;
GtkItemFactoryEntry *entry;
+ menu_item_t *curnode, *child;
/*
* The menu path must be relative.
@@ -438,6 +466,7 @@ register_tap_menu_item(char *name, GtkItemFactoryCallback callback)
/*
* Create any submenus required.
*/
+ curnode = &tap_menu_tree_root;
p = name;
while ((p = strchr(p, '/')) != NULL) {
/*
@@ -453,20 +482,42 @@ register_tap_menu_item(char *name, GtkItemFactoryCallback callback)
strncat(menupath, name, p - name);
/*
- * Does there exist an entry with that path in the main
- * menu item factory?
+ * Does there exist an entry with that path at this
+ * level of the Tools menu tree?
*/
- w = gtk_item_factory_get_widget(main_menu_factory, menupath);
- if (w == NULL) {
+ for (child = curnode->children; child != NULL;
+ child = child->next) {
+ if (strcmp(child->name, menupath) == 0)
+ break;
+ }
+ if (child == NULL) {
/*
- * No. Create such an item as a subtree.
+ * No. Create such an item as a subtree, and
+ * add it to the Tools menu tree.
*/
entry = g_malloc0(sizeof (GtkItemFactoryEntry));
entry->path = menupath;
entry->item_type = "<Branch>";
gtk_item_factory_create_item(main_menu_factory, entry,
NULL, 2);
+ set_menu_sensitivity(main_menu_factory, menupath,
+ FALSE); /* no children yet */
+ child = g_malloc(sizeof (menu_item_t));
+ child->name = menupath;
+ child->selected_packet_enabled = NULL;
+ child->selected_tree_row_enabled = NULL;
+ child->enabled = FALSE; /* no children yet */
+ child->parent = curnode;
+ child->children = NULL;
+ child->next = curnode->children;
+ curnode->children = child;
+ } else {
+ /*
+ * Yes. We don't need "menupath" any more.
+ */
+ g_free(menupath);
}
+ curnode = child;
/*
* Skip over the '/' we found.
@@ -494,9 +545,18 @@ register_tap_menu_item(char *name, GtkItemFactoryCallback callback)
entry->path = menupath;
entry->callback = callback;
gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
+ set_menu_sensitivity(main_menu_factory, menupath, FALSE); /* no capture file yet */
+ child = g_malloc(sizeof (menu_item_t));
+ child->name = menupath;
+ child->enabled = FALSE; /* no capture file yet, hence no taps yet */
+ child->selected_packet_enabled = selected_packet_enabled;
+ child->selected_tree_row_enabled = selected_tree_row_enabled;
+ child->parent = curnode;
+ child->children = NULL;
+ child->next = curnode->children;
+ curnode->children = child;
}
-
/*
* Enable/disable menu sensitivity.
*/
@@ -661,6 +721,68 @@ set_menus_for_capture_in_progress(gboolean capture_in_progress)
/* Enable or disable menu items based on whether you have some captured
packets. */
+static gboolean
+walk_menu_tree_for_captured_packets(menu_item_t *node,
+ gboolean have_captured_packets)
+{
+ gboolean is_enabled;
+ menu_item_t *child;
+
+ /*
+ * Is this a leaf node or an interior node?
+ */
+ if (node->children == NULL) {
+ /*
+ * It's a leaf node.
+ *
+ * If it has no "selected_packet_enabled()" or
+ * "selected_tree_row_enabled()" routines, we enable
+ * it if we have captured packets and disable it if
+ * we don't - it doesn't depend on whether we have a
+ * packet or tree row selected or not or on the selected
+ * packet or tree row.
+ *
+ * If it has either of those routines, we disable it for
+ * now - as long as, when a capture is first available,
+ * we don't get called after a packet or tree row is
+ * selected, that's OK.
+ * XXX - that should be done better.
+ */
+ if (node->selected_packet_enabled == NULL)
+ node->enabled = have_captured_packets;
+ else
+ node->enabled = FALSE;
+ } else {
+ /*
+ * It's an interior node; call
+ * "walk_menu_tree_for_captured_packets()" on all its
+ * children and, if any of them are enabled, enable
+ * this node, otherwise disable it.
+ *
+ * XXX - should we just leave all interior nodes enabled?
+ * Which is a better UI choice?
+ */
+ is_enabled = FALSE;
+ for (child = node->children; child != NULL; child =
+ child->next) {
+ if (walk_menu_tree_for_captured_packets(child,
+ have_captured_packets))
+ is_enabled = TRUE;
+ }
+ node->enabled = is_enabled;
+ }
+
+ /*
+ * The root node doesn't correspond to a menu tree item; it
+ * has a null name pointer.
+ */
+ if (node->name != NULL) {
+ set_menu_sensitivity(main_menu_factory, node->name,
+ node->enabled);
+ }
+ return node->enabled;
+}
+
void
set_menus_for_captured_packets(gboolean have_captured_packets)
{
@@ -688,11 +810,68 @@ set_menus_for_captured_packets(gboolean have_captured_packets)
have_captured_packets);
set_menu_sensitivity(packet_list_menu_factory, "/Prepare",
have_captured_packets);
- set_menu_sensitivity(main_menu_factory, "/Tools/Statistics",
+ walk_menu_tree_for_captured_packets(&tap_menu_tree_root,
have_captured_packets);
}
-/* Enable or disable menu items based on whether a packet is selected. */
+static gboolean
+walk_menu_tree_for_selected_packet(menu_item_t *node,
+ gboolean have_selected_packet)
+{
+ gboolean is_enabled;
+ menu_item_t *child;
+
+ /*
+ * Is this a leaf node or an interior node?
+ */
+ if (node->children == NULL) {
+ /*
+ * It's a leaf node.
+ *
+ * If it has no "selected_packet_enabled()" routine,
+ * leave its enabled/disabled status alone - it
+ * doesn't depend on whether we have a packet selected
+ * or not or on the selected packet.
+ *
+ * If it has a "selected_packet_enabled()" routine,
+ * call it and set the item's enabled/disabled status
+ * based on its return value.
+ */
+ if (node->selected_packet_enabled != NULL) {
+ node->enabled =
+ node->selected_packet_enabled(have_selected_packet);
+ }
+ } else {
+ /*
+ * It's an interior node; call
+ * "walk_menu_tree_for_selected_packet()" on all its
+ * children and, if any of them are enabled, enable
+ * this node, otherwise disable it.
+ *
+ * XXX - should we just leave all interior nodes enabled?
+ * Which is a better UI choice?
+ */
+ is_enabled = FALSE;
+ for (child = node->children; child != NULL; child =
+ child->next) {
+ if (walk_menu_tree_for_selected_packet(child,
+ have_selected_packet))
+ is_enabled = TRUE;
+ }
+ node->enabled = is_enabled;
+ }
+
+ /*
+ * The root node doesn't correspond to a menu tree item; it
+ * has a null name pointer.
+ */
+ if (node->name != NULL) {
+ set_menu_sensitivity(main_menu_factory, node->name,
+ node->enabled);
+ }
+ return node->enabled;
+}
+
void
set_menus_for_selected_packet(gboolean have_selected_packet)
{
@@ -732,12 +911,71 @@ set_menus_for_selected_packet(gboolean have_selected_packet)
have_selected_packet && g_resolv_flags == 0);
set_menu_sensitivity(main_menu_factory, "/Tools/TCP Stream Analysis",
have_selected_packet ? (cfile.edt->pi.ipproto == 6) : FALSE);
+ walk_menu_tree_for_selected_packet(&tap_menu_tree_root, have_selected_packet);
}
/* Enable or disable menu items based on whether a tree row is selected
- and and on whether a "Match" can be done. */
+ and on whether a "Match" can be done. */
+static gboolean
+walk_menu_tree_for_selected_tree_row(menu_item_t *node,
+ gboolean have_selected_tree_row)
+{
+ gboolean is_enabled;
+ menu_item_t *child;
+
+ /*
+ * Is this a leaf node or an interior node?
+ */
+ if (node->children == NULL) {
+ /*
+ * It's a leaf node.
+ *
+ * If it has no "selected_tree_row_enabled()" routine,
+ * leave its enabled/disabled status alone - it
+ * doesn't depend on whether we have a tree row selected
+ * or not or on the selected tree row.
+ *
+ * If it has a "selected_tree_row_enabled()" routine,
+ * call it and set the item's enabled/disabled status
+ * based on its return value.
+ */
+ if (node->selected_tree_row_enabled != NULL) {
+ node->enabled =
+ node->selected_tree_row_enabled(have_selected_tree_row);
+ }
+ } else {
+ /*
+ * It's an interior node; call
+ * "walk_menu_tree_for_selected_tree_row()" on all its
+ * children and, if any of them are enabled, enable
+ * this node, otherwise disable it.
+ *
+ * XXX - should we just leave all interior nodes enabled?
+ * Which is a better UI choice?
+ */
+ is_enabled = FALSE;
+ for (child = node->children; child != NULL; child =
+ child->next) {
+ if (walk_menu_tree_for_selected_tree_row(child,
+ have_selected_tree_row))
+ is_enabled = TRUE;
+ }
+ node->enabled = is_enabled;
+ }
+
+ /*
+ * The root node doesn't correspond to a menu tree item; it
+ * has a null name pointer.
+ */
+ if (node->name != NULL) {
+ set_menu_sensitivity(main_menu_factory, node->name,
+ node->enabled);
+ }
+ return node->enabled;
+}
+
void
-set_menus_for_selected_tree_row(gboolean have_selected_tree)
+set_menus_for_selected_tree_row(gboolean have_selected_tree_row)
{
gboolean properties = FALSE;
@@ -779,5 +1017,8 @@ set_menus_for_selected_tree_row(gboolean have_selected_tree)
}
set_menu_sensitivity(tree_view_menu_factory, "/Protocol Properties...",
- have_selected_tree && properties);
+ have_selected_tree_row && properties);
+
+ walk_menu_tree_for_selected_tree_row(&tap_menu_tree_root,
+ have_selected_tree_row);
}
diff --git a/gtk/menu.h b/gtk/menu.h
index 3fb5e35f12..d19df6440e 100644
--- a/gtk/menu.h
+++ b/gtk/menu.h
@@ -1,13 +1,12 @@
/* menu.h
* Menu definitions
*
- * $Id: menu.h,v 1.9 2003/04/23 05:37:22 guy Exp $
+ * $Id: menu.h,v 1.10 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
* 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
* as published by the Free Software Foundation; either version 2
@@ -34,13 +33,31 @@ void get_main_menu (GtkWidget **, GtkAccelGroup **);
void set_menu_object_data (gchar *path, gchar *key, gpointer data);
gint popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data);
+
/*
- * Add a new menu item for a statistical tap.
+ * Add a new menu item for a tap.
* This must be called after we've created the main menu, so it can't
* be called from the routine that registers taps - we have to introduce
* another per-tap registration routine.
+ *
+ * "callback" gets called when the menu item is selected; it should do
+ * the work of creating the tap window.
+ *
+ * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
+ * it's passed a Boolean that's TRUE if a packet is selected and FALSE
+ * otherwise, and should return TRUE if the tap will work now (which
+ * might depend on whether a packet is selected and, if one is, on the
+ * packet) and FALSE if not.
+ *
+ * "selected_tree_row_enabled" gets called by
+ * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
+ * a protocol tree row is selected and FALSE otherwise, and should return
+ * TRUE if the tap will work now (which might depend on whether a tree row
+ * is selected and, if one is, on the tree row) and FALSE if not.
*/
-extern void register_tap_menu_item(char *name, GtkItemFactoryCallback callback);
+extern void register_tap_menu_item(char *name, GtkItemFactoryCallback callback,
+ gboolean (*selected_packet_enabled)(gboolean),
+ gboolean (*selected_tree_row_enabled)(gboolean));
extern GtkWidget *popup_menu_object;
diff --git a/gtk/mgcp_stat.c b/gtk/mgcp_stat.c
index e3fd437d60..02dc874001 100644
--- a/gtk/mgcp_stat.c
+++ b/gtk/mgcp_stat.c
@@ -2,7 +2,7 @@
* mgcp-statistics for ethereal
* Copyright 2003 Lars Roland
*
- * $Id: mgcp_stat.c,v 1.13 2003/09/17 19:39:33 guy Exp $
+ * $Id: mgcp_stat.c,v 1.14 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -394,6 +394,7 @@ void
register_tap_menu_gtkmgcpstat(void)
{
if (find_tap_id("mgcp"))
- register_tap_menu_item("Statistics/Service Response Time/MGCP", gtk_mgcpstat_cb);
+ register_tap_menu_item("Statistics/Service Response Time/MGCP",
+ gtk_mgcpstat_cb, NULL, NULL);
}
diff --git a/gtk/rpc_progs.c b/gtk/rpc_progs.c
index 678baaade0..d63d6c6451 100644
--- a/gtk/rpc_progs.c
+++ b/gtk/rpc_progs.c
@@ -1,7 +1,7 @@
/* rpc_progs.c
* rpc_progs 2002 Ronnie Sahlberg
*
- * $Id: rpc_progs.c,v 1.10 2003/09/17 19:39:33 guy Exp $
+ * $Id: rpc_progs.c,v 1.11 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -407,6 +407,7 @@ register_tap_listener_gtkrpcprogs(void)
void
register_tap_menu_gtkrpcprogs(void)
{
- register_tap_menu_item("Statistics/ONC-RPC/Programs", gtk_rpcprogs_cb);
+ register_tap_menu_item("Statistics/ONC-RPC/Programs", gtk_rpcprogs_cb,
+ NULL, NULL);
}
diff --git a/gtk/rpc_stat.c b/gtk/rpc_stat.c
index 83fc7f7d9f..d2f019a9b4 100644
--- a/gtk/rpc_stat.c
+++ b/gtk/rpc_stat.c
@@ -1,7 +1,7 @@
/* rpc_stat.c
* rpc_stat 2002 Ronnie Sahlberg
*
- * $Id: rpc_stat.c,v 1.20 2003/09/17 19:39:33 guy Exp $
+ * $Id: rpc_stat.c,v 1.21 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -465,5 +465,6 @@ register_tap_listener_gtkrpcstat(void)
void
register_tap_menu_gtkrpcstat(void)
{
- register_tap_menu_item("Statistics/Service Response Time/ONC-RPC", gtk_rpcstat_cb);
+ register_tap_menu_item("Statistics/Service Response Time/ONC-RPC",
+ gtk_rpcstat_cb, NULL, NULL);
}
diff --git a/gtk/smb_stat.c b/gtk/smb_stat.c
index a1e3aa4050..04878af25b 100644
--- a/gtk/smb_stat.c
+++ b/gtk/smb_stat.c
@@ -1,7 +1,7 @@
/* smb_stat.c
* smb_stat 2003 Ronnie Sahlberg
*
- * $Id: smb_stat.c,v 1.17 2003/09/17 19:39:33 guy Exp $
+ * $Id: smb_stat.c,v 1.18 2003/09/19 07:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -303,5 +303,6 @@ register_tap_listener_gtksmbstat(void)
void
register_tap_menu_gtksmbstat(void)
{
- register_tap_menu_item("Statistics/Service Response Time/SMB", gtk_smbstat_cb);
+ register_tap_menu_item("Statistics/Service Response Time/SMB",
+ gtk_smbstat_cb, NULL, NULL);
}
diff --git a/gtk/tap_rtp.c b/gtk/tap_rtp.c
index fa42a3915d..0682b5400f 100644
--- a/gtk/tap_rtp.c
+++ b/gtk/tap_rtp.c
@@ -1,7 +1,7 @@
/*
* tap_rtp.c
*
- * $Id: tap_rtp.c,v 1.16 2003/09/17 19:39:33 guy Exp $
+ * $Id: tap_rtp.c,v 1.17 2003/09/19 07:24:39 guy Exp $
*
* RTP analysing addition for ethereal
*
@@ -1575,7 +1575,8 @@ register_tap_listener_gtkrtp(void)
void
register_tap_menu_gtkrtp(void)
{
- register_tap_menu_item("Statistics/RTP Analysis...", rtp_analyse_cb);
+ register_tap_menu_item("Statistics/RTP Analysis...", rtp_analyse_cb,
+ NULL, NULL);
}
diff --git a/gtk/wsp_stat.c b/gtk/wsp_stat.c
index 743fe96001..c80ca17f1a 100644
--- a/gtk/wsp_stat.c
+++ b/gtk/wsp_stat.c
@@ -1,7 +1,7 @@
/* wsp_stat.c
* wsp_stat 2003 Jean-Michel FAYARD
*
- * $Id: wsp_stat.c,v 1.2 2003/09/17 19:39:34 guy Exp $
+ * $Id: wsp_stat.c,v 1.3 2003/09/19 07:24:39 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -479,5 +479,6 @@ register_tap_listener_gtkwspstat(void)
void
register_tap_menu_gtkwspstat(void)
{
- register_tap_menu_item("Statistics/Watch protocol/WAP-WSP", gtk_wspstat_cb);
+ register_tap_menu_item("Statistics/Watch protocol/WAP-WSP",
+ gtk_wspstat_cb, NULL, NULL);
}