forked from osmocom/wireshark
GTK+ v2 port.
All the deprecated widgets have not been replaced yet : GtkList and GtkCList ==> GtkTreeView conversion : - color_dlg.c - column_prefs.c - decode_as_dlg.c : done - dfilter_expr_dialog - filter_prefs.c - main.c - plugins_dlg.c : done GtkCTree ==> GtkTreeView conversion : done GtkText ==> GtkTextView conversion : done Remaining problems : - gtk_font_selection_dialog_set_filter doesn't exist anymore (but hasn't been removed from the documentation). I don't know how to filter the font selection dialog to get only fixed width fonts ; - we have to remove GUI prefs which are not usefule anymore : tree line style and tree expander style. svn path=/trunk/; revision=6153
This commit is contained in:
parent
2d8152c072
commit
6c5954dac7
27
Makefile.am
27
Makefile.am
|
@ -1,22 +1,22 @@
|
|||
# Makefile.am
|
||||
# Automake file for Ethereal
|
||||
#
|
||||
# $Id: Makefile.am,v 1.463 2002/08/30 02:08:50 sharpe Exp $
|
||||
# $Id: Makefile.am,v 1.464 2002/08/31 09:55:18 oabad Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# 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
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
|
@ -63,7 +63,7 @@ ACLOCAL_AMFLAGS = `./aclocal-flags`
|
|||
bin_PROGRAMS = @ethereal_bin@ @editcap_bin@ @mergecap_bin@ @tethereal_bin@ @dftest_bin@ @randpkt_bin@ @text2pcap_bin@
|
||||
bin_SCRIPTS = @idl2eth_bin@
|
||||
man1_MANS = @ethereal_man@ @editcap_man@ @mergecap_man@ @tethereal_man@ @text2pcap_man@ @idl2eth_man@
|
||||
man_MANS =
|
||||
man_MANS =
|
||||
|
||||
EXTRA_PROGRAMS = ethereal ethereal_static tethereal tethereal_static editcap mergecap dftest text2pcap
|
||||
EXTRA_SCRIPTS = idl2eth
|
||||
|
@ -543,7 +543,7 @@ noinst_HEADERS = \
|
|||
packet-ypbind.h \
|
||||
packet-yppasswd.h \
|
||||
packet-ypserv.h \
|
||||
packet-ypxfr.h
|
||||
packet-ypxfr.h
|
||||
|
||||
ETHEREAL_COMMON_SRC = \
|
||||
afn.c \
|
||||
|
@ -645,7 +645,7 @@ ethereal_static_SOURCES = \
|
|||
statusbar.h \
|
||||
summary.c \
|
||||
summary.h \
|
||||
ui_util.h
|
||||
ui_util.h
|
||||
|
||||
EXTRA_ethereal_SOURCES = \
|
||||
snprintf.c \
|
||||
|
@ -673,12 +673,21 @@ ethereal_optional_objects = @SNPRINTF_O@ @STRERROR_O@ \
|
|||
|
||||
# Additional libs that I know how to build. These will be
|
||||
# linked into the ethereal executable.
|
||||
if USE_GTK2
|
||||
ethereal_additional_libs = \
|
||||
wiretap/libwiretap.a \
|
||||
gtk2/libui.a \
|
||||
epan/libethereal.a \
|
||||
epan/ftypes/libftypes.a \
|
||||
epan/dfilter/libdfilter.a
|
||||
else
|
||||
ethereal_additional_libs = \
|
||||
wiretap/libwiretap.a \
|
||||
gtk/libui.a \
|
||||
epan/libethereal.a \
|
||||
epan/ftypes/libftypes.a \
|
||||
epan/dfilter/libdfilter.a
|
||||
endif
|
||||
|
||||
# This is the automake dependency variable for the executable
|
||||
ethereal_DEPENDENCIES = \
|
||||
|
@ -710,7 +719,7 @@ ethereal_static_LDADD = \
|
|||
$(ethereal_optional_objects) \
|
||||
$(ethereal_additional_libs) \
|
||||
@SNMP_LIBS@ @SSL_LIBS@ \
|
||||
@PCAP_LIBS@ @GTK_LIBS@
|
||||
@PCAP_LIBS@ @GTK_LIBS@
|
||||
|
||||
ethereal_LDFLAGS = -export-dynamic
|
||||
ethereal_static_LDFLAGS = -Wl,-static
|
||||
|
@ -743,7 +752,7 @@ tethereal_DEPENDENCIES = \
|
|||
|
||||
tethereal_static_DEPENDENCIES = \
|
||||
$(ethereal_optional_objects) \
|
||||
$(tethereal_additional_libs)
|
||||
$(tethereal_additional_libs)
|
||||
|
||||
# This automake variable adds to the link-line for the executable
|
||||
tethereal_LDADD = wiretap/libwiretap.a \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: configure.in,v 1.174 2002/08/28 00:37:17 jmayer Exp $
|
||||
# $Id: configure.in,v 1.175 2002/08/31 09:55:18 oabad Exp $
|
||||
dnl
|
||||
dnl Process this file with autoconf 2.13 or later to produce a
|
||||
dnl configure script; 2.12 doesn't generate a "configure" script that
|
||||
|
@ -219,6 +219,7 @@ AC_ARG_ENABLE(ethereal,
|
|||
|
||||
AC_ARG_ENABLE(gtk2,
|
||||
[ --enable-gtk2 build Glib2/Gtk2+-based (t)ethereal. [default=no]],enable_gtk2=yes,enable_gtk2=no)
|
||||
AM_CONDITIONAL(USE_GTK2, test x$enable_gtk2 = xyes)
|
||||
|
||||
# GTK checks
|
||||
# We don't add $GLIB_LIBS to LIBS, because we don't want to force all
|
||||
|
@ -247,7 +248,7 @@ fi
|
|||
if test "$GTK_OK" = "two" ; then
|
||||
ethereal_bin="ethereal"
|
||||
ethereal_man="ethereal.1"
|
||||
ethereal_SUBDIRS="gtk" # <--- change to gtk2, if we can't use the same directory
|
||||
ethereal_SUBDIRS="gtk2"
|
||||
|
||||
# Ignore GLIB_CFLAGS
|
||||
AM_PATH_GLIB_2_0(2.0.0, , AC_MSG_ERROR(GLib distribution not found.), gmodule)
|
||||
|
@ -702,6 +703,7 @@ AC_OUTPUT(
|
|||
Makefile
|
||||
doc/Makefile
|
||||
gtk/Makefile
|
||||
gtk2/Makefile
|
||||
packaging/Makefile
|
||||
packaging/nsis/Makefile
|
||||
packaging/rpm/Makefile
|
||||
|
@ -753,6 +755,7 @@ echo " Build dftest : $enable_dftest"
|
|||
echo ""
|
||||
echo " Install setuid : $setuid_message"
|
||||
echo " Use plugins : $have_plugins"
|
||||
echo " Use GTK+ v2 library : $enable_gtk2"
|
||||
echo " Use pcap library : $want_pcap"
|
||||
echo " Use zlib library : $zlib_message"
|
||||
echo " Use IPv6 name resolution : $enable_ipv6"
|
||||
|
|
24
file.c
24
file.c
|
@ -1,7 +1,7 @@
|
|||
/* file.c
|
||||
* File I/O routines
|
||||
*
|
||||
* $Id: file.c,v 1.287 2002/08/28 21:00:06 jmayer Exp $
|
||||
* $Id: file.c,v 1.288 2002/08/31 09:55:18 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -63,9 +63,17 @@
|
|||
#include <epan/epan.h>
|
||||
#include <epan/filesystem.h>
|
||||
|
||||
#if GTK_MAJOR_VERSION == 1
|
||||
#include "gtk/main.h"
|
||||
#else
|
||||
#include "gtk2/main.h"
|
||||
#endif
|
||||
#include "color.h"
|
||||
#if GTK_MAJOR_VERSION == 1
|
||||
#include "gtk/color_utils.h"
|
||||
#else
|
||||
#include "gtk2/color_utils.h"
|
||||
#endif
|
||||
#include "column.h"
|
||||
#include <epan/packet.h>
|
||||
#include "print.h"
|
||||
|
@ -77,12 +85,21 @@
|
|||
#include "ui_util.h"
|
||||
#include "statusbar.h"
|
||||
#include "prefs.h"
|
||||
#if GTK_MAJOR_VERSION == 1
|
||||
#include "gtk/proto_draw.h"
|
||||
#include "gtk/packet_win.h"
|
||||
#else
|
||||
#include "gtk2/proto_draw.h"
|
||||
#include "gtk2/packet_win.h"
|
||||
#endif
|
||||
#include <epan/dfilter/dfilter.h>
|
||||
#include <epan/conversation.h>
|
||||
#include "globals.h"
|
||||
#if GTK_MAJOR_VERSION == 1
|
||||
#include "gtk/colors.h"
|
||||
#else
|
||||
#include "gtk2/colors.h"
|
||||
#endif
|
||||
#include <epan/epan_dissect.h>
|
||||
|
||||
extern GtkWidget *packet_list, *byte_nb_ptr, *tree_view;
|
||||
|
@ -1429,7 +1446,12 @@ change_time_formats(capture_file *cf)
|
|||
for (i = 0; i < cf->cinfo.num_cols; i++) {
|
||||
if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
|
||||
gtk_clist_set_column_width(GTK_CLIST(packet_list), i,
|
||||
#if GTK_MAJOR_VERSION == 1
|
||||
gdk_string_width(pl_style->font, get_column_longest_string(COL_CLS_TIME)));
|
||||
#else
|
||||
gdk_string_width(gdk_font_from_description(pl_style->font_desc),
|
||||
get_column_longest_string(COL_CLS_TIME)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
stamp-h.in
|
||||
config.status
|
||||
aclocal.m4
|
||||
*.obj
|
||||
*.lib
|
||||
*.pdb
|
|
@ -0,0 +1,101 @@
|
|||
# Makefile.am
|
||||
# Automake file for the GTK2 interface routines for Ethereal
|
||||
#
|
||||
# $Id: Makefile.am,v 1.1 2002/08/31 09:55:20 oabad Exp $
|
||||
#
|
||||
# Ethereal - Network traffic analyzer
|
||||
# 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
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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.
|
||||
|
||||
noinst_LIBRARIES = libui.a
|
||||
|
||||
CLEANFILES = \
|
||||
libui.a \
|
||||
*~
|
||||
|
||||
libui_a_SOURCES = \
|
||||
capture_dlg.c \
|
||||
capture_dlg.h \
|
||||
capture_prefs.c \
|
||||
capture_prefs.h \
|
||||
color_dlg.c \
|
||||
color_dlg.h \
|
||||
colors.c \
|
||||
colors.h \
|
||||
color_utils.c \
|
||||
color_utils.h \
|
||||
column_prefs.c \
|
||||
column_prefs.h \
|
||||
decode_as_dlg.c \
|
||||
decode_as_dlg.h \
|
||||
dfilter_expr_dlg.c \
|
||||
dfilter_expr_dlg.h \
|
||||
display_opts.c \
|
||||
display_opts.h \
|
||||
dlg_utils.c \
|
||||
dlg_utils.h \
|
||||
file_dlg.c \
|
||||
file_dlg.h \
|
||||
filter_prefs.c \
|
||||
filter_prefs.h \
|
||||
find_dlg.c \
|
||||
find_dlg.h \
|
||||
follow_dlg.c \
|
||||
follow_dlg.h \
|
||||
goto_dlg.c \
|
||||
goto_dlg.h \
|
||||
gtkglobals.h \
|
||||
gui_prefs.c \
|
||||
gui_prefs.h \
|
||||
help_dlg.c \
|
||||
help_dlg.h \
|
||||
keys.h \
|
||||
main.c \
|
||||
main.h \
|
||||
menu.c \
|
||||
menu.h \
|
||||
nameres_prefs.c \
|
||||
nameres_prefs.h \
|
||||
packet_win.c \
|
||||
packet_win.h \
|
||||
plugins_dlg.c \
|
||||
prefs_dlg.c \
|
||||
prefs_dlg.h \
|
||||
print_dlg.c \
|
||||
print_prefs.c \
|
||||
print_prefs.h \
|
||||
progress_dlg.c \
|
||||
proto_dlg.c \
|
||||
proto_dlg.h \
|
||||
proto_draw.c \
|
||||
proto_draw.h \
|
||||
proto_hier_stats_dlg.h \
|
||||
proto_hier_stats_dlg.c \
|
||||
simple_dialog.c \
|
||||
stream_prefs.c \
|
||||
stream_prefs.h \
|
||||
summary_dlg.c \
|
||||
summary_dlg.h \
|
||||
tcp_graph.c \
|
||||
tcp_graph.h \
|
||||
ui_util.c \
|
||||
ui_util.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.nmake \
|
||||
print_mswin.c \
|
||||
print_mswin.h
|
|
@ -0,0 +1,68 @@
|
|||
## Makefile for building ethereal.exe with Microsoft C and nmake
|
||||
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
|
||||
#
|
||||
# $Id: Makefile.nmake,v 1.1 2002/08/31 09:55:20 oabad Exp $
|
||||
|
||||
include ..\config.nmake
|
||||
|
||||
############### no need to modify below this line #########
|
||||
|
||||
CFLAGS=-DHAVE_CONFIG_H /I.. /I../wiretap \
|
||||
/I$(GLIB_DIR) /I$(GTK_DIR) /I$(GLIB_DIR)/gmodule \
|
||||
/I$(GTK_DIR)\gdk /I$(GTK_DIR)\gdk\win32 \
|
||||
/I$(PCAP_DIR)\WPCAP\LIBPCAP /I$(PCAP_DIR)\WPCAP\LIBPCAP\bpf \
|
||||
/I$(PCAP_DIR)\WPCAP\LIBPCAP\lbl \
|
||||
/I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
|
||||
|
||||
CVARSDLL=-DWIN32 -DNULL=0 -D_MT -D_DLL
|
||||
|
||||
.c.obj::
|
||||
$(CC) $(CVARSDLL) $(CFLAGS) -Fd.\ -c $<
|
||||
|
||||
# gtkclist.obj is not in here because it is gtk+-1.2 code,
|
||||
# while the DLL for GTK+ on windows is gtk+-1.3, and there's
|
||||
# some functions that have disappeared in gtk+-1.3. I might
|
||||
# get around to #ifdef'ing them out in our gtkclist.c.
|
||||
OBJECTS=capture_dlg.obj \
|
||||
capture_prefs.obj \
|
||||
color_dlg.obj \
|
||||
colors.obj \
|
||||
color_utils.obj \
|
||||
column_prefs.obj \
|
||||
decode_as_dlg.obj \
|
||||
dfilter_expr_dlg.obj \
|
||||
display_opts.obj \
|
||||
dlg_utils.obj \
|
||||
file_dlg.obj \
|
||||
filter_prefs.obj \
|
||||
find_dlg.obj \
|
||||
follow_dlg.obj \
|
||||
goto_dlg.obj \
|
||||
gui_prefs.obj \
|
||||
help_dlg.obj \
|
||||
main.obj \
|
||||
menu.obj \
|
||||
nameres_prefs.obj \
|
||||
packet_win.obj \
|
||||
plugins_dlg.obj \
|
||||
prefs_dlg.obj \
|
||||
print_dlg.obj \
|
||||
print_mswin.obj \
|
||||
print_prefs.obj \
|
||||
progress_dlg.obj \
|
||||
proto_dlg.obj \
|
||||
proto_draw.obj \
|
||||
proto_hier_stats_dlg.obj \
|
||||
simple_dialog.obj \
|
||||
stream_prefs.obj \
|
||||
summary_dlg.obj \
|
||||
tcp_graph.obj \
|
||||
ui_util.obj
|
||||
|
||||
|
||||
libui.lib : ..\config.h $(OBJECTS)
|
||||
lib /out:libui.lib $(OBJECTS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) libui.lib $(PDB_FILE)
|
|
@ -0,0 +1,955 @@
|
|||
/* capture_dlg.c
|
||||
* Routines for packet capture windows
|
||||
*
|
||||
* $Id: capture_dlg.c,v 1.1 2002/08/31 09:55:20 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#ifdef NEED_SNPRINTF_H
|
||||
# include "snprintf.h"
|
||||
#endif
|
||||
|
||||
#include "capture.h"
|
||||
#include "globals.h"
|
||||
#include <epan/resolv.h>
|
||||
#include "main.h"
|
||||
#include "ui_util.h"
|
||||
#include "capture_dlg.h"
|
||||
#include "filter_prefs.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "pcap-util.h"
|
||||
#include "prefs.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "capture-wpcap.h"
|
||||
#endif
|
||||
|
||||
/* Capture callback data keys */
|
||||
#define E_CAP_IFACE_KEY "cap_iface"
|
||||
#define E_CAP_SNAP_CB_KEY "cap_snap_cb"
|
||||
#define E_CAP_SNAP_SB_KEY "cap_snap_sb"
|
||||
#define E_CAP_PROMISC_KEY "cap_promisc"
|
||||
#define E_CAP_FILT_KEY "cap_filter_te"
|
||||
#define E_CAP_FILE_TE_KEY "cap_file_te"
|
||||
#define E_CAP_RING_ON_TB_KEY "cap_ringbuffer_on_tb"
|
||||
#define E_CAP_RING_NBF_LB_KEY "cap_ringbuffer_nbf_lb"
|
||||
#define E_CAP_RING_NBF_SB_KEY "cap_ringbuffer_nbf_sb"
|
||||
#define E_CAP_SYNC_KEY "cap_sync"
|
||||
#define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
|
||||
#define E_CAP_COUNT_CB_KEY "cap_count_cb"
|
||||
#define E_CAP_COUNT_SB_KEY "cap_count_sb"
|
||||
#define E_CAP_FILESIZE_CB_KEY "cap_filesize_cb"
|
||||
#define E_CAP_FILESIZE_SB_KEY "cap_filesize_sb"
|
||||
#define E_CAP_FILESIZE_LB_KEY "cap_filesize_lb"
|
||||
#define E_CAP_DURATION_CB_KEY "cap_duration_cb"
|
||||
#define E_CAP_DURATION_SB_KEY "cap_duration_sb"
|
||||
#define E_CAP_M_RESOLVE_KEY "cap_m_resolve"
|
||||
#define E_CAP_N_RESOLVE_KEY "cap_n_resolve"
|
||||
#define E_CAP_T_RESOLVE_KEY "cap_t_resolve"
|
||||
|
||||
#define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
|
||||
#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
|
||||
|
||||
static void
|
||||
capture_prep_file_cb(GtkWidget *w, gpointer te);
|
||||
|
||||
static void
|
||||
cap_prep_fs_ok_cb(GtkWidget *w, gpointer data);
|
||||
|
||||
static void
|
||||
cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
|
||||
|
||||
static void
|
||||
cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data);
|
||||
|
||||
static void
|
||||
capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
|
||||
|
||||
static void
|
||||
capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
|
||||
|
||||
static void
|
||||
capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w);
|
||||
|
||||
static void
|
||||
capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
|
||||
|
||||
void
|
||||
capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
capture_stop();
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Capture Options" window, if
|
||||
* any, so that if somebody tries to do "Capture:Start" while there's
|
||||
* already a "Capture Options" window up, we just pop up the existing
|
||||
* one, rather than creating a new one.
|
||||
*/
|
||||
static GtkWidget *cap_open_w;
|
||||
|
||||
void
|
||||
capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
GtkWidget *main_vb,
|
||||
*capture_fr, *capture_vb,
|
||||
*if_hb, *if_cb, *if_lb,
|
||||
*snap_hb, *snap_cb, *snap_sb, *snap_lb,
|
||||
*promisc_cb,
|
||||
*filter_hb, *filter_bt, *filter_te,
|
||||
*file_fr, *file_vb,
|
||||
*file_hb, *file_bt, *file_te,
|
||||
*ringbuffer_hb, *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb,
|
||||
*display_fr, *display_vb,
|
||||
*sync_cb, *auto_scroll_cb,
|
||||
*limit_fr, *limit_vb,
|
||||
*count_hb, *count_cb, *count_sb, *count_lb,
|
||||
*filesize_hb, *filesize_cb, *filesize_sb, *filesize_lb,
|
||||
*duration_hb, *duration_cb, *duration_sb, *duration_lb,
|
||||
*resolv_fr, *resolv_vb,
|
||||
*m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
|
||||
*bbox, *ok_bt, *cancel_bt;
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
|
||||
*count_adj, *filesize_adj, *duration_adj;
|
||||
GList *if_list;
|
||||
int err;
|
||||
char err_str[PCAP_ERRBUF_SIZE];
|
||||
|
||||
if (cap_open_w != NULL) {
|
||||
/* There's already a "Capture Options" dialog box; reactivate it. */
|
||||
reactivate_window(cap_open_w);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Is WPcap loaded? */
|
||||
if (!has_wpcap) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
|
||||
"to capture packets.\n\n"
|
||||
"In order to capture packets, WinPcap must be installed; see\n"
|
||||
"\n"
|
||||
" http://winpcap.polito.it/\n"
|
||||
"\n"
|
||||
"or the mirror at\n"
|
||||
"\n"
|
||||
" http://winpcap.mirror.ethereal.com/\n"
|
||||
"\n"
|
||||
"or the mirror at\n"
|
||||
"\n"
|
||||
" http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
|
||||
"\n"
|
||||
"for a downloadable version of WinPcap and for instructions\n"
|
||||
"on how to install WinPcap.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if_list = get_interface_list(&err, err_str);
|
||||
if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, "Can't get list of interfaces: %s",
|
||||
err_str);
|
||||
}
|
||||
|
||||
cap_open_w = dlg_window_new("Ethereal: Capture Options");
|
||||
g_signal_connect(G_OBJECT(cap_open_w), "destroy",
|
||||
G_CALLBACK(capture_prep_destroy_cb), NULL);
|
||||
|
||||
/* Accelerator group for the accelerators (or, as they're called in
|
||||
Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
|
||||
Ctrl+<key> is an accelerator). */
|
||||
accel_group = gtk_accel_group_new();
|
||||
gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
|
||||
|
||||
main_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* Capture-related options frame */
|
||||
capture_fr = gtk_frame_new("Capture");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
|
||||
gtk_widget_show(capture_fr);
|
||||
|
||||
capture_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
|
||||
gtk_widget_show(capture_vb);
|
||||
|
||||
/* Interface row */
|
||||
if_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
|
||||
gtk_widget_show(if_hb);
|
||||
|
||||
if_lb = gtk_label_new("Interface:");
|
||||
gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
|
||||
gtk_widget_show(if_lb);
|
||||
|
||||
if_cb = gtk_combo_new();
|
||||
if (if_list != NULL)
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list);
|
||||
if (cfile.iface == NULL && prefs.capture_device != NULL) {
|
||||
/* No interface was specified on the command line or in a previous
|
||||
capture, but there is one specified in the preferences file;
|
||||
make the one from the preferences file the default */
|
||||
cfile.iface = g_strdup(prefs.capture_device);
|
||||
}
|
||||
if (cfile.iface != NULL)
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
|
||||
else if (if_list != NULL)
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), if_list->data);
|
||||
gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
|
||||
gtk_widget_show(if_cb);
|
||||
|
||||
free_interface_list(if_list);
|
||||
|
||||
/* Capture length row */
|
||||
snap_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
|
||||
gtk_widget_show(snap_hb);
|
||||
|
||||
snap_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"_Limit each packet to", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
|
||||
capture_opts.has_snaplen);
|
||||
g_signal_connect(G_OBJECT(snap_cb), "toggled",
|
||||
G_CALLBACK(capture_prep_adjust_sensitivity),
|
||||
GTK_OBJECT(cap_open_w));
|
||||
gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(snap_cb);
|
||||
|
||||
snap_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.snaplen,
|
||||
MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
|
||||
snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
|
||||
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
|
||||
gtk_widget_set_size_request(snap_sb, 80, -1);
|
||||
gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(snap_sb);
|
||||
|
||||
snap_lb = gtk_label_new("bytes");
|
||||
gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
|
||||
gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(snap_lb);
|
||||
|
||||
/* Promiscuous mode row */
|
||||
promisc_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Capture packets in _promiscuous mode", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
|
||||
capture_opts.promisc_mode);
|
||||
gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
|
||||
gtk_widget_show(promisc_cb);
|
||||
|
||||
/* Filter row */
|
||||
filter_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(capture_vb), filter_hb);
|
||||
gtk_widget_show(filter_hb);
|
||||
|
||||
filter_bt = gtk_button_new_with_label("Filter:");
|
||||
g_signal_connect(G_OBJECT(filter_bt), "clicked",
|
||||
G_CALLBACK(capture_filter_construct_cb), NULL);
|
||||
gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
|
||||
gtk_widget_show(filter_bt);
|
||||
|
||||
filter_te = gtk_entry_new();
|
||||
if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
|
||||
gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
|
||||
gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3);
|
||||
gtk_widget_show(filter_te);
|
||||
|
||||
/* Capture file-related options frame */
|
||||
file_fr = gtk_frame_new("Capture file(s)");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), file_fr);
|
||||
gtk_widget_show(file_fr);
|
||||
|
||||
file_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
|
||||
gtk_widget_show(file_vb);
|
||||
|
||||
/* File row */
|
||||
file_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(file_vb), file_hb);
|
||||
gtk_widget_show(file_hb);
|
||||
|
||||
file_bt = gtk_button_new_with_label("File:");
|
||||
gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3);
|
||||
gtk_widget_show(file_bt);
|
||||
|
||||
file_te = gtk_entry_new();
|
||||
gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
|
||||
gtk_widget_show(file_te);
|
||||
|
||||
g_signal_connect(G_OBJECT(file_bt), "clicked",
|
||||
G_CALLBACK(capture_prep_file_cb), GTK_OBJECT(file_te));
|
||||
|
||||
/* Ring buffer row */
|
||||
ringbuffer_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_hb);
|
||||
gtk_widget_show(ringbuffer_hb);
|
||||
|
||||
ringbuffer_on_tb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Use _ring buffer", accel_group);
|
||||
/* Ring buffer mode is allowed only if we're not doing an "Update list of
|
||||
packets in real time" capture, so force it off if we're doing such
|
||||
a capture. */
|
||||
if (capture_opts.sync_mode)
|
||||
capture_opts.ringbuffer_on = FALSE;
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_on_tb),
|
||||
capture_opts.ringbuffer_on);
|
||||
g_signal_connect(G_OBJECT(ringbuffer_on_tb), "toggled",
|
||||
G_CALLBACK(capture_prep_adjust_sensitivity),
|
||||
GTK_OBJECT(cap_open_w));
|
||||
gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_on_tb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(ringbuffer_on_tb);
|
||||
|
||||
ringbuffer_nbf_lb = gtk_label_new("Number of files");
|
||||
gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 1, 0.5);
|
||||
gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_nbf_lb, FALSE, FALSE, 6);
|
||||
gtk_widget_show(ringbuffer_nbf_lb);
|
||||
|
||||
ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.ringbuffer_num_files,
|
||||
RINGBUFFER_MIN_NUM_FILES, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
|
||||
ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
|
||||
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
|
||||
gtk_widget_set_size_request(ringbuffer_nbf_sb, 40, -1);
|
||||
gtk_box_pack_start (GTK_BOX(ringbuffer_hb), ringbuffer_nbf_sb, TRUE, TRUE, 0);
|
||||
gtk_widget_show(ringbuffer_nbf_sb);
|
||||
|
||||
/* Display-related options frame */
|
||||
display_fr = gtk_frame_new("Display options");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), display_fr);
|
||||
gtk_widget_show(display_fr);
|
||||
|
||||
display_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
|
||||
gtk_widget_show(display_vb);
|
||||
|
||||
/* "Update display in real time" row */
|
||||
sync_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"_Update list of packets in real time", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
|
||||
capture_opts.sync_mode);
|
||||
g_signal_connect(G_OBJECT(sync_cb), "toggled",
|
||||
G_CALLBACK(capture_prep_adjust_sensitivity),
|
||||
GTK_OBJECT(cap_open_w));
|
||||
gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
|
||||
gtk_widget_show(sync_cb);
|
||||
|
||||
/* "Auto-scroll live update" row */
|
||||
auto_scroll_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"_Automatic scrolling in live capture", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
|
||||
gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
|
||||
gtk_widget_show(auto_scroll_cb);
|
||||
|
||||
/* Capture limits frame */
|
||||
limit_fr = gtk_frame_new("Capture limits");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), limit_fr);
|
||||
gtk_widget_show(limit_fr);
|
||||
|
||||
limit_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
|
||||
gtk_widget_show(limit_vb);
|
||||
|
||||
/* Count row */
|
||||
count_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(limit_vb), count_hb);
|
||||
gtk_widget_show(count_hb);
|
||||
|
||||
count_cb = gtk_check_button_new_with_label("Stop capture after");
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(count_cb),
|
||||
capture_opts.has_autostop_count);
|
||||
g_signal_connect(G_OBJECT(count_cb), "toggled",
|
||||
G_CALLBACK(capture_prep_adjust_sensitivity),
|
||||
GTK_OBJECT(cap_open_w));
|
||||
gtk_box_pack_start(GTK_BOX(count_hb), count_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(count_cb);
|
||||
|
||||
count_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_count,
|
||||
1, INT_MAX, 1.0, 10.0, 0.0);
|
||||
count_sb = gtk_spin_button_new (count_adj, 0, 0);
|
||||
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (count_sb), TRUE);
|
||||
gtk_widget_set_size_request(count_sb, 80, -1);
|
||||
gtk_box_pack_start (GTK_BOX(count_hb), count_sb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(count_sb);
|
||||
|
||||
count_lb = gtk_label_new("packet(s) captured");
|
||||
gtk_misc_set_alignment(GTK_MISC(count_lb), 0, 0.5);
|
||||
gtk_box_pack_start(GTK_BOX(count_hb), count_lb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(count_lb);
|
||||
|
||||
/* Filesize row */
|
||||
filesize_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(limit_vb), filesize_hb);
|
||||
gtk_widget_show(filesize_hb);
|
||||
|
||||
filesize_cb = gtk_check_button_new_with_label("");
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb),
|
||||
capture_opts.has_autostop_filesize);
|
||||
g_signal_connect(G_OBJECT(filesize_cb), "toggled",
|
||||
G_CALLBACK(capture_prep_adjust_sensitivity),
|
||||
GTK_OBJECT(cap_open_w));
|
||||
gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(filesize_cb);
|
||||
|
||||
filesize_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_filesize,
|
||||
1, INT_MAX, 1.0, 10.0, 0.0);
|
||||
filesize_sb = gtk_spin_button_new (filesize_adj, 0, 0);
|
||||
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (filesize_sb), TRUE);
|
||||
gtk_widget_set_size_request(filesize_sb, 80, -1);
|
||||
gtk_box_pack_start (GTK_BOX(filesize_hb), filesize_sb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(filesize_sb);
|
||||
|
||||
filesize_lb = gtk_label_new("");
|
||||
gtk_misc_set_alignment(GTK_MISC(filesize_lb), 0, 0.5);
|
||||
gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_lb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(filesize_lb);
|
||||
|
||||
/* Duration row */
|
||||
duration_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(limit_vb), duration_hb);
|
||||
gtk_widget_show(duration_hb);
|
||||
|
||||
duration_cb = gtk_check_button_new_with_label("Stop capture after");
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(duration_cb),
|
||||
capture_opts.has_autostop_duration);
|
||||
g_signal_connect(G_OBJECT(duration_cb), "toggled",
|
||||
G_CALLBACK(capture_prep_adjust_sensitivity),
|
||||
GTK_OBJECT(cap_open_w));
|
||||
gtk_box_pack_start(GTK_BOX(duration_hb), duration_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(duration_cb);
|
||||
|
||||
duration_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_duration,
|
||||
1, INT_MAX, 1.0, 10.0, 0.0);
|
||||
duration_sb = gtk_spin_button_new (duration_adj, 0, 0);
|
||||
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (duration_sb), TRUE);
|
||||
gtk_widget_set_size_request(duration_sb, 80, -1);
|
||||
gtk_box_pack_start (GTK_BOX(duration_hb), duration_sb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(duration_sb);
|
||||
|
||||
duration_lb = gtk_label_new("second(s)");
|
||||
gtk_misc_set_alignment(GTK_MISC(duration_lb), 0, 0.5);
|
||||
gtk_box_pack_start(GTK_BOX(duration_hb), duration_lb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(duration_lb);
|
||||
|
||||
/* Resolution options frame */
|
||||
resolv_fr = gtk_frame_new("Name resolution");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), resolv_fr);
|
||||
gtk_widget_show(resolv_fr);
|
||||
|
||||
resolv_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
|
||||
gtk_widget_show(resolv_vb);
|
||||
|
||||
m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _MAC name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
|
||||
g_resolv_flags & RESOLV_MAC);
|
||||
gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
|
||||
gtk_widget_show(m_resolv_cb);
|
||||
|
||||
n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _network name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
|
||||
g_resolv_flags & RESOLV_NETWORK);
|
||||
gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
|
||||
gtk_widget_show(n_resolv_cb);
|
||||
|
||||
t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _transport name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
|
||||
g_resolv_flags & RESOLV_TRANSPORT);
|
||||
gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
|
||||
gtk_widget_show(t_resolv_cb);
|
||||
|
||||
/* Button row: OK and cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock (GTK_STOCK_OK);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(capture_prep_ok_cb), GTK_OBJECT(cap_open_w));
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_bt), "clicked",
|
||||
G_CALLBACK(capture_prep_close_cb), GTK_OBJECT(cap_open_w));
|
||||
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
|
||||
/* Attach pointers to needed widgets to the capture prefs window/object */
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_IFACE_KEY, if_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_CB_KEY, snap_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_SB_KEY, snap_sb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_PROMISC_KEY, promisc_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILT_KEY, filter_te);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILE_TE_KEY, file_te);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_ON_TB_KEY, ringbuffer_on_tb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_NBF_LB_KEY, ringbuffer_nbf_lb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_NBF_SB_KEY, ringbuffer_nbf_sb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SYNC_KEY, sync_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_CB_KEY, count_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_SB_KEY, count_sb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_CB_KEY, filesize_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_SB_KEY, filesize_sb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_LB_KEY, filesize_lb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_DURATION_CB_KEY, duration_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_DURATION_SB_KEY, duration_sb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_M_RESOLVE_KEY, m_resolv_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_N_RESOLVE_KEY, n_resolv_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_T_RESOLVE_KEY, t_resolv_cb);
|
||||
|
||||
/* Set the sensitivity of various widgets as per the settings of other
|
||||
widgets. */
|
||||
capture_prep_adjust_sensitivity(NULL, cap_open_w);
|
||||
|
||||
/* Catch the "activate" signal on the frame number and file name text
|
||||
entries, so that if the user types Return there, we act as if the
|
||||
"OK" button had been selected, as happens if Return is typed if some
|
||||
widget that *doesn't* handle the Return key has the input focus. */
|
||||
dlg_set_activate(filter_te, ok_bt);
|
||||
dlg_set_activate(file_te, ok_bt);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(cap_open_w, cancel_bt);
|
||||
|
||||
/* XXX - why does not
|
||||
|
||||
gtk_widget_grab_focus(if_cb);
|
||||
|
||||
give the initial focus to the "Interface" combo box?
|
||||
|
||||
Or should I phrase that as "why does GTK+ continually frustrate
|
||||
attempts to make GUIs driveable from the keyboard?" We have to
|
||||
go catch the activate signal on every single GtkEntry widget
|
||||
(rather than having widgets whose activate signal is *not*
|
||||
caught not catch the Return keystroke, so that it passes on,
|
||||
ultimately, to the window, which can activate the default
|
||||
widget, i.e. the "OK" button); we have to catch the "key_press_event"
|
||||
signal and have the handler check for ESC, so that we can have ESC
|
||||
activate the "Cancel" button; in order to support Alt+<key> mnemonics
|
||||
for buttons and the like, we may have to construct an accelerator
|
||||
group by hand and set up the accelerators by hand (if that even
|
||||
works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
|
||||
to keep some container widget from getting the initial focus, so that
|
||||
you don't have to tab into the first widget in order to start typing
|
||||
in it; and it now appears that you simply *can't* make a combo box
|
||||
get the initial focus, at least not in the obvious fashion. Sigh.... */
|
||||
|
||||
gtk_widget_show(cap_open_w);
|
||||
}
|
||||
|
||||
static void
|
||||
capture_prep_file_cb(GtkWidget *w, gpointer file_te)
|
||||
{
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(w);
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Has a file selection dialog box already been opened for that top-level
|
||||
widget? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Just re-activate that dialog box. */
|
||||
reactivate_window(fs);
|
||||
return;
|
||||
}
|
||||
|
||||
fs = gtk_file_selection_new ("Ethereal: Capture File");
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(fs), E_CAP_FILE_TE_KEY, file_te);
|
||||
|
||||
/* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
|
||||
gtk_object_set_data(GTK_OBJECT(fs), E_FS_CALLER_PTR_KEY, caller);
|
||||
|
||||
/* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, fs);
|
||||
|
||||
/* Call a handler when the file selection box is destroyed, so we can inform
|
||||
our caller, if any, that it's been destroyed. */
|
||||
g_signal_connect(G_OBJECT(fs), "destroy",
|
||||
G_CALLBACK(cap_prep_fs_destroy_cb), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked",
|
||||
G_CALLBACK(cap_prep_fs_ok_cb), fs);
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->cancel_button), "clicked",
|
||||
G_CALLBACK(cap_prep_fs_cancel_cb), fs);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
|
||||
|
||||
gtk_widget_show(fs);
|
||||
}
|
||||
|
||||
static void
|
||||
cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
|
||||
E_CAP_FILE_TE_KEY)),
|
||||
gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void
|
||||
cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void
|
||||
cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *caller;
|
||||
|
||||
/* Get the widget that requested that we be popped up.
|
||||
(It should arrange to destroy us if it's destroyed, so
|
||||
that we don't get a pointer to a non-existent window here.) */
|
||||
caller = gtk_object_get_data(GTK_OBJECT(win), E_FS_CALLER_PTR_KEY);
|
||||
|
||||
/* Tell it we no longer exist. */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, NULL);
|
||||
|
||||
/* Now nuke this window. */
|
||||
gtk_grab_remove(GTK_WIDGET(win));
|
||||
gtk_widget_destroy(GTK_WIDGET(win));
|
||||
}
|
||||
|
||||
static void
|
||||
capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
|
||||
GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
|
||||
*file_te, *ringbuffer_on_tb, *ringbuffer_nbf_sb,
|
||||
*sync_cb, *auto_scroll_cb,
|
||||
*count_cb, *count_sb,
|
||||
*filesize_cb, *filesize_sb,
|
||||
*duration_cb, *duration_sb,
|
||||
*m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
|
||||
gchar *if_text;
|
||||
gchar *if_name;
|
||||
const gchar *filter_text;
|
||||
const gchar *save_file;
|
||||
|
||||
if_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IFACE_KEY);
|
||||
snap_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY);
|
||||
snap_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_SB_KEY);
|
||||
promisc_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_PROMISC_KEY);
|
||||
filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILT_KEY);
|
||||
file_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILE_TE_KEY);
|
||||
ringbuffer_on_tb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_ON_TB_KEY);
|
||||
ringbuffer_nbf_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
|
||||
sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
|
||||
auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
|
||||
count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_CB_KEY);
|
||||
count_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_SB_KEY);
|
||||
filesize_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_CB_KEY);
|
||||
filesize_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_SB_KEY);
|
||||
duration_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_CB_KEY);
|
||||
duration_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_SB_KEY);
|
||||
m_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_M_RESOLVE_KEY);
|
||||
n_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY);
|
||||
t_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY);
|
||||
|
||||
if_text =
|
||||
g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
|
||||
/* Windows combo entries have a description followed by the interface name */
|
||||
if_name = strrchr(if_text, ' ');
|
||||
if (if_name == NULL) {
|
||||
if_name = if_text;
|
||||
} else {
|
||||
if_name++;
|
||||
}
|
||||
if (if_name == NULL) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"You didn't specify an interface on which to capture packets.");
|
||||
g_free(if_text);
|
||||
return;
|
||||
}
|
||||
if (cfile.iface)
|
||||
g_free(cfile.iface);
|
||||
cfile.iface = g_strdup(if_name);
|
||||
g_free(if_text);
|
||||
|
||||
capture_opts.has_snaplen =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
|
||||
if (capture_opts.has_snaplen) {
|
||||
capture_opts.snaplen =
|
||||
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
|
||||
if (capture_opts.snaplen < 1)
|
||||
capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
|
||||
else if (capture_opts.snaplen < MIN_PACKET_SIZE)
|
||||
capture_opts.snaplen = MIN_PACKET_SIZE;
|
||||
}
|
||||
|
||||
capture_opts.promisc_mode =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
|
||||
|
||||
/* XXX - don't try to get clever and set "cfile.filter" to NULL if the
|
||||
filter string is empty, as an indication that we don't have a filter
|
||||
and thus don't have to set a filter when capturing - the version of
|
||||
libpcap in Red Hat Linux 6.1, and versions based on later patches
|
||||
in that series, don't bind the AF_PACKET socket to an interface
|
||||
until a filter is set, which means they aren't bound at all if
|
||||
no filter is set, which means no packets arrive as input on that
|
||||
socket, which means Ethereal never sees any packets. */
|
||||
filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
|
||||
if (cfile.cfilter)
|
||||
g_free(cfile.cfilter);
|
||||
g_assert(filter_text != NULL);
|
||||
cfile.cfilter = g_strdup(filter_text);
|
||||
|
||||
save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
|
||||
if (save_file && save_file[0]) {
|
||||
/* User specified a file to which the capture should be written. */
|
||||
save_file = g_strdup(save_file);
|
||||
} else {
|
||||
/* User didn't specify a file; save to a temporary file. */
|
||||
save_file = NULL;
|
||||
}
|
||||
|
||||
capture_opts.has_autostop_count =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb));
|
||||
if (capture_opts.has_autostop_count)
|
||||
capture_opts.autostop_count =
|
||||
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(count_sb));
|
||||
|
||||
capture_opts.has_autostop_filesize =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb));
|
||||
if (capture_opts.has_autostop_filesize)
|
||||
capture_opts.autostop_filesize =
|
||||
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filesize_sb));
|
||||
|
||||
capture_opts.has_autostop_duration =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb));
|
||||
if (capture_opts.has_autostop_duration)
|
||||
capture_opts.autostop_duration =
|
||||
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_sb));
|
||||
|
||||
capture_opts.sync_mode =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
|
||||
|
||||
auto_scroll_live =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
|
||||
|
||||
g_resolv_flags = RESOLV_NONE;
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
|
||||
g_resolv_flags |= RESOLV_MAC;
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
|
||||
g_resolv_flags |= RESOLV_NETWORK;
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
|
||||
g_resolv_flags |= RESOLV_TRANSPORT;
|
||||
|
||||
capture_opts.ringbuffer_on =
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb)) &&
|
||||
!(capture_opts.sync_mode);
|
||||
if (capture_opts.ringbuffer_on) {
|
||||
if (save_file == NULL) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"You must specify a save file if you want to use the ring buffer.");
|
||||
return;
|
||||
} else if (!capture_opts.has_autostop_filesize) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"You must specify a file size at which to rotate the capture files\n"
|
||||
"if you want to use the ring buffer.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
capture_opts.ringbuffer_num_files =
|
||||
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
|
||||
if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
|
||||
capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
|
||||
else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
|
||||
capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
|
||||
do_capture(save_file);
|
||||
}
|
||||
|
||||
static void
|
||||
capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gtk_grab_remove(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
||||
|
||||
static void
|
||||
capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
|
||||
{
|
||||
GtkWidget *capture_prep_filter_w;
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Is there a filter edit/selection dialog associated with this
|
||||
Capture Options dialog? */
|
||||
capture_prep_filter_w = gtk_object_get_data(GTK_OBJECT(win), E_FILT_DIALOG_PTR_KEY);
|
||||
|
||||
if (capture_prep_filter_w != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(capture_prep_filter_w);
|
||||
}
|
||||
|
||||
/* Is there a file selection dialog associated with this
|
||||
Print File dialog? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(win), E_FILE_SEL_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(fs);
|
||||
}
|
||||
|
||||
/* Note that we no longer have a "Capture Options" dialog box. */
|
||||
cap_open_w = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust the sensitivity of various widgets as per the current setting
|
||||
* of other widgets.
|
||||
*/
|
||||
static void
|
||||
capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
|
||||
{
|
||||
GtkWidget *snap_cb, *snap_sb,
|
||||
*ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb,
|
||||
*sync_cb, *auto_scroll_cb,
|
||||
*count_cb, *count_sb,
|
||||
*filesize_cb, *filesize_sb, *filesize_lb,
|
||||
*duration_cb, *duration_sb;
|
||||
|
||||
snap_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY);
|
||||
snap_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_SB_KEY);
|
||||
ringbuffer_on_tb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_ON_TB_KEY);
|
||||
ringbuffer_nbf_lb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_LB_KEY);
|
||||
ringbuffer_nbf_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
|
||||
sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
|
||||
auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
|
||||
count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_CB_KEY);
|
||||
count_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_SB_KEY);
|
||||
filesize_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_CB_KEY);
|
||||
filesize_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_SB_KEY);
|
||||
filesize_lb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_LB_KEY);
|
||||
duration_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_CB_KEY);
|
||||
duration_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_SB_KEY);
|
||||
|
||||
/* The snapshot length spinbox is sensitive iff the "Limit each packet
|
||||
to" checkbox is on. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
|
||||
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
|
||||
/* "Update list of packets in real time" captures enabled; we don't
|
||||
support ring buffer mode for those captures, so turn ring buffer
|
||||
mode off if it's on, and make its toggle button, and the spin
|
||||
button for the number of ring buffer files (and the spin button's
|
||||
label), insensitive. */
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), FALSE);
|
||||
}
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), FALSE);
|
||||
|
||||
/* Auto-scroll mode is meaningful only in "Update list of packets
|
||||
in real time" captures, so make its toggle button sensitive. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
|
||||
} else {
|
||||
/* "Update list of packets in real time" captures disabled; that
|
||||
means ring buffer mode is OK, so make its toggle button
|
||||
sensitive. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), TRUE);
|
||||
|
||||
/* Auto-scroll mode is meaningful only in "Update list of packets
|
||||
in real time" captures, so make its toggle button insensitive. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
|
||||
}
|
||||
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
|
||||
/* Ring buffer mode enabled. Make the spin button for the number
|
||||
of ring buffer files, and its label, sensitive. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), TRUE);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), TRUE);
|
||||
|
||||
/* Also, indicate that the file size is a size at which to switch
|
||||
ring buffer files, not a size at which to stop the capture,
|
||||
turn its button on. */
|
||||
gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child),
|
||||
"Rotate capture file every");
|
||||
gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s)");
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb), TRUE);
|
||||
} else {
|
||||
/* Ring buffer mode disabled. Make the spin button for the number
|
||||
of ring buffer files, and its label insensitive. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
|
||||
|
||||
/* Also, indicate that the file size is a size at which to stop the
|
||||
capture, not a size at which to switch ring buffer files. */
|
||||
gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child),
|
||||
"Stop capture after");
|
||||
gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s) captured");
|
||||
}
|
||||
|
||||
/* The maximum packet count spinbox is sensitive iff the "Stop capture
|
||||
after N packets captured" checkbox is on. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(count_sb),
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb)));
|
||||
|
||||
/* The maximum file size spinbox is sensitive iff the "Stop capture
|
||||
after N kilobytes captured" checkbox is on. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb),
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb)));
|
||||
|
||||
/* The capture duration spinbox is sensitive iff the "Stop capture
|
||||
after N seconds" checkbox is on. */
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(duration_sb),
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb)));
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBPCAP */
|
|
@ -0,0 +1,32 @@
|
|||
/* capture_dlg.h
|
||||
* Definitions for packet capture windows
|
||||
*
|
||||
* $Id: capture_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __CAPTURE_DLG_H__
|
||||
#define __CAPTURE_DLG_H__
|
||||
|
||||
void capture_prep_cb(GtkWidget *, gpointer);
|
||||
void capture_stop_cb(GtkWidget *, gpointer);
|
||||
|
||||
#endif /* capture.h */
|
|
@ -0,0 +1,167 @@
|
|||
/* capture_prefs.c
|
||||
* Dialog box for capture preferences
|
||||
*
|
||||
* $Id: capture_prefs.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "capture_prefs.h"
|
||||
#include "gtkglobals.h"
|
||||
#include "prefs.h"
|
||||
#include "prefs_dlg.h"
|
||||
#include "ui_util.h"
|
||||
#include "pcap-util.h"
|
||||
#include "main.h"
|
||||
|
||||
#define DEVICE_KEY "device"
|
||||
#define PROM_MODE_KEY "prom_mode"
|
||||
#define CAPTURE_REAL_TIME_KEY "capture_real_time"
|
||||
#define AUTO_SCROLL_KEY "auto_scroll"
|
||||
|
||||
#define CAPTURE_TABLE_ROWS 4
|
||||
GtkWidget*
|
||||
capture_prefs_show(void)
|
||||
{
|
||||
GtkWidget *main_tb, *main_vb;
|
||||
GtkWidget *if_cb, *if_lb, *promisc_cb, *sync_cb, *auto_scroll_cb;
|
||||
GList *if_list;
|
||||
int err;
|
||||
char err_str[PCAP_ERRBUF_SIZE];
|
||||
|
||||
/* Main vertical box */
|
||||
main_vb = gtk_vbox_new(FALSE, 7);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
|
||||
/* Main table */
|
||||
main_tb = gtk_table_new(CAPTURE_TABLE_ROWS, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
gtk_widget_show(main_tb);
|
||||
|
||||
/* Default device */
|
||||
if_lb = gtk_label_new("Interface:");
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), if_lb, 0, 1, 0, 1);
|
||||
gtk_misc_set_alignment(GTK_MISC(if_lb), 1.0, 0.5);
|
||||
gtk_widget_show(if_lb);
|
||||
|
||||
if_cb = gtk_combo_new();
|
||||
/*
|
||||
* XXX - what if we can't get the list?
|
||||
*/
|
||||
if_list = get_interface_list(&err, err_str);
|
||||
if (if_list != NULL)
|
||||
gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list);
|
||||
if (prefs.capture_device)
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
|
||||
prefs.capture_device);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), if_cb, 1, 2, 0, 1);
|
||||
gtk_widget_show(if_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), DEVICE_KEY, if_cb);
|
||||
|
||||
free_interface_list(if_list);
|
||||
|
||||
/* Promiscuous mode */
|
||||
promisc_cb = create_preference_check_button(main_tb, 1,
|
||||
"Capture packets in promiscuous mode:", NULL,
|
||||
prefs.capture_prom_mode);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PROM_MODE_KEY, promisc_cb);
|
||||
|
||||
/* Real-time capture */
|
||||
sync_cb = create_preference_check_button(main_tb, 2,
|
||||
"Update list of packets in real time:", NULL,
|
||||
prefs.capture_real_time);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), CAPTURE_REAL_TIME_KEY,
|
||||
sync_cb);
|
||||
|
||||
/* Auto-scroll real-time capture */
|
||||
auto_scroll_cb = create_preference_check_button(main_tb, 3,
|
||||
"Automatic scrolling in live capture:", NULL,
|
||||
prefs.capture_auto_scroll);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), AUTO_SCROLL_KEY,
|
||||
auto_scroll_cb);
|
||||
|
||||
/* Show 'em what we got */
|
||||
gtk_widget_show_all(main_vb);
|
||||
|
||||
return(main_vb);
|
||||
}
|
||||
|
||||
void
|
||||
capture_prefs_fetch(GtkWidget *w)
|
||||
{
|
||||
GtkWidget *if_cb, *promisc_cb, *sync_cb, *auto_scroll_cb;
|
||||
gchar *if_text;
|
||||
|
||||
if_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w), DEVICE_KEY);
|
||||
promisc_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w),
|
||||
PROM_MODE_KEY);
|
||||
sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w),
|
||||
CAPTURE_REAL_TIME_KEY);
|
||||
auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w),
|
||||
AUTO_SCROLL_KEY);
|
||||
|
||||
if (prefs.capture_device != NULL) {
|
||||
g_free(prefs.capture_device);
|
||||
prefs.capture_device = NULL;
|
||||
}
|
||||
if_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
|
||||
/* Strip out white space */
|
||||
g_strstrip(if_text);
|
||||
/* If there was nothing but white space, treat that as an
|
||||
indication that the user doesn't want to wire in a default
|
||||
device, and just wants the first device in the list chosen. */
|
||||
if (*if_text == '\0') {
|
||||
g_free(if_text);
|
||||
if_text = NULL;
|
||||
}
|
||||
prefs.capture_device = if_text;
|
||||
|
||||
prefs.capture_prom_mode = GTK_TOGGLE_BUTTON (promisc_cb)->active;
|
||||
|
||||
prefs.capture_real_time = GTK_TOGGLE_BUTTON (sync_cb)->active;
|
||||
|
||||
prefs.capture_auto_scroll = GTK_TOGGLE_BUTTON (auto_scroll_cb)->active;
|
||||
}
|
||||
|
||||
void
|
||||
capture_prefs_apply(GtkWidget *w _U_)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
capture_prefs_destroy(GtkWidget *w _U_)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBPCAP */
|
|
@ -0,0 +1,33 @@
|
|||
/* capture_prefs.h
|
||||
* Definitions for capture preferences window
|
||||
*
|
||||
* $Id: capture_prefs.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __CAPTURE_PREFS_H__
|
||||
#define __CAPTURE_PREFS_H__
|
||||
|
||||
GtkWidget *capture_prefs_show(void);
|
||||
void capture_prefs_fetch(GtkWidget *w);
|
||||
void capture_prefs_apply(GtkWidget *w);
|
||||
void capture_prefs_destroy(GtkWidget *w);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
/* color_dlg.h
|
||||
* Definitions for dialog boxes for color filters
|
||||
*
|
||||
* $Id: color_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __COLOR_DLG_H__
|
||||
#define __COLOR_DLG_H__
|
||||
|
||||
void color_display_cb(GtkWidget *w, gpointer d);
|
||||
|
||||
#endif /* color_dlg.h */
|
|
@ -0,0 +1,53 @@
|
|||
/* color_utils.c
|
||||
* Utilities for converting between "toolkit-independent" and GDK
|
||||
* notions of color
|
||||
*
|
||||
* $Id: color_utils.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "prefs.h" /* to declare "color_t" */
|
||||
|
||||
void
|
||||
color_t_to_gdkcolor(GdkColor *target, color_t *source)
|
||||
{
|
||||
target->pixel = source->pixel;
|
||||
target->red = source->red;
|
||||
target->green = source->green;
|
||||
target->blue = source->blue;
|
||||
}
|
||||
|
||||
void
|
||||
gdkcolor_to_color_t(color_t *target, GdkColor *source)
|
||||
{
|
||||
target->pixel = source->pixel;
|
||||
target->red = source->red;
|
||||
target->green = source->green;
|
||||
target->blue = source->blue;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* color_utils.h
|
||||
* Declarations of utilities for converting between "toolkit-independent"
|
||||
* and GDK notions of color
|
||||
*
|
||||
* $Id: color_utils.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __COLOR_UTILS_H__
|
||||
#define __COLOR_UTILS_H__
|
||||
|
||||
void color_t_to_gdkcolor(GdkColor *, color_t *);
|
||||
void gdkcolor_to_color_t(color_t *, GdkColor *);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,291 @@
|
|||
/* colors.c
|
||||
* Definitions for color structures and routines
|
||||
*
|
||||
* $Id: colors.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* Updated 1 Dec 10 jjm
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <epan/filesystem.h>
|
||||
|
||||
#include "gtk/main.h"
|
||||
#include <epan/packet.h>
|
||||
#include "colors.h"
|
||||
#include "file.h"
|
||||
#include <epan/dfilter/dfilter.h>
|
||||
#include "simple_dialog.h"
|
||||
|
||||
extern capture_file cf;
|
||||
|
||||
static gboolean read_filters(void);
|
||||
|
||||
GSList *filter_list;
|
||||
|
||||
static GdkColormap* sys_cmap;
|
||||
static GdkColormap* our_cmap = NULL;
|
||||
|
||||
GdkColor WHITE = { 0, 65535, 65535, 65535 };
|
||||
GdkColor BLACK = { 0, 0, 0, 0 };
|
||||
|
||||
/* Initialize the filter structures (reading from file) */
|
||||
void
|
||||
colfilter_init(void)
|
||||
{
|
||||
gboolean got_white, got_black;
|
||||
|
||||
sys_cmap = gdk_colormap_get_system();
|
||||
|
||||
/* Allocate "constant" colors. */
|
||||
got_white = get_color(&WHITE);
|
||||
got_black = get_color(&BLACK);
|
||||
|
||||
/* Got milk? */
|
||||
if (!got_white) {
|
||||
if (!got_black)
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Could not allocate colors black or white.");
|
||||
else
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Could not allocate color white.");
|
||||
} else {
|
||||
if (!got_black)
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Could not allocate color black.");
|
||||
}
|
||||
|
||||
read_filters();
|
||||
}
|
||||
|
||||
/* Create a new filter */
|
||||
color_filter_t *
|
||||
new_color_filter(gchar *name, /* The name of the filter to create */
|
||||
gchar *filter_string) /* The string representing the filter */
|
||||
{
|
||||
color_filter_t *colorf;
|
||||
|
||||
colorf = (color_filter_t *)g_malloc(sizeof (color_filter_t));
|
||||
colorf->filter_name = g_strdup(name);
|
||||
colorf->filter_text = g_strdup(filter_string);
|
||||
colorf->bg_color = WHITE;
|
||||
colorf->fg_color = BLACK;
|
||||
colorf->c_colorfilter = NULL;
|
||||
colorf->edit_dialog = NULL;
|
||||
filter_list = g_slist_append(filter_list, colorf);
|
||||
return colorf;
|
||||
}
|
||||
|
||||
/* delete the specified filter */
|
||||
void
|
||||
delete_color_filter(color_filter_t *colorf)
|
||||
{
|
||||
if (colorf->filter_name != NULL)
|
||||
g_free(colorf->filter_name);
|
||||
if (colorf->filter_text != NULL)
|
||||
g_free(colorf->filter_text);
|
||||
if (colorf->c_colorfilter != NULL)
|
||||
dfilter_free(colorf->c_colorfilter);
|
||||
filter_list = g_slist_remove(filter_list, colorf);
|
||||
g_free(colorf);
|
||||
}
|
||||
|
||||
static void
|
||||
prime_edt(gpointer data, gpointer user_data)
|
||||
{
|
||||
color_filter_t *colorf = data;
|
||||
epan_dissect_t *edt = user_data;
|
||||
|
||||
if (colorf->c_colorfilter != NULL)
|
||||
epan_dissect_prime_dfilter(edt, colorf->c_colorfilter);
|
||||
}
|
||||
|
||||
/* Prime the epan_dissect_t with all the compiler
|
||||
* color filters in 'filter_list'. */
|
||||
void
|
||||
filter_list_prime_edt(epan_dissect_t *edt)
|
||||
{
|
||||
g_slist_foreach(filter_list, prime_edt, edt);
|
||||
}
|
||||
|
||||
|
||||
/* read filters from the file */
|
||||
static gboolean
|
||||
read_filters(void)
|
||||
{
|
||||
/* TODO: Lots more syntax checking on the file */
|
||||
/* I hate these fixed length names! TODO: make more dynamic */
|
||||
/* XXX - buffer overflow possibility here
|
||||
* sscanf blocks max size of name and filter_exp; buf is used for
|
||||
* reading only */
|
||||
gchar name[256],filter_exp[256], buf[1024];
|
||||
guint16 fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
|
||||
GdkColor fg_color, bg_color;
|
||||
color_filter_t *colorf;
|
||||
gchar *path;
|
||||
FILE *f;
|
||||
dfilter_t *temp_dfilter;
|
||||
|
||||
/* decide what file to open (from dfilter code) */
|
||||
path = get_persconffile_path("colorfilters", FALSE);
|
||||
if ((f = fopen(path, "r")) == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Could not open filter file\n\"%s\": %s.", path,
|
||||
strerror(errno));
|
||||
}
|
||||
g_free((gchar *)path);
|
||||
return FALSE;
|
||||
}
|
||||
g_free((gchar *)path);
|
||||
path = NULL;
|
||||
|
||||
do {
|
||||
if (fgets(buf,sizeof buf, f) == NULL)
|
||||
break;
|
||||
|
||||
if (strspn(buf," \t") == (size_t)((strchr(buf,'*') - buf))) {
|
||||
/* leading # comment */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we get the @ delimiter. It is not in any strings
|
||||
* Format is:
|
||||
* @name@filter expression@[background r,g,b][foreground r,g,b]
|
||||
*/
|
||||
if (sscanf(buf," @%256[^@]@%256[^@]@[%hu,%hu,%hu][%hu,%hu,%hu]",
|
||||
name, filter_exp, &bg_r, &bg_g, &bg_b, &fg_r, &fg_g, &fg_b)
|
||||
== 8) {
|
||||
/* we got a filter */
|
||||
|
||||
if (!dfilter_compile(filter_exp, &temp_dfilter)) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Could not compile color filter %s from saved filters.\n%s",
|
||||
name, dfilter_error_msg);
|
||||
continue;
|
||||
}
|
||||
if (!get_color(&fg_color)) {
|
||||
/* oops */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Could not allocate foreground color "
|
||||
"specified in input file for %s.", name);
|
||||
dfilter_free(temp_dfilter);
|
||||
continue;
|
||||
}
|
||||
if (!get_color(&bg_color)) {
|
||||
/* oops */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Could not allocate background color "
|
||||
"specified in input file for %s.", name);
|
||||
dfilter_free(temp_dfilter);
|
||||
continue;
|
||||
}
|
||||
|
||||
colorf = new_color_filter(name, filter_exp);
|
||||
colorf->c_colorfilter = temp_dfilter;
|
||||
fg_color.red = fg_r;
|
||||
fg_color.green = fg_g;
|
||||
fg_color.blue = fg_b;
|
||||
bg_color.red = bg_r;
|
||||
bg_color.green = bg_g;
|
||||
bg_color.blue = bg_b;
|
||||
|
||||
colorf->bg_color = bg_color;
|
||||
colorf->fg_color = fg_color;
|
||||
} /* if sscanf */
|
||||
} while(!feof(f));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
write_filter(gpointer filter_arg, gpointer file_arg)
|
||||
{
|
||||
color_filter_t *colorf = filter_arg;
|
||||
FILE *f = file_arg;
|
||||
|
||||
fprintf(f,"@%s@%s@[%d,%d,%d][%d,%d,%d]\n",
|
||||
colorf->filter_name,
|
||||
colorf->filter_text,
|
||||
colorf->bg_color.red,
|
||||
colorf->bg_color.green,
|
||||
colorf->bg_color.blue,
|
||||
colorf->fg_color.red,
|
||||
colorf->fg_color.green,
|
||||
colorf->fg_color.blue);
|
||||
}
|
||||
|
||||
/* save filters in filter file */
|
||||
gboolean
|
||||
write_filters(void)
|
||||
{
|
||||
gchar *pf_dir_path;
|
||||
const gchar *path;
|
||||
FILE *f;
|
||||
|
||||
/* Create the directory that holds personal configuration files,
|
||||
if necessary. */
|
||||
if (create_persconffile_dir(&pf_dir_path) == -1) {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Can't create directory\n\"%s\"\nfor color files: %s.",
|
||||
pf_dir_path, strerror(errno));
|
||||
g_free(pf_dir_path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
path = get_persconffile_path("colorfilters", TRUE);
|
||||
if ((f = fopen(path, "w+")) == NULL) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Could not open\n%s\nfor writing: %s.",
|
||||
path, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Ethereal\n");
|
||||
g_slist_foreach(filter_list, write_filter, f);
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* allocate a color from the color map */
|
||||
gboolean
|
||||
get_color (GdkColor *new_color)
|
||||
{
|
||||
GdkVisual *pv;
|
||||
|
||||
if (!our_cmap) {
|
||||
if ( !gdk_colormap_alloc_color (sys_cmap, new_color, FALSE, TRUE)) {
|
||||
pv = gdk_visual_get_best();
|
||||
if ( !(our_cmap = gdk_colormap_new(pv, TRUE)))
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, "Could not create new colormap");
|
||||
} else
|
||||
return (TRUE);
|
||||
}
|
||||
return ( gdk_colormap_alloc_color ( our_cmap, new_color, FALSE, TRUE) );
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/* colors.h
|
||||
* Definitions for color structures and routines
|
||||
*
|
||||
* $Id: colors.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __COLORS_H__
|
||||
#define __COLORS_H__
|
||||
|
||||
#include <epan/proto.h>
|
||||
#include <epan/dfilter/dfilter.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <epan/epan.h>
|
||||
|
||||
#define MAXCOLORS 255
|
||||
#define MAX_COLOR_FILTER_NAME_LEN 33
|
||||
#define MAX_COLOR_FILTER_STRING_LEN 256
|
||||
|
||||
#define CFILTERS_CONTAINS_FILTER(filter) \
|
||||
((filter)->num_of_filters != 0)
|
||||
|
||||
extern GdkColor WHITE;
|
||||
extern GdkColor BLACK;
|
||||
|
||||
/* Data for a color filter. */
|
||||
typedef struct _color_filter {
|
||||
gchar *filter_name; /* name of the filter */
|
||||
gchar *filter_text; /* text of the filter expression */
|
||||
GdkColor bg_color; /* background color for packets that match */
|
||||
GdkColor fg_color; /* foreground color for packets that match */
|
||||
dfilter_t *c_colorfilter; /* compiled filter expression */
|
||||
GtkWidget *edit_dialog; /* if filter is being edited, dialog box for it */
|
||||
} color_filter_t;
|
||||
|
||||
/* List of all color filters. */
|
||||
extern GSList *filter_list;
|
||||
|
||||
void colfilter_init(void);
|
||||
|
||||
gboolean write_filters(void);
|
||||
|
||||
color_filter_t *new_color_filter(gchar *name, gchar *filter_string);
|
||||
void delete_color_filter(color_filter_t *colorf);
|
||||
|
||||
gboolean get_color (GdkColor *new_color);
|
||||
|
||||
void
|
||||
filter_list_prime_edt(epan_dissect_t *edt);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,377 @@
|
|||
/* column_prefs.c
|
||||
* Dialog box for column preferences
|
||||
*
|
||||
* $Id: column_prefs.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "column_prefs.h"
|
||||
#include "gtkglobals.h"
|
||||
#include "prefs.h"
|
||||
#include "column.h"
|
||||
|
||||
static GtkWidget *column_l, *del_bt, *title_te, *fmt_m, *up_bt, *dn_bt;
|
||||
static gint cur_fmt, cur_row;
|
||||
|
||||
static void column_list_select_cb(GtkCList *clist, gint row, gint column,
|
||||
GdkEvent *event, gpointer user_data);
|
||||
static void column_list_unselect_cb(GtkCList *clist, gint row, gint column,
|
||||
GdkEvent *event, gpointer user_data);
|
||||
static void column_list_new_cb(GtkWidget *, gpointer);
|
||||
static void column_entry_changed_cb(GtkEditable *, gpointer);
|
||||
static void column_menu_changed_cb(GtkWidget *, gpointer);
|
||||
static void column_list_delete_cb(GtkWidget *, gpointer);
|
||||
static void column_arrow_cb(GtkWidget *, gpointer);
|
||||
void column_set_arrow_button_sensitivity(GList *);
|
||||
|
||||
#define E_COL_NAME_KEY "column_name"
|
||||
#define E_COL_LBL_KEY "column_label"
|
||||
#define E_COL_CM_KEY "in_col_cancel_mode"
|
||||
|
||||
/* Create and display the column selection widgets. */
|
||||
/* Called when the 'Columns' preference notebook page is selected. */
|
||||
GtkWidget *
|
||||
column_prefs_show() {
|
||||
GtkWidget *main_vb, *top_hb, *list_bb, *new_bt, *column_sc,
|
||||
*tb, *lb, *menu, *mitem, *arrow_hb;
|
||||
GList *clp = NULL;
|
||||
fmt_data *cfmt;
|
||||
gint i, row;
|
||||
gchar *column_titles[] = {"Title", "Format"}, *col_ent[2];
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_widget_show(main_vb);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), E_COL_CM_KEY, (gpointer)FALSE);
|
||||
|
||||
/* Top row: Column list and buttons */
|
||||
top_hb = gtk_hbox_new(FALSE, 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), top_hb);
|
||||
gtk_widget_show(top_hb);
|
||||
|
||||
list_bb = gtk_vbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (list_bb), GTK_BUTTONBOX_START);
|
||||
gtk_container_add(GTK_CONTAINER(top_hb), list_bb);
|
||||
gtk_widget_show(list_bb);
|
||||
|
||||
new_bt = gtk_button_new_from_stock(GTK_STOCK_NEW);
|
||||
g_signal_connect(G_OBJECT(new_bt), "clicked",
|
||||
G_CALLBACK(column_list_new_cb), NULL);
|
||||
gtk_container_add(GTK_CONTAINER(list_bb), new_bt);
|
||||
gtk_widget_show(new_bt);
|
||||
|
||||
del_bt = gtk_button_new_from_stock (GTK_STOCK_DELETE);
|
||||
gtk_widget_set_sensitive(del_bt, FALSE);
|
||||
g_signal_connect(G_OBJECT(del_bt), "clicked",
|
||||
G_CALLBACK(column_list_delete_cb), NULL);
|
||||
gtk_container_add(GTK_CONTAINER(list_bb), del_bt);
|
||||
gtk_widget_show(del_bt);
|
||||
|
||||
arrow_hb = gtk_hbox_new(TRUE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(list_bb), arrow_hb);
|
||||
gtk_widget_show(arrow_hb);
|
||||
|
||||
up_bt = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
|
||||
gtk_widget_set_sensitive(up_bt, FALSE);
|
||||
g_signal_connect(G_OBJECT(up_bt), "clicked",
|
||||
G_CALLBACK(column_arrow_cb), NULL);
|
||||
gtk_box_pack_start(GTK_BOX(arrow_hb), up_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(up_bt);
|
||||
|
||||
dn_bt = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
|
||||
gtk_widget_set_sensitive(dn_bt, FALSE);
|
||||
g_signal_connect(G_OBJECT(dn_bt), "clicked",
|
||||
G_CALLBACK(column_arrow_cb), NULL);
|
||||
gtk_box_pack_start(GTK_BOX(arrow_hb), dn_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(dn_bt);
|
||||
|
||||
column_sc = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(column_sc),
|
||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_set_size_request(column_sc, 250, 150);
|
||||
gtk_container_add(GTK_CONTAINER(top_hb), column_sc);
|
||||
gtk_widget_show(column_sc);
|
||||
|
||||
column_l = gtk_clist_new_with_titles(2, column_titles);
|
||||
/* XXX - make this match the packet list prefs? */
|
||||
gtk_clist_set_selection_mode(GTK_CLIST(column_l), GTK_SELECTION_SINGLE);
|
||||
gtk_clist_column_titles_passive(GTK_CLIST(column_l));
|
||||
gtk_clist_column_titles_show(GTK_CLIST(column_l));
|
||||
gtk_clist_set_column_auto_resize(GTK_CLIST(column_l), 0, TRUE);
|
||||
gtk_clist_set_column_auto_resize(GTK_CLIST(column_l), 1, TRUE);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(column_l), "select-row",
|
||||
GTK_SIGNAL_FUNC(column_list_select_cb), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(column_l), "unselect-row",
|
||||
GTK_SIGNAL_FUNC(column_list_unselect_cb), NULL);
|
||||
gtk_container_add(GTK_CONTAINER(column_sc), column_l);
|
||||
gtk_widget_show(column_l);
|
||||
|
||||
clp = g_list_first(prefs.col_list);
|
||||
while (clp) {
|
||||
cfmt = (fmt_data *) clp->data;
|
||||
col_ent[0] = cfmt->title;
|
||||
col_ent[1] = col_format_desc(get_column_format_from_str(cfmt->fmt));
|
||||
row = gtk_clist_append(GTK_CLIST(column_l), col_ent);
|
||||
gtk_clist_set_row_data(GTK_CLIST(column_l), row, clp);
|
||||
clp = clp->next;
|
||||
}
|
||||
|
||||
/* Colunm name entry and format selection */
|
||||
tb = gtk_table_new(2, 2, FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), tb);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(tb), 15);
|
||||
gtk_widget_show(tb);
|
||||
|
||||
lb = gtk_label_new("Column title:");
|
||||
gtk_misc_set_alignment(GTK_MISC(lb), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(tb), lb, 0, 1, 0, 1);
|
||||
gtk_widget_show(lb);
|
||||
|
||||
title_te = gtk_entry_new();
|
||||
gtk_table_attach_defaults(GTK_TABLE(tb), title_te, 1, 2, 0, 1);
|
||||
gtk_signal_connect(GTK_OBJECT(title_te), "changed",
|
||||
GTK_SIGNAL_FUNC(column_entry_changed_cb), column_l);
|
||||
gtk_widget_set_sensitive(title_te, FALSE);
|
||||
gtk_widget_show(title_te);
|
||||
|
||||
lb = gtk_label_new("Column format:");
|
||||
gtk_misc_set_alignment(GTK_MISC(lb), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(tb), lb, 0, 1, 1, 2);
|
||||
gtk_widget_show(lb);
|
||||
|
||||
top_hb = gtk_hbox_new(FALSE, 5);
|
||||
gtk_table_attach(GTK_TABLE(tb), top_hb, 1, 2, 1, 2, GTK_FILL,
|
||||
GTK_SHRINK, 0, 0);
|
||||
gtk_widget_show(top_hb);
|
||||
|
||||
fmt_m = gtk_option_menu_new();
|
||||
menu = gtk_menu_new();
|
||||
for (i = 0; i < NUM_COL_FMTS; i++) {
|
||||
mitem = gtk_menu_item_new_with_label(col_format_desc(i));
|
||||
gtk_menu_append(GTK_MENU(menu), mitem);
|
||||
g_signal_connect(G_OBJECT(mitem), "activate",
|
||||
G_CALLBACK(column_menu_changed_cb), (gpointer) i);
|
||||
gtk_widget_show(mitem);
|
||||
}
|
||||
gtk_option_menu_set_menu(GTK_OPTION_MENU(fmt_m), menu);
|
||||
cur_fmt = 0;
|
||||
gtk_option_menu_set_history(GTK_OPTION_MENU(fmt_m), cur_fmt);
|
||||
gtk_widget_set_sensitive(fmt_m, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(top_hb), fmt_m, FALSE, FALSE, 0);
|
||||
gtk_widget_show(fmt_m);
|
||||
|
||||
return(main_vb);
|
||||
}
|
||||
|
||||
/* For each selection, set the entry and option menu widgets to match
|
||||
* the currently selected item. Set the up/down button sensitivity.
|
||||
* Draw focus to the entry widget. */
|
||||
static void
|
||||
column_list_select_cb(GtkCList *clist,
|
||||
gint row,
|
||||
gint column _U_,
|
||||
GdkEvent *event _U_,
|
||||
gpointer user_data _U_) {
|
||||
fmt_data *cfmt;
|
||||
GList *clp;
|
||||
|
||||
clp = gtk_clist_get_row_data(clist, row);
|
||||
g_assert(clp != NULL);
|
||||
cfmt = (fmt_data *) clp->data;
|
||||
cur_fmt = get_column_format_from_str(cfmt->fmt);
|
||||
g_assert(cur_fmt != -1); /* It should always be valid */
|
||||
cur_row = row;
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(title_te), cfmt->title);
|
||||
gtk_editable_select_region(GTK_EDITABLE(title_te), 0, -1);
|
||||
gtk_widget_grab_focus(title_te);
|
||||
|
||||
gtk_option_menu_set_history(GTK_OPTION_MENU(fmt_m), cur_fmt);
|
||||
|
||||
gtk_widget_set_sensitive(del_bt, TRUE);
|
||||
gtk_widget_set_sensitive(title_te, TRUE);
|
||||
gtk_widget_set_sensitive(fmt_m, TRUE);
|
||||
column_set_arrow_button_sensitivity(clp);
|
||||
}
|
||||
|
||||
/* A row was deselected. Clear the text entry box and disable various
|
||||
* widgets. */
|
||||
static void
|
||||
column_list_unselect_cb(GtkCList *clist _U_,
|
||||
gint row _U_,
|
||||
gint column _U_,
|
||||
GdkEvent *event _U_,
|
||||
gpointer user_data _U_) {
|
||||
|
||||
cur_row = -1;
|
||||
gtk_editable_delete_text(GTK_EDITABLE(title_te), 0, -1);
|
||||
|
||||
gtk_widget_set_sensitive(del_bt, FALSE);
|
||||
gtk_widget_set_sensitive(title_te, FALSE);
|
||||
gtk_widget_set_sensitive(fmt_m, FALSE);
|
||||
gtk_widget_set_sensitive(up_bt, FALSE);
|
||||
gtk_widget_set_sensitive(dn_bt, FALSE);
|
||||
}
|
||||
|
||||
/* To do: add input checking to each of these callbacks */
|
||||
|
||||
static void
|
||||
column_list_new_cb(GtkWidget *w _U_, gpointer data _U_) {
|
||||
fmt_data *cfmt;
|
||||
gchar *title = "New Column", *col_ent[2];
|
||||
|
||||
cur_fmt = 0;
|
||||
cfmt = (fmt_data *) g_malloc(sizeof(fmt_data));
|
||||
cfmt->title = g_strdup(title);
|
||||
cfmt->fmt = g_strdup(col_format_to_string(cur_fmt));
|
||||
prefs.col_list = g_list_append(prefs.col_list, cfmt);
|
||||
|
||||
col_ent[0] = title;
|
||||
col_ent[1] = col_format_desc(cur_fmt);
|
||||
cur_row = gtk_clist_append(GTK_CLIST(column_l), col_ent);
|
||||
gtk_clist_set_row_data(GTK_CLIST(column_l), cur_row,
|
||||
g_list_last(prefs.col_list));
|
||||
|
||||
gtk_clist_select_row(GTK_CLIST(column_l), cur_row, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
column_list_delete_cb(GtkWidget *w _U_, gpointer data _U_) {
|
||||
GList *clp;
|
||||
fmt_data *cfmt;
|
||||
|
||||
g_assert(cur_row >= 0);
|
||||
clp = gtk_clist_get_row_data(GTK_CLIST(column_l), cur_row);
|
||||
|
||||
cfmt = (fmt_data *) clp->data;
|
||||
g_free(cfmt->title);
|
||||
g_free(cfmt->fmt);
|
||||
g_free(cfmt);
|
||||
prefs.col_list = g_list_remove_link(prefs.col_list, clp);
|
||||
|
||||
gtk_clist_remove(GTK_CLIST(column_l), cur_row);
|
||||
}
|
||||
|
||||
/* The user changed the column title entry box. */
|
||||
static void
|
||||
column_entry_changed_cb(GtkEditable *te, gpointer data) {
|
||||
fmt_data *cfmt;
|
||||
GList *clp;
|
||||
GtkCList *cl = data;
|
||||
gchar *title;
|
||||
|
||||
if (cur_row >= 0) {
|
||||
title = gtk_editable_get_chars(te, 0, -1);
|
||||
clp = gtk_clist_get_row_data(cl, cur_row);
|
||||
cfmt = (fmt_data *) clp->data;
|
||||
|
||||
gtk_clist_set_text(cl, cur_row, 0, title);
|
||||
g_free(cfmt->title);
|
||||
cfmt->title = title;
|
||||
}
|
||||
}
|
||||
|
||||
/* The user changed the format menu. */
|
||||
static void
|
||||
column_menu_changed_cb(GtkWidget *w _U_, gpointer data) {
|
||||
fmt_data *cfmt;
|
||||
GList *clp;
|
||||
|
||||
if (cur_row >= 0) {
|
||||
cur_fmt = (gint) data;
|
||||
clp = gtk_clist_get_row_data(GTK_CLIST(column_l), cur_row);
|
||||
cfmt = (fmt_data *) clp->data;
|
||||
|
||||
gtk_clist_set_text(GTK_CLIST(column_l), cur_row, 1,
|
||||
col_format_desc(cur_fmt));
|
||||
g_free(cfmt->fmt);
|
||||
cfmt->fmt = g_strdup(col_format_to_string(cur_fmt));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
column_arrow_cb(GtkWidget *w, gpointer data _U_) {
|
||||
GList *clp;
|
||||
fmt_data *cfmt;
|
||||
gint inc = 1;
|
||||
|
||||
g_assert(cur_row >= 0);
|
||||
|
||||
if (w == up_bt)
|
||||
inc = -1;
|
||||
|
||||
/* This would end up appending to the list. We shouldn't have to
|
||||
* check for appending past the end of the list. */
|
||||
g_assert((cur_row + inc) >= 0);
|
||||
|
||||
clp = gtk_clist_get_row_data(GTK_CLIST(column_l), cur_row);
|
||||
cfmt = (fmt_data *) clp->data;
|
||||
prefs.col_list = g_list_remove(prefs.col_list, cfmt);
|
||||
prefs.col_list = g_list_insert(prefs.col_list, cfmt, cur_row + inc);
|
||||
|
||||
gtk_clist_row_move(GTK_CLIST(column_l), cur_row, cur_row + inc);
|
||||
clp = g_list_find(prefs.col_list, cfmt);
|
||||
cur_row += inc;
|
||||
gtk_clist_set_row_data(GTK_CLIST(column_l), cur_row, clp);
|
||||
|
||||
column_set_arrow_button_sensitivity(clp);
|
||||
}
|
||||
|
||||
void
|
||||
column_set_arrow_button_sensitivity(GList *clp) {
|
||||
gint up_sens = FALSE, dn_sens = FALSE;
|
||||
|
||||
if (clp != g_list_first(prefs.col_list))
|
||||
up_sens = TRUE;
|
||||
if (clp != g_list_last(prefs.col_list))
|
||||
dn_sens = TRUE;
|
||||
|
||||
gtk_widget_set_sensitive(up_bt, up_sens);
|
||||
gtk_widget_set_sensitive(dn_bt, dn_sens);
|
||||
}
|
||||
|
||||
void
|
||||
column_prefs_fetch(GtkWidget *w _U_) {
|
||||
}
|
||||
|
||||
void
|
||||
column_prefs_apply(GtkWidget *w _U_) {
|
||||
}
|
||||
|
||||
void
|
||||
column_prefs_destroy(GtkWidget *w) {
|
||||
|
||||
/* Let the list cb know we're about to destroy the widget tree, so it */
|
||||
/* doesn't operate on widgets that don't exist. */
|
||||
gtk_object_set_data(GTK_OBJECT(w), E_COL_CM_KEY, (gpointer)TRUE);
|
||||
gtk_widget_destroy(GTK_WIDGET(w));
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/* gui_prefs.h
|
||||
* Definitions for column preferences window
|
||||
*
|
||||
* $Id: column_prefs.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
GtkWidget *column_prefs_show(void);
|
||||
void column_prefs_fetch(GtkWidget *);
|
||||
void column_prefs_apply(GtkWidget *);
|
||||
void column_prefs_destroy(GtkWidget *);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,33 @@
|
|||
/* decode_as_dlg.c
|
||||
*
|
||||
* $Id: decode_as_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Routines to modify dissector tables on the fly.
|
||||
*
|
||||
* By David Hampton <dhampton@mac.com>
|
||||
* Copyright 2001 David Hampton
|
||||
*
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DECODE_AS_DLG_H__
|
||||
#define __DECODE_AS_DLG_H__
|
||||
|
||||
void decode_as_cb(GtkWidget *, gpointer);
|
||||
void decode_show_cb(GtkWidget *, gpointer);
|
||||
gboolean decode_as_ok(void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
/* dfilter_expr_dlg.h
|
||||
* Definitions for dialog boxes for display filter expression construction
|
||||
*
|
||||
* $Id: dfilter_expr_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __DFILTER_EXPR_DLG_H__
|
||||
#define __DFILTER_EXPR_DLG_H__
|
||||
|
||||
void dfilter_expr_dlg_new(GtkWidget *);
|
||||
|
||||
#endif /* dfilter_expr_dlg.h */
|
|
@ -0,0 +1,337 @@
|
|||
/* display_opts.c
|
||||
* Routines for packet display windows
|
||||
*
|
||||
* $Id: display_opts.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKIO_H
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
#include <epan/resolv.h>
|
||||
#include <epan/timestamp.h>
|
||||
#include <epan/packet.h>
|
||||
#include "file.h"
|
||||
#include "display_opts.h"
|
||||
#include "ui_util.h"
|
||||
#include "dlg_utils.h"
|
||||
|
||||
extern capture_file cfile;
|
||||
|
||||
/* Display callback data keys */
|
||||
#define E_DISPLAY_TIME_ABS_KEY "display_time_abs"
|
||||
#define E_DISPLAY_DATE_TIME_ABS_KEY "display_date_time_abs"
|
||||
#define E_DISPLAY_TIME_REL_KEY "display_time_rel"
|
||||
#define E_DISPLAY_TIME_DELTA_KEY "display_time_delta"
|
||||
#ifdef HAVE_LIBPCAP
|
||||
#define E_DISPLAY_AUTO_SCROLL_KEY "display_auto_scroll"
|
||||
#endif
|
||||
#define E_DISPLAY_M_NAME_RESOLUTION_KEY "display_mac_name_resolution"
|
||||
#define E_DISPLAY_N_NAME_RESOLUTION_KEY "display_network_name_resolution"
|
||||
#define E_DISPLAY_T_NAME_RESOLUTION_KEY "display_transport_name_resolution"
|
||||
|
||||
static void display_opt_ok_cb(GtkWidget *, gpointer);
|
||||
static void display_opt_apply_cb(GtkWidget *, gpointer);
|
||||
static void get_display_options(GtkWidget *);
|
||||
static void update_display(void);
|
||||
static void display_opt_close_cb(GtkWidget *, gpointer);
|
||||
static void display_opt_destroy_cb(GtkWidget *, gpointer);
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Display Options" window, if any,
|
||||
* so that if somebody tries to do "Display:Options" while there's already
|
||||
* a "Display Options" window up, we just pop up the existing one, rather
|
||||
* than creating a new one.
|
||||
*/
|
||||
static GtkWidget *display_opt_w;
|
||||
|
||||
static ts_type initial_timestamp_type;
|
||||
static ts_type current_timestamp_type;
|
||||
|
||||
void
|
||||
display_opt_cb(GtkWidget *w _U_, gpointer d _U_) {
|
||||
GtkWidget *button, *main_vb, *bbox, *ok_bt, *apply_bt, *cancel_bt;
|
||||
GtkAccelGroup *accel_group;
|
||||
|
||||
if (display_opt_w != NULL) {
|
||||
/* There's already a "Display Options" dialog box; reactivate it. */
|
||||
reactivate_window(display_opt_w);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the timestamp type value as of when the dialog box was first popped
|
||||
up, so that "Cancel" can put it back if we've changed it with "Apply". */
|
||||
initial_timestamp_type = timestamp_type;
|
||||
|
||||
/* Save the current timestamp type so that we know whether it has changed;
|
||||
we don't want to redisplay the time fields unless we've changed the way
|
||||
they should be displayed (as redisplaying the time fields could be
|
||||
expensive - we have to scan through all the packets and rebuild the
|
||||
packet list).*/
|
||||
current_timestamp_type = timestamp_type;
|
||||
|
||||
display_opt_w = dlg_window_new("Ethereal: Display Options");
|
||||
g_signal_connect(G_OBJECT(display_opt_w), "destroy",
|
||||
G_CALLBACK(display_opt_destroy_cb), NULL);
|
||||
|
||||
/* Accelerator group for the accelerators (or, as they're called in
|
||||
Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
|
||||
Ctrl+<key> is an accelerator). */
|
||||
accel_group = gtk_accel_group_new();
|
||||
gtk_window_add_accel_group(GTK_WINDOW(display_opt_w), accel_group);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(display_opt_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(NULL, "_Time of day",
|
||||
accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(timestamp_type == ABSOLUTE));
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_TIME_ABS_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_show(button);
|
||||
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(
|
||||
gtk_radio_button_group(GTK_RADIO_BUTTON(button)),
|
||||
"_Date and time of day", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(timestamp_type == ABSOLUTE_WITH_DATE));
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_DATE_TIME_ABS_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(
|
||||
gtk_radio_button_group(GTK_RADIO_BUTTON(button)),
|
||||
"Seconds since _beginning of capture", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(timestamp_type == RELATIVE));
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_TIME_REL_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(
|
||||
gtk_radio_button_group(GTK_RADIO_BUTTON(button)),
|
||||
"Seconds since _previous frame", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(timestamp_type == DELTA));
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_TIME_DELTA_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
button = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"_Automatic scrolling in live capture", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), auto_scroll_live);
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_AUTO_SCROLL_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
#endif
|
||||
|
||||
button = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _MAC name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
g_resolv_flags & RESOLV_MAC);
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_M_NAME_RESOLUTION_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
button = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _network name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
g_resolv_flags & RESOLV_NETWORK);
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_N_NAME_RESOLUTION_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
button = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _transport name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
g_resolv_flags & RESOLV_TRANSPORT);
|
||||
gtk_object_set_data(GTK_OBJECT(display_opt_w), E_DISPLAY_T_NAME_RESOLUTION_KEY,
|
||||
button);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
/* Button row: OK, Apply, and Cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked", G_CALLBACK(display_opt_ok_cb),
|
||||
GTK_OBJECT(display_opt_w));
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
|
||||
apply_bt = gtk_button_new_from_stock(GTK_STOCK_APPLY);
|
||||
g_signal_connect(G_OBJECT(apply_bt), "clicked",
|
||||
G_CALLBACK(display_opt_apply_cb), GTK_OBJECT(display_opt_w));
|
||||
GTK_WIDGET_SET_FLAGS(apply_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), apply_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(apply_bt);
|
||||
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_bt), "clicked",
|
||||
G_CALLBACK(display_opt_close_cb), GTK_OBJECT(display_opt_w));
|
||||
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(display_opt_w, cancel_bt);
|
||||
|
||||
gtk_widget_show(display_opt_w);
|
||||
}
|
||||
|
||||
static void
|
||||
display_opt_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
|
||||
get_display_options(GTK_WIDGET(parent_w));
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
|
||||
update_display();
|
||||
}
|
||||
|
||||
static void
|
||||
display_opt_apply_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
|
||||
get_display_options(GTK_WIDGET(parent_w));
|
||||
|
||||
update_display();
|
||||
}
|
||||
|
||||
static void
|
||||
get_display_options(GtkWidget *parent_w)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_TIME_ABS_KEY);
|
||||
if (GTK_TOGGLE_BUTTON (button)->active)
|
||||
timestamp_type = ABSOLUTE;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_DATE_TIME_ABS_KEY);
|
||||
if (GTK_TOGGLE_BUTTON (button)->active)
|
||||
timestamp_type = ABSOLUTE_WITH_DATE;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_TIME_REL_KEY);
|
||||
if (GTK_TOGGLE_BUTTON (button)->active)
|
||||
timestamp_type = RELATIVE;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_TIME_DELTA_KEY);
|
||||
if (GTK_TOGGLE_BUTTON (button)->active)
|
||||
timestamp_type = DELTA;
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_AUTO_SCROLL_KEY);
|
||||
auto_scroll_live = (GTK_TOGGLE_BUTTON (button)->active);
|
||||
#endif
|
||||
|
||||
g_resolv_flags = RESOLV_NONE;
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_M_NAME_RESOLUTION_KEY);
|
||||
g_resolv_flags |= (GTK_TOGGLE_BUTTON (button)->active ? RESOLV_MAC : RESOLV_NONE);
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_N_NAME_RESOLUTION_KEY);
|
||||
g_resolv_flags |= (GTK_TOGGLE_BUTTON (button)->active ? RESOLV_NETWORK : RESOLV_NONE);
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
E_DISPLAY_T_NAME_RESOLUTION_KEY);
|
||||
g_resolv_flags |= (GTK_TOGGLE_BUTTON (button)->active ? RESOLV_TRANSPORT : RESOLV_NONE);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
update_display(void)
|
||||
{
|
||||
if (timestamp_type != current_timestamp_type) {
|
||||
/* Time stamp format changed; update the display.
|
||||
|
||||
XXX - redissecting the packets could actually be faster;
|
||||
we have to find the row number for each frame, in order to
|
||||
update the time stamp columns, and doing that is linear in
|
||||
the row number, which means the whole process is N^2 in
|
||||
the number of rows, whilst redissecting the packets is only
|
||||
linear in the number of rows (assuming you're using our
|
||||
CList code, or the GTK+ 1.2.8 CList code, or other CList
|
||||
code which doesn't have to scan the entire list to find the
|
||||
last element), even though the latter involves doing more work
|
||||
per packet. */
|
||||
current_timestamp_type = timestamp_type;
|
||||
change_time_formats(&cfile);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
display_opt_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
|
||||
{
|
||||
/* Revert the timestamp type to the value it has when we started. */
|
||||
timestamp_type = initial_timestamp_type;
|
||||
|
||||
/* Update the display if either of those changed. */
|
||||
update_display();
|
||||
|
||||
gtk_grab_remove(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
||||
|
||||
static void
|
||||
display_opt_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* Note that we no longer have a "Display Options" dialog box. */
|
||||
display_opt_w = NULL;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* display_opts.h
|
||||
* Definitions for display option window
|
||||
*
|
||||
* $Id: display_opts.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __DISPLAY_OPTS_H__
|
||||
#define __DISPLAY_OPTS_H__
|
||||
|
||||
void display_opt_cb(GtkWidget *, gpointer);
|
||||
|
||||
#endif /* display_opts.h */
|
|
@ -0,0 +1,167 @@
|
|||
/* dlg_utils.c
|
||||
* Utilities to use when constructing dialogs
|
||||
*
|
||||
* $Id: dlg_utils.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "gtkglobals.h"
|
||||
#include "ui_util.h"
|
||||
|
||||
static void
|
||||
dlg_activate (GtkWidget *widget, gpointer ok_button);
|
||||
|
||||
static gint
|
||||
dlg_key_press (GtkWidget *widget, GdkEventKey *event, gpointer cancel_button);
|
||||
|
||||
/* Create a dialog box window that belongs to Ethereal's main window. */
|
||||
GtkWidget *
|
||||
dlg_window_new(const gchar *title)
|
||||
{
|
||||
GtkWidget *win;
|
||||
|
||||
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for(GTK_WINDOW(win), GTK_WINDOW(top_level));
|
||||
gtk_window_set_title(GTK_WINDOW(win), title);
|
||||
g_signal_connect(G_OBJECT(win), "realize",
|
||||
G_CALLBACK(window_icon_realize_cb), NULL);
|
||||
return win;
|
||||
}
|
||||
|
||||
/* Set the "activate" signal for a widget to call a routine to
|
||||
activate the "OK" button for a dialog box.
|
||||
|
||||
XXX - there should be a way to specify that a GtkEntry widget
|
||||
shouldn't itself handle the Return key, but should let it be
|
||||
passed on to the parent, so that you don't have to do this
|
||||
by hand for every GtkEntry widget in a dialog box, but, alas,
|
||||
there isn't. (Does this problem exist for other widgets?
|
||||
I.e., are there any others that seize the Return key? */
|
||||
void
|
||||
dlg_set_activate(GtkWidget *widget, GtkWidget *ok_button)
|
||||
{
|
||||
g_signal_connect(G_OBJECT(widget), "activate",
|
||||
G_CALLBACK(dlg_activate), ok_button);
|
||||
}
|
||||
|
||||
static void
|
||||
dlg_activate (GtkWidget *widget _U_, gpointer ok_button)
|
||||
{
|
||||
gtk_widget_activate(GTK_WIDGET(ok_button));
|
||||
}
|
||||
|
||||
/* Set the "key_press_event" signal for a top-level dialog window to
|
||||
call a routine to activate the "Cancel" button for a dialog box if
|
||||
the key being pressed is the <Esc> key.
|
||||
|
||||
XXX - there should be a GTK+ widget that'll do that for you, and
|
||||
let you specify a "Cancel" button. It should also not impose
|
||||
a requirement that there be a separator in the dialog box, as
|
||||
the GtkDialog widget does; the visual convention that there's
|
||||
such a separator between the rest of the dialog boxes and buttons
|
||||
such as "OK" and "Cancel" is, for better or worse, not universal
|
||||
(not even in GTK+ - look at the GtkFileSelection dialog!). */
|
||||
void
|
||||
dlg_set_cancel(GtkWidget *widget, GtkWidget *cancel_button)
|
||||
{
|
||||
g_signal_connect(G_OBJECT(widget), "key_press_event",
|
||||
G_CALLBACK(dlg_key_press), cancel_button);
|
||||
}
|
||||
|
||||
static gint
|
||||
dlg_key_press (GtkWidget *widget, GdkEventKey *event, gpointer cancel_button)
|
||||
{
|
||||
g_return_val_if_fail (widget != NULL, FALSE);
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
|
||||
if (event->keyval == GDK_Escape) {
|
||||
gtk_widget_activate(GTK_WIDGET(cancel_button));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Sigh. GTK+ appears not to acknowledge that it should be possible
|
||||
to attach mnemonics to anything other than menu items; provide
|
||||
routines to create radio and check buttons with labels that
|
||||
include mnemonics. */
|
||||
typedef struct {
|
||||
GtkWidget *button;
|
||||
GtkAccelGroup *accel_group;
|
||||
} fix_label_args_t;
|
||||
|
||||
static void
|
||||
dlg_fix_label_callback(GtkWidget *label_widget, gpointer data)
|
||||
{
|
||||
fix_label_args_t *args = data;
|
||||
gchar *label;
|
||||
guint accel_key;
|
||||
|
||||
gtk_label_get(GTK_LABEL(label_widget), &label);
|
||||
accel_key = gtk_label_parse_uline(GTK_LABEL(label_widget), label);
|
||||
if (accel_key != GDK_VoidSymbol) {
|
||||
/* Yes, we have a mnemonic. */
|
||||
gtk_widget_add_accelerator(args->button, "clicked", args->accel_group,
|
||||
accel_key, 0, GTK_ACCEL_LOCKED);
|
||||
gtk_widget_add_accelerator(args->button, "clicked", args->accel_group,
|
||||
accel_key, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dlg_fix_button_label(GtkWidget *button, GtkAccelGroup *accel_group)
|
||||
{
|
||||
fix_label_args_t args;
|
||||
|
||||
args.button = button;
|
||||
args.accel_group = accel_group;
|
||||
gtk_container_foreach(GTK_CONTAINER(button), dlg_fix_label_callback, &args);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
dlg_radio_button_new_with_label_with_mnemonic(GSList *group,
|
||||
const gchar *label, GtkAccelGroup *accel_group)
|
||||
{
|
||||
GtkWidget *radio_button;
|
||||
|
||||
radio_button = gtk_radio_button_new_with_label (group, label);
|
||||
dlg_fix_button_label(radio_button, accel_group);
|
||||
return radio_button;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
dlg_check_button_new_with_label_with_mnemonic(const gchar *label,
|
||||
GtkAccelGroup *accel_group)
|
||||
{
|
||||
GtkWidget *check_button;
|
||||
|
||||
check_button = gtk_check_button_new_with_label (label);
|
||||
dlg_fix_button_label(check_button, accel_group);
|
||||
return check_button;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* dlg_utils.h
|
||||
* Declarations of utilities to use when constructing dialogs
|
||||
*
|
||||
* $Id: dlg_utils.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __DLG_UTILS_H__
|
||||
#define __DLG_UTILS_H__
|
||||
|
||||
/* Create a dialog box window that belongs to Ethereal's main window. */
|
||||
GtkWidget *dlg_window_new(const gchar *);
|
||||
|
||||
/* Set the "activate" signal for a widget to call a routine to
|
||||
activate the "OK" button for a dialog box. */
|
||||
void dlg_set_activate(GtkWidget *widget, GtkWidget *ok_button);
|
||||
|
||||
/* Set the "key_press_event" signal for a top-level dialog window to
|
||||
call a routine to activate the "Cancel" button for a dialog box if
|
||||
the key being pressed is the <Esc> key. */
|
||||
void dlg_set_cancel(GtkWidget *widget, GtkWidget *cancel_button);
|
||||
|
||||
GtkWidget *dlg_radio_button_new_with_label_with_mnemonic(GSList *group,
|
||||
const gchar *label, GtkAccelGroup *accel_group);
|
||||
GtkWidget *dlg_check_button_new_with_label_with_mnemonic(const gchar *label,
|
||||
GtkAccelGroup *accel_group);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,647 @@
|
|||
/* file_dlg.c
|
||||
* Dialog boxes for handling files
|
||||
*
|
||||
* $Id: file_dlg.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DIRECT_H
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <epan/filesystem.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "gtkglobals.h"
|
||||
#include <epan/resolv.h>
|
||||
#include "keys.h"
|
||||
#include "filter_prefs.h"
|
||||
#include "ui_util.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "menu.h"
|
||||
#include "file_dlg.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "main.h"
|
||||
|
||||
static void file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs);
|
||||
static void file_open_destroy_cb(GtkWidget *win, gpointer user_data);
|
||||
static void select_file_type_cb(GtkWidget *w, gpointer data);
|
||||
static void file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs);
|
||||
static void file_save_as_destroy_cb(GtkWidget *win, gpointer user_data);
|
||||
|
||||
#define E_FILE_M_RESOLVE_KEY "file_dlg_mac_resolve_key"
|
||||
#define E_FILE_N_RESOLVE_KEY "file_dlg_network_resolve_key"
|
||||
#define E_FILE_T_RESOLVE_KEY "file_dlg_transport_resolve_key"
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Open Capture File" window, if
|
||||
* any, so that if somebody tries to do "File:Open" while there's already
|
||||
* an "Open Capture File" window up, we just pop up the existing one,
|
||||
* rather than creating a new one.
|
||||
*/
|
||||
static GtkWidget *file_open_w;
|
||||
|
||||
/* Open a file */
|
||||
void
|
||||
file_open_cmd_cb(GtkWidget *w, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *main_vb, *filter_hbox, *filter_bt, *filter_te,
|
||||
*m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
|
||||
GtkAccelGroup *accel_group;
|
||||
/* No Apply button, and "OK" just sets our text widget, it doesn't
|
||||
activate it (i.e., it doesn't cause us to try to open the file). */
|
||||
static construct_args_t args = {
|
||||
"Ethereal: Read Filter",
|
||||
FALSE,
|
||||
FALSE
|
||||
};
|
||||
|
||||
if (file_open_w != NULL) {
|
||||
/* There's already an "Open Capture File" dialog box; reactivate it. */
|
||||
reactivate_window(file_open_w);
|
||||
return;
|
||||
}
|
||||
|
||||
file_open_w = gtk_file_selection_new ("Ethereal: Open Capture File");
|
||||
g_signal_connect(G_OBJECT(file_open_w), "destroy",
|
||||
G_CALLBACK(file_open_destroy_cb), NULL);
|
||||
|
||||
/* Accelerator group for the accelerators (or, as they're called in
|
||||
Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
|
||||
Ctrl+<key> is an accelerator). */
|
||||
accel_group = gtk_accel_group_new();
|
||||
gtk_window_add_accel_group(GTK_WINDOW(file_open_w), accel_group);
|
||||
|
||||
/* If we've opened a file, start out by showing the files in the directory
|
||||
in which that file resided. */
|
||||
if (last_open_dir)
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_open_w), last_open_dir);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_open_w)->action_area),
|
||||
main_vb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
filter_hbox = gtk_hbox_new(FALSE, 1);
|
||||
gtk_container_border_width(GTK_CONTAINER(filter_hbox), 0);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), filter_hbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show(filter_hbox);
|
||||
|
||||
filter_bt = gtk_button_new_with_label("Filter:");
|
||||
g_signal_connect(G_OBJECT(filter_bt), "clicked",
|
||||
G_CALLBACK(display_filter_construct_cb), &args);
|
||||
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_bt, FALSE, TRUE, 0);
|
||||
gtk_widget_show(filter_bt);
|
||||
|
||||
filter_te = gtk_entry_new();
|
||||
gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
|
||||
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_te, TRUE, TRUE, 3);
|
||||
gtk_widget_show(filter_te);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
|
||||
E_RFILTER_TE_KEY, filter_te);
|
||||
|
||||
m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _MAC name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
|
||||
g_resolv_flags & RESOLV_MAC);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), m_resolv_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(m_resolv_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
|
||||
E_FILE_M_RESOLVE_KEY, m_resolv_cb);
|
||||
|
||||
n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _network name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
|
||||
g_resolv_flags & RESOLV_NETWORK);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), n_resolv_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(n_resolv_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
|
||||
E_FILE_N_RESOLVE_KEY, n_resolv_cb);
|
||||
|
||||
t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
|
||||
"Enable _transport name resolution", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
|
||||
g_resolv_flags & RESOLV_TRANSPORT);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), t_resolv_cb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(t_resolv_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
|
||||
E_FILE_T_RESOLVE_KEY, t_resolv_cb);
|
||||
|
||||
/* Connect the ok_button to file_open_ok_cb function and pass along a
|
||||
pointer to the file selection box widget */
|
||||
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
|
||||
"clicked", G_CALLBACK(file_open_ok_cb), file_open_w);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->ok_button),
|
||||
E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY));
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(file_open_w)->cancel_button),
|
||||
"clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(file_open_w));
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(file_open_w, GTK_FILE_SELECTION(file_open_w)->cancel_button);
|
||||
|
||||
gtk_widget_show(file_open_w);
|
||||
}
|
||||
|
||||
static void
|
||||
file_open_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
|
||||
gchar *cf_name, *s;
|
||||
GtkWidget *filter_te, *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
|
||||
dfilter_t *rfcode = NULL;
|
||||
int err;
|
||||
const gchar *rfilter;
|
||||
|
||||
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
|
||||
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_RFILTER_TE_KEY);
|
||||
rfilter = gtk_entry_get_text(GTK_ENTRY(filter_te));
|
||||
if (!dfilter_compile(rfilter, &rfcode)) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perhaps the user specified a directory instead of a file.
|
||||
Check whether they did. */
|
||||
if (test_for_directory(cf_name) == EISDIR) {
|
||||
/* It's a directory - set the file selection box to display that
|
||||
directory, don't try to open the directory as a capture file. */
|
||||
set_last_open_dir(cf_name);
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try to open the capture file. */
|
||||
if ((err = open_cap_file(cf_name, FALSE, &cfile)) != 0) {
|
||||
/* We couldn't open it; don't dismiss the open dialog box,
|
||||
just leave it around so that the user can, after they
|
||||
dismiss the alert box popped up for the open error,
|
||||
try again. */
|
||||
if (rfcode != NULL)
|
||||
dfilter_free(rfcode);
|
||||
g_free(cf_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Attach the new read filter to "cf" ("open_cap_file()" succeeded, so
|
||||
it closed the previous capture file, and thus destroyed any
|
||||
previous read filter attached to "cf"). */
|
||||
cfile.rfcode = rfcode;
|
||||
|
||||
/* Set the global resolving variable */
|
||||
g_resolv_flags = 0;
|
||||
m_resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_M_RESOLVE_KEY);
|
||||
g_resolv_flags |= GTK_TOGGLE_BUTTON (m_resolv_cb)->active ? RESOLV_MAC : RESOLV_NONE;
|
||||
n_resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_N_RESOLVE_KEY);
|
||||
g_resolv_flags |= GTK_TOGGLE_BUTTON (n_resolv_cb)->active ? RESOLV_NETWORK : RESOLV_NONE;
|
||||
t_resolv_cb = gtk_object_get_data(GTK_OBJECT(w), E_FILE_T_RESOLVE_KEY);
|
||||
g_resolv_flags |= GTK_TOGGLE_BUTTON (t_resolv_cb)->active ? RESOLV_TRANSPORT : RESOLV_NONE;
|
||||
|
||||
/* We've crossed the Rubicon; get rid of the file selection box. */
|
||||
gtk_widget_hide(GTK_WIDGET (fs));
|
||||
gtk_widget_destroy(GTK_WIDGET (fs));
|
||||
|
||||
switch (read_cap_file(&cfile, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* The user bailed out of re-reading the capture file; the
|
||||
capture file has been closed - just free the capture file name
|
||||
string and return (without changing the last containing
|
||||
directory). */
|
||||
g_free(cf_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the name of the containing directory specified in the path name,
|
||||
if any; we can write over cf_name, which is a good thing, given that
|
||||
"get_dirname()" does write over its argument. */
|
||||
s = get_dirname(cf_name);
|
||||
set_last_open_dir(s);
|
||||
|
||||
g_free(cf_name);
|
||||
}
|
||||
|
||||
static void
|
||||
file_open_destroy_cb(GtkWidget *win, gpointer user_data _U_)
|
||||
{
|
||||
GtkWidget *file_open_filter_w;
|
||||
|
||||
/* Is there a filter edit/selection dialog associated with this
|
||||
Open Capture File dialog? */
|
||||
file_open_filter_w = gtk_object_get_data(GTK_OBJECT(win), E_FILT_DIALOG_PTR_KEY);
|
||||
|
||||
if (file_open_filter_w != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(file_open_filter_w);
|
||||
}
|
||||
|
||||
/* Note that we no longer have a "Open Capture File" dialog box. */
|
||||
file_open_w = NULL;
|
||||
}
|
||||
|
||||
/* Close a file */
|
||||
void
|
||||
file_close_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) {
|
||||
close_cap_file(&cfile);
|
||||
}
|
||||
|
||||
void
|
||||
file_save_cmd_cb(GtkWidget *w, gpointer data) {
|
||||
/* If the file's already been saved, do nothing. */
|
||||
if (cfile.user_saved)
|
||||
return;
|
||||
|
||||
/* Do a "Save As". */
|
||||
file_save_as_cmd_cb(w, data);
|
||||
}
|
||||
|
||||
/* XXX - can we make these not be static? */
|
||||
static gboolean filtered;
|
||||
static gboolean marked;
|
||||
static int filetype;
|
||||
static GtkWidget *filter_cb;
|
||||
static GtkWidget *mark_cb;
|
||||
static GtkWidget *ft_om;
|
||||
|
||||
static gboolean
|
||||
can_save_with_wiretap(int ft)
|
||||
{
|
||||
/* To save a file with Wiretap, Wiretap has to handle that format,
|
||||
and its code to handle that format must be able to write a file
|
||||
with this file's encapsulation type. */
|
||||
return wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cfile.lnk_t);
|
||||
}
|
||||
|
||||
/* Generate a list of the file types we can save this file as.
|
||||
|
||||
"filetype" is the type it has now.
|
||||
|
||||
"encap" is the encapsulation for its packets (which could be
|
||||
"unknown" or "per-packet").
|
||||
|
||||
"filtered" is TRUE if we're to save only the packets that passed
|
||||
the display filter (in which case we have to save it using Wiretap)
|
||||
and FALSE if we're to save the entire file (in which case, if we're
|
||||
saving it in the type it has already, we can just copy it).
|
||||
|
||||
"marked" is TRUE if we have to save only the marked packets,
|
||||
the same remark as "filtered" applies.
|
||||
*/
|
||||
static void
|
||||
set_file_type_list(GtkWidget *option_menu)
|
||||
{
|
||||
GtkWidget *ft_menu, *ft_menu_item;
|
||||
int ft;
|
||||
guint index;
|
||||
guint item_to_select;
|
||||
|
||||
/* Default to the first supported file type, if the file's current
|
||||
type isn't supported. */
|
||||
item_to_select = 0;
|
||||
|
||||
ft_menu = gtk_menu_new();
|
||||
|
||||
/* Check all file types. */
|
||||
index = 0;
|
||||
for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
|
||||
if (filtered || marked || ft != cfile.cd_t) {
|
||||
/* Filtered, marked or a different file type. We have to use Wiretap. */
|
||||
if (!can_save_with_wiretap(ft))
|
||||
continue; /* We can't. */
|
||||
}
|
||||
|
||||
/* OK, we can write it out in this type. */
|
||||
ft_menu_item = gtk_menu_item_new_with_label(wtap_file_type_string(ft));
|
||||
if (ft == filetype) {
|
||||
/* Default to the same format as the file, if it's supported. */
|
||||
item_to_select = index;
|
||||
}
|
||||
g_signal_connect(G_OBJECT(ft_menu_item), "activate",
|
||||
G_CALLBACK(select_file_type_cb), (gpointer)ft);
|
||||
gtk_menu_append(GTK_MENU(ft_menu), ft_menu_item);
|
||||
gtk_widget_show(ft_menu_item);
|
||||
index++;
|
||||
}
|
||||
|
||||
gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), ft_menu);
|
||||
gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu), item_to_select);
|
||||
}
|
||||
|
||||
static void
|
||||
select_file_type_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
int new_filetype = (int)data;
|
||||
|
||||
if (filetype != new_filetype) {
|
||||
/* We can select only the filtered or marked packets to be saved if we can
|
||||
use Wiretap to save the file. */
|
||||
gtk_widget_set_sensitive(filter_cb, can_save_with_wiretap(new_filetype));
|
||||
filetype = new_filetype;
|
||||
file_set_save_marked_sensitive();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_filtered_cb(GtkWidget *widget, gpointer data _U_)
|
||||
{
|
||||
gboolean new_filtered;
|
||||
|
||||
new_filtered = GTK_TOGGLE_BUTTON (widget)->active;
|
||||
|
||||
if (filtered != new_filtered) {
|
||||
/* They changed the state of the "filtered" button. */
|
||||
filtered = new_filtered;
|
||||
set_file_type_list(ft_om);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_marked_cb(GtkWidget *widget, gpointer data _U_)
|
||||
{
|
||||
gboolean new_marked;
|
||||
|
||||
new_marked = GTK_TOGGLE_BUTTON (widget)->active;
|
||||
|
||||
if (marked != new_marked) {
|
||||
/* They changed the state of the "marked" button. */
|
||||
marked = new_marked;
|
||||
set_file_type_list(ft_om);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Save Capture File As" window, if
|
||||
* any, so that if somebody tries to do "File:Save" or "File:Save As"
|
||||
* while there's already a "Save Capture File As" window up, we just pop
|
||||
* up the existing one, rather than creating a new one.
|
||||
*/
|
||||
static GtkWidget *file_save_as_w;
|
||||
|
||||
void
|
||||
file_save_as_cmd_cb(GtkWidget *w _U_, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *ok_bt, *main_vb, *ft_hb, *ft_lb;
|
||||
|
||||
if (file_save_as_w != NULL) {
|
||||
/* There's already an "Save Capture File As" dialog box; reactivate it. */
|
||||
reactivate_window(file_save_as_w);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Default to saving all packets, in the file's current format. */
|
||||
filtered = FALSE;
|
||||
marked = FALSE;
|
||||
filetype = cfile.cd_t;
|
||||
|
||||
file_save_as_w = gtk_file_selection_new ("Ethereal: Save Capture File As");
|
||||
g_signal_connect(G_OBJECT(file_save_as_w), "destroy",
|
||||
G_CALLBACK(file_save_as_destroy_cb), NULL);
|
||||
|
||||
/* If we've opened a file, start out by showing the files in the directory
|
||||
in which that file resided. */
|
||||
if (last_open_dir)
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_save_as_w), last_open_dir);
|
||||
|
||||
/* Connect the ok_button to file_save_as_ok_cb function and pass along a
|
||||
pointer to the file selection box widget */
|
||||
ok_bt = GTK_FILE_SELECTION (file_save_as_w)->ok_button;
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(file_save_as_ok_cb), file_save_as_w);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_save_as_w)->action_area),
|
||||
main_vb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/*
|
||||
* XXX - should this be sensitive only if the current display filter
|
||||
* has rejected some packets, so that not all packets are currently
|
||||
* being displayed, and if it has accepted some packets, so that some
|
||||
* packets are currently being displayed?
|
||||
*
|
||||
* I'd say "no", as that complicates the UI code, and as one could,
|
||||
* I guess, argue that the user may want to "save all the displayed
|
||||
* packets" even if there aren't any, i.e. save an empty file.
|
||||
*/
|
||||
filter_cb = gtk_check_button_new_with_label("Save only packets currently being displayed");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), filter_cb);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filter_cb), FALSE);
|
||||
g_signal_connect(G_OBJECT(filter_cb), "toggled",
|
||||
G_CALLBACK(toggle_filtered_cb), NULL);
|
||||
gtk_widget_set_sensitive(filter_cb, can_save_with_wiretap(filetype));
|
||||
gtk_widget_show(filter_cb);
|
||||
|
||||
/*
|
||||
* The argument above could, I guess, be applied to the marked packets,
|
||||
* except that you can't easily tell whether there are any marked
|
||||
* packets, so I could imagine users doing "Save only marked packets"
|
||||
* when there aren't any marked packets, not knowing that they'd
|
||||
* failed to mark them, so I'm more inclined to have the "Save only
|
||||
* marked packets" toggle button enabled only if there are marked
|
||||
* packets to save.
|
||||
*/
|
||||
mark_cb = gtk_check_button_new_with_label("Save only marked packets");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), mark_cb);
|
||||
marked = FALSE;
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(mark_cb), FALSE);
|
||||
g_signal_connect(G_OBJECT(mark_cb), "toggled",
|
||||
G_CALLBACK(toggle_marked_cb), NULL);
|
||||
gtk_widget_show(mark_cb);
|
||||
|
||||
/* File type row */
|
||||
ft_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), ft_hb);
|
||||
gtk_widget_show(ft_hb);
|
||||
|
||||
ft_lb = gtk_label_new("File type:");
|
||||
gtk_box_pack_start(GTK_BOX(ft_hb), ft_lb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(ft_lb);
|
||||
|
||||
ft_om = gtk_option_menu_new();
|
||||
|
||||
/* Generate the list of file types we can save. */
|
||||
set_file_type_list(ft_om);
|
||||
gtk_box_pack_start(GTK_BOX(ft_hb), ft_om, FALSE, FALSE, 0);
|
||||
gtk_widget_show(ft_om);
|
||||
|
||||
/*
|
||||
* Set the sensitivity of the "Save only marked packets" toggle
|
||||
* button
|
||||
*
|
||||
* This has to be done after we create the file type menu option,
|
||||
* as the routine that sets it also sets that menu.
|
||||
*/
|
||||
file_set_save_marked_sensitive();
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(file_save_as_w)->cancel_button),
|
||||
"clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(file_save_as_w));
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(file_save_as_w, GTK_FILE_SELECTION(file_save_as_w)->cancel_button);
|
||||
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_save_as_w), "");
|
||||
|
||||
gtk_widget_show(file_save_as_w);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the "Save only marked packets" toggle button as appropriate for
|
||||
* the current output file type and count of marked packets.
|
||||
*
|
||||
* Called when the "Save As..." dialog box is created and when either
|
||||
* the file type or the marked count changes.
|
||||
*/
|
||||
void
|
||||
file_set_save_marked_sensitive(void)
|
||||
{
|
||||
if (file_save_as_w == NULL) {
|
||||
/* We don't currently have a "Save As..." dialog box up. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* We can request that only the marked packets be saved only if we
|
||||
can use Wiretap to save the file and if there *are* marked packets. */
|
||||
if (can_save_with_wiretap(filetype) && cfile.marked_count != 0)
|
||||
gtk_widget_set_sensitive(mark_cb, TRUE);
|
||||
else {
|
||||
/* Force the "Save only marked packets" toggle to "false", turn
|
||||
off the flag it controls, and update the list of types we can
|
||||
save the file as. */
|
||||
marked = FALSE;
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(mark_cb), FALSE);
|
||||
set_file_type_list(ft_om);
|
||||
gtk_widget_set_sensitive(mark_cb, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
file_save_as_ok_cb(GtkWidget *w _U_, GtkFileSelection *fs) {
|
||||
gchar *cf_name;
|
||||
|
||||
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
|
||||
gtk_widget_hide(GTK_WIDGET (fs));
|
||||
gtk_widget_destroy(GTK_WIDGET (fs));
|
||||
|
||||
/* Write out the packets (all, or only the ones that are currently
|
||||
displayed or marked) to the file with the specified name. */
|
||||
save_cap_file(cf_name, &cfile, filtered, marked, filetype);
|
||||
|
||||
/* If "save_cap_file()" saved the file name we handed it, it saved
|
||||
a copy, so we should free up our copy. */
|
||||
g_free(cf_name);
|
||||
}
|
||||
|
||||
static void
|
||||
file_save_as_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
|
||||
{
|
||||
/* Note that we no longer have a "Save Capture File As" dialog box. */
|
||||
file_save_as_w = NULL;
|
||||
}
|
||||
|
||||
/* Reload a file using the current read and display filters */
|
||||
void
|
||||
file_reload_cmd_cb(GtkWidget *w, gpointer data _U_) {
|
||||
/*GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);*/
|
||||
GtkWidget *filter_te;
|
||||
gchar *filename;
|
||||
gboolean is_tempfile;
|
||||
int err;
|
||||
|
||||
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
|
||||
|
||||
if (cfile.dfilter)
|
||||
g_free(cfile.dfilter);
|
||||
cfile.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
|
||||
|
||||
/* If the file could be opened, "open_cap_file()" calls "close_cap_file()"
|
||||
to get rid of state for the old capture file before filling in state
|
||||
for the new capture file. "close_cap_file()" will remove the file if
|
||||
it's a temporary file; we don't want that to happen (for one thing,
|
||||
it'd prevent subsequent reopens from working). Remember whether it's
|
||||
a temporary file, mark it as not being a temporary file, and then
|
||||
reopen it as the type of file it was.
|
||||
|
||||
Also, "close_cap_file()" will free "cfile.filename", so we must make
|
||||
a copy of it first. */
|
||||
filename = g_strdup(cfile.filename);
|
||||
is_tempfile = cfile.is_tempfile;
|
||||
cfile.is_tempfile = FALSE;
|
||||
if (open_cap_file(filename, is_tempfile, &cfile) == 0) {
|
||||
switch (read_cap_file(&cfile, &err)) {
|
||||
|
||||
case READ_SUCCESS:
|
||||
case READ_ERROR:
|
||||
/* Just because we got an error, that doesn't mean we were unable
|
||||
to read any of the file; we handle what we could get from the
|
||||
file. */
|
||||
break;
|
||||
|
||||
case READ_ABORTED:
|
||||
/* The user bailed out of re-reading the capture file; the
|
||||
capture file has been closed - just free the capture file name
|
||||
string and return (without changing the last containing
|
||||
directory). */
|
||||
g_free(filename);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* The open failed, so "cfile.is_tempfile" wasn't set to "is_tempfile".
|
||||
Instead, the file was left open, so we should restore "cfile.is_tempfile"
|
||||
ourselves.
|
||||
|
||||
XXX - change the menu? Presumably "open_cap_file()" will do that;
|
||||
make sure it does! */
|
||||
cfile.is_tempfile = is_tempfile;
|
||||
}
|
||||
/* "open_cap_file()" made a copy of the file name we handed it, so
|
||||
we should free up our copy. */
|
||||
g_free(filename);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* file_dlg.h
|
||||
* Definitions for dialog boxes for handling files
|
||||
*
|
||||
* $Id: file_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __FILE_DLG_H__
|
||||
#define __FILE_DLG_H__
|
||||
|
||||
void file_open_cmd_cb(GtkWidget *, gpointer);
|
||||
void file_save_cmd_cb(GtkWidget *, gpointer);
|
||||
void file_save_as_cmd_cb(GtkWidget *, gpointer);
|
||||
void file_close_cmd_cb(GtkWidget *, gpointer);
|
||||
void file_reload_cmd_cb(GtkWidget *, gpointer);
|
||||
|
||||
/*
|
||||
* Set the "Save only marked packets" toggle button as appropriate for
|
||||
* the current output file type and count of marked packets.
|
||||
* Called when the "Save As..." dialog box is created and when either
|
||||
* the file type or the marked count changes.
|
||||
*/
|
||||
void file_set_save_marked_sensitive(void);
|
||||
|
||||
#endif /* file_dlg.h */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,51 @@
|
|||
/* filter_prefs.h
|
||||
* Definitions for dialog boxes for filter editing
|
||||
* (This used to be a notebook page under "Preferences", hence the
|
||||
* "prefs" in the file name.)
|
||||
*
|
||||
* $Id: filter_prefs.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __FILTER_H__
|
||||
#define __FILTER_H__
|
||||
|
||||
/*
|
||||
* Structure giving properties of the filter editing dialog box to be
|
||||
* created.
|
||||
*/
|
||||
typedef struct {
|
||||
gchar *title; /* title of dialog box */
|
||||
gboolean wants_apply_button; /* if it should have an Apply button */
|
||||
gboolean activate_on_ok; /* if parent text widget should be
|
||||
activated on "Ok" or "Apply" */
|
||||
} construct_args_t;
|
||||
|
||||
void capture_filter_construct_cb(GtkWidget *w, gpointer user_data);
|
||||
void display_filter_construct_cb(GtkWidget *w, gpointer construct_args_ptr);
|
||||
void cfilter_dialog_cb(GtkWidget *w);
|
||||
void dfilter_dialog_cb(GtkWidget *w);
|
||||
|
||||
#define E_FILT_TE_PTR_KEY "filter_te_ptr"
|
||||
#define E_FILT_CALLER_PTR_KEY "filter_caller_ptr"
|
||||
#define E_FILT_DIALOG_PTR_KEY "filter_dialog_ptr"
|
||||
|
||||
#endif /* filter.h */
|
|
@ -0,0 +1,282 @@
|
|||
/* find_dlg.c
|
||||
* Routines for "find frame" window
|
||||
*
|
||||
* $Id: find_dlg.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <epan/proto.h>
|
||||
#include <epan/dfilter/dfilter.h>
|
||||
#include "globals.h"
|
||||
|
||||
#include "ui_util.h"
|
||||
#include "find_dlg.h"
|
||||
#include "filter_prefs.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "dlg_utils.h"
|
||||
|
||||
/* Capture callback data keys */
|
||||
#define E_FIND_FILT_KEY "find_filter_te"
|
||||
#define E_FIND_BACKWARD_KEY "find_backward"
|
||||
|
||||
static void
|
||||
find_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
|
||||
|
||||
static void
|
||||
find_frame_close_cb(GtkWidget *close_bt, gpointer parent_w);
|
||||
|
||||
static void
|
||||
find_frame_destroy_cb(GtkWidget *win, gpointer user_data);
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Find Frame" window, if any, so
|
||||
* that if somebody tries to do "Find Frame" while there's already a
|
||||
* "Find Frame" window up, we just pop up the existing one, rather than
|
||||
* creating a new one.
|
||||
*/
|
||||
static GtkWidget *find_frame_w;
|
||||
|
||||
void
|
||||
find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
GtkWidget *main_vb, *filter_hb, *filter_bt, *filter_te,
|
||||
*direction_hb, *forward_rb, *backward_rb,
|
||||
*bbox, *ok_bt, *cancel_bt;
|
||||
GtkAccelGroup *accel_group;
|
||||
/* No Apply button, but "OK" not only sets our text widget, it
|
||||
activates it (i.e., it causes us to do the search). */
|
||||
static construct_args_t args = {
|
||||
"Ethereal: Search Filter",
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
if (find_frame_w != NULL) {
|
||||
/* There's already a "Find Frame" dialog box; reactivate it. */
|
||||
reactivate_window(find_frame_w);
|
||||
return;
|
||||
}
|
||||
|
||||
find_frame_w = dlg_window_new("Ethereal: Find Frame");
|
||||
g_signal_connect(G_OBJECT(find_frame_w), "destroy",
|
||||
G_CALLBACK(find_frame_destroy_cb), NULL);
|
||||
|
||||
/* Accelerator group for the accelerators (or, as they're called in
|
||||
Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
|
||||
Ctrl+<key> is an accelerator). */
|
||||
accel_group = gtk_accel_group_new();
|
||||
gtk_window_add_accel_group(GTK_WINDOW(find_frame_w), accel_group);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(find_frame_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* Filter row */
|
||||
filter_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), filter_hb);
|
||||
gtk_widget_show(filter_hb);
|
||||
|
||||
filter_bt = gtk_button_new_with_label("Filter:");
|
||||
g_signal_connect(G_OBJECT(filter_bt), "clicked",
|
||||
G_CALLBACK(display_filter_construct_cb), &args);
|
||||
gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, TRUE, 0);
|
||||
gtk_widget_show(filter_bt);
|
||||
|
||||
filter_te = gtk_entry_new();
|
||||
if (cfile.sfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.sfilter);
|
||||
gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
|
||||
gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 0);
|
||||
gtk_widget_show(filter_te);
|
||||
|
||||
/* Misc row: Forward and reverse radio buttons */
|
||||
direction_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), direction_hb);
|
||||
gtk_widget_show(direction_hb);
|
||||
|
||||
forward_rb = dlg_radio_button_new_with_label_with_mnemonic(NULL, "_Forward",
|
||||
accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(forward_rb), !cfile.sbackward);
|
||||
gtk_box_pack_start(GTK_BOX(direction_hb), forward_rb, TRUE, TRUE, 0);
|
||||
gtk_widget_show(forward_rb);
|
||||
|
||||
backward_rb = dlg_radio_button_new_with_label_with_mnemonic(
|
||||
gtk_radio_button_group(GTK_RADIO_BUTTON(forward_rb)),
|
||||
"_Backward", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(backward_rb), cfile.sbackward);
|
||||
gtk_box_pack_start(GTK_BOX(direction_hb), backward_rb, TRUE, TRUE, 0);
|
||||
gtk_widget_show(backward_rb);
|
||||
|
||||
/* Button row: OK and cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(find_frame_ok_cb), GTK_OBJECT(find_frame_w));
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_bt), "clicked",
|
||||
G_CALLBACK(find_frame_close_cb), GTK_OBJECT(find_frame_w));
|
||||
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
|
||||
/* Attach pointers to needed widgets to the capture prefs window/object */
|
||||
gtk_object_set_data(GTK_OBJECT(find_frame_w), E_FIND_FILT_KEY, filter_te);
|
||||
gtk_object_set_data(GTK_OBJECT(find_frame_w), E_FIND_BACKWARD_KEY, backward_rb);
|
||||
|
||||
/* Catch the "activate" signal on the frame number text entry, so that
|
||||
if the user types Return there, we act as if the "OK" button
|
||||
had been selected, as happens if Return is typed if some widget
|
||||
that *doesn't* handle the Return key has the input focus. */
|
||||
dlg_set_activate(filter_te, ok_bt);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(find_frame_w, cancel_bt);
|
||||
|
||||
/* Give the initial focus to the "Filter" entry box. */
|
||||
gtk_widget_grab_focus(filter_te);
|
||||
|
||||
gtk_widget_show(find_frame_w);
|
||||
}
|
||||
|
||||
static void
|
||||
find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
|
||||
{
|
||||
GtkWidget *filter_te, *backward_rb;
|
||||
const gchar *filter_text;
|
||||
dfilter_t *sfcode;
|
||||
|
||||
filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_FIND_FILT_KEY);
|
||||
backward_rb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_FIND_BACKWARD_KEY);
|
||||
|
||||
filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
|
||||
|
||||
/*
|
||||
* Try to compile the filter.
|
||||
*/
|
||||
if (!dfilter_compile(filter_text, &sfcode)) {
|
||||
/* The attempt failed; report an error. */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Was it empty? */
|
||||
if (sfcode == NULL) {
|
||||
/* Yes - complain. */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"You didn't specify a filter to use when searching for a frame.");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remember the filter.
|
||||
*/
|
||||
if (cfile.sfilter)
|
||||
g_free(cfile.sfilter);
|
||||
cfile.sfilter = g_strdup(filter_text);
|
||||
|
||||
cfile.sbackward = GTK_TOGGLE_BUTTON (backward_rb)->active;
|
||||
|
||||
if (!find_packet(&cfile, sfcode)) {
|
||||
/* We didn't find the packet. */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, "No packet matched that filter.");
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
||||
|
||||
static void
|
||||
find_frame_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gtk_grab_remove(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
||||
|
||||
static void
|
||||
find_frame_destroy_cb(GtkWidget *win, gpointer user_data _U_)
|
||||
{
|
||||
GtkWidget *find_frame_filter_w;
|
||||
|
||||
/* Is there a filter edit/selection dialog associated with this
|
||||
Find Frame dialog? */
|
||||
find_frame_filter_w = gtk_object_get_data(GTK_OBJECT(win), E_FILT_DIALOG_PTR_KEY);
|
||||
|
||||
if (find_frame_filter_w != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(find_frame_filter_w);
|
||||
}
|
||||
|
||||
/* Note that we no longer have a "Find Frame" dialog box. */
|
||||
find_frame_w = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
find_previous_next(GtkWidget *w, gpointer d, gboolean sens)
|
||||
{
|
||||
dfilter_t *sfcode;
|
||||
|
||||
if (cfile.sfilter) {
|
||||
if (!dfilter_compile(cfile.sfilter, &sfcode))
|
||||
return;
|
||||
if (sfcode == NULL)
|
||||
return;
|
||||
cfile.sbackward = sens;
|
||||
find_packet(&cfile, sfcode);
|
||||
} else
|
||||
find_frame_cb(w, d);
|
||||
}
|
||||
|
||||
void
|
||||
find_next_cb(GtkWidget *w , gpointer d)
|
||||
{
|
||||
find_previous_next(w, d, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
find_previous_cb(GtkWidget *w , gpointer d)
|
||||
{
|
||||
find_previous_next(w, d, TRUE);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* find_dlg.h
|
||||
* Definitions for "find frame" window
|
||||
*
|
||||
* $Id: find_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __FIND_DLG_H__
|
||||
#define __FIND_DLG_H__
|
||||
|
||||
void find_frame_cb(GtkWidget *, gpointer);
|
||||
void find_next_cb(GtkWidget *, gpointer);
|
||||
void find_previous_cb(GtkWidget *, gpointer);
|
||||
|
||||
#endif /* find_dlg.h */
|
|
@ -0,0 +1,819 @@
|
|||
/* follow_dlg.c
|
||||
*
|
||||
* $Id: follow_dlg.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 2000 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h> /* open/close on win32 */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_SNPRINTF_H
|
||||
# include "snprintf.h"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <langinfo.h>
|
||||
#include <iconv.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "color_utils.h"
|
||||
#include "file.h"
|
||||
#include "follow_dlg.h"
|
||||
#include "follow.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "keys.h"
|
||||
#include "globals.h"
|
||||
#include "gtkglobals.h"
|
||||
#include "main.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "packet-ipv6.h"
|
||||
#include "prefs.h"
|
||||
#include <epan/resolv.h>
|
||||
#include "util.h"
|
||||
#include "ui_util.h"
|
||||
#include <epan/epan_dissect.h>
|
||||
|
||||
/* Show Stream */
|
||||
typedef enum {
|
||||
FROM_CLIENT,
|
||||
FROM_SERVER,
|
||||
BOTH_HOSTS
|
||||
} show_stream_t;
|
||||
|
||||
/* Show Type */
|
||||
typedef enum {
|
||||
SHOW_ASCII,
|
||||
SHOW_EBCDIC,
|
||||
SHOW_HEXDUMP
|
||||
} show_type_t;
|
||||
|
||||
typedef struct {
|
||||
show_stream_t show_stream;
|
||||
show_type_t show_type;
|
||||
char data_out_filename[128 + 1];
|
||||
GtkWidget *text;
|
||||
GtkWidget *ascii_bt;
|
||||
GtkWidget *ebcdic_bt;
|
||||
GtkWidget *hexdump_bt;
|
||||
GtkWidget *follow_save_as_w;
|
||||
gboolean is_ipv6;
|
||||
} follow_info_t;
|
||||
|
||||
static void follow_destroy_cb(GtkWidget * win, gpointer data);
|
||||
static void follow_charset_toggle_cb(GtkWidget * w, gpointer parent_w);
|
||||
static void follow_load_text(follow_info_t *follow_info);
|
||||
static void follow_print_stream(GtkWidget * w, gpointer parent_w);
|
||||
static void follow_save_as_cmd_cb(GtkWidget * w, gpointer data);
|
||||
static void follow_save_as_ok_cb(GtkWidget * w, GtkFileSelection * fs);
|
||||
static void follow_save_as_destroy_cb(GtkWidget * win, gpointer user_data);
|
||||
static void follow_stream_om_both(GtkWidget * w, gpointer data);
|
||||
static void follow_stream_om_client(GtkWidget * w, gpointer data);
|
||||
static void follow_stream_om_server(GtkWidget * w, gpointer data);
|
||||
|
||||
|
||||
extern FILE *data_out_file;
|
||||
|
||||
|
||||
#define E_FOLLOW_INFO_KEY "follow_info_key"
|
||||
|
||||
/* List of "follow_info_t" structures for all "Follow TCP Stream" windows,
|
||||
so we can redraw them all if the colors or font changes. */
|
||||
static GList *follow_infos;
|
||||
|
||||
/* Add a "follow_info_t" structure to the list. */
|
||||
static void
|
||||
remember_follow_info(follow_info_t *follow_info)
|
||||
{
|
||||
follow_infos = g_list_append(follow_infos, follow_info);
|
||||
}
|
||||
|
||||
/* Remove a "follow_info_t" structure from the list. */
|
||||
static void
|
||||
forget_follow_info(follow_info_t *follow_info)
|
||||
{
|
||||
follow_infos = g_list_remove(follow_infos, follow_info);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_redraw(gpointer data, gpointer user_data _U_)
|
||||
{
|
||||
follow_load_text((follow_info_t *)data);
|
||||
}
|
||||
|
||||
/* Redraw the text in all "Follow TCP Stream" windows. */
|
||||
void
|
||||
follow_redraw_all(void)
|
||||
{
|
||||
g_list_foreach(follow_infos, follow_redraw, NULL);
|
||||
}
|
||||
|
||||
/* Follow the TCP stream, if any, to which the last packet that we called
|
||||
a dissection routine on belongs (this might be the most recently
|
||||
selected packet, or it might be the last packet in the file). */
|
||||
void
|
||||
follow_stream_cb(GtkWidget * w, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *streamwindow, *vbox, *txt_scrollw, *text, *filter_te;
|
||||
GtkWidget *hbox, *button, *radio_bt;
|
||||
GtkWidget *stream_om, *stream_menu, *stream_mi;
|
||||
int tmp_fd;
|
||||
gchar *follow_filter;
|
||||
const char *hostname0, *hostname1;
|
||||
char *port0, *port1;
|
||||
char string[128];
|
||||
follow_tcp_stats_t stats;
|
||||
follow_info_t *follow_info;
|
||||
|
||||
/* we got tcp so we can follow */
|
||||
if (cfile.edt->pi.ipproto != 6) {
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Error following stream. Please make\n"
|
||||
"sure you have a TCP packet selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
follow_info = g_new0(follow_info_t, 1);
|
||||
|
||||
/* Create a temporary file into which to dump the reassembled data
|
||||
from the TCP stream, and set "data_out_file" to refer to it, so
|
||||
that the TCP code will write to it.
|
||||
|
||||
XXX - it might be nicer to just have the TCP code directly
|
||||
append stuff to the text widget for the TCP stream window,
|
||||
if we can arrange that said window not pop up until we're
|
||||
done. */
|
||||
tmp_fd = create_tempfile(follow_info->data_out_filename,
|
||||
sizeof follow_info->data_out_filename, "follow");
|
||||
|
||||
if (tmp_fd == -1) {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Could not create temporary file %s: %s",
|
||||
follow_info->data_out_filename, strerror(errno));
|
||||
g_free(follow_info);
|
||||
return;
|
||||
}
|
||||
|
||||
data_out_file = fdopen(tmp_fd, "wb");
|
||||
if (data_out_file == NULL) {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Could not create temporary file %s: %s",
|
||||
follow_info->data_out_filename, strerror(errno));
|
||||
close(tmp_fd);
|
||||
unlink(follow_info->data_out_filename);
|
||||
g_free(follow_info);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a new filter that matches all packets in the TCP stream,
|
||||
and set the display filter entry accordingly */
|
||||
reset_tcp_reassembly();
|
||||
follow_filter = build_follow_filter(&cfile.edt->pi);
|
||||
|
||||
/* Set the display filter entry accordingly */
|
||||
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
|
||||
gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter);
|
||||
|
||||
/* Run the display filter so it goes in effect. */
|
||||
filter_packets(&cfile, follow_filter);
|
||||
|
||||
/* Free the filter string, as we're done with it. */
|
||||
g_free(follow_filter);
|
||||
|
||||
/* The data_out_file should now be full of the streams information */
|
||||
fclose(data_out_file);
|
||||
|
||||
/* The data_out_filename file now has all the text that was in the session */
|
||||
streamwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_set_name(streamwindow, "TCP stream window");
|
||||
|
||||
g_signal_connect(G_OBJECT(streamwindow), "destroy",
|
||||
G_CALLBACK(follow_destroy_cb), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(streamwindow), "realize",
|
||||
G_CALLBACK(window_icon_realize_cb), NULL);
|
||||
if (incomplete_tcp_stream) {
|
||||
gtk_window_set_title(GTK_WINDOW(streamwindow),
|
||||
"Contents of TCP stream (incomplete)");
|
||||
} else {
|
||||
gtk_window_set_title(GTK_WINDOW(streamwindow),
|
||||
"Contents of TCP stream");
|
||||
}
|
||||
gtk_widget_set_size_request(GTK_WIDGET(streamwindow), -1,
|
||||
DEF_HEIGHT);
|
||||
gtk_container_border_width(GTK_CONTAINER(streamwindow), 2);
|
||||
|
||||
/* setup the container */
|
||||
vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(streamwindow), vbox);
|
||||
|
||||
/* create a scrolled window for the text */
|
||||
txt_scrollw = scrolled_window_new(NULL, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), txt_scrollw, TRUE, TRUE, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
/* create a text box */
|
||||
text = gtk_text_view_new();
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(txt_scrollw), text);
|
||||
follow_info->text = text;
|
||||
|
||||
/* Create hbox */
|
||||
hbox = gtk_hbox_new(FALSE, 1);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
/* Stream to show */
|
||||
follow_tcp_stats(&stats);
|
||||
|
||||
if (stats.is_ipv6) {
|
||||
struct e_in6_addr ipaddr;
|
||||
memcpy(&ipaddr, stats.ip_address[0], 16);
|
||||
hostname0 = get_hostname6(&ipaddr);
|
||||
memcpy(&ipaddr, stats.ip_address[0], 16);
|
||||
hostname1 = get_hostname6(&ipaddr);
|
||||
} else {
|
||||
guint32 ipaddr;
|
||||
memcpy(&ipaddr, stats.ip_address[0], 4);
|
||||
hostname0 = get_hostname(ipaddr);
|
||||
memcpy(&ipaddr, stats.ip_address[1], 4);
|
||||
hostname1 = get_hostname(ipaddr);
|
||||
}
|
||||
|
||||
port0 = get_tcp_port(stats.tcp_port[0]);
|
||||
port1 = get_tcp_port(stats.tcp_port[1]);
|
||||
|
||||
follow_info->is_ipv6 = stats.is_ipv6;
|
||||
|
||||
stream_om = gtk_option_menu_new();
|
||||
stream_menu = gtk_menu_new();
|
||||
|
||||
/* Both Hosts */
|
||||
snprintf(string, sizeof(string),
|
||||
"Entire conversation (%u bytes)",
|
||||
stats.bytes_written[0] + stats.bytes_written[1]);
|
||||
stream_mi = gtk_menu_item_new_with_label(string);
|
||||
g_signal_connect(G_OBJECT(stream_mi), "activate",
|
||||
G_CALLBACK(follow_stream_om_both), follow_info);
|
||||
gtk_menu_append(GTK_MENU(stream_menu), stream_mi);
|
||||
gtk_widget_show(stream_mi);
|
||||
follow_info->show_stream = BOTH_HOSTS;
|
||||
|
||||
/* Host 0 --> Host 1 */
|
||||
snprintf(string, sizeof(string), "%s:%s --> %s:%s (%u bytes)",
|
||||
hostname0, port0, hostname1, port1,
|
||||
stats.bytes_written[0]);
|
||||
stream_mi = gtk_menu_item_new_with_label(string);
|
||||
g_signal_connect(G_OBJECT(stream_mi), "activate",
|
||||
G_CALLBACK(follow_stream_om_client), follow_info);
|
||||
gtk_menu_append(GTK_MENU(stream_menu), stream_mi);
|
||||
gtk_widget_show(stream_mi);
|
||||
|
||||
/* Host 1 --> Host 0 */
|
||||
snprintf(string, sizeof(string), "%s:%s --> %s:%s (%u bytes)",
|
||||
hostname1, port1, hostname0, port0,
|
||||
stats.bytes_written[1]);
|
||||
stream_mi = gtk_menu_item_new_with_label(string);
|
||||
g_signal_connect(G_OBJECT(stream_mi), "activate",
|
||||
G_CALLBACK(follow_stream_om_server), follow_info);
|
||||
gtk_menu_append(GTK_MENU(stream_menu), stream_mi);
|
||||
gtk_widget_show(stream_mi);
|
||||
|
||||
gtk_option_menu_set_menu(GTK_OPTION_MENU(stream_om), stream_menu);
|
||||
/* Set history to 0th item, i.e., the first item. */
|
||||
gtk_option_menu_set_history(GTK_OPTION_MENU(stream_om), 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), stream_om, FALSE, FALSE, 0);
|
||||
|
||||
/* ASCII radio button */
|
||||
radio_bt = gtk_radio_button_new_with_label(NULL, "ASCII");
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), TRUE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), radio_bt, FALSE, FALSE, 0);
|
||||
g_signal_connect(G_OBJECT(radio_bt), "toggled",
|
||||
G_CALLBACK(follow_charset_toggle_cb),
|
||||
follow_info);
|
||||
follow_info->ascii_bt = radio_bt;
|
||||
follow_info->show_type = SHOW_ASCII;
|
||||
|
||||
/* EBCDIC radio button */
|
||||
radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_group
|
||||
(GTK_RADIO_BUTTON(radio_bt)),
|
||||
"EBCDIC");
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), radio_bt, FALSE, FALSE, 0);
|
||||
g_signal_connect(G_OBJECT(radio_bt), "toggled",
|
||||
G_CALLBACK(follow_charset_toggle_cb),
|
||||
follow_info);
|
||||
follow_info->ebcdic_bt = radio_bt;
|
||||
|
||||
/* HEX DUMP radio button */
|
||||
radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_group
|
||||
(GTK_RADIO_BUTTON(radio_bt)),
|
||||
"Hex Dump");
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), radio_bt, FALSE, FALSE, 0);
|
||||
g_signal_connect(G_OBJECT(radio_bt), "toggled",
|
||||
G_CALLBACK(follow_charset_toggle_cb),
|
||||
follow_info);
|
||||
follow_info->hexdump_bt = radio_bt;
|
||||
|
||||
/* Create Close Button */
|
||||
button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
|
||||
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(streamwindow));
|
||||
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(streamwindow, button);
|
||||
|
||||
/* Create Save As Button */
|
||||
button = gtk_button_new_from_stock(GTK_STOCK_SAVE_AS);
|
||||
g_signal_connect(G_OBJECT(button), "clicked",
|
||||
G_CALLBACK(follow_save_as_cmd_cb),
|
||||
follow_info);
|
||||
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
|
||||
|
||||
/* Create Print Button */
|
||||
button = gtk_button_new_from_stock(GTK_STOCK_PRINT);
|
||||
g_signal_connect(G_OBJECT(button), "clicked",
|
||||
G_CALLBACK(follow_print_stream), follow_info);
|
||||
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
/* Tuck away the follow_info object into the window */
|
||||
gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_INFO_KEY,
|
||||
follow_info);
|
||||
|
||||
follow_load_text(follow_info);
|
||||
remember_follow_info(follow_info);
|
||||
|
||||
data_out_file = NULL;
|
||||
|
||||
/* Make sure this widget gets destroyed if we quit the main loop,
|
||||
so that if we exit, we clean up any temporary files we have
|
||||
for "Follow TCP Stream" windows. */
|
||||
gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(streamwindow));
|
||||
gtk_widget_show_all(streamwindow);
|
||||
}
|
||||
|
||||
/* The destroy call back has the responsibility of
|
||||
* unlinking the temporary file */
|
||||
static void
|
||||
follow_destroy_cb(GtkWidget *w, gpointer data _U_)
|
||||
{
|
||||
follow_info_t *follow_info;
|
||||
|
||||
follow_info = gtk_object_get_data(GTK_OBJECT(w), E_FOLLOW_INFO_KEY);
|
||||
unlink(follow_info->data_out_filename);
|
||||
gtk_widget_destroy(w);
|
||||
forget_follow_info(follow_info);
|
||||
g_free(follow_info);
|
||||
}
|
||||
|
||||
/* XXX - can I emulate follow_charset_toggle_cb() instead of having
|
||||
* 3 different functions here? */
|
||||
static void
|
||||
follow_stream_om_both(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
follow_info_t *follow_info = data;
|
||||
follow_info->show_stream = BOTH_HOSTS;
|
||||
follow_load_text(follow_info);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_stream_om_client(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
follow_info_t *follow_info = data;
|
||||
follow_info->show_stream = FROM_CLIENT;
|
||||
follow_load_text(follow_info);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_stream_om_server(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
follow_info_t *follow_info = data;
|
||||
follow_info->show_stream = FROM_SERVER;
|
||||
follow_load_text(follow_info);
|
||||
}
|
||||
|
||||
|
||||
/* Handles the ASCII/EBCDIC toggling */
|
||||
static void
|
||||
follow_charset_toggle_cb(GtkWidget * w _U_, gpointer data)
|
||||
{
|
||||
follow_info_t *follow_info = data;
|
||||
|
||||
if (GTK_TOGGLE_BUTTON(follow_info->ebcdic_bt)->active)
|
||||
follow_info->show_type = SHOW_EBCDIC;
|
||||
else if (GTK_TOGGLE_BUTTON(follow_info->hexdump_bt)->active)
|
||||
follow_info->show_type = SHOW_HEXDUMP;
|
||||
else if (GTK_TOGGLE_BUTTON(follow_info->ascii_bt)->active)
|
||||
follow_info->show_type = SHOW_ASCII;
|
||||
else
|
||||
g_assert_not_reached();
|
||||
|
||||
follow_load_text(follow_info);
|
||||
}
|
||||
|
||||
#define FLT_BUF_SIZE 1024
|
||||
static void
|
||||
follow_read_stream(follow_info_t *follow_info,
|
||||
void (*print_line) (char *, int, gboolean, void *),
|
||||
void *arg)
|
||||
{
|
||||
tcp_stream_chunk sc;
|
||||
int bcount, iplen;
|
||||
guint8 client_addr[MAX_IPADDR_LEN];
|
||||
guint16 client_port = 0;
|
||||
gboolean is_server;
|
||||
guint16 current_pos, global_client_pos = 0, global_server_pos = 0;
|
||||
guint16 *global_pos;
|
||||
gboolean skip;
|
||||
|
||||
iplen = (follow_info->is_ipv6) ? 16 : 4;
|
||||
|
||||
data_out_file = fopen(follow_info->data_out_filename, "rb");
|
||||
if (data_out_file) {
|
||||
char buffer[FLT_BUF_SIZE];
|
||||
int nchars;
|
||||
while (fread(&sc, 1, sizeof(sc), data_out_file)) {
|
||||
if (client_port == 0) {
|
||||
memcpy(client_addr, sc.src_addr, iplen);
|
||||
client_port = sc.src_port;
|
||||
}
|
||||
skip = FALSE;
|
||||
if (memcmp(client_addr, sc.src_addr, iplen) == 0 &&
|
||||
client_port == sc.src_port) {
|
||||
is_server = FALSE;
|
||||
global_pos = &global_client_pos;
|
||||
if (follow_info->show_stream == FROM_SERVER) {
|
||||
skip = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
is_server = TRUE;
|
||||
global_pos = &global_server_pos;
|
||||
if (follow_info->show_stream == FROM_CLIENT) {
|
||||
skip = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
while (sc.dlen > 0) {
|
||||
bcount = (sc.dlen < FLT_BUF_SIZE) ? sc.dlen : FLT_BUF_SIZE;
|
||||
nchars = fread(buffer, 1, bcount, data_out_file);
|
||||
if (nchars == 0)
|
||||
break;
|
||||
sc.dlen -= bcount;
|
||||
if (!skip) {
|
||||
switch (follow_info->show_type) {
|
||||
case SHOW_EBCDIC:
|
||||
/* If our native arch is ASCII, call: */
|
||||
EBCDIC_to_ASCII(buffer, nchars);
|
||||
(*print_line) (buffer, nchars, is_server, arg);
|
||||
break;
|
||||
case SHOW_ASCII:
|
||||
/* If our native arch is EBCDIC, call:
|
||||
* ASCII_TO_EBCDIC(buffer, nchars);
|
||||
*/
|
||||
(*print_line) (buffer, nchars, is_server, arg);
|
||||
break;
|
||||
case SHOW_HEXDUMP:
|
||||
current_pos = 0;
|
||||
while (current_pos < nchars) {
|
||||
gchar hexbuf[256];
|
||||
gchar hexchars[] = "0123456789abcdef";
|
||||
int i, cur;
|
||||
/* is_server indentation : put 63 spaces at the begenning
|
||||
* of the string */
|
||||
sprintf(hexbuf, (is_server &&
|
||||
follow_info->show_stream == BOTH_HOSTS) ?
|
||||
" "
|
||||
" %08X " :
|
||||
"%08X ", *global_pos);
|
||||
cur = strlen(hexbuf);
|
||||
for (i = 0; i < 16 && current_pos + i < nchars;
|
||||
i++) {
|
||||
hexbuf[cur++] =
|
||||
hexchars[(buffer[current_pos + i] & 0xf0)
|
||||
>> 4];
|
||||
hexbuf[cur++] =
|
||||
hexchars[buffer[current_pos + i] & 0x0f];
|
||||
if (i == 7) {
|
||||
hexbuf[cur++] = ' ';
|
||||
hexbuf[cur++] = ' ';
|
||||
} else if (i != 15)
|
||||
hexbuf[cur++] = ' ';
|
||||
}
|
||||
/* Fill it up if column isn't complete */
|
||||
if (i < 16) {
|
||||
int j;
|
||||
|
||||
for (j = i; j < 16; j++) {
|
||||
if (j == 7) hexbuf[cur++] = ' ';
|
||||
hexbuf[cur++] = ' ';
|
||||
hexbuf[cur++] = ' ';
|
||||
hexbuf[cur++] = ' ';
|
||||
}
|
||||
} else
|
||||
hexbuf[cur++] = ' ';
|
||||
|
||||
/* Now dump bytes as text */
|
||||
for (i = 0; i < 16 && current_pos + i < nchars;
|
||||
i++) {
|
||||
hexbuf[cur++] =
|
||||
(isprint((guchar)buffer[current_pos + i]) ?
|
||||
buffer[current_pos + i] : '.' );
|
||||
if (i == 7) {
|
||||
hexbuf[cur++] = ' ';
|
||||
}
|
||||
}
|
||||
current_pos += i;
|
||||
(*global_pos) += i;
|
||||
hexbuf[cur++] = '\n';
|
||||
hexbuf[cur] = 0;
|
||||
(*print_line) (hexbuf, strlen(hexbuf), is_server, arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ferror(data_out_file)) {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Error reading temporary file %s: %s", follow_info->data_out_filename,
|
||||
strerror(errno));
|
||||
}
|
||||
fclose(data_out_file);
|
||||
data_out_file = NULL;
|
||||
} else {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Could not open temporary file %s: %s", follow_info->data_out_filename,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - for text printing, we probably want to wrap lines at 80 characters;
|
||||
* for PostScript printing, we probably want to wrap them at the appropriate
|
||||
* width, and perhaps put some kind of dingbat (to use the technical term)
|
||||
* to indicate a wrapped line, along the lines of what's done when displaying
|
||||
* this in a window, as per Warren Young's suggestion.
|
||||
*
|
||||
* For now, we support only text printing.
|
||||
*/
|
||||
static void
|
||||
follow_print_text(char *buffer, int nchars, gboolean is_server _U_, void *arg)
|
||||
{
|
||||
FILE *fh = arg;
|
||||
|
||||
fwrite(buffer, nchars, 1, fh);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_print_stream(GtkWidget * w _U_, gpointer data)
|
||||
{
|
||||
FILE *fh;
|
||||
gboolean to_file;
|
||||
char *print_dest;
|
||||
follow_info_t *follow_info = data;
|
||||
|
||||
switch (prefs.pr_dest) {
|
||||
case PR_DEST_CMD:
|
||||
print_dest = prefs.pr_cmd;
|
||||
to_file = FALSE;
|
||||
break;
|
||||
|
||||
case PR_DEST_FILE:
|
||||
print_dest = prefs.pr_file;
|
||||
to_file = TRUE;
|
||||
break;
|
||||
default: /* "Can't happen" */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"Couldn't figure out where to send the print "
|
||||
"job. Check your preferences.");
|
||||
return;
|
||||
}
|
||||
|
||||
fh = open_print_dest(to_file, print_dest);
|
||||
if (fh == NULL) {
|
||||
switch (to_file) {
|
||||
case FALSE:
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
"Couldn't run print command %s.", prefs.pr_cmd);
|
||||
break;
|
||||
|
||||
case TRUE:
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
file_write_error_message(errno), prefs.pr_file);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
print_preamble(fh, PR_FMT_TEXT);
|
||||
follow_read_stream(follow_info, follow_print_text, fh);
|
||||
print_finale(fh, PR_FMT_TEXT);
|
||||
close_print_dest(to_file, fh);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server,
|
||||
void *arg)
|
||||
{
|
||||
GtkWidget *text = arg;
|
||||
GdkColor fg, bg;
|
||||
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
|
||||
GtkTextIter iter;
|
||||
GtkTextTag *tag;
|
||||
gsize outbytes;
|
||||
gchar *convbuf;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* While our isprint() hack is in place, we
|
||||
* have to use convert some chars to '.' in order
|
||||
* to be able to see the data we *should* see
|
||||
* in the GtkText widget.
|
||||
*/
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nchars; i++) {
|
||||
if (buffer[i] == 0x0a || buffer[i] == 0x0d) {
|
||||
continue;
|
||||
}
|
||||
else if (! isprint(buffer[i])) {
|
||||
buffer[i] = '.';
|
||||
}
|
||||
}
|
||||
#else
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nchars; i++) {
|
||||
if (buffer[i] == '\n')
|
||||
continue;
|
||||
if (! isprint(buffer[i])) {
|
||||
buffer[i] = '.';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_server) {
|
||||
color_t_to_gdkcolor(&fg, &prefs.st_server_fg);
|
||||
color_t_to_gdkcolor(&bg, &prefs.st_server_bg);
|
||||
} else {
|
||||
color_t_to_gdkcolor(&fg, &prefs.st_client_fg);
|
||||
color_t_to_gdkcolor(&bg, &prefs.st_client_bg);
|
||||
}
|
||||
gtk_text_buffer_get_end_iter(buf, &iter);
|
||||
tag = gtk_text_buffer_create_tag(buf, NULL, "foreground-gdk", &fg,
|
||||
"background-gdk", &bg, "font-desc",
|
||||
m_r_font, NULL);
|
||||
convbuf = g_locale_to_utf8(buffer, nchars, NULL, &outbytes, NULL);
|
||||
gtk_text_buffer_insert_with_tags(buf, &iter, convbuf, outbytes, tag,
|
||||
NULL);
|
||||
g_free(convbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_load_text(follow_info_t *follow_info)
|
||||
{
|
||||
GtkTextBuffer *buf;
|
||||
|
||||
buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(follow_info->text));
|
||||
|
||||
/* Delete any info already in text box */
|
||||
gtk_text_buffer_set_text(buf, "", -1);
|
||||
|
||||
follow_read_stream(follow_info, follow_add_to_gtk_text, follow_info->text);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Save TCP Follow Stream As" window, if
|
||||
* any, so that if somebody tries to do "Save"
|
||||
* while there's already a "Save TCP Follow Stream" window up, we just pop
|
||||
* up the existing one, rather than creating a new one.
|
||||
*/
|
||||
static void
|
||||
follow_save_as_cmd_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
GtkWidget *ok_bt, *new_win;
|
||||
follow_info_t *follow_info = data;
|
||||
|
||||
if (follow_info->follow_save_as_w != NULL) {
|
||||
/* There's already a dialog box; reactivate it. */
|
||||
reactivate_window(follow_info->follow_save_as_w);
|
||||
return;
|
||||
}
|
||||
|
||||
new_win = gtk_file_selection_new("Ethereal: Save TCP Follow Stream As");
|
||||
follow_info->follow_save_as_w = new_win;
|
||||
g_signal_connect(G_OBJECT(new_win), "destroy",
|
||||
G_CALLBACK(follow_save_as_destroy_cb), follow_info);
|
||||
|
||||
/* Tuck away the follow_info object into the window */
|
||||
gtk_object_set_data(GTK_OBJECT(new_win), E_FOLLOW_INFO_KEY,
|
||||
follow_info);
|
||||
|
||||
/* If we've opened a file, start out by showing the files in the directory
|
||||
in which that file resided. */
|
||||
if (last_open_dir)
|
||||
gtk_file_selection_complete(GTK_FILE_SELECTION(new_win),
|
||||
last_open_dir);
|
||||
|
||||
/* Connect the ok_button to file_save_as_ok_cb function and pass along a
|
||||
pointer to the file selection box widget */
|
||||
ok_bt = GTK_FILE_SELECTION(new_win)->ok_button;
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(follow_save_as_ok_cb), new_win);
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(new_win)->cancel_button),
|
||||
"clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(new_win));
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(new_win,
|
||||
GTK_FILE_SELECTION(new_win)->cancel_button);
|
||||
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(new_win), "");
|
||||
gtk_widget_show_all(new_win);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
follow_save_as_ok_cb(GtkWidget * w _U_, GtkFileSelection * fs)
|
||||
{
|
||||
gchar *to_name;
|
||||
follow_info_t *follow_info;
|
||||
FILE *fh;
|
||||
|
||||
to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
|
||||
|
||||
gtk_widget_hide(GTK_WIDGET(fs));
|
||||
follow_info = gtk_object_get_data(GTK_OBJECT(fs), E_FOLLOW_INFO_KEY);
|
||||
gtk_widget_destroy(GTK_WIDGET(fs));
|
||||
|
||||
fh = fopen(to_name, "wb");
|
||||
if (fh == NULL) {
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
file_write_error_message(errno), to_name);
|
||||
return;
|
||||
}
|
||||
|
||||
follow_read_stream(follow_info, follow_print_text, fh);
|
||||
fclose(fh);
|
||||
g_free(to_name);
|
||||
}
|
||||
|
||||
static void
|
||||
follow_save_as_destroy_cb(GtkWidget * win _U_, gpointer data)
|
||||
{
|
||||
follow_info_t *follow_info = data;
|
||||
|
||||
/* Note that we no longer have a dialog box. */
|
||||
follow_info->follow_save_as_w = NULL;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* follow_dlg.c
|
||||
*
|
||||
* $Id: follow_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* Copyright 2000 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FOLLOW_DLG_H__
|
||||
#define __FOLLOW_DLG_H__
|
||||
|
||||
void follow_stream_cb( GtkWidget *, gpointer);
|
||||
|
||||
/* Redraw the text in all "Follow TCP Stream" windows. */
|
||||
void follow_redraw_all(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,169 @@
|
|||
/* goto_dlg.c
|
||||
* Routines for "go to frame" window
|
||||
*
|
||||
* $Id: goto_dlg.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <epan/proto.h>
|
||||
#include "globals.h"
|
||||
|
||||
#include "goto_dlg.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "dlg_utils.h"
|
||||
|
||||
/* Capture callback data keys */
|
||||
#define E_GOTO_FNUMBER_KEY "goto_fnumber_te"
|
||||
|
||||
static void
|
||||
goto_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
|
||||
|
||||
static void
|
||||
goto_frame_close_cb(GtkWidget *close_bt, gpointer parent_w);
|
||||
|
||||
void
|
||||
goto_frame_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
GtkWidget *goto_frame_w, *main_vb, *fnumber_hb, *fnumber_lb, *fnumber_te,
|
||||
*bbox, *ok_bt, *cancel_bt;
|
||||
|
||||
goto_frame_w = dlg_window_new("Ethereal: Go To Frame");
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(goto_frame_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* Frame number row */
|
||||
fnumber_hb = gtk_hbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), fnumber_hb);
|
||||
gtk_widget_show(fnumber_hb);
|
||||
|
||||
fnumber_lb = gtk_label_new("Frame number:");
|
||||
gtk_box_pack_start(GTK_BOX(fnumber_hb), fnumber_lb, FALSE, FALSE, 0);
|
||||
gtk_widget_show(fnumber_lb);
|
||||
|
||||
fnumber_te = gtk_entry_new();
|
||||
gtk_box_pack_start(GTK_BOX(fnumber_hb), fnumber_te, FALSE, FALSE, 0);
|
||||
gtk_widget_show(fnumber_te);
|
||||
|
||||
/* Button row: OK and cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(goto_frame_ok_cb), GTK_OBJECT(goto_frame_w));
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_bt), "clicked",
|
||||
G_CALLBACK(goto_frame_close_cb), GTK_OBJECT(goto_frame_w));
|
||||
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
|
||||
/* Attach pointers to needed widgets to the capture prefs window/object */
|
||||
gtk_object_set_data(GTK_OBJECT(goto_frame_w), E_GOTO_FNUMBER_KEY, fnumber_te);
|
||||
|
||||
/* Catch the "activate" signal on the frame number text entry, so that
|
||||
if the user types Return there, we act as if the "OK" button
|
||||
had been selected, as happens if Return is typed if some widget
|
||||
that *doesn't* handle the Return key has the input focus. */
|
||||
dlg_set_activate(fnumber_te, ok_bt);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(goto_frame_w, cancel_bt);
|
||||
|
||||
/* Give the initial focus to the "Frame number" entry box. */
|
||||
gtk_widget_grab_focus(fnumber_te);
|
||||
|
||||
gtk_widget_show(goto_frame_w);
|
||||
}
|
||||
|
||||
static void
|
||||
goto_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
|
||||
{
|
||||
GtkWidget *fnumber_te;
|
||||
const gchar *fnumber_text;
|
||||
guint fnumber;
|
||||
char *p;
|
||||
|
||||
fnumber_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_GOTO_FNUMBER_KEY);
|
||||
|
||||
fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
|
||||
fnumber = strtoul(fnumber_text, &p, 10);
|
||||
if (p == fnumber_text || *p != '\0') {
|
||||
/* Illegal number.
|
||||
XXX - what about negative numbers (which "strtoul()" allows)?
|
||||
Can we hack up signal handlers for the widget to make it
|
||||
reject attempts to type in characters other than digits? */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL,
|
||||
"The frame number you entered isn't a valid number.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (goto_frame(&cfile, fnumber)) {
|
||||
|
||||
case NO_SUCH_FRAME:
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, "There is no frame with that frame number.");
|
||||
return;
|
||||
|
||||
case FRAME_NOT_DISPLAYED:
|
||||
/* XXX - add it to the display filter? */
|
||||
simple_dialog(ESD_TYPE_CRIT, NULL, "The frame with that frame number is not currently being displayed.");
|
||||
return;
|
||||
|
||||
case FOUND_FRAME:
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
goto_frame_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gtk_grab_remove(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* goto_dlg.h
|
||||
* Definitions for "go to frame" window
|
||||
*
|
||||
* $Id: goto_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GOTO_DLG_H__
|
||||
#define __GOTO_DLG_H__
|
||||
|
||||
void goto_frame_cb(GtkWidget *, gpointer);
|
||||
|
||||
#endif /* goto_dlg.h */
|
|
@ -0,0 +1,58 @@
|
|||
/* gtkglobals.h
|
||||
* GTK-related Global defines, etc.
|
||||
*
|
||||
* $Id: gtkglobals.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GTKGLOBALS_H__
|
||||
#define __GTKGLOBALS_H__
|
||||
|
||||
#ifndef __GTK_H__
|
||||
#include <gtk/gtk.h>
|
||||
#endif
|
||||
|
||||
extern GtkWidget *top_level, *packet_list, *tree_view, *byte_nb_ptr;
|
||||
extern PangoFontDescription *m_r_font, *m_b_font;
|
||||
|
||||
void set_plist_sel_browse(gboolean);
|
||||
void set_plist_font(PangoFontDescription *font);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* It appears that isprint() is not working well
|
||||
* with gtk+'s text widget. By narrowing down what
|
||||
* we print, the ascii portion of the hex display works.
|
||||
* MSVCRT's isprint() returns true on values like 0xd2,
|
||||
* which cause the GtkTextWidget to go wacko.
|
||||
*
|
||||
* (I.e., whilst non-ASCII characters are considered printable
|
||||
* in the locale in which Ethereal is running - which they might
|
||||
* well be, if, for example, the locale supports ISO Latin 1 -
|
||||
* GTK+'s text widget on Windows doesn't seem to handle them
|
||||
* correctly.)
|
||||
*
|
||||
* This is a quick fix for the symptom, not the
|
||||
* underlying problem.
|
||||
*/
|
||||
#undef isprint
|
||||
#define isprint(c) (c >= 0x20 && c <= 0x7f)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,732 @@
|
|||
/* gui_prefs.c
|
||||
* Dialog box for GUI preferences
|
||||
*
|
||||
* $Id: gui_prefs.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "color_utils.h"
|
||||
#include "globals.h"
|
||||
#include "gui_prefs.h"
|
||||
#include "gtkglobals.h"
|
||||
#include "follow_dlg.h"
|
||||
#include "help_dlg.h"
|
||||
#include "prefs.h"
|
||||
#include "prefs_dlg.h"
|
||||
#include "ui_util.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "proto_draw.h"
|
||||
#include "main.h"
|
||||
|
||||
static void font_browse_cb(GtkWidget *w, gpointer data);
|
||||
static void font_browse_ok_cb(GtkWidget *w, GtkFontSelectionDialog *fs);
|
||||
static void font_browse_destroy(GtkWidget *win, gpointer data);
|
||||
static gint fetch_enum_value(gpointer control, const enum_val_t *enumvals);
|
||||
static void color_browse_cb(GtkWidget *w, gpointer data);
|
||||
static void update_text_color(GtkWidget *w, gpointer data);
|
||||
static void update_current_color(GtkWidget *w, gpointer data);
|
||||
static void color_ok_cb(GtkWidget *w, gpointer data);
|
||||
static void color_cancel_cb(GtkWidget *w, gpointer data);
|
||||
static gboolean color_delete_cb(GtkWidget *prefs_w, gpointer dummy);
|
||||
static void color_destroy_cb(GtkWidget *w, gpointer data);
|
||||
static void fetch_colors(void);
|
||||
|
||||
#define SCROLLBAR_PLACEMENT_KEY "scrollbar_placement"
|
||||
#define PLIST_SEL_BROWSE_KEY "plist_sel_browse"
|
||||
#define PTREE_SEL_BROWSE_KEY "ptree_sel_browse"
|
||||
#define PTREE_LINE_STYLE_KEY "ptree_line_style"
|
||||
#define PTREE_EXPANDER_STYLE_KEY "ptree_expander_style"
|
||||
#define HEX_DUMP_HIGHLIGHT_STYLE_KEY "hex_dump_highlight_style"
|
||||
#define GEOMETRY_POSITION_KEY "geometry_position"
|
||||
#define GEOMETRY_SIZE_KEY "geometry_size"
|
||||
|
||||
#define FONT_DIALOG_PTR_KEY "font_dialog_ptr"
|
||||
#define FONT_CALLER_PTR_KEY "font_caller_ptr"
|
||||
#define COLOR_DIALOG_PTR_KEY "color_dialog_ptr"
|
||||
#define COLOR_CALLER_PTR_KEY "color_caller_ptr"
|
||||
#define COLOR_SAMPLE_PTR_KEY "color_sample_ptr"
|
||||
#define COLOR_SELECTION_PTR_KEY "color_selection_ptr"
|
||||
|
||||
static const enum_val_t scrollbar_placement_vals[] = {
|
||||
{ "Left", FALSE },
|
||||
{ "Right", TRUE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const enum_val_t selection_mode_vals[] = {
|
||||
{ "Selects", FALSE },
|
||||
{ "Browses", TRUE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const enum_val_t line_style_vals[] = {
|
||||
{ "None", 0 },
|
||||
{ "Solid", 1 },
|
||||
{ "Dotted", 2 },
|
||||
{ "Tabbed", 3 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const enum_val_t expander_style_vals[] = {
|
||||
{ "None", 0 },
|
||||
{ "Square", 1 },
|
||||
{ "Triangle", 2 },
|
||||
{ "Circular", 3 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const enum_val_t highlight_style_vals[] = {
|
||||
{ "Bold", 0 },
|
||||
{ "Inverse", 1 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* Set to FALSE initially; set to TRUE if the user ever hits "OK" on
|
||||
the "Colors..." dialog, so that we know that they (probably) changed
|
||||
colors, and therefore that the "apply" function needs to recolor
|
||||
any marked packets. */
|
||||
static gboolean colors_changed;
|
||||
|
||||
/* Set to FALSE initially; set to TRUE if the user ever hits "OK" on
|
||||
the "Font..." dialog, so that we know that they (probably) changed
|
||||
the font, and therefore that the "apply" function needs to take care
|
||||
of that */
|
||||
static gboolean font_changed;
|
||||
|
||||
/* Font name from the font dialog box; if "font_changed" is TRUE, this
|
||||
has been set to the name of the font the user selected. */
|
||||
static gchar *new_font_name;
|
||||
|
||||
#define GUI_TABLE_ROWS 8
|
||||
GtkWidget*
|
||||
gui_prefs_show(void)
|
||||
{
|
||||
GtkWidget *main_tb, *main_vb, *hbox, *font_bt, *color_bt;
|
||||
GtkWidget *scrollbar_om, *plist_browse_om;
|
||||
GtkWidget *ptree_browse_om, *line_style_om;
|
||||
GtkWidget *expander_style_om, *highlight_style_om;
|
||||
GtkWidget *save_position_cb, *save_size_cb;
|
||||
|
||||
/* The colors or font haven't been changed yet. */
|
||||
colors_changed = FALSE;
|
||||
font_changed = FALSE;
|
||||
|
||||
/* Main vertical box */
|
||||
main_vb = gtk_vbox_new(FALSE, 7);
|
||||
gtk_container_border_width( GTK_CONTAINER(main_vb), 5 );
|
||||
|
||||
/* Main horizontal box */
|
||||
/* XXX - Is therea a better way to center the table? */
|
||||
hbox = gtk_hbox_new(FALSE, 7);
|
||||
gtk_box_pack_start (GTK_BOX(main_vb), hbox, TRUE, FALSE, 0);
|
||||
|
||||
/* Main table */
|
||||
main_tb = gtk_table_new(GUI_TABLE_ROWS, 3, FALSE);
|
||||
gtk_box_pack_start( GTK_BOX(hbox), main_tb, TRUE, FALSE, 0 );
|
||||
gtk_table_set_row_spacings( GTK_TABLE(main_tb), 10 );
|
||||
gtk_table_set_col_spacings( GTK_TABLE(main_tb), 15 );
|
||||
gtk_table_set_col_spacing( GTK_TABLE(main_tb), 1, 50 );
|
||||
|
||||
/* Scrollbar placement */
|
||||
scrollbar_om = create_preference_option_menu(main_tb, 0,
|
||||
"Vertical scrollbar placement:", NULL, scrollbar_placement_vals,
|
||||
prefs.gui_scrollbar_on_right);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), SCROLLBAR_PLACEMENT_KEY,
|
||||
scrollbar_om);
|
||||
|
||||
/* Packet list selection browseable */
|
||||
plist_browse_om = create_preference_option_menu(main_tb, 1,
|
||||
"Packet list mouse behavior:", NULL, selection_mode_vals,
|
||||
prefs.gui_plist_sel_browse);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PLIST_SEL_BROWSE_KEY,
|
||||
plist_browse_om);
|
||||
|
||||
/* Proto tree selection browseable */
|
||||
ptree_browse_om = create_preference_option_menu(main_tb, 2,
|
||||
"Protocol tree mouse behavior:", NULL, selection_mode_vals,
|
||||
prefs.gui_ptree_sel_browse);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PTREE_SEL_BROWSE_KEY,
|
||||
ptree_browse_om);
|
||||
|
||||
/* Tree line style */
|
||||
line_style_om = create_preference_option_menu(main_tb, 3,
|
||||
"Tree line style:", NULL, line_style_vals,
|
||||
prefs.gui_ptree_line_style);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PTREE_LINE_STYLE_KEY,
|
||||
line_style_om);
|
||||
|
||||
/* Tree expander style */
|
||||
expander_style_om = create_preference_option_menu(main_tb, 4,
|
||||
"Tree expander style:", NULL, expander_style_vals,
|
||||
prefs.gui_ptree_expander_style);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PTREE_EXPANDER_STYLE_KEY,
|
||||
expander_style_om);
|
||||
|
||||
/* Hex Dump highlight style */
|
||||
highlight_style_om = create_preference_option_menu(main_tb, 5,
|
||||
"Hex display highlight style:", NULL, highlight_style_vals,
|
||||
prefs.gui_hex_dump_highlight_style);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), HEX_DUMP_HIGHLIGHT_STYLE_KEY,
|
||||
highlight_style_om);
|
||||
|
||||
/* Geometry prefs */
|
||||
save_position_cb = create_preference_check_button(main_tb,
|
||||
6, "Save window position:", NULL, prefs.gui_geometry_save_position);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), GEOMETRY_POSITION_KEY,
|
||||
save_position_cb);
|
||||
|
||||
save_size_cb = create_preference_check_button(main_tb,
|
||||
7, "Save window size:", NULL, prefs.gui_geometry_save_size);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), GEOMETRY_SIZE_KEY,
|
||||
save_size_cb);
|
||||
|
||||
/* "Font..." button - click to open a font selection dialog box. */
|
||||
font_bt = gtk_button_new_from_stock(GTK_STOCK_SELECT_FONT);
|
||||
g_signal_connect(G_OBJECT(font_bt), "clicked",
|
||||
G_CALLBACK(font_browse_cb), NULL);
|
||||
gtk_table_attach_defaults( GTK_TABLE(main_tb), font_bt, 2, 3, 0, 1 );
|
||||
|
||||
/* "Colors..." button - click to open a color selection dialog box. */
|
||||
color_bt = gtk_button_new_from_stock(GTK_STOCK_SELECT_COLOR);
|
||||
g_signal_connect(G_OBJECT(color_bt), "clicked",
|
||||
G_CALLBACK(color_browse_cb), NULL);
|
||||
gtk_table_attach_defaults( GTK_TABLE(main_tb), color_bt, 2, 3, 1, 2 );
|
||||
|
||||
/* Show 'em what we got */
|
||||
gtk_widget_show_all(main_vb);
|
||||
|
||||
return(main_vb);
|
||||
}
|
||||
|
||||
/* Create a font dialog for browsing. */
|
||||
static void
|
||||
font_browse_cb(GtkWidget *w, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(w);
|
||||
GtkWidget *font_browse_w;
|
||||
static gchar *fixedwidths[] = { "c", "m", NULL };
|
||||
|
||||
/* Has a font dialog box already been opened for that top-level
|
||||
widget? */
|
||||
font_browse_w = gtk_object_get_data(GTK_OBJECT(caller),
|
||||
FONT_DIALOG_PTR_KEY);
|
||||
|
||||
if (font_browse_w != NULL) {
|
||||
/* Yes. Just re-activate that dialog box. */
|
||||
reactivate_window(font_browse_w);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now create a new dialog. */
|
||||
font_browse_w = gtk_font_selection_dialog_new("Ethereal: Select Font");
|
||||
gtk_window_set_transient_for(GTK_WINDOW(font_browse_w),
|
||||
GTK_WINDOW(top_level));
|
||||
|
||||
/* Call a handler when we're destroyed, so we can inform
|
||||
our caller, if any, that we've been destroyed. */
|
||||
g_signal_connect(G_OBJECT(font_browse_w), "destroy",
|
||||
G_CALLBACK(font_browse_destroy), NULL);
|
||||
|
||||
/* Set its filter to show only fixed_width fonts. */
|
||||
#if 0
|
||||
/* XXX - doesn't work with GTK+ v2 */
|
||||
gtk_font_selection_dialog_set_filter(
|
||||
GTK_FONT_SELECTION_DIALOG(font_browse_w),
|
||||
GTK_FONT_FILTER_BASE, /* user can't change the filter */
|
||||
GTK_FONT_ALL, /* bitmap or scalable are fine */
|
||||
NULL, /* all foundries are OK */
|
||||
NULL, /* all weights are OK (XXX - normal only?) */
|
||||
NULL, /* all slants are OK (XXX - Roman only?) */
|
||||
NULL, /* all setwidths are OK */
|
||||
fixedwidths, /* ONLY fixed-width fonts */
|
||||
NULL); /* all charsets are OK (XXX - ISO 8859/1 only?) */
|
||||
#endif
|
||||
/* Set the font to the current font. */
|
||||
gtk_font_selection_dialog_set_font_name(
|
||||
GTK_FONT_SELECTION_DIALOG(font_browse_w), prefs.gui_font_name);
|
||||
|
||||
/* Set the FONT_CALLER_PTR_KEY for the new dialog to point to
|
||||
our caller. */
|
||||
gtk_object_set_data(GTK_OBJECT(font_browse_w), FONT_CALLER_PTR_KEY,
|
||||
caller);
|
||||
|
||||
/* Set the FONT_DIALOG_PTR_KEY for the caller to point to us */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), FONT_DIALOG_PTR_KEY,
|
||||
font_browse_w);
|
||||
|
||||
/* Connect the ok_button to font_browse_ok_cb function and pass along a
|
||||
pointer to the font selection box widget */
|
||||
g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(font_browse_w)->ok_button),
|
||||
"clicked", G_CALLBACK(font_browse_ok_cb),
|
||||
font_browse_w);
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_browse_w)->cancel_button),
|
||||
"clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(font_browse_w));
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can
|
||||
catch the ESC key being pressed and act as if the "Cancel" button
|
||||
had been selected. */
|
||||
dlg_set_cancel(font_browse_w,
|
||||
GTK_FONT_SELECTION_DIALOG(font_browse_w)->cancel_button);
|
||||
|
||||
gtk_widget_show(font_browse_w);
|
||||
}
|
||||
|
||||
static void
|
||||
font_browse_ok_cb(GtkWidget *w _U_, GtkFontSelectionDialog *fs)
|
||||
{
|
||||
gchar *font_name;
|
||||
PangoFontDescription *new_r_font, *new_b_font;
|
||||
|
||||
font_name = g_strdup(gtk_font_selection_dialog_get_font_name(
|
||||
GTK_FONT_SELECTION_DIALOG(fs)));
|
||||
if (font_name == NULL) {
|
||||
/* No font was selected; let the user know, but don't
|
||||
tear down the font selection dialog, so they can
|
||||
try again. */
|
||||
simple_dialog(ESD_TYPE_CRIT | ESD_TYPE_MODAL, NULL,
|
||||
"You have not selected a font.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now load those fonts, just to make sure we can. */
|
||||
new_r_font = pango_font_description_from_string(font_name);
|
||||
if (new_r_font == NULL) {
|
||||
/* Oops, that font didn't work.
|
||||
Tell the user, but don't tear down the font selection
|
||||
dialog, so that they can try again. */
|
||||
simple_dialog(ESD_TYPE_CRIT | ESD_TYPE_MODAL, NULL,
|
||||
"The font you selected cannot be loaded.");
|
||||
|
||||
g_free(font_name);
|
||||
return;
|
||||
}
|
||||
|
||||
new_b_font = pango_font_description_copy(new_r_font);
|
||||
pango_font_description_set_weight(new_b_font,
|
||||
PANGO_WEIGHT_BOLD);
|
||||
if (new_b_font == NULL) {
|
||||
/* Oops, that font didn't work.
|
||||
Tell the user, but don't tear down the font selection
|
||||
dialog, so that they can try again. */
|
||||
simple_dialog(ESD_TYPE_CRIT | ESD_TYPE_MODAL, NULL,
|
||||
"The font you selected doesn't have a boldface version.");
|
||||
|
||||
g_free(font_name);
|
||||
pango_font_description_free(new_r_font);
|
||||
return;
|
||||
}
|
||||
|
||||
font_changed = TRUE;
|
||||
new_font_name = font_name;
|
||||
|
||||
gtk_widget_hide(GTK_WIDGET(fs));
|
||||
gtk_widget_destroy(GTK_WIDGET(fs));
|
||||
}
|
||||
|
||||
static void
|
||||
font_browse_destroy(GtkWidget *win, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *caller;
|
||||
|
||||
/* Get the widget that requested that we be popped up, if any.
|
||||
(It should arrange to destroy us if it's destroyed, so
|
||||
that we don't get a pointer to a non-existent window here.) */
|
||||
caller = gtk_object_get_data(GTK_OBJECT(win), FONT_CALLER_PTR_KEY);
|
||||
|
||||
if (caller != NULL) {
|
||||
/* Tell it we no longer exist. */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), FONT_DIALOG_PTR_KEY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Now nuke this window. */
|
||||
gtk_grab_remove(GTK_WIDGET(win));
|
||||
gtk_widget_destroy(GTK_WIDGET(win));
|
||||
}
|
||||
|
||||
static gint
|
||||
fetch_enum_value(gpointer control, const enum_val_t *enumvals)
|
||||
{
|
||||
return fetch_preference_option_menu_val(GTK_WIDGET(control), enumvals);
|
||||
}
|
||||
|
||||
void
|
||||
gui_prefs_fetch(GtkWidget *w)
|
||||
{
|
||||
prefs.gui_scrollbar_on_right = fetch_enum_value(
|
||||
gtk_object_get_data(GTK_OBJECT(w), SCROLLBAR_PLACEMENT_KEY),
|
||||
scrollbar_placement_vals);
|
||||
prefs.gui_plist_sel_browse = fetch_enum_value(
|
||||
gtk_object_get_data(GTK_OBJECT(w), PLIST_SEL_BROWSE_KEY),
|
||||
selection_mode_vals);
|
||||
prefs.gui_ptree_sel_browse = fetch_enum_value(
|
||||
gtk_object_get_data(GTK_OBJECT(w), PTREE_SEL_BROWSE_KEY),
|
||||
selection_mode_vals);
|
||||
prefs.gui_ptree_line_style = fetch_enum_value(
|
||||
gtk_object_get_data(GTK_OBJECT(w), PTREE_LINE_STYLE_KEY),
|
||||
line_style_vals);
|
||||
prefs.gui_ptree_expander_style = fetch_enum_value(
|
||||
gtk_object_get_data(GTK_OBJECT(w), PTREE_EXPANDER_STYLE_KEY),
|
||||
expander_style_vals);
|
||||
prefs.gui_hex_dump_highlight_style = fetch_enum_value(
|
||||
gtk_object_get_data(GTK_OBJECT(w), HEX_DUMP_HIGHLIGHT_STYLE_KEY),
|
||||
highlight_style_vals);
|
||||
prefs.gui_geometry_save_position =
|
||||
gtk_toggle_button_get_active(gtk_object_get_data(GTK_OBJECT(w),
|
||||
GEOMETRY_POSITION_KEY));
|
||||
prefs.gui_geometry_save_size =
|
||||
gtk_toggle_button_get_active(gtk_object_get_data(GTK_OBJECT(w),
|
||||
GEOMETRY_SIZE_KEY));
|
||||
|
||||
if (font_changed) {
|
||||
if (prefs.gui_font_name != NULL)
|
||||
g_free(prefs.gui_font_name);
|
||||
prefs.gui_font_name = g_strdup(new_font_name);
|
||||
}
|
||||
|
||||
if (colors_changed)
|
||||
fetch_colors();
|
||||
}
|
||||
|
||||
void
|
||||
gui_prefs_apply(GtkWidget *w _U_)
|
||||
{
|
||||
PangoFontDescription *new_r_font, *new_b_font;
|
||||
PangoFontDescription *old_r_font = NULL, *old_b_font = NULL;
|
||||
|
||||
if (font_changed) {
|
||||
/* XXX - what if the world changed out from under
|
||||
us, so that one or both of these fonts cannot
|
||||
be loaded? */
|
||||
new_r_font = pango_font_description_from_string(prefs.gui_font_name);
|
||||
new_b_font = pango_font_description_copy(new_r_font);
|
||||
pango_font_description_set_weight(new_b_font,
|
||||
PANGO_WEIGHT_BOLD);
|
||||
set_plist_font(new_r_font);
|
||||
set_ptree_font_all(new_r_font);
|
||||
old_r_font = m_r_font;
|
||||
old_b_font = m_b_font;
|
||||
set_fonts(new_r_font, new_b_font);
|
||||
}
|
||||
|
||||
/* Redraw the hex dump windows, in case either the font or the
|
||||
highlight style changed. */
|
||||
redraw_hex_dump_all();
|
||||
|
||||
/* Redraw the help window. */
|
||||
help_redraw();
|
||||
|
||||
/* Redraw the "Follow TCP Stream" windows, in case either the font
|
||||
or the colors to use changed. */
|
||||
follow_redraw_all();
|
||||
|
||||
set_scrollbar_placement_all();
|
||||
set_plist_sel_browse(prefs.gui_plist_sel_browse);
|
||||
set_ptree_sel_browse_all(prefs.gui_ptree_sel_browse);
|
||||
if (colors_changed)
|
||||
update_marked_frames();
|
||||
|
||||
/* We're no longer using the old fonts; unreference them. */
|
||||
if (old_r_font != NULL)
|
||||
pango_font_description_free(old_r_font);
|
||||
if (old_b_font != NULL)
|
||||
pango_font_description_free(old_b_font);
|
||||
}
|
||||
|
||||
void
|
||||
gui_prefs_destroy(GtkWidget *w)
|
||||
{
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(w);
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Is there a font selection dialog associated with this
|
||||
Preferences dialog? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(caller), FONT_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(fs);
|
||||
}
|
||||
|
||||
/* Is there a color selection dialog associated with this
|
||||
Preferences dialog? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(caller), COLOR_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(fs);
|
||||
}
|
||||
|
||||
/* Free up any saved font name. */
|
||||
if (new_font_name != NULL) {
|
||||
g_free(new_font_name);
|
||||
new_font_name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* color selection part */
|
||||
|
||||
#define MAX_HANDLED_COL 2
|
||||
|
||||
typedef struct {
|
||||
GdkColor color;
|
||||
char *label;
|
||||
} color_info_t;
|
||||
|
||||
static color_info_t color_info[MAX_HANDLED_COL] = {
|
||||
#define MFG_IDX 0
|
||||
{ {0.0, 0.0, 0.0, 0.0}, "Marked frame foreground" },
|
||||
#define MBG_IDX 1
|
||||
{ {0.0, 0.0, 0.0, 0.0}, "Marked frame background" }
|
||||
};
|
||||
|
||||
#define SAMPLE_MARKED_TEXT "Sample marked frame text\n"
|
||||
|
||||
#define CS_RED 0
|
||||
#define CS_GREEN 1
|
||||
#define CS_BLUE 2
|
||||
#define CS_OPACITY 3
|
||||
|
||||
static GdkColor *curcolor = NULL;
|
||||
|
||||
static void
|
||||
color_browse_cb(GtkWidget *w, gpointer data _U_)
|
||||
{
|
||||
|
||||
GtkWidget *main_vb, *main_tb, *label, *optmenu, *menu, *menuitem;
|
||||
GtkWidget *sample, *colorsel, *bbox, *cancel_bt, *ok_bt, *color_w;
|
||||
int i;
|
||||
gdouble scolor[4];
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(w);
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
|
||||
/* Has a color dialog box already been opened for that top-level
|
||||
widget? */
|
||||
color_w = gtk_object_get_data(GTK_OBJECT(caller),
|
||||
COLOR_DIALOG_PTR_KEY);
|
||||
|
||||
if (color_w != NULL) {
|
||||
/* Yes. Just re-activate that dialog box. */
|
||||
reactivate_window(color_w);
|
||||
return;
|
||||
}
|
||||
|
||||
color_t_to_gdkcolor(&color_info[MFG_IDX].color, &prefs.gui_marked_fg);
|
||||
color_t_to_gdkcolor(&color_info[MBG_IDX].color, &prefs.gui_marked_bg);
|
||||
curcolor = &color_info[MFG_IDX].color;
|
||||
scolor[CS_RED] = (gdouble) (curcolor->red) / 65535.0;
|
||||
scolor[CS_GREEN] = (gdouble) (curcolor->green) / 65535.0;
|
||||
scolor[CS_BLUE] = (gdouble) (curcolor->blue) / 65535.0;
|
||||
scolor[CS_OPACITY] = 1.0;
|
||||
|
||||
/* Now create a new dialog.
|
||||
You can't put your own extra widgets into a color selection
|
||||
dialog, as you can with a file selection dialog, so we have to
|
||||
construct our own dialog and put a color selection widget
|
||||
into it. */
|
||||
color_w = dlg_window_new("Ethereal: Select Color");
|
||||
|
||||
g_signal_connect(G_OBJECT(color_w), "delete_event",
|
||||
G_CALLBACK(color_delete_cb), NULL);
|
||||
|
||||
/* Call a handler when we're destroyed, so we can inform our caller,
|
||||
if any, that we've been destroyed. */
|
||||
g_signal_connect(G_OBJECT(color_w), "destroy",
|
||||
G_CALLBACK(color_destroy_cb), NULL);
|
||||
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add (GTK_CONTAINER (color_w), main_vb);
|
||||
main_tb = gtk_table_new(3, 3, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
gtk_widget_show(main_tb);
|
||||
label = gtk_label_new("Set:");
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, 0, 1);
|
||||
gtk_widget_show(label);
|
||||
|
||||
colorsel = gtk_color_selection_new();
|
||||
optmenu = gtk_option_menu_new();
|
||||
menu = gtk_menu_new();
|
||||
for (i = 0; i < MAX_HANDLED_COL; i++){
|
||||
menuitem = gtk_menu_item_new_with_label(color_info[i].label);
|
||||
gtk_object_set_data(GTK_OBJECT(menuitem), COLOR_SELECTION_PTR_KEY,
|
||||
(gpointer) colorsel);
|
||||
g_signal_connect(G_OBJECT(menuitem), "activate",
|
||||
G_CALLBACK(update_current_color),
|
||||
&color_info[i].color);
|
||||
gtk_widget_show(menuitem);
|
||||
gtk_menu_append(GTK_MENU (menu), menuitem);
|
||||
}
|
||||
gtk_option_menu_set_menu (GTK_OPTION_MENU (optmenu), menu);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), optmenu, 1, 2, 0, 1);
|
||||
gtk_widget_show(optmenu);
|
||||
|
||||
sample = gtk_text_view_new();
|
||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sample));
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(sample), FALSE);
|
||||
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(sample), FALSE);
|
||||
gtk_text_buffer_create_tag(buffer, "color", "foreground-gdk",
|
||||
&color_info[MFG_IDX].color, "background-gdk",
|
||||
&color_info[MBG_IDX].color, NULL);
|
||||
gtk_text_buffer_get_start_iter(buffer, &iter);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, SAMPLE_MARKED_TEXT,
|
||||
-1, "color", NULL);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), sample, 2, 3, 0, 2);
|
||||
gtk_widget_show(sample);
|
||||
gtk_color_selection_set_color(GTK_COLOR_SELECTION(colorsel),
|
||||
&scolor[CS_RED]);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), colorsel, 0, 3, 2, 3);
|
||||
gtk_object_set_data(GTK_OBJECT(colorsel), COLOR_SAMPLE_PTR_KEY,
|
||||
(gpointer) sample);
|
||||
g_signal_connect(G_OBJECT(colorsel), "color-changed",
|
||||
G_CALLBACK(update_text_color), NULL);
|
||||
gtk_widget_show(colorsel);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(color_w), COLOR_CALLER_PTR_KEY, caller);
|
||||
gtk_object_set_data(GTK_OBJECT(caller), COLOR_DIALOG_PTR_KEY, color_w);
|
||||
|
||||
/* Ok, Cancel Buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(color_ok_cb), color_w);
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
gtk_signal_connect_object(GTK_OBJECT(cancel_bt), "clicked",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(color_w));
|
||||
gtk_box_pack_start(GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
dlg_set_cancel(color_w, cancel_bt);
|
||||
|
||||
gtk_widget_show(color_w);
|
||||
}
|
||||
|
||||
static void
|
||||
update_text_color(GtkWidget *w, gpointer data _U_) {
|
||||
GtkWidget *sample = gtk_object_get_data(GTK_OBJECT(w),
|
||||
COLOR_SAMPLE_PTR_KEY);
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sample));
|
||||
GtkTextTag *tag;
|
||||
gdouble scolor[4];
|
||||
|
||||
gtk_color_selection_get_color(GTK_COLOR_SELECTION(w), &scolor[CS_RED]);
|
||||
|
||||
curcolor->red = (gushort) (scolor[CS_RED] * 65535.0);
|
||||
curcolor->green = (gushort) (scolor[CS_GREEN] * 65535.0);
|
||||
curcolor->blue = (gushort) (scolor[CS_BLUE] * 65535.0);
|
||||
|
||||
tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer),
|
||||
"color");
|
||||
g_object_set(tag, "foreground-gdk", &color_info[MFG_IDX].color,
|
||||
"background-gdk", &color_info[MBG_IDX].color, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_color(GtkWidget *w, gpointer data)
|
||||
{
|
||||
GtkColorSelection *colorsel;
|
||||
gdouble scolor[4];
|
||||
|
||||
colorsel = GTK_COLOR_SELECTION(gtk_object_get_data(GTK_OBJECT(w),
|
||||
COLOR_SELECTION_PTR_KEY));
|
||||
curcolor = (GdkColor *)data;
|
||||
scolor[CS_RED] = (gdouble) (curcolor->red) / 65535.0;
|
||||
scolor[CS_GREEN] = (gdouble) (curcolor->green) / 65535.0;
|
||||
scolor[CS_BLUE] = (gdouble) (curcolor->blue) / 65535.0;
|
||||
scolor[CS_OPACITY] = 1.0;
|
||||
|
||||
gtk_color_selection_set_color(colorsel, &scolor[CS_RED]);
|
||||
}
|
||||
|
||||
static void
|
||||
color_ok_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
/* We assume the user actually changed a color here. */
|
||||
colors_changed = TRUE;
|
||||
|
||||
gtk_widget_hide(GTK_WIDGET(data));
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void
|
||||
color_cancel_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
/* Revert the colors to the current preference settings. */
|
||||
color_t_to_gdkcolor(&color_info[MFG_IDX].color, &prefs.gui_marked_fg);
|
||||
color_t_to_gdkcolor(&color_info[MBG_IDX].color, &prefs.gui_marked_bg);
|
||||
gtk_widget_hide(GTK_WIDGET(data));
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
/* Treat this as a cancel, by calling "color_cancel_cb()".
|
||||
XXX - that'll destroy the Select Color dialog; will that upset
|
||||
a higher-level handler that says "OK, we've been asked to delete
|
||||
this, so destroy it"? */
|
||||
static gboolean
|
||||
color_delete_cb(GtkWidget *prefs_w _U_, gpointer dummy _U_)
|
||||
{
|
||||
color_cancel_cb(NULL, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
color_destroy_cb(GtkWidget *w, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *caller = gtk_object_get_data(GTK_OBJECT(w),
|
||||
COLOR_CALLER_PTR_KEY);
|
||||
if (caller != NULL) {
|
||||
gtk_object_set_data(GTK_OBJECT(caller), COLOR_DIALOG_PTR_KEY, NULL);
|
||||
}
|
||||
gtk_grab_remove(GTK_WIDGET(w));
|
||||
gtk_widget_destroy(GTK_WIDGET(w));
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_colors(void)
|
||||
{
|
||||
gdkcolor_to_color_t(&prefs.gui_marked_fg, &color_info[MFG_IDX].color);
|
||||
gdkcolor_to_color_t(&prefs.gui_marked_bg, &color_info[MBG_IDX].color);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* gui_prefs.h
|
||||
* Definitions for GUI preferences window
|
||||
*
|
||||
* $Id: gui_prefs.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GUI_PREFS_H__
|
||||
#define __GUI_PREFS_H__
|
||||
|
||||
GtkWidget *gui_prefs_show(void);
|
||||
void gui_prefs_fetch(GtkWidget *w);
|
||||
void gui_prefs_apply(GtkWidget *w);
|
||||
void gui_prefs_destroy(GtkWidget *w);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,397 @@
|
|||
/* help_dlg.c
|
||||
*
|
||||
* $Id: help_dlg.c,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Laurent Deniel <deniel@worldnet.fr>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 2000 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NEED_SNPRINTF_H
|
||||
# include "snprintf.h"
|
||||
#endif
|
||||
|
||||
#include "help_dlg.h"
|
||||
#include "prefs.h"
|
||||
#include "globals.h"
|
||||
#include "gtkglobals.h"
|
||||
#include "main.h"
|
||||
#include "ui_util.h"
|
||||
#include <epan/proto.h>
|
||||
|
||||
typedef enum {
|
||||
OVERVIEW_HELP,
|
||||
PROTOCOL_HELP,
|
||||
DFILTER_HELP,
|
||||
CFILTER_HELP
|
||||
} help_type_t;
|
||||
|
||||
static void help_close_cb(GtkWidget *w, gpointer data);
|
||||
static void help_destroy_cb(GtkWidget *w, gpointer data);
|
||||
static void insert_text(GtkWidget *w, char *buffer, int nchars);
|
||||
static void set_help_text(GtkWidget *w, help_type_t type);
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Help" window, if any, so that
|
||||
* if somebody tries to do "Help->Help" while there's already a
|
||||
* "Help" window up, we just pop up the existing one, rather than
|
||||
* creating a new one.
|
||||
*/
|
||||
static GtkWidget *help_w = NULL;
|
||||
|
||||
/*
|
||||
* Keep static pointers to the text widgets as well.
|
||||
*/
|
||||
GtkWidget *overview_text, *proto_text, *dfilter_text, *cfilter_text;
|
||||
|
||||
void help_cb(GtkWidget *w _U_, gpointer data _U_)
|
||||
{
|
||||
|
||||
GtkWidget *main_vb, *bbox, *help_nb, *close_bt, *label, *txt_scrollw,
|
||||
*overview_vb,
|
||||
*proto_vb,
|
||||
*dfilter_vb,
|
||||
*cfilter_vb;
|
||||
|
||||
if (help_w != NULL) {
|
||||
/* There's already a "Help" dialog box; reactivate it. */
|
||||
reactivate_window(help_w);
|
||||
return;
|
||||
}
|
||||
|
||||
help_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_widget_set_name(help_w, "Ethereal Help window" );
|
||||
gtk_window_set_title(GTK_WINDOW(help_w), "Ethereal: Help");
|
||||
g_signal_connect(G_OBJECT(help_w), "destroy",
|
||||
G_CALLBACK(help_destroy_cb), NULL);
|
||||
g_signal_connect(G_OBJECT(help_w), "realize",
|
||||
G_CALLBACK(window_icon_realize_cb), NULL);
|
||||
gtk_widget_set_size_request(GTK_WIDGET(help_w), DEF_WIDTH * 2/3,
|
||||
DEF_HEIGHT * 2/3);
|
||||
gtk_container_border_width(GTK_CONTAINER(help_w), 2);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
|
||||
main_vb = gtk_vbox_new(FALSE, 1);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 1);
|
||||
gtk_container_add(GTK_CONTAINER(help_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* help topics container */
|
||||
|
||||
help_nb = gtk_notebook_new();
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), help_nb);
|
||||
|
||||
/* Overview panel */
|
||||
|
||||
overview_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(overview_vb), 1);
|
||||
txt_scrollw = scrolled_window_new(NULL, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(overview_vb), txt_scrollw, TRUE, TRUE, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
overview_text = gtk_text_view_new();
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(overview_text), FALSE);
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(overview_text), GTK_WRAP_WORD);
|
||||
set_help_text(overview_text, OVERVIEW_HELP);
|
||||
gtk_container_add(GTK_CONTAINER(txt_scrollw), overview_text);
|
||||
gtk_widget_show(txt_scrollw);
|
||||
gtk_widget_show(overview_text);
|
||||
gtk_widget_show(overview_vb);
|
||||
label = gtk_label_new("Overview");
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(help_nb), overview_vb, label);
|
||||
|
||||
/* protocol list */
|
||||
|
||||
proto_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(proto_vb), 1);
|
||||
|
||||
txt_scrollw = scrolled_window_new(NULL, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(proto_vb), txt_scrollw, TRUE, TRUE, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
proto_text = gtk_text_view_new();
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(proto_text), FALSE);
|
||||
set_help_text(proto_text, PROTOCOL_HELP);
|
||||
gtk_container_add(GTK_CONTAINER(txt_scrollw), proto_text);
|
||||
gtk_widget_show(txt_scrollw);
|
||||
gtk_widget_show(proto_text);
|
||||
gtk_widget_show(proto_vb);
|
||||
label = gtk_label_new("Protocols");
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(help_nb), proto_vb, label);
|
||||
|
||||
/* display filter help */
|
||||
/* X windows have a maximum size of 32767. Since the height can easily
|
||||
exceed this, we have to jump through some hoops to have a functional
|
||||
vertical scroll bar. */
|
||||
|
||||
dfilter_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(dfilter_vb), 1);
|
||||
|
||||
txt_scrollw = scrolled_window_new(NULL, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(dfilter_vb), txt_scrollw, TRUE, TRUE, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
dfilter_text = gtk_text_view_new();
|
||||
if (prefs.gui_scrollbar_on_right) {
|
||||
gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_CORNER_TOP_LEFT);
|
||||
}
|
||||
else {
|
||||
gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_CORNER_TOP_RIGHT);
|
||||
}
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(dfilter_text), FALSE);
|
||||
set_help_text(dfilter_text, DFILTER_HELP);
|
||||
gtk_container_add(GTK_CONTAINER(txt_scrollw), dfilter_text);
|
||||
gtk_widget_show(txt_scrollw);
|
||||
gtk_widget_show(dfilter_text);
|
||||
gtk_widget_show(dfilter_vb);
|
||||
label = gtk_label_new("Display Filters");
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(help_nb), dfilter_vb, label);
|
||||
|
||||
/* capture filter help (this one has no horizontal scrollbar) */
|
||||
|
||||
cfilter_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(cfilter_vb), 1);
|
||||
txt_scrollw = scrolled_window_new(NULL, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(cfilter_vb), txt_scrollw, TRUE, TRUE, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scrollw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
cfilter_text = gtk_text_view_new();
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(cfilter_text), FALSE);
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(cfilter_text), GTK_WRAP_WORD);
|
||||
set_help_text(cfilter_text, CFILTER_HELP);
|
||||
gtk_container_add(GTK_CONTAINER(txt_scrollw), cfilter_text);
|
||||
gtk_widget_show(txt_scrollw);
|
||||
gtk_widget_show(cfilter_text);
|
||||
gtk_widget_show(cfilter_vb);
|
||||
label = gtk_label_new("Capture Filters");
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(help_nb), cfilter_vb, label);
|
||||
|
||||
/* XXX add other help panels here ... */
|
||||
|
||||
gtk_widget_show(help_nb);
|
||||
|
||||
/* Buttons (only one for now) */
|
||||
|
||||
bbox = gtk_hbox_new(FALSE, 1);
|
||||
gtk_box_pack_end(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show(bbox);
|
||||
close_bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
|
||||
g_signal_connect(G_OBJECT(close_bt), "clicked",
|
||||
G_CALLBACK(help_close_cb), GTK_OBJECT(help_w));
|
||||
GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT);
|
||||
gtk_container_add(GTK_CONTAINER(bbox), close_bt);
|
||||
gtk_widget_grab_default(close_bt);
|
||||
gtk_widget_show(close_bt);
|
||||
|
||||
gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(help_w));
|
||||
gtk_widget_show(help_w);
|
||||
|
||||
} /* help_cb */
|
||||
|
||||
static void help_close_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void help_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
|
||||
{
|
||||
/* Note that we no longer have a Help window. */
|
||||
help_w = NULL;
|
||||
}
|
||||
|
||||
static void insert_text(GtkWidget *w, char *buffer, int nchars)
|
||||
{
|
||||
GtkTextBuffer *buf= gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
|
||||
GtkTextIter iter;
|
||||
|
||||
gtk_text_buffer_get_end_iter(buf, &iter);
|
||||
gtk_widget_modify_font(w, m_r_font);
|
||||
if (!g_utf8_validate(buffer, -1, NULL))
|
||||
printf(buffer);
|
||||
gtk_text_buffer_insert(buf, &iter, buffer, nchars);
|
||||
}
|
||||
|
||||
static char *proto_help =
|
||||
"The protocols (and packet types) currently supported by\n"
|
||||
"Ethereal are the following:\n\n";
|
||||
|
||||
static char *dfilter_help =
|
||||
"The following list shows all per-protocol fields that\n"
|
||||
"can be used in a display filter:\n";
|
||||
|
||||
static char *cfilter_help =
|
||||
"Packet capturing is performed with the pcap library. The capture filter "
|
||||
"syntax follows the rules of this library.\nSo this syntax is different "
|
||||
"from the display filter syntax: see manual page of tcpdump.\n"
|
||||
#ifndef HAVE_LIBPCAP
|
||||
"\nNote: packet capturing is not enabled in this version.\n";
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
static char *overview_help =
|
||||
"Ethereal is a GUI network protocol analyzer. It lets you interactively "
|
||||
"browse packet data from a live network or from a previously saved capture "
|
||||
"file.\n\nEthereal knows how to read libpcap capture files, including those "
|
||||
"of tcpdump. In addition, Ethereal can read capture files from snoop "
|
||||
"(including Shomiti) and atmsnoop, LanAlyzer, Sniffer (compressed or "
|
||||
"uncompressed), Microsoft Network Monitor, AIX's iptrace, NetXray, "
|
||||
"Sniffer Pro, RADCOM's WAN/LAN analyzer, Lucent/Ascend router debug output, "
|
||||
"HP-UX's nettl, the dump output from Toshiba's ISDN routers, the output from "
|
||||
"i4btrace from the ISDN4BSD project, and output in IPLog format from the "
|
||||
"Cisco Secure Intrusion Detection System.\n\n"
|
||||
"There is no need to tell Ethereal what type of file you are reading; it will "
|
||||
"determine the file type by itself. Ethereal is also capable of reading any "
|
||||
"of these file formats if they are compressed using gzip. Ethereal recognizes "
|
||||
"this directly from the file; the '.gz' extension is not required for this "
|
||||
"purpose.";
|
||||
|
||||
static void set_help_text(GtkWidget *w, help_type_t type)
|
||||
{
|
||||
|
||||
#define BUFF_LEN 4096
|
||||
#define B_LEN 256
|
||||
char buffer[BUFF_LEN];
|
||||
header_field_info *hfinfo;
|
||||
int i, len, maxlen = 0, maxlen2 = 0;
|
||||
const char *type_name;
|
||||
char blanks[B_LEN];
|
||||
int blks;
|
||||
void *cookie;
|
||||
|
||||
memset(blanks, ' ', B_LEN - 1);
|
||||
blanks[B_LEN-1] = '\0';
|
||||
|
||||
switch(type) {
|
||||
|
||||
case OVERVIEW_HELP :
|
||||
insert_text(w, overview_help, -1);
|
||||
break;
|
||||
|
||||
case PROTOCOL_HELP :
|
||||
/* first pass to know the maximum length of first field */
|
||||
for (i = proto_get_first_protocol(&cookie); i != -1;
|
||||
i = proto_get_next_protocol(&cookie)) {
|
||||
hfinfo = proto_registrar_get_nth(i);
|
||||
if ((len = strlen(hfinfo->abbrev)) > maxlen)
|
||||
maxlen = len;
|
||||
}
|
||||
maxlen++;
|
||||
|
||||
insert_text(w, proto_help, strlen(proto_help));
|
||||
|
||||
/* ok, display the correctly aligned strings */
|
||||
for (i = proto_get_first_protocol(&cookie); i != -1;
|
||||
i = proto_get_next_protocol(&cookie)) {
|
||||
hfinfo = proto_registrar_get_nth(i);
|
||||
blks = maxlen - strlen(hfinfo->abbrev);
|
||||
snprintf(buffer, BUFF_LEN, "%s%s%s\n",
|
||||
hfinfo->abbrev,
|
||||
&blanks[B_LEN - blks - 2],
|
||||
hfinfo->name);
|
||||
insert_text(w, buffer, strlen(buffer));
|
||||
}
|
||||
break;
|
||||
|
||||
case DFILTER_HELP :
|
||||
|
||||
/* XXX we should display hinfo->blurb instead of name (if not empty) */
|
||||
|
||||
/* first pass to know the maximum length of first and second fields */
|
||||
for (i = 0; i < proto_registrar_n() ; i++) {
|
||||
if (!proto_registrar_is_protocol(i)) {
|
||||
hfinfo = proto_registrar_get_nth(i);
|
||||
if ((len = strlen(hfinfo->abbrev)) > maxlen)
|
||||
maxlen = len;
|
||||
if ((len = strlen(hfinfo->name)) > maxlen2)
|
||||
maxlen2 = len;
|
||||
}
|
||||
}
|
||||
maxlen++;
|
||||
maxlen2++;
|
||||
|
||||
insert_text(w, dfilter_help, strlen(dfilter_help));
|
||||
|
||||
for (i = 0; i < proto_registrar_n() ; i++) {
|
||||
hfinfo = proto_registrar_get_nth(i);
|
||||
if (proto_registrar_is_protocol(i)) {
|
||||
snprintf(buffer, BUFF_LEN, "\n%s:\n", hfinfo->name);
|
||||
insert_text(w, buffer, strlen(buffer));
|
||||
} else {
|
||||
|
||||
type_name = ftype_pretty_name(hfinfo->type);
|
||||
snprintf(buffer, BUFF_LEN, "%s%s%s%s(%s)\n",
|
||||
hfinfo->abbrev,
|
||||
&blanks[B_LEN - (maxlen - strlen(hfinfo->abbrev)) - 2],
|
||||
hfinfo->name,
|
||||
&blanks[B_LEN - (maxlen2 - strlen(hfinfo->name)) - 2],
|
||||
type_name);
|
||||
insert_text(w, buffer, strlen(buffer));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CFILTER_HELP :
|
||||
insert_text(w, cfilter_help, -1);
|
||||
break;
|
||||
default :
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
} /* switch(type) */
|
||||
} /* set_help_text */
|
||||
|
||||
static void clear_help_text(GtkWidget *w)
|
||||
{
|
||||
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
|
||||
|
||||
gtk_text_buffer_set_text(buf, "", 0);
|
||||
}
|
||||
|
||||
/* Redraw all the text widgets, to use a new font. */
|
||||
void help_redraw(void)
|
||||
{
|
||||
if (help_w != NULL) {
|
||||
clear_help_text(overview_text);
|
||||
set_help_text(overview_text, OVERVIEW_HELP);
|
||||
|
||||
clear_help_text(proto_text);
|
||||
set_help_text(proto_text, PROTOCOL_HELP);
|
||||
|
||||
clear_help_text(dfilter_text);
|
||||
set_help_text(dfilter_text, DFILTER_HELP);
|
||||
|
||||
clear_help_text(cfilter_text);
|
||||
set_help_text(cfilter_text, CFILTER_HELP);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* help_dlg.h
|
||||
*
|
||||
* $Id: help_dlg.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Laurent Deniel <deniel@worldnet.fr>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* Copyright 2000 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HELP_DLG_H__
|
||||
#define __HELP_DLG_H__
|
||||
|
||||
void help_cb(GtkWidget *, gpointer);
|
||||
|
||||
/* Redraw all the text widgets, to use a new font. */
|
||||
void help_redraw(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,48 @@
|
|||
/* keys.h
|
||||
* Key definitions for various objects
|
||||
*
|
||||
* $Id: keys.h,v 1.1 2002/08/31 09:55:21 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __KEYS_H__
|
||||
#define __KEYS_H__
|
||||
|
||||
/* Keys for gtk_object_set_data */
|
||||
|
||||
#define E_DFILTER_TE_KEY "display_filter_entry"
|
||||
#define E_RFILTER_TE_KEY "read_filter_te"
|
||||
#define E_MPACKET_LIST_KEY "menu_packet_list"
|
||||
#define E_MPACKET_LIST_ROW_KEY "menu_packet_list_row"
|
||||
#define E_MPACKET_LIST_COL_KEY "menu_packet_list_col"
|
||||
|
||||
#define PRINT_CMD_LB_KEY "printer_command_label"
|
||||
#define PRINT_CMD_TE_KEY "printer_command_entry"
|
||||
#define PRINT_FILE_BT_KEY "printer_file_button"
|
||||
#define PRINT_FILE_TE_KEY "printer_file_entry"
|
||||
|
||||
#define PLUGINS_DFILTER_TE "plugins_dfilter_te"
|
||||
|
||||
#define PM_MENU_LIST_KEY "popup_menu_menu_list"
|
||||
#define PM_PACKET_LIST_KEY "popup_menu_packet_list"
|
||||
#define PM_TREE_VIEW_KEY "popup_menu_tree_view"
|
||||
#define PM_HEXDUMP_KEY "popup_menu_hexdump"
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,102 @@
|
|||
/* main.h
|
||||
* Global defines, etc.
|
||||
*
|
||||
* $Id: main.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MAIN_H__
|
||||
#define __MAIN_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
/*
|
||||
* File under personal preferences directory in which GTK settings for
|
||||
* Ethereal are stored.
|
||||
*/
|
||||
#define RC_FILE "gtkrc"
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
#define DEF_READY_MESSAGE " Ready to load or capture"
|
||||
#else
|
||||
#define DEF_READY_MESSAGE " Ready to load file"
|
||||
#endif
|
||||
|
||||
#define MATCH_SELECTED_REPLACE 0
|
||||
#define MATCH_SELECTED_AND 1
|
||||
#define MATCH_SELECTED_OR 2
|
||||
#define MATCH_SELECTED_NOT 3
|
||||
#define MATCH_SELECTED_AND_NOT 4
|
||||
#define MATCH_SELECTED_OR_NOT 5
|
||||
|
||||
#define MATCH_SELECTED_MASK 0x0ff
|
||||
#define MATCH_SELECTED_APPLY_NOW 0x100
|
||||
|
||||
typedef struct _selection_info {
|
||||
GtkWidget *tree;
|
||||
GtkWidget *text;
|
||||
} selection_info;
|
||||
|
||||
void about_ethereal( GtkWidget *, gpointer);
|
||||
void match_selected_cb_replace_ptree( GtkWidget *, gpointer);
|
||||
void match_selected_cb_and_ptree( GtkWidget *, gpointer);
|
||||
void match_selected_cb_or_ptree( GtkWidget *, gpointer);
|
||||
void match_selected_cb_not_ptree( GtkWidget *, gpointer);
|
||||
void match_selected_cb_and_ptree_not( GtkWidget *, gpointer);
|
||||
void match_selected_cb_or_ptree_not( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_replace_ptree( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_and_ptree( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_or_ptree( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_not_ptree( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_and_ptree_not( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_or_ptree_not( GtkWidget *, gpointer);
|
||||
void match_selected_cb_replace_plist( GtkWidget *, gpointer);
|
||||
void match_selected_cb_and_plist( GtkWidget *, gpointer);
|
||||
void match_selected_cb_or_plist( GtkWidget *, gpointer);
|
||||
void match_selected_cb_not_plist( GtkWidget *, gpointer);
|
||||
void match_selected_cb_and_plist_not( GtkWidget *, gpointer);
|
||||
void match_selected_cb_or_plist_not( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_replace_plist( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_and_plist( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_or_plist( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_not_plist( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_and_plist_not( GtkWidget *, gpointer);
|
||||
void prepare_selected_cb_or_plist_not( GtkWidget *, gpointer);
|
||||
void file_quit_cmd_cb(GtkWidget *, gpointer);
|
||||
void file_print_cmd_cb(GtkWidget *, gpointer);
|
||||
void file_print_packet_cmd_cb(GtkWidget *, gpointer);
|
||||
void tools_plugins_cmd_cb(GtkWidget *, gpointer);
|
||||
void expand_all_cb(GtkWidget *, gpointer);
|
||||
void collapse_all_cb(GtkWidget *, gpointer);
|
||||
void resolve_name_cb(GtkWidget *, gpointer);
|
||||
void mark_frame_cb(GtkWidget *, gpointer);
|
||||
void mark_all_frames_cb(GtkWidget *w, gpointer);
|
||||
void unmark_all_frames_cb(GtkWidget *w, gpointer);
|
||||
void update_marked_frames(void);
|
||||
|
||||
char *boldify(const char *);
|
||||
void set_fonts(PangoFontDescription *regular, PangoFontDescription *bold);
|
||||
void set_last_open_dir(char *dirname);
|
||||
|
||||
#endif /* __MAIN_H__ */
|
|
@ -0,0 +1,527 @@
|
|||
/* menu.c
|
||||
* Menu routines
|
||||
*
|
||||
* $Id: menu.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../menu.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "menu.h"
|
||||
#include <epan/packet.h>
|
||||
#include <epan/resolv.h>
|
||||
#include "prefs.h"
|
||||
#include "capture_dlg.h"
|
||||
#include "color_dlg.h"
|
||||
#include "file_dlg.h"
|
||||
#include "filter_prefs.h"
|
||||
#include "find_dlg.h"
|
||||
#include "goto_dlg.h"
|
||||
#include "summary_dlg.h"
|
||||
#include "display_opts.h"
|
||||
#include "prefs_dlg.h"
|
||||
#include "packet_win.h"
|
||||
#include "print.h"
|
||||
#include "follow_dlg.h"
|
||||
#include "decode_as_dlg.h"
|
||||
#include "help_dlg.h"
|
||||
#include "proto_dlg.h"
|
||||
#include "proto_hier_stats_dlg.h"
|
||||
#include "keys.h"
|
||||
#include <epan/plugins.h>
|
||||
#include "tcp_graph.h"
|
||||
#include <epan/epan_dissect.h>
|
||||
|
||||
GtkWidget *popup_menu_object;
|
||||
|
||||
#define GTK_MENU_FUNC(a) ((GtkItemFactoryCallback)(a))
|
||||
|
||||
static void menus_init(void);
|
||||
static void set_menu_sensitivity (gchar *, gint);
|
||||
|
||||
/* This is the GtkItemFactoryEntry structure used to generate new menus.
|
||||
Item 1: The menu path. The letter after the underscore indicates an
|
||||
accelerator key once the menu is open.
|
||||
Item 2: The accelerator key for the entry
|
||||
Item 3: The callback function.
|
||||
Item 4: The callback action. This changes the parameters with
|
||||
which the function is called. The default is 0.
|
||||
Item 5: The item type, used to define what kind of an item it is.
|
||||
Here are the possible values:
|
||||
|
||||
NULL -> "<Item>"
|
||||
"" -> "<Item>"
|
||||
"<Title>" -> create a title item
|
||||
"<Item>" -> create a simple item
|
||||
"<CheckItem>" -> create a check item
|
||||
"<ToggleItem>" -> create a toggle item
|
||||
"<RadioItem>" -> create a radio item
|
||||
<path> -> path of a radio item to link against
|
||||
"<Separator>" -> create a separator
|
||||
"<Branch>" -> create an item to hold sub items (optional)
|
||||
"<LastBranch>" -> create a right justified branch
|
||||
*/
|
||||
|
||||
/* main menu */
|
||||
static GtkItemFactoryEntry menu_items[] =
|
||||
{
|
||||
{"/_File", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/File/_Open...", "<control>O", GTK_MENU_FUNC(file_open_cmd_cb), 0, "<StockItem>", GTK_STOCK_OPEN },
|
||||
{"/File/_Close", "<control>W", GTK_MENU_FUNC(file_close_cmd_cb), 0, "<StockItem>", GTK_STOCK_CLOSE },
|
||||
{"/File/_Save", "<control>S", GTK_MENU_FUNC(file_save_cmd_cb), 0, "<StockItem>", GTK_STOCK_SAVE },
|
||||
{"/File/Save _As...", NULL, GTK_MENU_FUNC(file_save_as_cmd_cb), 0, "<StockItem>", GTK_STOCK_SAVE_AS },
|
||||
{"/File/_Reload", "<control>R", GTK_MENU_FUNC(file_reload_cmd_cb), 0, "<StockItem>", GTK_STOCK_REFRESH },
|
||||
{"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/File/_Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, "<StockItem>", GTK_STOCK_PRINT },
|
||||
{"/File/Print Pac_ket", "<control>P", GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL, NULL },
|
||||
{"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/File/_Quit", "<control>Q", GTK_MENU_FUNC(file_quit_cmd_cb), 0, "<StockItem>", GTK_STOCK_QUIT },
|
||||
{"/_Edit", NULL, NULL, 0, "<Branch>", NULL },
|
||||
#if 0
|
||||
/* Un-#if this when we actually implement Cut/Copy/Paste. */
|
||||
{"/Edit/Cut", "<control>X", NULL, 0, NULL},
|
||||
{"/Edit/Copy", "<control>C", NULL, 0, NULL},
|
||||
{"/Edit/Paste", "<control>V", NULL, 0, NULL},
|
||||
{"/Edit/<separator>", NULL, NULL, 0, "<Separator>"},
|
||||
#endif
|
||||
{"/Edit/_Find Frame...", "<control>F", GTK_MENU_FUNC(find_frame_cb), 0, "<StockItem>", GTK_STOCK_FIND },
|
||||
{"/Edit/Find _Next", "<control>N", GTK_MENU_FUNC(find_next_cb), 0, "<StockItem>", GTK_STOCK_GO_FORWARD},
|
||||
{"/Edit/Find _Previous", "<control>B", GTK_MENU_FUNC(find_previous_cb), 0, "<StockItem>", GTK_STOCK_GO_BACK},
|
||||
{"/Edit/_Go To Frame...", "<control>G", GTK_MENU_FUNC(goto_frame_cb), 0, "<StockItem>", GTK_STOCK_JUMP_TO },
|
||||
{"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Edit/_Mark Frame", "<control>M", GTK_MENU_FUNC(mark_frame_cb), 0, NULL, NULL },
|
||||
{"/Edit/Mark _All Frames", NULL, GTK_MENU_FUNC(mark_all_frames_cb), 0, NULL, NULL },
|
||||
{"/Edit/_Unmark All Frames", NULL, GTK_MENU_FUNC(unmark_all_frames_cb), 0, NULL, NULL },
|
||||
{"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Edit/_Preferences...", NULL, GTK_MENU_FUNC(prefs_cb), 0, "<StockItem>", GTK_STOCK_PREFERENCES },
|
||||
#ifdef HAVE_LIBPCAP
|
||||
{"/Edit/_Capture Filters...", NULL, GTK_MENU_FUNC(cfilter_dialog_cb), 0, NULL, NULL },
|
||||
#endif
|
||||
{"/Edit/_Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL, NULL },
|
||||
{"/Edit/P_rotocols...", NULL, GTK_MENU_FUNC(proto_cb), 0, NULL, NULL },
|
||||
#ifdef HAVE_LIBPCAP
|
||||
{"/_Capture", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Capture/_Start...", "<control>K", GTK_MENU_FUNC(capture_prep_cb), 0, "<StockItem>", GTK_STOCK_EXECUTE },
|
||||
/*
|
||||
* XXX - this doesn't yet work in Win32.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
{"/Capture/S_top", "<control>E", GTK_MENU_FUNC(capture_stop_cb), 0, "<StockItem>", GTK_STOCK_STOP },
|
||||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
{"/_Display", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Display/_Options...", NULL, GTK_MENU_FUNC(display_opt_cb), 0, NULL, NULL },
|
||||
{"/Display/_Match", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Display/Match/_Selected", NULL, GTK_MENU_FUNC(match_selected_cb_replace_ptree), 0, NULL, NULL },
|
||||
{"/Display/Match/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_not_ptree), 0, NULL, NULL },
|
||||
{"/Display/Match/_And Selected", NULL, GTK_MENU_FUNC(match_selected_cb_and_ptree), 0, NULL, NULL },
|
||||
{"/Display/Match/_Or Selected", NULL, GTK_MENU_FUNC(match_selected_cb_or_ptree), 0, NULL, NULL },
|
||||
{"/Display/Match/A_nd Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_and_ptree_not), 0, NULL, NULL },
|
||||
{"/Display/Match/O_r Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_or_ptree_not), 0, NULL, NULL },
|
||||
{"/Display/_Prepare", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Display/Prepare/_Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_replace_ptree), 0, NULL, NULL },
|
||||
{"/Display/Prepare/_Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_not_ptree), 0, NULL, NULL },
|
||||
{"/Display/Prepare/_And Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_and_ptree), 0, NULL, NULL },
|
||||
{"/Display/Prepare/_Or Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_or_ptree), 0, NULL, NULL },
|
||||
{"/Display/Prepare/A_nd Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_and_ptree_not), 0, NULL, NULL },
|
||||
{"/Display/Prepare/O_r Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_or_ptree_not), 0, NULL, NULL },
|
||||
{"/Display/_Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL, NULL },
|
||||
{"/Display/Collapse _All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL, NULL },
|
||||
{"/Display/_Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL, NULL },
|
||||
{"/Display/_Show Packet In New Window", NULL, GTK_MENU_FUNC(new_window_cb), 0, NULL, NULL },
|
||||
{"/Display/User Specified Decodes...", NULL, GTK_MENU_FUNC(decode_show_cb), 0, NULL, NULL },
|
||||
{"/_Tools", NULL, NULL, 0, "<Branch>", NULL },
|
||||
#ifdef HAVE_PLUGINS
|
||||
{"/Tools/_Plugins...", NULL, GTK_MENU_FUNC(tools_plugins_cmd_cb), 0, NULL, NULL },
|
||||
#endif
|
||||
{"/Tools/_Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL, NULL },
|
||||
{"/Tools/_Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL, NULL },
|
||||
/* {"/Tools/Graph", NULL, NULL, 0, NULL}, future use */
|
||||
{"/_Tools/TCP Stream Analysis", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/_Tools/TCP Stream Analysis/Time-Sequence Graph (Stevens)", NULL, GTK_MENU_FUNC (tcp_graph_cb), 0, NULL, NULL },
|
||||
{"/_Tools/TCP Stream Analysis/Time-Sequence Graph (tcptrace)", NULL, GTK_MENU_FUNC (tcp_graph_cb), 1, NULL, NULL },
|
||||
{"/_Tools/TCP Stream Analysis/Throughput Graph", NULL, GTK_MENU_FUNC (tcp_graph_cb), 2, NULL, NULL },
|
||||
{"/_Tools/TCP Stream Analysis/RTT Graph", NULL, GTK_MENU_FUNC (tcp_graph_cb), 3, NULL, NULL },
|
||||
{"/Tools/_Summary", NULL, GTK_MENU_FUNC(summary_open_cb), 0, NULL, NULL },
|
||||
{"/Tools/Protocol Hierarchy Statistics", NULL, GTK_MENU_FUNC(proto_hier_stats_cb), 0, NULL, NULL },
|
||||
{"/_Help", NULL, NULL, 0, "<LastBranch>", NULL },
|
||||
{"/Help/_Help", NULL, GTK_MENU_FUNC(help_cb), 0, "<StockItem>", GTK_STOCK_HELP },
|
||||
{"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Help/_About Ethereal...", NULL, GTK_MENU_FUNC(about_ethereal), 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/* calculate the number of menu_items */
|
||||
static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
|
||||
|
||||
/* packet list popup */
|
||||
static GtkItemFactoryEntry packet_list_menu_items[] =
|
||||
{
|
||||
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL, NULL },
|
||||
{"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL, NULL },
|
||||
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL, NULL },
|
||||
{"/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Mark Frame", NULL, GTK_MENU_FUNC(mark_frame_cb), 0, NULL, NULL },
|
||||
{"/Match", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Match/_Selected", NULL, GTK_MENU_FUNC(match_selected_cb_replace_plist), 0, NULL, NULL },
|
||||
{"/Match/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_not_plist), 0, NULL, NULL },
|
||||
{"/Match/_And Selected", NULL, GTK_MENU_FUNC(match_selected_cb_and_plist), 0, NULL, NULL },
|
||||
{"/Match/_Or Selected", NULL, GTK_MENU_FUNC(match_selected_cb_or_plist), 0, NULL, NULL },
|
||||
{"/Match/A_nd Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_and_plist_not), 0, NULL, NULL },
|
||||
{"/Match/O_r Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_or_plist_not), 0, NULL, NULL },
|
||||
{"/Prepare", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Prepare/_Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_replace_plist), 0, NULL, NULL },
|
||||
{"/Prepare/_Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_not_plist), 0, NULL, NULL },
|
||||
{"/Prepare/_And Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_and_plist), 0, NULL, NULL },
|
||||
{"/Prepare/_Or Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_or_plist), 0, NULL, NULL },
|
||||
{"/Prepare/A_nd Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_and_plist_not), 0, NULL, NULL },
|
||||
{"/Prepare/O_r Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_or_plist_not), 0, NULL, NULL },
|
||||
{"/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL, NULL },
|
||||
{"/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL, NULL },
|
||||
{"/Print Packet", NULL, GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL, NULL },
|
||||
{"/Show Packet In New Window", NULL, GTK_MENU_FUNC(new_window_cb), 0, NULL, NULL },
|
||||
};
|
||||
|
||||
static GtkItemFactoryEntry tree_view_menu_items[] =
|
||||
{
|
||||
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL, NULL },
|
||||
{"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL, NULL },
|
||||
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL, NULL },
|
||||
{"/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Resolve Name", NULL, GTK_MENU_FUNC(resolve_name_cb), 0, NULL, NULL },
|
||||
{"/Protocol Properties...", NULL, GTK_MENU_FUNC(properties_cb), 0, NULL, NULL },
|
||||
{"/Match", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Match/_Selected", NULL, GTK_MENU_FUNC(match_selected_cb_replace_ptree), 0, NULL, NULL },
|
||||
{"/Match/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_not_ptree), 0, NULL, NULL },
|
||||
{"/Match/_And Selected", NULL, GTK_MENU_FUNC(match_selected_cb_and_ptree), 0, NULL, NULL },
|
||||
{"/Match/_Or Selected", NULL, GTK_MENU_FUNC(match_selected_cb_or_ptree), 0, NULL, NULL },
|
||||
{"/Match/A_nd Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_and_ptree_not), 0, NULL, NULL },
|
||||
{"/Match/O_r Not Selected", NULL, GTK_MENU_FUNC(match_selected_cb_or_ptree_not), 0, NULL, NULL },
|
||||
{"/Prepare", NULL, NULL, 0, "<Branch>", NULL },
|
||||
{"/Prepare/_Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_replace_ptree), 0, NULL, NULL },
|
||||
{"/Prepare/_Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_not_ptree), 0, NULL, NULL },
|
||||
{"/Prepare/_And Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_and_ptree), 0, NULL, NULL },
|
||||
{"/Prepare/_Or Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_or_ptree), 0, NULL, NULL },
|
||||
{"/Prepare/A_nd Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_and_ptree_not), 0, NULL, NULL },
|
||||
{"/Prepare/O_r Not Selected", NULL, GTK_MENU_FUNC(prepare_selected_cb_or_ptree_not), 0, NULL, NULL },
|
||||
{"/<separator>", NULL, NULL, 0, "<Separator>", NULL },
|
||||
{"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL, NULL },
|
||||
{"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static GtkItemFactoryEntry hexdump_menu_items[] =
|
||||
{
|
||||
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL, NULL },
|
||||
{"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL, NULL },
|
||||
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static int initialize = TRUE;
|
||||
static GtkItemFactory *factory = NULL;
|
||||
static GtkItemFactory *packet_list_menu_factory = NULL;
|
||||
static GtkItemFactory *tree_view_menu_factory = NULL;
|
||||
static GtkItemFactory *hexdump_menu_factory = NULL;
|
||||
|
||||
static GSList *popup_menu_list = NULL;
|
||||
|
||||
static GtkAccelGroup *grp;
|
||||
|
||||
void
|
||||
get_main_menu(GtkWidget ** menubar, GtkAccelGroup ** table) {
|
||||
|
||||
grp = gtk_accel_group_new();
|
||||
|
||||
if (initialize) {
|
||||
popup_menu_object = gtk_widget_new(GTK_TYPE_WIDGET, NULL);
|
||||
menus_init();
|
||||
}
|
||||
|
||||
if (menubar)
|
||||
*menubar = factory->widget;
|
||||
|
||||
if (table)
|
||||
*table = grp;
|
||||
}
|
||||
|
||||
static void
|
||||
menus_init(void) {
|
||||
|
||||
if (initialize) {
|
||||
initialize = FALSE;
|
||||
|
||||
/* popup */
|
||||
|
||||
packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
|
||||
gtk_item_factory_create_items_ac(packet_list_menu_factory, sizeof(packet_list_menu_items)/sizeof(packet_list_menu_items[0]), packet_list_menu_items, popup_menu_object, 2);
|
||||
gtk_object_set_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY, packet_list_menu_factory->widget);
|
||||
popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
|
||||
|
||||
tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
|
||||
gtk_item_factory_create_items_ac(tree_view_menu_factory, sizeof(tree_view_menu_items)/sizeof(tree_view_menu_items[0]), tree_view_menu_items, popup_menu_object, 2);
|
||||
gtk_object_set_data(GTK_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY, tree_view_menu_factory->widget);
|
||||
popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
|
||||
|
||||
hexdump_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
|
||||
gtk_item_factory_create_items_ac(hexdump_menu_factory, sizeof(hexdump_menu_items)/sizeof(hexdump_menu_items[0]), hexdump_menu_items, popup_menu_object, 2);
|
||||
gtk_object_set_data(GTK_OBJECT(popup_menu_object), PM_HEXDUMP_KEY, hexdump_menu_factory->widget);
|
||||
popup_menu_list = g_slist_append((GSList *)popup_menu_list, hexdump_menu_factory);
|
||||
|
||||
factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
|
||||
gtk_item_factory_create_items_ac(factory, nmenu_items, menu_items, NULL,2);
|
||||
set_menus_for_unsaved_capture_file(FALSE);
|
||||
set_menus_for_capture_file(FALSE);
|
||||
#if 0
|
||||
/* Un-#if this when we actually implement Cut/Copy/Paste.
|
||||
Then make sure you enable them when they can be done. */
|
||||
set_menu_sensitivity("/Edit/Cut", FALSE);
|
||||
set_menu_sensitivity("/Edit/Copy", FALSE);
|
||||
set_menu_sensitivity("/Edit/Paste", FALSE);
|
||||
#endif
|
||||
set_menus_for_captured_packets(FALSE);
|
||||
set_menus_for_selected_packet(FALSE);
|
||||
set_menus_for_selected_tree_row(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_menu_sensitivity_meat(GtkItemFactory *ifactory, gchar *path, gint val) {
|
||||
GtkWidget *menu = NULL;
|
||||
|
||||
if((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL) {
|
||||
gtk_widget_set_sensitive(menu,val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable/disable menu sensitivity */
|
||||
/* /menu/path - old functionality */
|
||||
/* <MenuName>/menu/path - new functionality */
|
||||
/* MenuName: <Main>, <PacketList>, <TreeView>, <HexDump> */
|
||||
static void
|
||||
set_menu_sensitivity (gchar *path, gint val) {
|
||||
GSList *menu_list = popup_menu_list;
|
||||
gchar *prefix;
|
||||
gchar *shortpath;
|
||||
|
||||
if ('<' == *path) {
|
||||
/* New functionality => selective enable/disable per menu */
|
||||
prefix=strchr(path, '/');
|
||||
shortpath=strrchr(prefix, '/');
|
||||
|
||||
if (0 == strncmp(path, "<Main>", 6))
|
||||
set_menu_sensitivity_meat(factory, prefix, val);
|
||||
else if (0 == strncmp(path, "<PacketList>", 12))
|
||||
set_menu_sensitivity_meat(packet_list_menu_factory, shortpath, val);
|
||||
else if (0 == strncmp(path, "<TreeView>", 10))
|
||||
set_menu_sensitivity_meat(tree_view_menu_factory, shortpath, val);
|
||||
else if (0 == strncmp(path, "<HexDump>", 9))
|
||||
set_menu_sensitivity_meat(hexdump_menu_factory, shortpath, val);
|
||||
} else {
|
||||
/* Old functionality => enable/disable all menus with same shortpath */
|
||||
shortpath = strrchr(path, '/');
|
||||
|
||||
set_menu_sensitivity_meat(factory, path, val);
|
||||
|
||||
while (menu_list != NULL) {
|
||||
set_menu_sensitivity_meat(menu_list->data, shortpath, val);
|
||||
menu_list = g_slist_next(menu_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_menu_object_data_meat(GtkItemFactory *ifactory, gchar *path, gchar *key, gpointer data)
|
||||
{
|
||||
GtkWidget *menu = NULL;
|
||||
|
||||
if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
|
||||
gtk_object_set_data(GTK_OBJECT(menu), key, data);
|
||||
}
|
||||
|
||||
void
|
||||
set_menu_object_data (gchar *path, gchar *key, gpointer data) {
|
||||
GSList *menu_list = popup_menu_list;
|
||||
gchar *shortpath = strrchr(path, '/');
|
||||
|
||||
set_menu_object_data_meat(factory, path, key, data);
|
||||
while (menu_list != NULL) {
|
||||
set_menu_object_data_meat(menu_list->data, shortpath, key, data);
|
||||
menu_list = g_slist_next(menu_list);
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
|
||||
{
|
||||
GtkWidget *menu = NULL;
|
||||
GdkEventButton *event_button = NULL;
|
||||
GtkCList *packet_list = NULL;
|
||||
gint row, column;
|
||||
|
||||
if(widget == NULL || event == NULL || data == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we ever want to make the menu differ based on what row
|
||||
* and/or column we're above, we'd use "gtk_clist_get_selection_info()"
|
||||
* to find the row and column number for the coordinates; a CTree is,
|
||||
* I guess, like a CList with one column(?) and the expander widget
|
||||
* as a pixmap.
|
||||
*/
|
||||
/* Check if we are on packet_list object */
|
||||
if (widget == gtk_object_get_data(GTK_OBJECT(popup_menu_object),
|
||||
E_MPACKET_LIST_KEY)) {
|
||||
packet_list=GTK_CLIST(widget);
|
||||
if (gtk_clist_get_selection_info(GTK_CLIST(packet_list),
|
||||
((GdkEventButton *)event)->x,
|
||||
((GdkEventButton *)event)->y,&row,&column)) {
|
||||
gtk_object_set_data(GTK_OBJECT(popup_menu_object),
|
||||
E_MPACKET_LIST_ROW_KEY, (gpointer *)row);
|
||||
gtk_object_set_data(GTK_OBJECT(popup_menu_object),
|
||||
E_MPACKET_LIST_COL_KEY, (gpointer *)column);
|
||||
}
|
||||
}
|
||||
menu = (GtkWidget *)data;
|
||||
if(event->type == GDK_BUTTON_PRESS) {
|
||||
event_button = (GdkEventButton *) event;
|
||||
|
||||
if(event_button->button == 3) {
|
||||
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event_button->button, event_button->time);
|
||||
gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "button_press_event");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Enable or disable menu items based on whether you have a capture file
|
||||
you've finished reading. */
|
||||
void
|
||||
set_menus_for_capture_file(gboolean have_capture_file)
|
||||
{
|
||||
set_menu_sensitivity("/File/Open...", have_capture_file);
|
||||
set_menu_sensitivity("/File/Save As...", have_capture_file);
|
||||
set_menu_sensitivity("/File/Close", have_capture_file);
|
||||
set_menu_sensitivity("/File/Reload", have_capture_file);
|
||||
}
|
||||
|
||||
/* Enable or disable menu items based on whether you have an unsaved
|
||||
capture file you've finished reading. */
|
||||
void
|
||||
set_menus_for_unsaved_capture_file(gboolean have_unsaved_capture_file)
|
||||
{
|
||||
set_menu_sensitivity("/File/Save", have_unsaved_capture_file);
|
||||
}
|
||||
|
||||
/* Enable or disable menu items based on whether there's a capture in
|
||||
progress. */
|
||||
void
|
||||
set_menus_for_capture_in_progress(gboolean capture_in_progress)
|
||||
{
|
||||
set_menu_sensitivity("/File/Open...", !capture_in_progress);
|
||||
set_menu_sensitivity("/Capture/Start...", !capture_in_progress);
|
||||
/*
|
||||
* XXX - this doesn't yet work in Win32.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
set_menu_sensitivity("/Capture/Stop", capture_in_progress);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Enable or disable menu items based on whether you have some captured
|
||||
packets. */
|
||||
void
|
||||
set_menus_for_captured_packets(gboolean have_captured_packets)
|
||||
{
|
||||
set_menu_sensitivity("/File/Print...", have_captured_packets);
|
||||
set_menu_sensitivity("/Edit/Find Frame...", have_captured_packets);
|
||||
set_menu_sensitivity("/Edit/Find Next", have_captured_packets);
|
||||
set_menu_sensitivity("/Edit/Find Previous", have_captured_packets);
|
||||
set_menu_sensitivity("/Edit/Go To Frame...", have_captured_packets);
|
||||
set_menu_sensitivity("/Display/Colorize Display...", have_captured_packets);
|
||||
set_menu_sensitivity("/Tools/Summary", have_captured_packets);
|
||||
set_menu_sensitivity("/Tools/Protocol Hierarchy Statistics", have_captured_packets);
|
||||
set_menu_sensitivity("<PacketList>/Display/Match", have_captured_packets);
|
||||
set_menu_sensitivity("<PacketList>/Display/Prepare", have_captured_packets);
|
||||
}
|
||||
|
||||
/* Enable or disable menu items based on whether a packet is selected. */
|
||||
void
|
||||
set_menus_for_selected_packet(gboolean have_selected_packet)
|
||||
{
|
||||
set_menu_sensitivity("/File/Print Packet", have_selected_packet);
|
||||
set_menu_sensitivity("/Edit/Mark Frame", have_selected_packet);
|
||||
set_menu_sensitivity("/Edit/Mark All Frames", have_selected_packet);
|
||||
set_menu_sensitivity("/Edit/Unmark All Frames", have_selected_packet);
|
||||
set_menu_sensitivity("/Display/Collapse All", have_selected_packet);
|
||||
set_menu_sensitivity("/Display/Expand All", have_selected_packet);
|
||||
set_menu_sensitivity("/Display/Show Packet In New Window", have_selected_packet);
|
||||
set_menu_sensitivity("/Tools/Follow TCP Stream",
|
||||
have_selected_packet ? (cfile.edt->pi.ipproto == 6) : FALSE);
|
||||
set_menu_sensitivity("/Tools/Decode As...",
|
||||
have_selected_packet && decode_as_ok());
|
||||
set_menu_sensitivity("/Resolve Name",
|
||||
have_selected_packet && g_resolv_flags == 0);
|
||||
set_menu_sensitivity("/Tools/TCP Stream Analysis",
|
||||
have_selected_packet ? (cfile.edt->pi.ipproto == 6) : FALSE);
|
||||
}
|
||||
|
||||
/* Enable or disable menu items based on whether a tree row is selected
|
||||
and and on whether a "Match" can be done. */
|
||||
void
|
||||
set_menus_for_selected_tree_row(gboolean have_selected_tree)
|
||||
{
|
||||
gboolean properties = FALSE;
|
||||
|
||||
if (finfo_selected) {
|
||||
header_field_info *hfinfo = finfo_selected->hfinfo;
|
||||
if (hfinfo->parent == -1) {
|
||||
properties = prefs_is_registered_protocol(hfinfo->abbrev);
|
||||
} else {
|
||||
properties = prefs_is_registered_protocol(proto_registrar_get_abbrev(hfinfo->parent));
|
||||
}
|
||||
set_menu_sensitivity("<Main>/Display/Match",
|
||||
proto_can_match_selected(finfo_selected));
|
||||
set_menu_sensitivity("<TreeView>/Display/Match",
|
||||
proto_can_match_selected(finfo_selected));
|
||||
set_menu_sensitivity("<Main>/Display/Prepare",
|
||||
proto_can_match_selected(finfo_selected));
|
||||
set_menu_sensitivity("<TreeView>/Display/Prepare",
|
||||
proto_can_match_selected(finfo_selected));
|
||||
} else {
|
||||
set_menu_sensitivity("<Main>/Display/Match", FALSE);
|
||||
set_menu_sensitivity("<TreeView>/Display/Match", FALSE);
|
||||
set_menu_sensitivity("<Main>/Display/Prepare", FALSE);
|
||||
set_menu_sensitivity("<TreeView>/Display/Prepare", FALSE);
|
||||
}
|
||||
|
||||
set_menu_sensitivity("/Protocol Properties...", have_selected_tree && properties);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* menu.h
|
||||
* Menu definitions
|
||||
*
|
||||
* $Id: menu.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GTKGUIMENU_H__
|
||||
#define __GTKGUIMENU_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
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);
|
||||
|
||||
extern GtkWidget *popup_menu_object;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __GTKGUIMENU_H__ */
|
|
@ -0,0 +1,129 @@
|
|||
/* nameres_prefs.c
|
||||
* Dialog box for name resolution preferences
|
||||
*
|
||||
* $Id: nameres_prefs.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "nameres_prefs.h"
|
||||
#include "gtkglobals.h"
|
||||
#include <epan/resolv.h>
|
||||
#include "prefs.h"
|
||||
#include "prefs_dlg.h"
|
||||
#include "ui_util.h"
|
||||
#include "main.h"
|
||||
|
||||
#define M_RESOLVE_KEY "m_resolve"
|
||||
#define N_RESOLVE_KEY "n_resolve"
|
||||
#define T_RESOLVE_KEY "t_resolve"
|
||||
|
||||
#define RESOLV_TABLE_ROWS 3
|
||||
GtkWidget*
|
||||
nameres_prefs_show(void)
|
||||
{
|
||||
GtkWidget *main_tb, *main_vb;
|
||||
GtkWidget *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
|
||||
|
||||
/*
|
||||
* XXX - it would be nice if the current setting of the resolver
|
||||
* flags could be different from the preference flags, so that
|
||||
* the preference flags would represent what the user *typically*
|
||||
* wants, but they could override them for particular captures
|
||||
* without a subsequent editing of the preferences recording the
|
||||
* temporary settings as permanent preferences.
|
||||
*/
|
||||
prefs.name_resolve = g_resolv_flags;
|
||||
|
||||
/* Main vertical box */
|
||||
main_vb = gtk_vbox_new(FALSE, 7);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
|
||||
/* Main table */
|
||||
main_tb = gtk_table_new(RESOLV_TABLE_ROWS, 3, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
gtk_widget_show(main_tb);
|
||||
|
||||
/* Resolve MAC addresses */
|
||||
m_resolv_cb = create_preference_check_button(main_tb, 0,
|
||||
"Enable MAC name resolution:", NULL,
|
||||
prefs.name_resolve & RESOLV_MAC);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), M_RESOLVE_KEY, m_resolv_cb);
|
||||
|
||||
/* Resolve network addresses */
|
||||
n_resolv_cb = create_preference_check_button(main_tb, 1,
|
||||
"Enable network name resolution:", NULL,
|
||||
prefs.name_resolve & RESOLV_NETWORK);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), N_RESOLVE_KEY, n_resolv_cb);
|
||||
|
||||
/* Resolve transport addresses */
|
||||
t_resolv_cb = create_preference_check_button(main_tb, 2,
|
||||
"Enable transport name resolution:", NULL,
|
||||
prefs.name_resolve & RESOLV_TRANSPORT);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), T_RESOLVE_KEY, t_resolv_cb);
|
||||
|
||||
/* Show 'em what we got */
|
||||
gtk_widget_show_all(main_vb);
|
||||
|
||||
return(main_vb);
|
||||
}
|
||||
|
||||
void
|
||||
nameres_prefs_fetch(GtkWidget *w)
|
||||
{
|
||||
GtkWidget *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
|
||||
|
||||
m_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w),
|
||||
M_RESOLVE_KEY);
|
||||
n_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w),
|
||||
N_RESOLVE_KEY);
|
||||
t_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w),
|
||||
T_RESOLVE_KEY);
|
||||
|
||||
prefs.name_resolve = RESOLV_NONE;
|
||||
prefs.name_resolve |= (GTK_TOGGLE_BUTTON (m_resolv_cb)->active ? RESOLV_MAC : RESOLV_NONE);
|
||||
prefs.name_resolve |= (GTK_TOGGLE_BUTTON (n_resolv_cb)->active ? RESOLV_NETWORK : RESOLV_NONE);
|
||||
prefs.name_resolve |= (GTK_TOGGLE_BUTTON (t_resolv_cb)->active ? RESOLV_TRANSPORT : RESOLV_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
nameres_prefs_apply(GtkWidget *w _U_)
|
||||
{
|
||||
/*
|
||||
* XXX - force a regeneration of the protocol list if this has
|
||||
* changed?
|
||||
*/
|
||||
g_resolv_flags = prefs.name_resolve;
|
||||
}
|
||||
|
||||
void
|
||||
nameres_prefs_destroy(GtkWidget *w _U_)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* nameres_prefs.h
|
||||
* Definitions for name resolution preferences window
|
||||
*
|
||||
* $Id: nameres_prefs.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __NAMERES_PREFS_H__
|
||||
#define __NAMERES_PREFS_H__
|
||||
|
||||
GtkWidget *nameres_prefs_show(void);
|
||||
void nameres_prefs_fetch(GtkWidget *w);
|
||||
void nameres_prefs_apply(GtkWidget *w);
|
||||
void nameres_prefs_destroy(GtkWidget *w);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,263 @@
|
|||
/* packet_win.c
|
||||
* Routines for popping a window to display current packet
|
||||
*
|
||||
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
|
||||
*
|
||||
* $Id: packet_win.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* To do:
|
||||
* - Add close button to bottom.
|
||||
* - improve the window Title and allow user to config it
|
||||
* - Add print support ? ( could be a mess)
|
||||
* - Add button to have main window jump to this packet ?
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <epan/epan.h>
|
||||
#include "main.h"
|
||||
#include <epan/timestamp.h>
|
||||
#include <epan/packet.h>
|
||||
#include "summary.h"
|
||||
#include "file.h"
|
||||
#include "prefs.h"
|
||||
#include "menu.h"
|
||||
#include "../menu.h"
|
||||
#include "column.h"
|
||||
#include "print.h"
|
||||
#include <epan/resolv.h>
|
||||
#include "packet_win.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "proto_draw.h"
|
||||
#include "keys.h"
|
||||
#include "gtkglobals.h"
|
||||
#include <epan/plugins.h>
|
||||
#include <epan/epan_dissect.h>
|
||||
|
||||
/* Data structure holding information about a packet-detail window. */
|
||||
struct PacketWinData {
|
||||
frame_data *frame; /* The frame being displayed */
|
||||
union wtap_pseudo_header pseudo_header; /* Pseudo-header for packet */
|
||||
guint8 *pd; /* Data for packet */
|
||||
GtkWidget *main;
|
||||
GtkWidget *tv_scrollw;
|
||||
GtkWidget *tree_view;
|
||||
GtkWidget *bv_nb_ptr;
|
||||
field_info *finfo_selected;
|
||||
epan_dissect_t *edt;
|
||||
};
|
||||
|
||||
/* List of all the packet-detail windows popped up. */
|
||||
static GList *detail_windows;
|
||||
|
||||
static void new_tree_view_selection_changed_cb(GtkTreeSelection *sel,
|
||||
gpointer user_data);
|
||||
|
||||
static void destroy_new_window(GtkObject *object, gpointer user_data);
|
||||
|
||||
void new_window_cb(GtkWidget *w _U_)
|
||||
{
|
||||
#define NewWinTitleLen 1000
|
||||
char Title[NewWinTitleLen] = "";
|
||||
char *TextPtr;
|
||||
gint tv_size = 95, bv_size = 75;
|
||||
GtkWidget *main_w, *main_vbox, *pane,
|
||||
*tree_view, *tv_scrollw,
|
||||
*bv_nb_ptr;
|
||||
struct PacketWinData *DataPtr;
|
||||
int i;
|
||||
|
||||
/* Allocate data structure to represent this window. */
|
||||
DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
|
||||
|
||||
DataPtr->frame = cfile.current_frame;
|
||||
memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header,
|
||||
sizeof DataPtr->pseudo_header);
|
||||
DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
|
||||
memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
|
||||
DataPtr->edt = epan_dissect_new(TRUE, TRUE);
|
||||
epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
|
||||
DataPtr->frame, &cfile.cinfo);
|
||||
epan_dissect_fill_in_columns(DataPtr->edt);
|
||||
|
||||
main_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
/*
|
||||
* Build title of window by getting column data constructed when the
|
||||
* frame was dissected.
|
||||
*/
|
||||
for (i = 0; i < cfile.cinfo.num_cols; ++i) {
|
||||
TextPtr = cfile.cinfo.col_data[i];
|
||||
if ((strlen(Title) + strlen(TextPtr)) < NewWinTitleLen - 1) {
|
||||
strcat(Title, TextPtr);
|
||||
strcat(Title, " ");
|
||||
}
|
||||
}
|
||||
|
||||
gtk_window_set_title(GTK_WINDOW(main_w), Title);
|
||||
gtk_window_set_default_size(GTK_WINDOW(main_w), DEF_WIDTH, -1);
|
||||
|
||||
/* Container for paned windows */
|
||||
main_vbox = gtk_vbox_new(FALSE, 1);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
|
||||
gtk_container_add(GTK_CONTAINER(main_w), main_vbox);
|
||||
gtk_widget_show(main_vbox);
|
||||
|
||||
/* Panes for the tree and byte view */
|
||||
pane = gtk_vpaned_new();
|
||||
gtk_paned_gutter_size(GTK_PANED(pane), (GTK_PANED(pane))->handle_size);
|
||||
gtk_container_add(GTK_CONTAINER(main_vbox), pane);
|
||||
gtk_widget_show(pane);
|
||||
|
||||
/* Tree view */
|
||||
create_tree_view(tv_size, &prefs, pane, &tv_scrollw, &tree_view);
|
||||
gtk_widget_show(tree_view);
|
||||
|
||||
/* Byte view */
|
||||
bv_nb_ptr = create_byte_view(bv_size, pane);
|
||||
|
||||
DataPtr->main = main_w;
|
||||
DataPtr->tv_scrollw = tv_scrollw;
|
||||
DataPtr->tree_view = tree_view;
|
||||
DataPtr->bv_nb_ptr = bv_nb_ptr;
|
||||
detail_windows = g_list_append(detail_windows, DataPtr);
|
||||
|
||||
/* load callback handlers */
|
||||
g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view))),
|
||||
"changed", G_CALLBACK(new_tree_view_selection_changed_cb),
|
||||
DataPtr);
|
||||
g_signal_connect(G_OBJECT(main_w), "destroy",
|
||||
G_CALLBACK(destroy_new_window), DataPtr);
|
||||
|
||||
/* draw the protocol tree & print hex data */
|
||||
add_byte_views(DataPtr->edt, tree_view, DataPtr->bv_nb_ptr);
|
||||
proto_tree_draw(DataPtr->edt->tree, tree_view);
|
||||
|
||||
DataPtr->finfo_selected = NULL;
|
||||
gtk_widget_show(main_w);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_new_window(GtkObject *object _U_, gpointer user_data)
|
||||
{
|
||||
struct PacketWinData *DataPtr = user_data;
|
||||
|
||||
detail_windows = g_list_remove(detail_windows, DataPtr);
|
||||
epan_dissect_free(DataPtr->edt);
|
||||
g_free(DataPtr->pd);
|
||||
g_free(DataPtr);
|
||||
}
|
||||
|
||||
|
||||
/* called when a tree row is (un)selected in the popup packet window */
|
||||
static void
|
||||
new_tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data)
|
||||
{
|
||||
field_info *finfo;
|
||||
GtkWidget *byte_view;
|
||||
const guint8 *data;
|
||||
guint len;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
|
||||
|
||||
/* if something is selected */
|
||||
if (gtk_tree_selection_get_selected(sel, &model, &iter))
|
||||
{
|
||||
gtk_tree_model_get(model, &iter, 1, &finfo, -1);
|
||||
if (!finfo) return;
|
||||
|
||||
set_notebook_page(DataPtr->bv_nb_ptr, finfo->ds_tvb);
|
||||
byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
|
||||
if (!byte_view) /* exit if no hex window to write in */
|
||||
return;
|
||||
|
||||
data = get_byte_view_data_and_length(byte_view, &len);
|
||||
if (data == NULL) {
|
||||
data = DataPtr->pd;
|
||||
len = DataPtr->frame->cap_len;
|
||||
}
|
||||
|
||||
DataPtr->finfo_selected = finfo;
|
||||
packet_hex_print(GTK_TEXT_VIEW(byte_view), data,
|
||||
DataPtr->frame, finfo, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataPtr->finfo_selected = NULL;
|
||||
|
||||
byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
|
||||
if (!byte_view) /* exit if no hex window to write in */
|
||||
return;
|
||||
|
||||
data = get_byte_view_data_and_length(byte_view, &len);
|
||||
g_assert(data != NULL);
|
||||
packet_hex_reprint(GTK_TEXT_VIEW(byte_view));
|
||||
}
|
||||
}
|
||||
|
||||
/* Functions called from elsewhere to act on all popup packet windows. */
|
||||
|
||||
/* Destroy all popup packet windows. */
|
||||
void
|
||||
destroy_packet_wins(void)
|
||||
{
|
||||
struct PacketWinData *DataPtr;
|
||||
|
||||
/* Destroying a packet window causes it to be removed from
|
||||
the list of packet windows, so we can't do a "g_list_foreach()"
|
||||
to go through the list of all packet windows and destroy them
|
||||
as we find them; instead, as long as the list is non-empty,
|
||||
we destroy the first window on the list. */
|
||||
while (detail_windows != NULL) {
|
||||
DataPtr = (struct PacketWinData *)(detail_windows->data);
|
||||
gtk_widget_destroy(DataPtr->main);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
redraw_hex_dump_cb(gpointer data, gpointer user_data _U_)
|
||||
{
|
||||
struct PacketWinData *DataPtr = (struct PacketWinData *)data;
|
||||
|
||||
redraw_hex_dump(DataPtr->bv_nb_ptr, DataPtr->frame, DataPtr->finfo_selected);
|
||||
}
|
||||
|
||||
/* Redraw the hex dump part of all the popup packet windows. */
|
||||
void
|
||||
redraw_hex_dump_packet_wins(void)
|
||||
{
|
||||
g_list_foreach(detail_windows, redraw_hex_dump_cb, NULL);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* packet_win.h
|
||||
* Declarations for popping a window to display current packet
|
||||
*
|
||||
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
|
||||
*
|
||||
* $Id: packet_win.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __PACKET_WIN_H__
|
||||
#define __PACKET_WIN_H__
|
||||
|
||||
/* Create a new packet window. */
|
||||
extern void new_window_cb(GtkWidget *w);
|
||||
|
||||
/* Destroy all popup packet windows. */
|
||||
void destroy_packet_wins(void);
|
||||
|
||||
/* Redraw the hex dump panes of all packet windows. */
|
||||
void redraw_hex_dump_packet_wins(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,164 @@
|
|||
/* plugins_dlg.c
|
||||
* Dialog boxes for plugins
|
||||
*
|
||||
* $Id: plugins_dlg.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1999 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include <epan/plugins.h>
|
||||
#include "dlg_utils.h"
|
||||
|
||||
#ifdef HAVE_PLUGINS
|
||||
|
||||
static void plugins_close_cb(GtkWidget *, gpointer);
|
||||
static void plugins_scan(GtkListStore *);
|
||||
|
||||
enum
|
||||
{
|
||||
COLUMN_NAME,
|
||||
COLUMN_VERSION,
|
||||
NUM_COLUMNS
|
||||
};
|
||||
|
||||
void
|
||||
tools_plugins_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *plugins_window;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *main_frame;
|
||||
GtkWidget *frame_hbox;
|
||||
GtkWidget *scrolledwindow;
|
||||
GtkWidget *plugins_list;
|
||||
GtkWidget *frame_vbnbox;
|
||||
GtkWidget *main_hbnbox;
|
||||
GtkWidget *close_bn;
|
||||
gchar *titles[] = {"Name", "Version"};
|
||||
GtkListStore *store;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
plugins_window = dlg_window_new("Ethereal: Plugins");
|
||||
|
||||
main_vbox = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(plugins_window), main_vbox);
|
||||
gtk_widget_show(main_vbox);
|
||||
|
||||
main_frame = gtk_frame_new("Plugins List");
|
||||
gtk_box_pack_start(GTK_BOX(main_vbox), main_frame, TRUE, TRUE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(main_frame), 10);
|
||||
gtk_widget_show(main_frame);
|
||||
|
||||
frame_hbox = gtk_hbox_new(FALSE,0);
|
||||
gtk_container_add(GTK_CONTAINER(main_frame), frame_hbox);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(frame_hbox), 5);
|
||||
gtk_widget_show(frame_hbox);
|
||||
|
||||
scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(frame_hbox), scrolledwindow, TRUE, TRUE, 0);
|
||||
gtk_widget_set_size_request(scrolledwindow, 400, 150);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow),
|
||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_show(scrolledwindow);
|
||||
|
||||
store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
|
||||
plugins_scan(store);
|
||||
plugins_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(plugins_list), TRUE);
|
||||
gtk_tree_view_set_search_column(GTK_TREE_VIEW(plugins_list), 0);
|
||||
g_object_unref(G_OBJECT(store));
|
||||
gtk_container_add(GTK_CONTAINER(scrolledwindow), plugins_list);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text",
|
||||
COLUMN_NAME, NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, COLUMN_NAME);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(plugins_list), column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Version", renderer,
|
||||
"text", COLUMN_VERSION,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sort_column_id(column, COLUMN_VERSION);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(plugins_list), column);
|
||||
gtk_widget_show(plugins_list);
|
||||
|
||||
frame_vbnbox = gtk_vbutton_box_new();
|
||||
gtk_box_pack_start(GTK_BOX(frame_hbox), frame_vbnbox, FALSE, TRUE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(frame_vbnbox), 20);
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(frame_vbnbox),
|
||||
GTK_BUTTONBOX_SPREAD);
|
||||
gtk_widget_show(frame_vbnbox);
|
||||
|
||||
main_hbnbox = gtk_hbutton_box_new();
|
||||
gtk_box_pack_start(GTK_BOX(main_vbox), main_hbnbox, FALSE, TRUE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(main_hbnbox), 10);
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(main_hbnbox),
|
||||
GTK_BUTTONBOX_SPREAD);
|
||||
gtk_widget_show(main_hbnbox);
|
||||
|
||||
close_bn = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
|
||||
gtk_container_add(GTK_CONTAINER(main_hbnbox), close_bn);
|
||||
gtk_widget_show(close_bn);
|
||||
g_signal_connect(G_OBJECT(close_bn), "clicked",
|
||||
G_CALLBACK(plugins_close_cb), GTK_OBJECT(plugins_window));
|
||||
|
||||
gtk_widget_show(plugins_window);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the list widget with a list of the plugin modules.
|
||||
*/
|
||||
static void
|
||||
plugins_scan(GtkListStore *store)
|
||||
{
|
||||
plugin *pt_plug;
|
||||
GtkTreeIter iter;
|
||||
|
||||
pt_plug = plugin_list;
|
||||
while (pt_plug)
|
||||
{
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_list_store_set(store, &iter, COLUMN_NAME, pt_plug->name,
|
||||
COLUMN_VERSION, pt_plug->version, -1);
|
||||
pt_plug = pt_plug->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
plugins_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gtk_grab_remove(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
|||
/* prefs_dlg.h
|
||||
* Definitions for preference handling routines
|
||||
*
|
||||
* $Id: prefs_dlg.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __PREFS_DLG_H__
|
||||
#define __PREFS_DLG_H__
|
||||
|
||||
void prefs_cb(GtkWidget *, gpointer);
|
||||
void properties_cb(GtkWidget *, gpointer);
|
||||
|
||||
GtkWidget *create_preference_check_button(GtkWidget *, int, const gchar *,
|
||||
const gchar *, gboolean);
|
||||
GtkWidget *create_preference_radio_buttons(GtkWidget *, int, const gchar *,
|
||||
const gchar *, const enum_val_t *, gint);
|
||||
gint fetch_preference_radio_buttons_val(GtkWidget *, const enum_val_t *);
|
||||
GtkWidget *create_preference_option_menu(GtkWidget *, int, const gchar *,
|
||||
const gchar *, const enum_val_t *, gint);
|
||||
gint fetch_preference_option_menu_val(GtkWidget *, const enum_val_t *);
|
||||
GtkWidget *create_preference_entry(GtkWidget *, int, const gchar *,
|
||||
const gchar *, char *);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,690 @@
|
|||
/* print_dlg.c
|
||||
* Dialog boxes for printing
|
||||
*
|
||||
* $Id: print_dlg.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "keys.h"
|
||||
#include "print.h"
|
||||
#include "prefs.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "ui_util.h"
|
||||
#include "dlg_utils.h"
|
||||
#include <epan/epan_dissect.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include "print_mswin.h"
|
||||
#endif
|
||||
|
||||
/* On Win32, a GUI application apparently can't use "popen()" (it
|
||||
"returns an invalid file handle, if used in a Windows program,
|
||||
that will cause the program to hang indefinitely"), so we can't
|
||||
use a pipe to a print command to print to a printer.
|
||||
|
||||
Eventually, we should try to use the native Win32 printing API
|
||||
for this (and also use various UNIX printing APIs, when present?).
|
||||
*/
|
||||
static void print_cmd_toggle_dest(GtkWidget *widget, gpointer data);
|
||||
static void print_cmd_toggle_detail(GtkWidget *widget, gpointer data);
|
||||
static void print_file_cb(GtkWidget *file_bt, gpointer file_te);
|
||||
static void print_fs_ok_cb(GtkWidget *w, gpointer data);
|
||||
static void print_fs_cancel_cb(GtkWidget *w, gpointer data);
|
||||
static void print_fs_destroy_cb(GtkWidget *win, gpointer data);
|
||||
static void print_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
|
||||
static void print_close_cb(GtkWidget *close_bt, gpointer parent_w);
|
||||
static void print_destroy_cb(GtkWidget *win, gpointer user_data);
|
||||
|
||||
/*
|
||||
* Remember whether we printed to a printer or a file the last time we
|
||||
* printed something.
|
||||
*/
|
||||
static int print_to_file;
|
||||
|
||||
/*
|
||||
* Remember whether we printed as text or PostScript the last time we
|
||||
* printed something.
|
||||
*/
|
||||
static gint print_format = PR_FMT_TEXT;
|
||||
|
||||
#define PRINT_FORMAT_RB_KEY "printer_format_radio_button"
|
||||
#define PRINT_DEST_RB_KEY "printer_destination_radio_button"
|
||||
|
||||
#define PRINT_SUMMARY_RB_KEY "printer_summary_radio_button"
|
||||
#define PRINT_HEX_CB_KEY "printer_hex_check_button"
|
||||
#define PRINT_EXPAND_ALL_RB_KEY "printer_expand_all_radio_button"
|
||||
#define PRINT_AS_DISPLAYED_RB_KEY "printer_as_displayed_radio_button"
|
||||
#define PRINT_SUPPRESS_UNMARKED_CB_KEY "printer_suppress_unmarked_check_button"
|
||||
|
||||
#define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
|
||||
#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the current "Print" window, if any, so that if
|
||||
* somebody tries to do "File:Print" while there's already a "Print" window
|
||||
* up, we just pop up the existing one, rather than creating a new one.
|
||||
*/
|
||||
static GtkWidget *print_w;
|
||||
|
||||
/* Print the capture */
|
||||
void
|
||||
file_print_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
|
||||
{
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkWidget *main_vb, *main_tb, *button;
|
||||
GtkWidget *format_rb;
|
||||
GtkWidget *format_hb, *format_lb;
|
||||
GSList *format_grp;
|
||||
GtkWidget *dest_rb;
|
||||
GtkWidget *dest_hb, *dest_lb;
|
||||
GtkWidget *cmd_lb, *cmd_te;
|
||||
GtkWidget *file_bt_hb, *file_bt, *file_te;
|
||||
GSList *dest_grp;
|
||||
GtkWidget *options_hb;
|
||||
GtkWidget *print_type_vb, *summary_rb, *detail_rb, *hex_cb,*marked_cb;
|
||||
GSList *summary_grp;
|
||||
GtkWidget *expand_vb, *expand_all_rb, *as_displayed_rb;
|
||||
GSList *expand_grp;
|
||||
GtkWidget *bbox, *ok_bt, *cancel_bt;
|
||||
|
||||
if (print_w != NULL) {
|
||||
/* There's already a "Print" dialog box; reactivate it. */
|
||||
reactivate_window(print_w);
|
||||
return;
|
||||
}
|
||||
|
||||
print_w = dlg_window_new("Ethereal: Print");
|
||||
g_signal_connect(G_OBJECT(print_w), "destroy",
|
||||
G_CALLBACK(print_destroy_cb), NULL);
|
||||
|
||||
/* Accelerator group for the accelerators (or, as they're called in
|
||||
Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
|
||||
Ctrl+<key> is an accelerator). */
|
||||
accel_group = gtk_accel_group_new();
|
||||
gtk_window_add_accel_group(GTK_WINDOW(print_w), accel_group);
|
||||
|
||||
/* Enclosing containers for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(print_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
main_tb = gtk_table_new(4, 2, FALSE);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
gtk_widget_show(main_tb);
|
||||
|
||||
/* Output format */
|
||||
format_lb = gtk_label_new("Format:");
|
||||
gtk_misc_set_alignment(GTK_MISC(format_lb), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), format_lb, 0, 1, 0, 1);
|
||||
gtk_widget_show(format_lb);
|
||||
|
||||
format_hb = gtk_hbox_new(FALSE, 0);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), format_hb, 1, 2, 0, 1);
|
||||
gtk_widget_show(format_hb);
|
||||
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(NULL, "Plain _Text",
|
||||
accel_group);
|
||||
if (print_format == PR_FMT_TEXT)
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
|
||||
format_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
|
||||
gtk_box_pack_start(GTK_BOX(format_hb), button, FALSE, FALSE, 10);
|
||||
gtk_widget_show(button);
|
||||
|
||||
format_rb = dlg_radio_button_new_with_label_with_mnemonic(format_grp,
|
||||
"_PostScript", accel_group);
|
||||
if (print_format == PR_FMT_PS)
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(format_rb), TRUE);
|
||||
gtk_box_pack_start(GTK_BOX(format_hb), format_rb, FALSE, FALSE, 10);
|
||||
gtk_widget_show(format_rb);
|
||||
|
||||
/* Output destination */
|
||||
dest_lb = gtk_label_new("Print to:");
|
||||
gtk_misc_set_alignment(GTK_MISC(dest_lb), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), dest_lb, 0, 1, 1, 2);
|
||||
gtk_widget_show(dest_lb);
|
||||
|
||||
dest_hb = gtk_hbox_new(FALSE, 0);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), dest_hb, 1, 2, 1, 2);
|
||||
gtk_widget_show(dest_hb);
|
||||
|
||||
#ifdef _WIN32
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(NULL, "_Printer"
|
||||
accel_group);
|
||||
#else
|
||||
button = dlg_radio_button_new_with_label_with_mnemonic(NULL, "_Command",
|
||||
accel_group);
|
||||
#endif
|
||||
if (!print_to_file)
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
|
||||
dest_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
|
||||
gtk_box_pack_start(GTK_BOX(dest_hb), button, FALSE, FALSE, 10);
|
||||
gtk_widget_show(button);
|
||||
|
||||
dest_rb = dlg_radio_button_new_with_label_with_mnemonic(dest_grp, "_File",
|
||||
accel_group);
|
||||
if (print_to_file)
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(dest_rb), TRUE);
|
||||
g_signal_connect(G_OBJECT(dest_rb), "toggled",
|
||||
G_CALLBACK(print_cmd_toggle_dest), NULL);
|
||||
gtk_box_pack_start(GTK_BOX(dest_hb), dest_rb, FALSE, FALSE, 10);
|
||||
gtk_widget_show(dest_rb);
|
||||
|
||||
/* Command text entry */
|
||||
|
||||
#ifndef _WIN32
|
||||
cmd_lb = gtk_label_new("Command:");
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_CMD_LB_KEY, cmd_lb);
|
||||
gtk_misc_set_alignment(GTK_MISC(cmd_lb), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), cmd_lb, 0, 1, 2, 3);
|
||||
gtk_widget_set_sensitive(cmd_lb, !print_to_file);
|
||||
gtk_widget_show(cmd_lb);
|
||||
|
||||
cmd_te = gtk_entry_new();
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_CMD_TE_KEY, cmd_te);
|
||||
if (prefs.pr_cmd)
|
||||
gtk_entry_set_text(GTK_ENTRY(cmd_te), prefs.pr_cmd);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), cmd_te, 1, 2, 2, 3);
|
||||
gtk_widget_set_sensitive(cmd_te, !print_to_file);
|
||||
gtk_widget_show(cmd_te);
|
||||
#endif
|
||||
|
||||
/* File button and text entry */
|
||||
file_bt_hb = gtk_hbox_new(FALSE, 0);
|
||||
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), file_bt_hb, 0, 1, 3, 4);
|
||||
gtk_widget_show(file_bt_hb);
|
||||
|
||||
file_bt = gtk_button_new_with_label("File:");
|
||||
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_FILE_BT_KEY, file_bt);
|
||||
gtk_box_pack_end(GTK_BOX(file_bt_hb), file_bt, FALSE, FALSE, 0);
|
||||
gtk_widget_set_sensitive(file_bt, print_to_file);
|
||||
gtk_widget_show(file_bt);
|
||||
|
||||
file_te = gtk_entry_new();
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_FILE_TE_KEY, file_te);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 3, 4);
|
||||
gtk_widget_set_sensitive(file_te, print_to_file);
|
||||
gtk_widget_show(file_te);
|
||||
|
||||
g_signal_connect(G_OBJECT(file_bt), "clicked",
|
||||
G_CALLBACK(print_file_cb), GTK_OBJECT(file_te));
|
||||
|
||||
/* Horizontal box into which to put two vertical boxes of option
|
||||
buttons. */
|
||||
options_hb = gtk_hbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(options_hb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), options_hb);
|
||||
gtk_widget_show(options_hb);
|
||||
|
||||
/* Vertical box into which to put the "Print summary"/"Print detail"
|
||||
radio buttons and the "Print hex" check button. */
|
||||
print_type_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(print_type_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(options_hb), print_type_vb);
|
||||
gtk_widget_show(print_type_vb);
|
||||
|
||||
/* "Print summary"/"Print detail" radio buttons */
|
||||
summary_rb = dlg_radio_button_new_with_label_with_mnemonic(NULL,
|
||||
"Print _summary", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(summary_rb), FALSE);
|
||||
summary_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(summary_rb));
|
||||
gtk_container_add(GTK_CONTAINER(print_type_vb), summary_rb);
|
||||
gtk_widget_show(summary_rb);
|
||||
detail_rb = dlg_radio_button_new_with_label_with_mnemonic(summary_grp,
|
||||
"Print _detail", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(detail_rb), TRUE);
|
||||
g_signal_connect(G_OBJECT(detail_rb), "toggled",
|
||||
G_CALLBACK(print_cmd_toggle_detail), NULL);
|
||||
gtk_container_add(GTK_CONTAINER(print_type_vb), detail_rb);
|
||||
gtk_widget_show(detail_rb);
|
||||
|
||||
/* "Print hex" check button. */
|
||||
hex_cb = dlg_check_button_new_with_label_with_mnemonic("Print _hex data",
|
||||
accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(hex_cb), FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(print_type_vb), hex_cb);
|
||||
gtk_widget_show(hex_cb);
|
||||
|
||||
/* "Suppress Unmarked" check button. */
|
||||
marked_cb = dlg_check_button_new_with_label_with_mnemonic("Suppress _unmarked frames",
|
||||
accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(marked_cb), FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(print_type_vb), marked_cb);
|
||||
gtk_widget_show(marked_cb);
|
||||
|
||||
/* Vertical box into which to put the "Expand all levels"/"Print as displayed"
|
||||
radio buttons. */
|
||||
expand_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(expand_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(options_hb), expand_vb);
|
||||
gtk_widget_show(expand_vb);
|
||||
|
||||
/* "Expand all levels"/"Print as displayed" radio buttons */
|
||||
expand_all_rb = dlg_radio_button_new_with_label_with_mnemonic(NULL,
|
||||
"_Expand all levels", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(expand_all_rb), TRUE);
|
||||
expand_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(expand_all_rb));
|
||||
gtk_container_add(GTK_CONTAINER(expand_vb), expand_all_rb);
|
||||
gtk_widget_show(expand_all_rb);
|
||||
as_displayed_rb = dlg_radio_button_new_with_label_with_mnemonic(expand_grp,
|
||||
"Print _as displayed", accel_group);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(as_displayed_rb), FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(expand_vb), as_displayed_rb);
|
||||
gtk_widget_show(as_displayed_rb);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(detail_rb), PRINT_EXPAND_ALL_RB_KEY,
|
||||
expand_all_rb);
|
||||
gtk_object_set_data(GTK_OBJECT(detail_rb), PRINT_AS_DISPLAYED_RB_KEY,
|
||||
as_displayed_rb);
|
||||
gtk_object_set_data(GTK_OBJECT(detail_rb), PRINT_HEX_CB_KEY,
|
||||
hex_cb);
|
||||
|
||||
/* Button row: OK and Cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_FORMAT_RB_KEY, format_rb);
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_DEST_RB_KEY, dest_rb);
|
||||
#ifndef _WIN32
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_CMD_TE_KEY, cmd_te);
|
||||
#endif
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_FILE_TE_KEY, file_te);
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_SUMMARY_RB_KEY, summary_rb);
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_HEX_CB_KEY, hex_cb);
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_EXPAND_ALL_RB_KEY, expand_all_rb);
|
||||
gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_SUPPRESS_UNMARKED_CB_KEY, marked_cb);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(print_ok_cb), GTK_OBJECT(print_w));
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_bt), "clicked",
|
||||
G_CALLBACK(print_close_cb), GTK_OBJECT(print_w));
|
||||
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
|
||||
/* Catch the "activate" signal on the "Command" and "File" text entries,
|
||||
so that if the user types Return there, we act as if the "OK" button
|
||||
had been selected, as happens if Return is typed if some widget
|
||||
that *doesn't* handle the Return key has the input focus. */
|
||||
|
||||
#ifndef _WIN32
|
||||
dlg_set_activate(cmd_te, ok_bt);
|
||||
#endif
|
||||
dlg_set_activate(file_te, ok_bt);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(print_w, cancel_bt);
|
||||
|
||||
gtk_widget_show(print_w);
|
||||
}
|
||||
|
||||
static void
|
||||
print_cmd_toggle_dest(GtkWidget *widget, gpointer data _U_)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
GtkWidget *cmd_lb, *cmd_te;
|
||||
#endif
|
||||
GtkWidget *file_bt, *file_te;
|
||||
int to_file;
|
||||
|
||||
#ifndef _WIN32
|
||||
cmd_lb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_CMD_LB_KEY));
|
||||
cmd_te = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_CMD_TE_KEY));
|
||||
#endif
|
||||
file_bt = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_FILE_BT_KEY));
|
||||
file_te = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_FILE_TE_KEY));
|
||||
if (GTK_TOGGLE_BUTTON (widget)->active) {
|
||||
/* They selected "Print to File" */
|
||||
to_file = TRUE;
|
||||
} else {
|
||||
/* They selected "Print to Command" on UNIX or "Print to Printer"
|
||||
on Windows */
|
||||
to_file = FALSE;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
gtk_widget_set_sensitive(cmd_lb, !to_file);
|
||||
gtk_widget_set_sensitive(cmd_te, !to_file);
|
||||
#endif
|
||||
gtk_widget_set_sensitive(file_bt, to_file);
|
||||
gtk_widget_set_sensitive(file_te, to_file);
|
||||
}
|
||||
|
||||
static void
|
||||
print_cmd_toggle_detail(GtkWidget *widget, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *expand_all_rb, *as_displayed_rb, *hex_cb;
|
||||
gboolean print_detail;
|
||||
|
||||
expand_all_rb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_EXPAND_ALL_RB_KEY));
|
||||
as_displayed_rb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_AS_DISPLAYED_RB_KEY));
|
||||
hex_cb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
|
||||
PRINT_HEX_CB_KEY));
|
||||
if (GTK_TOGGLE_BUTTON (widget)->active) {
|
||||
/* They selected "Print detail" */
|
||||
print_detail = TRUE;
|
||||
} else {
|
||||
/* They selected "Print summary" */
|
||||
print_detail = FALSE;
|
||||
}
|
||||
gtk_widget_set_sensitive(expand_all_rb, print_detail);
|
||||
gtk_widget_set_sensitive(as_displayed_rb, print_detail);
|
||||
gtk_widget_set_sensitive(hex_cb, print_detail);
|
||||
}
|
||||
|
||||
static void
|
||||
print_file_cb(GtkWidget *file_bt, gpointer file_te)
|
||||
{
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(file_bt);
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Has a file selection dialog box already been opened for that top-level
|
||||
widget? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Just re-activate that dialog box. */
|
||||
reactivate_window(fs);
|
||||
return;
|
||||
}
|
||||
|
||||
fs = gtk_file_selection_new ("Ethereal: Print to File");
|
||||
gtk_object_set_data(GTK_OBJECT(fs), PRINT_FILE_TE_KEY, file_te);
|
||||
|
||||
/* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
|
||||
gtk_object_set_data(GTK_OBJECT(fs), E_FS_CALLER_PTR_KEY, caller);
|
||||
|
||||
/* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, fs);
|
||||
|
||||
/* Call a handler when the file selection box is destroyed, so we can inform
|
||||
our caller, if any, that it's been destroyed. */
|
||||
g_signal_connect(G_OBJECT(fs), "destroy",
|
||||
G_CALLBACK(print_fs_destroy_cb), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked",
|
||||
G_CALLBACK(print_fs_ok_cb), fs);
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->cancel_button),
|
||||
"clicked", G_CALLBACK(print_fs_cancel_cb), fs);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
|
||||
|
||||
gtk_widget_show(fs);
|
||||
}
|
||||
|
||||
static void
|
||||
print_fs_ok_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
|
||||
PRINT_FILE_TE_KEY)),
|
||||
gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void
|
||||
print_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void
|
||||
print_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *caller;
|
||||
|
||||
/* Get the widget that requested that we be popped up.
|
||||
(It should arrange to destroy us if it's destroyed, so
|
||||
that we don't get a pointer to a non-existent window here.) */
|
||||
caller = gtk_object_get_data(GTK_OBJECT(win), E_FS_CALLER_PTR_KEY);
|
||||
|
||||
/* Tell it we no longer exist. */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, NULL);
|
||||
|
||||
/* Now nuke this window. */
|
||||
gtk_grab_remove(GTK_WIDGET(win));
|
||||
gtk_widget_destroy(GTK_WIDGET(win));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void setup_mswin_print( print_args_t *print_args) {
|
||||
|
||||
/*XXX should use temp file stuff in util routines */
|
||||
|
||||
char *path1;
|
||||
|
||||
path1 = tmpnam(NULL);
|
||||
|
||||
print_args->dest = g_strdup(path1);
|
||||
print_args->to_file = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
print_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
|
||||
{
|
||||
GtkWidget *button;
|
||||
print_args_t print_args;
|
||||
#ifdef _WIN32
|
||||
int win_printer_flag = FALSE;
|
||||
#endif
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_DEST_RB_KEY);
|
||||
print_to_file = GTK_TOGGLE_BUTTON (button)->active;
|
||||
print_args.to_file = print_to_file;
|
||||
|
||||
if (print_args.to_file) {
|
||||
print_args.dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_FILE_TE_KEY))));
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
win_printer_flag = TRUE;
|
||||
setup_mswin_print(&print_args);
|
||||
#else
|
||||
print_args.dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_CMD_TE_KEY))));
|
||||
#endif
|
||||
}
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_FORMAT_RB_KEY);
|
||||
if (GTK_TOGGLE_BUTTON (button)->active)
|
||||
print_format = PR_FMT_PS;
|
||||
else
|
||||
print_format = PR_FMT_TEXT;
|
||||
print_args.format = print_format;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_SUMMARY_RB_KEY);
|
||||
print_args.print_summary = GTK_TOGGLE_BUTTON (button)->active;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_HEX_CB_KEY);
|
||||
print_args.print_hex = GTK_TOGGLE_BUTTON (button)->active;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_EXPAND_ALL_RB_KEY);
|
||||
print_args.expand_all = GTK_TOGGLE_BUTTON (button)->active;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
|
||||
PRINT_SUPPRESS_UNMARKED_CB_KEY);
|
||||
print_args.suppress_unmarked = GTK_TOGGLE_BUTTON (button)->active;
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
|
||||
/* Now print the packets */
|
||||
if (!print_packets(&cfile, &print_args)) {
|
||||
if (print_args.to_file)
|
||||
simple_dialog(ESD_TYPE_WARN, NULL,
|
||||
file_write_error_message(errno), print_args.dest);
|
||||
else
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
|
||||
print_args.dest);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (win_printer_flag) {
|
||||
print_mswin(print_args.dest);
|
||||
|
||||
/* trash temp file */
|
||||
remove(print_args.dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_free(print_args.dest);
|
||||
}
|
||||
|
||||
static void
|
||||
print_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gtk_grab_remove(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
}
|
||||
|
||||
static void
|
||||
print_destroy_cb(GtkWidget *win, gpointer user_data _U_)
|
||||
{
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Is there a file selection dialog associated with this
|
||||
Print File dialog? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(win), E_FILE_SEL_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(fs);
|
||||
}
|
||||
|
||||
/* Note that we no longer have a "Print" dialog box. */
|
||||
print_w = NULL;
|
||||
}
|
||||
|
||||
/* Print a packet */
|
||||
void
|
||||
file_print_packet_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
|
||||
{
|
||||
FILE *fh;
|
||||
print_args_t print_args;
|
||||
#ifdef _WIN32
|
||||
int win_printer_flag = FALSE;
|
||||
#endif
|
||||
|
||||
switch (prefs.pr_dest) {
|
||||
|
||||
case PR_DEST_CMD:
|
||||
#ifdef _WIN32
|
||||
/* "PR_DEST_CMD" means "to printer" on Windows */
|
||||
win_printer_flag = TRUE;
|
||||
setup_mswin_print(&print_args);
|
||||
fh = fopen(print_args.dest, "w");
|
||||
print_args.to_file = TRUE;
|
||||
break;
|
||||
#else
|
||||
fh = popen(prefs.pr_cmd, "w");
|
||||
print_args.to_file = FALSE;
|
||||
print_args.dest = prefs.pr_cmd;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PR_DEST_FILE:
|
||||
fh = fopen(prefs.pr_file, "w");
|
||||
print_args.to_file = TRUE;
|
||||
print_args.dest = prefs.pr_file;
|
||||
break;
|
||||
|
||||
default:
|
||||
fh = NULL; /* XXX - "can't happen" */
|
||||
break;
|
||||
}
|
||||
if (fh == NULL) {
|
||||
switch (prefs.pr_dest) {
|
||||
|
||||
case PR_DEST_CMD:
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
|
||||
prefs.pr_cmd);
|
||||
break;
|
||||
|
||||
case PR_DEST_FILE:
|
||||
simple_dialog(ESD_TYPE_WARN, NULL, file_write_error_message(errno),
|
||||
prefs.pr_file);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
print_preamble(fh, prefs.pr_format);
|
||||
print_args.format = prefs.pr_format;
|
||||
print_args.print_summary = FALSE;
|
||||
print_args.print_hex = FALSE;
|
||||
print_args.expand_all = TRUE;
|
||||
print_args.suppress_unmarked = FALSE;
|
||||
proto_tree_print(&print_args, cfile.edt, fh);
|
||||
print_finale(fh, prefs.pr_format);
|
||||
close_print_dest(print_args.to_file, fh);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (win_printer_flag) {
|
||||
print_mswin(print_args.dest);
|
||||
|
||||
/* trash temp file */
|
||||
remove(print_args.dest);
|
||||
g_free(print_args.dest);
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
/* print_mswin.c
|
||||
* Printing support for MSWindows
|
||||
*
|
||||
* $$
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 2002, Jeffrey C. Foster <jfoste@woodward.com>
|
||||
*
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* This original code was from the Technet Article Q139652 :
|
||||
* HOWTO: Print a Document
|
||||
*/
|
||||
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <winspool.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
BOOL CALLBACK abort_proc( HDC hDC, int Error );
|
||||
HDC get_printer_dc(void);
|
||||
void init_doc_struct( DOCINFO* di, char* docname);
|
||||
void print_file( char* file_name, HDC hdc);
|
||||
|
||||
|
||||
|
||||
void print_mswin(char *file_name)
|
||||
|
||||
{
|
||||
HDC hDC;
|
||||
DOCINFO di;
|
||||
|
||||
HWND hWndParent = HWND_DESKTOP; /* would be better to be a real window */
|
||||
|
||||
/* Need a printer DC to print to. */
|
||||
hDC = get_printer_dc();
|
||||
|
||||
/* Did you get a good DC?, Cancel will return NULL also, so what to do? */
|
||||
if( !hDC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* You always have to use an AbortProc(). */
|
||||
if( SetAbortProc( hDC, abort_proc ) == SP_ERROR )
|
||||
{
|
||||
MessageBox( NULL, "Error setting up AbortProc",
|
||||
"Error", MB_APPLMODAL | MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Init the DOCINFO and start the document. */
|
||||
init_doc_struct( &di, "MyDoc");
|
||||
StartDoc( hDC, &di );
|
||||
|
||||
/* Print one page. */
|
||||
StartPage( hDC );
|
||||
print_file(file_name, hDC );
|
||||
EndPage( hDC );
|
||||
|
||||
/* Indicate end of document. */
|
||||
EndDoc( hDC );
|
||||
|
||||
/* Clean up */
|
||||
DeleteDC( hDC );
|
||||
}
|
||||
|
||||
/*===============================*/
|
||||
/* Obtain printer device context */
|
||||
/* ==============================*/
|
||||
HDC get_printer_dc(void)
|
||||
{
|
||||
PRINTDLG pdlg;
|
||||
|
||||
/* Initialize the PRINTDLG structure. */
|
||||
memset( &pdlg, 0, sizeof( PRINTDLG ) );
|
||||
pdlg.lStructSize = sizeof( PRINTDLG );
|
||||
/* Set the flag to return printer DC. */
|
||||
pdlg.Flags = PD_RETURNDC;
|
||||
|
||||
/* Invoke the printer dialog box. */
|
||||
PrintDlg( &pdlg );
|
||||
|
||||
/* hDC member of the PRINTDLG structure contains the printer DC. */
|
||||
return pdlg.hDC;
|
||||
}
|
||||
|
||||
/*===============================*/
|
||||
/* The Abort Procudure */
|
||||
/* ==============================*/
|
||||
BOOL CALLBACK abort_proc( HDC hDC, int Error )
|
||||
{
|
||||
MSG msg;
|
||||
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
|
||||
{
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessage( &msg );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*===============================*/
|
||||
/* Initialize DOCINFO structure */
|
||||
/* ==============================*/
|
||||
void init_doc_struct( DOCINFO* di, char* docname)
|
||||
{
|
||||
/* Always zero it before using it. */
|
||||
memset( di, 0, sizeof( DOCINFO ) );
|
||||
/* Fill in the required members. */
|
||||
di->cbSize = sizeof( DOCINFO );
|
||||
di->lpszDocName = docname;
|
||||
}
|
||||
|
||||
/*===============================*/
|
||||
/* Drawing on the DC */
|
||||
/* ==============================*/
|
||||
void print_file( char *file_name, HDC hdc) {
|
||||
|
||||
#define max_buf_size 1024
|
||||
#define max_lines 66
|
||||
#define y_offset 5
|
||||
#define x_offset 5
|
||||
|
||||
FILE* fh1;
|
||||
int results, cnt=0, y_pos = y_offset, y_cnt = 0;
|
||||
char buf[ max_buf_size];
|
||||
char ch;
|
||||
TEXTMETRIC tm;
|
||||
|
||||
GetTextMetrics(hdc, &tm);
|
||||
SetMapMode (hdc, MM_TEXT);
|
||||
|
||||
|
||||
fh1 = fopen( file_name, "r" );
|
||||
if( !fh1 )
|
||||
perror( "open failed on input file" );
|
||||
|
||||
else {
|
||||
while ((results = fread( &ch, 1, 1, fh1 )) != 0) {
|
||||
|
||||
/* if end of line send buffer and more y position */
|
||||
|
||||
if ( ch == 0x0a){
|
||||
buf[ cnt] = 0;
|
||||
TextOut(hdc, x_offset,y_pos, buf, strlen(buf));
|
||||
y_pos += tm.tmHeight;
|
||||
cnt = 0;
|
||||
if ( ++y_cnt == max_lines){
|
||||
/* Print one page. */
|
||||
EndPage( hdc );
|
||||
StartPage( hdc );
|
||||
y_pos = y_offset;
|
||||
y_cnt = 0;
|
||||
}
|
||||
|
||||
/* if line buffer is full, dump it */
|
||||
}else { if ( cnt == ( max_buf_size - 1)) {
|
||||
buf[ cnt] = 0;
|
||||
TextOut(hdc, x_offset, y_pos, buf, strlen(buf));
|
||||
y_pos += tm.tmHeight;
|
||||
cnt = 0;
|
||||
|
||||
if ( ++y_cnt == max_lines){
|
||||
/* Print one page. */
|
||||
EndPage( hdc );
|
||||
StartPage( hdc );
|
||||
y_pos = y_offset;
|
||||
y_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
buf[ cnt++] = ch;
|
||||
}
|
||||
}
|
||||
/*XXX need feof test here ? */
|
||||
|
||||
/* Print the last text if needed */
|
||||
if ( cnt > 0) {
|
||||
buf[ cnt] = 0;
|
||||
TextOut(hdc, 0,y_pos, buf, strlen(buf));
|
||||
}
|
||||
fclose(fh1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* print_mswin.h
|
||||
* Printing support for MSWindows
|
||||
*
|
||||
* $$
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 2002, Jeffrey C. Foster <jfoste@woodward.com>
|
||||
*
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void print_mswin(char *file_name);
|
|
@ -0,0 +1,250 @@
|
|||
/* print_prefs.c
|
||||
* Dialog boxes for preferences for printing
|
||||
*
|
||||
* $Id: print_prefs.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "globals.h"
|
||||
#include "print_prefs.h"
|
||||
#include "keys.h"
|
||||
#include "print.h"
|
||||
#include "prefs.h"
|
||||
#include "prefs_dlg.h"
|
||||
#include "util.h"
|
||||
#include "ui_util.h"
|
||||
#include "dlg_utils.h"
|
||||
|
||||
static void printer_opts_file_cb(GtkWidget *w, gpointer te);
|
||||
static void printer_opts_fs_ok_cb(GtkWidget *w, gpointer data);
|
||||
static void printer_opts_fs_cancel_cb(GtkWidget *w, gpointer data);
|
||||
static void printer_opts_fs_destroy_cb(GtkWidget *win, gpointer data);
|
||||
|
||||
#define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
|
||||
#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
|
||||
#define E_PRINT_FORMAT_KEY "print_format"
|
||||
#define E_PRINT_DESTINATION_KEY "print_destination"
|
||||
|
||||
static const enum_val_t print_format_vals[] = {
|
||||
{ "Plain Text", PR_FMT_TEXT },
|
||||
{ "Postscript", PR_FMT_PS },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const enum_val_t print_dest_vals[] = {
|
||||
#ifdef _WIN32
|
||||
/* "PR_DEST_CMD" means "to printer" on Windows */
|
||||
{ "Printer", PR_DEST_CMD },
|
||||
#else
|
||||
{ "Command", PR_DEST_CMD },
|
||||
#endif
|
||||
{ "File", PR_DEST_FILE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
GtkWidget * printer_prefs_show(void)
|
||||
{
|
||||
GtkWidget *main_vb, *main_tb, *button;
|
||||
#ifndef _WIN32
|
||||
GtkWidget *cmd_te;
|
||||
#endif
|
||||
GtkWidget *file_bt_hb, *file_bt, *file_te;
|
||||
|
||||
/* Enclosing containers for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
|
||||
main_tb = gtk_table_new(4, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
gtk_widget_show(main_tb);
|
||||
|
||||
/* Output format */
|
||||
button = create_preference_radio_buttons(main_tb, 0, "Format:",
|
||||
NULL, print_format_vals, prefs.pr_format);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), E_PRINT_FORMAT_KEY, button);
|
||||
|
||||
/* Output destination */
|
||||
button = create_preference_radio_buttons(main_tb, 1, "Print to:",
|
||||
NULL, print_dest_vals, prefs.pr_dest);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), E_PRINT_DESTINATION_KEY,
|
||||
button);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Command text entry */
|
||||
cmd_te = create_preference_entry(main_tb, 2, "Command:", NULL,
|
||||
prefs.pr_cmd);
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PRINT_CMD_TE_KEY, cmd_te);
|
||||
#endif
|
||||
|
||||
/* File button and text entry */
|
||||
file_bt_hb = gtk_hbox_new(FALSE, 0);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), file_bt_hb, 0, 1, 3, 4);
|
||||
gtk_widget_show(file_bt_hb);
|
||||
|
||||
file_bt = gtk_button_new_with_label("File:");
|
||||
gtk_box_pack_end(GTK_BOX(file_bt_hb), file_bt, FALSE, FALSE, 0);
|
||||
gtk_widget_show(file_bt);
|
||||
|
||||
file_te = gtk_entry_new();
|
||||
gtk_object_set_data(GTK_OBJECT(main_vb), PRINT_FILE_TE_KEY, file_te);
|
||||
if (prefs.pr_file) gtk_entry_set_text(GTK_ENTRY(file_te), prefs.pr_file);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 3, 4);
|
||||
gtk_widget_show(file_te);
|
||||
|
||||
g_signal_connect(G_OBJECT(file_bt), "clicked",
|
||||
G_CALLBACK(printer_opts_file_cb), GTK_OBJECT(file_te));
|
||||
|
||||
gtk_widget_show(main_vb);
|
||||
return(main_vb);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
printer_opts_file_cb(GtkWidget *file_bt, gpointer file_te) {
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(file_bt);
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Has a file selection dialog box already been opened for that top-level
|
||||
widget? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Just re-activate that dialog box. */
|
||||
reactivate_window(fs);
|
||||
return;
|
||||
}
|
||||
|
||||
fs = gtk_file_selection_new ("Ethereal: Print to a File");
|
||||
gtk_object_set_data(GTK_OBJECT(fs), PRINT_FILE_TE_KEY, file_te);
|
||||
|
||||
/* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
|
||||
gtk_object_set_data(GTK_OBJECT(fs), E_FS_CALLER_PTR_KEY, caller);
|
||||
|
||||
/* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, fs);
|
||||
|
||||
/* Call a handler when the file selection box is destroyed, so we can inform
|
||||
our caller, if any, that it's been destroyed. */
|
||||
g_signal_connect(G_OBJECT(fs), "destroy",
|
||||
G_CALLBACK(printer_opts_fs_destroy_cb), NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), "clicked",
|
||||
G_CALLBACK(printer_opts_fs_ok_cb), fs);
|
||||
|
||||
/* Connect the cancel_button to destroy the widget */
|
||||
g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->cancel_button), "clicked",
|
||||
G_CALLBACK(printer_opts_fs_cancel_cb), fs);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
|
||||
|
||||
gtk_widget_show(fs);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_opts_fs_ok_cb(GtkWidget *w, gpointer data) {
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
|
||||
PRINT_FILE_TE_KEY)),
|
||||
gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
|
||||
printer_opts_fs_cancel_cb(w, data);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_opts_fs_cancel_cb(GtkWidget *w _U_, gpointer data) {
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(data));
|
||||
}
|
||||
|
||||
static void
|
||||
printer_opts_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
|
||||
{
|
||||
GtkWidget *caller;
|
||||
|
||||
/* Get the widget that requested that we be popped up.
|
||||
(It should arrange to destroy us if it's destroyed, so
|
||||
that we don't get a pointer to a non-existent window here.) */
|
||||
caller = gtk_object_get_data(GTK_OBJECT(win), E_FS_CALLER_PTR_KEY);
|
||||
|
||||
/* Tell it we no longer exist. */
|
||||
gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, NULL);
|
||||
|
||||
/* Now nuke this window. */
|
||||
gtk_grab_remove(GTK_WIDGET(win));
|
||||
gtk_widget_destroy(GTK_WIDGET(win));
|
||||
}
|
||||
|
||||
void
|
||||
printer_prefs_fetch(GtkWidget *w)
|
||||
{
|
||||
prefs.pr_format = fetch_preference_radio_buttons_val(
|
||||
gtk_object_get_data(GTK_OBJECT(w), E_PRINT_FORMAT_KEY),
|
||||
print_format_vals);
|
||||
|
||||
prefs.pr_dest = fetch_preference_radio_buttons_val(
|
||||
gtk_object_get_data(GTK_OBJECT(w), E_PRINT_DESTINATION_KEY),
|
||||
print_dest_vals);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (prefs.pr_cmd)
|
||||
g_free(prefs.pr_cmd);
|
||||
prefs.pr_cmd = g_strdup(gtk_entry_get_text(
|
||||
GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(w),
|
||||
PRINT_CMD_TE_KEY))));
|
||||
#endif
|
||||
|
||||
if (prefs.pr_file)
|
||||
g_free(prefs.pr_file);
|
||||
prefs.pr_file = g_strdup(gtk_entry_get_text(
|
||||
GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(w),
|
||||
PRINT_FILE_TE_KEY))));
|
||||
}
|
||||
|
||||
void
|
||||
printer_prefs_apply(GtkWidget *w _U_)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
printer_prefs_destroy(GtkWidget *w)
|
||||
{
|
||||
GtkWidget *caller = gtk_widget_get_toplevel(w);
|
||||
GtkWidget *fs;
|
||||
|
||||
/* Is there a file selection dialog associated with this
|
||||
Preferences dialog? */
|
||||
fs = gtk_object_get_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY);
|
||||
|
||||
if (fs != NULL) {
|
||||
/* Yes. Destroy it. */
|
||||
gtk_widget_destroy(fs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* print_prefs.h
|
||||
* Definitions for print preferences window
|
||||
*
|
||||
* $Id: print_prefs.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __PRINT_PREFS_H__
|
||||
#define __PRINT_PREFS_H__
|
||||
|
||||
GtkWidget *printer_prefs_show(void);
|
||||
void printer_prefs_fetch(GtkWidget *w);
|
||||
void printer_prefs_apply(GtkWidget *w);
|
||||
void printer_prefs_destroy(GtkWidget *w);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,380 @@
|
|||
/* progress_dlg.c
|
||||
* Routines for progress-bar (modal) dialog
|
||||
*
|
||||
* $Id: progress_dlg.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gtkglobals.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "progress_dlg.h"
|
||||
|
||||
#define PROG_BAR_KEY "progress_bar"
|
||||
|
||||
static gint delete_event_cb(GtkWidget *w, GdkEvent *event, gpointer data);
|
||||
static void stop_cb(GtkWidget *w, gpointer data);
|
||||
|
||||
/*
|
||||
* Define the structure describing a progress dialog.
|
||||
*/
|
||||
struct progdlg {
|
||||
GtkWidget *dlg_w; /* top-level window widget */
|
||||
GTimeVal start_time;
|
||||
GtkLabel *status_lb;
|
||||
GtkLabel *elapsed_lb;
|
||||
GtkLabel *time_left_lb;
|
||||
GtkLabel *percentage_lb;
|
||||
gchar title[200];
|
||||
};
|
||||
|
||||
/*
|
||||
* Create and pop up the progress dialog; allocate a "progdlg_t"
|
||||
* and initialize it to contain all information the implementation
|
||||
* needs in order to manipulate the dialog, and return a pointer to
|
||||
* it.
|
||||
*
|
||||
* The first argument is the task to do, e.g. "Loading".
|
||||
* The second argument is the item to do, e.g. "capture.cap".
|
||||
* The third argument is the string to put in the "stop this operation" button.
|
||||
* The fourth argument is a pointer to a Boolean variable that will be
|
||||
* set to TRUE if the user hits that button.
|
||||
*
|
||||
* XXX - provide a way to specify the progress in units, with the total
|
||||
* number of units specified as an argument when the progress dialog
|
||||
* is created; updates would be given in units, with the progress dialog
|
||||
* code computing the percentage, and the progress bar would have a
|
||||
* label "0" on the left and <total number of units> on the right, with
|
||||
* a label in the middle giving the number of units we've processed
|
||||
* so far. This could be used when filtering packets, for example; we
|
||||
* wouldn't always use it, as we have no idea how many packets are to
|
||||
* be read.
|
||||
*/
|
||||
progdlg_t *
|
||||
create_progress_dlg(const gchar *task_title, const gchar *item_title,
|
||||
const gchar *stop_title, gboolean *stop_flag)
|
||||
{
|
||||
progdlg_t *dlg;
|
||||
GtkWidget *dlg_w, *main_vb, *title_lb, *status_lb, *elapsed_lb, *time_left_lb, *percentage_lb;
|
||||
GtkWidget *prog_bar, *bbox, *stop_bt;
|
||||
GtkWidget *static_vb, *tmp_lb, *main_hb, *dynamic_vb, *percentage_hb;
|
||||
gchar tmp[100];
|
||||
|
||||
dlg = g_malloc(sizeof (progdlg_t));
|
||||
|
||||
g_snprintf(dlg->title, sizeof(dlg->title), "%s: %s",
|
||||
task_title, item_title);
|
||||
|
||||
dlg_w = dlg_window_new(dlg->title);
|
||||
gtk_window_set_modal(GTK_WINDOW(dlg_w), TRUE);
|
||||
|
||||
/*
|
||||
* Container for dialog widgets.
|
||||
*/
|
||||
main_vb = gtk_vbox_new(FALSE, 1);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(dlg_w), main_vb);
|
||||
|
||||
/*
|
||||
* Static labels (left dialog side, labels aligned to the right)
|
||||
*/
|
||||
static_vb = gtk_vbox_new(FALSE, 1);
|
||||
g_snprintf (tmp, sizeof(tmp), "%s:", task_title);
|
||||
tmp_lb = gtk_label_new(tmp);
|
||||
gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0);
|
||||
gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3);
|
||||
tmp_lb = gtk_label_new("Status:");
|
||||
gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0);
|
||||
gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3);
|
||||
tmp_lb = gtk_label_new("Elapsed Time:");
|
||||
gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0);
|
||||
gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3);
|
||||
tmp_lb = gtk_label_new("Time Left:");
|
||||
gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0);
|
||||
gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3);
|
||||
tmp_lb = gtk_label_new("Progress:");
|
||||
gtk_misc_set_alignment(GTK_MISC(tmp_lb), 1.0, 0.0);
|
||||
gtk_box_pack_start(GTK_BOX(static_vb), tmp_lb, FALSE, TRUE, 3);
|
||||
|
||||
|
||||
/*
|
||||
* Dynamic labels (right dialog side, labels aligned to the left)
|
||||
*/
|
||||
dynamic_vb = gtk_vbox_new(FALSE, 1);
|
||||
|
||||
/*
|
||||
* Put the item_title here as a label indicating what we're
|
||||
* doing; set its alignment and padding so it's aligned on the
|
||||
* left.
|
||||
*/
|
||||
title_lb = gtk_label_new(item_title);
|
||||
gtk_box_pack_start(GTK_BOX(dynamic_vb), title_lb, FALSE, TRUE, 3);
|
||||
gtk_misc_set_alignment(GTK_MISC(title_lb), 0.0, 0.0);
|
||||
gtk_misc_set_padding(GTK_MISC(title_lb), 0.0, 0.0);
|
||||
|
||||
/* same for "Status" */
|
||||
status_lb = gtk_label_new("");
|
||||
gtk_box_pack_start(GTK_BOX(dynamic_vb), status_lb, FALSE, TRUE, 3);
|
||||
gtk_misc_set_alignment(GTK_MISC(status_lb), 0.0, 0.0);
|
||||
gtk_misc_set_padding(GTK_MISC(status_lb), 0.0, 0.0);
|
||||
dlg->status_lb = (GtkLabel *) status_lb;
|
||||
|
||||
/* same for "Elapsed Time" */
|
||||
elapsed_lb = gtk_label_new("00:00");
|
||||
gtk_box_pack_start(GTK_BOX(dynamic_vb), elapsed_lb, FALSE, TRUE, 3);
|
||||
gtk_misc_set_alignment(GTK_MISC(elapsed_lb), 0.0, 0.0);
|
||||
gtk_misc_set_padding(GTK_MISC(elapsed_lb), 0.0, 0.0);
|
||||
dlg->elapsed_lb = (GtkLabel *) elapsed_lb;
|
||||
|
||||
/* same for "Time Left" */
|
||||
time_left_lb = gtk_label_new("--:--");
|
||||
gtk_box_pack_start(GTK_BOX(dynamic_vb), time_left_lb, FALSE, TRUE, 3);
|
||||
gtk_misc_set_alignment(GTK_MISC(time_left_lb), 0.0, 0.0);
|
||||
gtk_misc_set_padding(GTK_MISC(time_left_lb), 0.0, 0.0);
|
||||
dlg->time_left_lb = (GtkLabel *) time_left_lb;
|
||||
|
||||
/*
|
||||
* The progress bar (in its own horizontal box, including percentage
|
||||
* value)
|
||||
*/
|
||||
percentage_hb = gtk_hbox_new(FALSE, 1);
|
||||
gtk_box_pack_start(GTK_BOX(dynamic_vb), percentage_hb, FALSE, TRUE, 3);
|
||||
|
||||
prog_bar = gtk_progress_bar_new();
|
||||
gtk_box_pack_start(GTK_BOX(percentage_hb), prog_bar, FALSE, TRUE, 3);
|
||||
|
||||
percentage_lb = gtk_label_new(" 0%");
|
||||
gtk_misc_set_alignment(GTK_MISC(percentage_lb), 0.0, 0.0);
|
||||
gtk_box_pack_start(GTK_BOX(percentage_hb), percentage_lb, FALSE, TRUE,
|
||||
3);
|
||||
dlg->percentage_lb = (GtkLabel *) percentage_lb;
|
||||
|
||||
/*
|
||||
* Attach a pointer to the progress bar widget to the top-level widget.
|
||||
*/
|
||||
gtk_object_set_data(GTK_OBJECT(dlg_w), PROG_BAR_KEY, prog_bar);
|
||||
|
||||
/*
|
||||
* Static and dynamic boxes are now complete
|
||||
*/
|
||||
main_hb = gtk_hbox_new(FALSE, 1);
|
||||
gtk_box_pack_start(GTK_BOX(main_hb), static_vb, FALSE, TRUE, 3);
|
||||
gtk_box_pack_start(GTK_BOX(main_hb), dynamic_vb, FALSE, TRUE, 3);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_hb, FALSE, TRUE, 3);
|
||||
|
||||
/*
|
||||
* Button row: cancel button.
|
||||
* (We put it in an HButtonBox, even though there's only one
|
||||
* of them, so that it doesn't expand to the width of the window.)
|
||||
*/
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
|
||||
/*
|
||||
* Allow user to either click a "stop this operation" button, or
|
||||
* the close button on the window, to stop an operation in
|
||||
* progress.
|
||||
*/
|
||||
stop_bt = gtk_button_new_with_label(stop_title);
|
||||
gtk_box_pack_start(GTK_BOX (bbox), stop_bt, TRUE, TRUE, 0);
|
||||
g_signal_connect(G_OBJECT(stop_bt), "clicked",
|
||||
G_CALLBACK(stop_cb), (gpointer) stop_flag);
|
||||
g_signal_connect(G_OBJECT(dlg_w), "delete_event",
|
||||
G_CALLBACK(delete_event_cb), (gpointer) stop_flag);
|
||||
GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
|
||||
gtk_widget_grab_default(stop_bt);
|
||||
GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
|
||||
gtk_widget_grab_default(stop_bt);
|
||||
|
||||
gtk_widget_show_all(dlg_w);
|
||||
|
||||
dlg->dlg_w = dlg_w;
|
||||
|
||||
g_get_current_time(&dlg->start_time);
|
||||
|
||||
return dlg;
|
||||
}
|
||||
|
||||
progdlg_t *
|
||||
delayed_create_progress_dlg(const gchar *task_title, const gchar *item_title,
|
||||
const gchar *stop_title, gboolean *stop_flag,
|
||||
const GTimeVal *start_time, gfloat progress)
|
||||
{
|
||||
GTimeVal time_now;
|
||||
gfloat delta_time;
|
||||
gfloat min_display;
|
||||
progdlg_t *dlg;
|
||||
|
||||
#define INIT_DELAY 0.5 * 1e6
|
||||
#define MIN_DISPLAY_DEFAULT 2.0 * 1e6
|
||||
|
||||
/* Create a progress dialog, but only if it's not likely to disappear
|
||||
* immediately, which can be disconcerting for the user.
|
||||
*
|
||||
* Arguments are as for create_progress_dlg(), plus:
|
||||
*
|
||||
* (a) A pointer to a GTimeVal structure which holds the time at which
|
||||
* the caller started to process the data.
|
||||
* (b) The current progress as a real number between 0 and 1.
|
||||
*/
|
||||
g_get_current_time(&time_now);
|
||||
|
||||
/* Get the time elapsed since the caller started processing the data */
|
||||
|
||||
delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
|
||||
time_now.tv_usec - start_time->tv_usec;
|
||||
|
||||
/* Do nothing for the first INIT_DELAY microseconds */
|
||||
if (delta_time < INIT_DELAY)
|
||||
return NULL;
|
||||
|
||||
/* If we create the progress dialog we want it to be displayed for a
|
||||
* minimum of MIN_DISPLAY_DEFAULT microseconds. However, if we
|
||||
* previously estimated that the progress dialog didn't need to be
|
||||
* created and the caller's processing is slowing down (perhaps due
|
||||
* to the action of the operating system's scheduler on a compute-
|
||||
* intensive task), we tail off the minimum display time such that
|
||||
* the progress dialog will always be created after
|
||||
* 2*MIN_DISPLAY_DEFAULT microseconds.
|
||||
*/
|
||||
|
||||
if (delta_time <= INIT_DELAY + MIN_DISPLAY_DEFAULT)
|
||||
min_display = MIN_DISPLAY_DEFAULT;
|
||||
else
|
||||
min_display = 2 * MIN_DISPLAY_DEFAULT - delta_time;
|
||||
/* = MIN_DISPLAY_DEFAULT - (delta_time - MIN_DISPLAY_DEFAULT) */
|
||||
|
||||
/* Assuming the progress increases linearly, see if the progress
|
||||
* dialog would be displayed for at least min_display microseconds if
|
||||
* we created it now.
|
||||
*/
|
||||
|
||||
if (progress >= (delta_time / (delta_time + min_display)))
|
||||
return NULL;
|
||||
|
||||
dlg = create_progress_dlg(task_title, item_title, stop_title,
|
||||
stop_flag);
|
||||
|
||||
/* set dialog start_time to the start of processing, not box creation */
|
||||
dlg->start_time = *start_time;
|
||||
|
||||
return dlg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when the dialog box is to be deleted.
|
||||
* Set the "stop" flag to TRUE, and return TRUE - we don't want the dialog
|
||||
* box deleted now, our caller will do so when they see that the
|
||||
* "stop" flag is TRUE and abort the operation.
|
||||
*/
|
||||
static gint
|
||||
delete_event_cb(GtkWidget *w _U_, GdkEvent *event _U_, gpointer data)
|
||||
{
|
||||
gboolean *stop_flag = (gboolean *) data;
|
||||
|
||||
*stop_flag = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when the "stop this operation" button is clicked.
|
||||
* Set the "stop" flag to TRUE; we don't have to destroy the dialog
|
||||
* box, as our caller will do so when they see that the "stop" flag is
|
||||
* true and abort the operation.
|
||||
*/
|
||||
static void
|
||||
stop_cb(GtkWidget *w _U_, gpointer data)
|
||||
{
|
||||
gboolean *stop_flag = (gboolean *) data;
|
||||
|
||||
*stop_flag = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the progress information of the progress dialog box.
|
||||
*/
|
||||
void
|
||||
update_progress_dlg(progdlg_t *dlg, gfloat percentage, char *status)
|
||||
{
|
||||
GtkWidget *dlg_w = dlg->dlg_w;
|
||||
GtkWidget *prog_bar;
|
||||
GTimeVal time_now;
|
||||
gfloat delta_time;
|
||||
gulong ul_left;
|
||||
gulong ul_elapsed;
|
||||
gulong ul_percentage;
|
||||
gchar tmp[100];
|
||||
|
||||
/* calculate some timing values */
|
||||
g_get_current_time(&time_now);
|
||||
|
||||
delta_time = (time_now.tv_sec - dlg->start_time.tv_sec) * 1e6 +
|
||||
time_now.tv_usec - dlg->start_time.tv_usec;
|
||||
ul_percentage = percentage * 100;
|
||||
ul_elapsed = delta_time / 1000 / 1000;
|
||||
|
||||
/* update labels */
|
||||
g_snprintf(tmp, sizeof(tmp), "%lu%% of %s", ul_percentage, dlg->title);
|
||||
gtk_window_set_title(GTK_WINDOW(dlg_w), tmp);
|
||||
|
||||
gtk_label_set_text(dlg->status_lb, status);
|
||||
|
||||
g_snprintf(tmp, sizeof(tmp), "%lu%%", ul_percentage);
|
||||
gtk_label_set_text(dlg->percentage_lb, tmp);
|
||||
|
||||
g_snprintf(tmp, sizeof(tmp), "%02lu:%02lu", ul_elapsed / 60,
|
||||
ul_elapsed % 60);
|
||||
gtk_label_set_text(dlg->elapsed_lb, tmp);
|
||||
|
||||
/* show "Time Left" only,
|
||||
* if at least 5% and 3 seconds running (to get a useful estimation) */
|
||||
if (ul_percentage >= 5 && delta_time >= 3 * 1e6) {
|
||||
ul_left = (delta_time / percentage - delta_time) / 1000 / 1000;
|
||||
g_snprintf(tmp, sizeof(tmp), "%02lu:%02lu", ul_left / 60,
|
||||
ul_left % 60);
|
||||
gtk_label_set_text(dlg->time_left_lb, tmp);
|
||||
}
|
||||
|
||||
/* update progress bar */
|
||||
prog_bar = gtk_object_get_data(GTK_OBJECT(dlg_w), PROG_BAR_KEY);
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prog_bar), percentage);
|
||||
|
||||
/*
|
||||
* Flush out the update and process any input events.
|
||||
*/
|
||||
while (gtk_events_pending())
|
||||
gtk_main_iteration();
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the progress dialog.
|
||||
*/
|
||||
void
|
||||
destroy_progress_dlg(progdlg_t *dlg)
|
||||
{
|
||||
GtkWidget *dlg_w = dlg->dlg_w;
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(dlg_w));
|
||||
g_free(dlg);
|
||||
}
|
|
@ -0,0 +1,412 @@
|
|||
/* proto_dlg.c
|
||||
*
|
||||
* $Id: proto_dlg.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Laurent Deniel <deniel@worldnet.fr>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 2000 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "prefs.h"
|
||||
#include "globals.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
#include "ui_util.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "proto_dlg.h"
|
||||
|
||||
static gboolean proto_delete_cb(GtkWidget *, gpointer);
|
||||
static void proto_ok_cb(GtkWidget *, gpointer);
|
||||
static void proto_apply_cb(GtkWidget *, gpointer);
|
||||
static void proto_cancel_cb(GtkWidget *, gpointer);
|
||||
static void proto_destroy_cb(GtkWidget *, gpointer);
|
||||
|
||||
static void show_proto_selection(GtkWidget *main, GtkWidget *container);
|
||||
static gboolean set_proto_selection(GtkWidget *);
|
||||
static gboolean revert_proto_selection(void);
|
||||
|
||||
static void toggle_all_cb(GtkWidget *button, gpointer parent_w);
|
||||
static void enable_all_cb(GtkWidget *button, gpointer parent_w);
|
||||
static void disable_all_cb(GtkWidget *button, gpointer parent_w);
|
||||
|
||||
static GtkWidget *proto_w = NULL;
|
||||
|
||||
/* list of protocols */
|
||||
static GSList *protocol_list = NULL;
|
||||
|
||||
typedef struct protocol_data {
|
||||
char *name;
|
||||
char *abbrev;
|
||||
int hfinfo_index;
|
||||
gboolean was_enabled;
|
||||
} protocol_data_t;
|
||||
|
||||
void proto_cb(GtkWidget *w _U_, gpointer data _U_)
|
||||
{
|
||||
|
||||
GtkWidget *main_vb, *bbox, *proto_nb, *apply_bt, *cancel_bt, *ok_bt,
|
||||
*label, *scrolled_w, *selection_vb, *button;
|
||||
|
||||
if (proto_w != NULL) {
|
||||
reactivate_window(proto_w);
|
||||
return;
|
||||
}
|
||||
|
||||
proto_w = dlg_window_new("Ethereal: Protocol");
|
||||
g_signal_connect(G_OBJECT(proto_w), "delete_event",
|
||||
G_CALLBACK(proto_delete_cb), NULL);
|
||||
g_signal_connect(G_OBJECT(proto_w), "destroy",
|
||||
G_CALLBACK(proto_destroy_cb), NULL);
|
||||
gtk_widget_set_size_request(GTK_WIDGET(proto_w), DEF_WIDTH * 2/3,
|
||||
DEF_HEIGHT * 2/3);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
|
||||
main_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 1);
|
||||
gtk_container_add(GTK_CONTAINER(proto_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* Protocol topics container */
|
||||
|
||||
proto_nb = gtk_notebook_new();
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), proto_nb);
|
||||
/* XXX do not know why I need this to fill all space around buttons */
|
||||
gtk_widget_set_size_request(GTK_WIDGET(proto_nb), DEF_WIDTH * 2/3 - 50,
|
||||
DEF_HEIGHT * 2/3 - 50);
|
||||
|
||||
/* Protocol selection panel ("enable/disable" protocols) */
|
||||
|
||||
selection_vb = gtk_vbox_new(FALSE, 0);
|
||||
gtk_container_border_width(GTK_CONTAINER(selection_vb), 1);
|
||||
label = gtk_label_new("Button pressed: protocol decoding is enabled");
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(selection_vb), label, FALSE, FALSE, 0);
|
||||
scrolled_w = scrolled_window_new(NULL, NULL);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(scrolled_w), 1);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_w),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_ALWAYS);
|
||||
gtk_box_pack_start(GTK_BOX(selection_vb), scrolled_w, TRUE, TRUE, 0);
|
||||
show_proto_selection(proto_w, scrolled_w);
|
||||
gtk_widget_show(scrolled_w);
|
||||
gtk_widget_show(selection_vb);
|
||||
label = gtk_label_new("Decoding");
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(proto_nb), selection_vb, label);
|
||||
label = gtk_label_new("Note that when a protocol is disabled, "
|
||||
"all linked sub-protocols are as well");
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(selection_vb), label, FALSE, FALSE, 0);
|
||||
|
||||
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_box_pack_start(GTK_BOX(selection_vb), bbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
/* Toggle All */
|
||||
button = gtk_button_new_with_label("Toggle All");
|
||||
g_signal_connect(G_OBJECT(button), "clicked",
|
||||
G_CALLBACK(toggle_all_cb), GTK_OBJECT(proto_w));
|
||||
gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
/* Enable All */
|
||||
button = gtk_button_new_with_label("Enable All");
|
||||
g_signal_connect(G_OBJECT(button), "clicked",
|
||||
G_CALLBACK(enable_all_cb), GTK_OBJECT(proto_w));
|
||||
gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
/* Disable All */
|
||||
button = gtk_button_new_with_label("Disable All");
|
||||
g_signal_connect(G_OBJECT(button), "clicked",
|
||||
G_CALLBACK(disable_all_cb), GTK_OBJECT(proto_w));
|
||||
gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
|
||||
/* XXX add other protocol-related panels here ... */
|
||||
|
||||
gtk_widget_show(proto_nb);
|
||||
|
||||
/* Ok, Apply, Cancel Buttons */
|
||||
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_bt = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
g_signal_connect(G_OBJECT(ok_bt), "clicked",
|
||||
G_CALLBACK(proto_ok_cb), GTK_OBJECT(proto_w));
|
||||
GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_grab_default(ok_bt);
|
||||
gtk_widget_show(ok_bt);
|
||||
|
||||
apply_bt = gtk_button_new_from_stock(GTK_STOCK_APPLY);
|
||||
g_signal_connect(G_OBJECT(apply_bt), "clicked",
|
||||
G_CALLBACK(proto_apply_cb), GTK_OBJECT(proto_w));
|
||||
GTK_WIDGET_SET_FLAGS(apply_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX (bbox), apply_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(apply_bt);
|
||||
|
||||
cancel_bt = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_bt), "clicked",
|
||||
G_CALLBACK(proto_cancel_cb), GTK_OBJECT(proto_w));
|
||||
GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
|
||||
gtk_widget_show(cancel_bt);
|
||||
|
||||
dlg_set_cancel(proto_w, cancel_bt);
|
||||
|
||||
gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(proto_w));
|
||||
gtk_widget_show(proto_w);
|
||||
|
||||
} /* proto_cb */
|
||||
|
||||
|
||||
/* Toggle All */
|
||||
static void
|
||||
toggle_all_cb(GtkWidget *button _U_, gpointer parent_w)
|
||||
{
|
||||
|
||||
GSList *entry;
|
||||
|
||||
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
|
||||
GtkWidget *button;
|
||||
protocol_data_t *p = entry->data;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
p->abbrev);
|
||||
/* gtk_toggle_button_toggled() didn't work for me... */
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
|
||||
!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable/Disable All Helper */
|
||||
static void
|
||||
set_active_all(gpointer parent_w, gboolean new_state)
|
||||
{
|
||||
|
||||
GSList *entry;
|
||||
|
||||
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
|
||||
GtkWidget *button;
|
||||
protocol_data_t *p = entry->data;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
p->abbrev);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), new_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable All */
|
||||
static void
|
||||
enable_all_cb(GtkWidget *button _U_, gpointer parent_w)
|
||||
{
|
||||
set_active_all(parent_w, TRUE);
|
||||
}
|
||||
|
||||
/* Disable All */
|
||||
static void
|
||||
disable_all_cb(GtkWidget *button _U_, gpointer parent_w)
|
||||
{
|
||||
set_active_all(parent_w, FALSE);
|
||||
}
|
||||
|
||||
static void proto_destroy_cb(GtkWidget *w _U_, gpointer data _U_)
|
||||
{
|
||||
GSList *entry;
|
||||
|
||||
if (proto_w)
|
||||
gtk_widget_destroy(proto_w);
|
||||
proto_w = NULL;
|
||||
|
||||
/* remove protocol list */
|
||||
if (protocol_list) {
|
||||
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
|
||||
g_free(entry->data);
|
||||
}
|
||||
g_slist_free(protocol_list);
|
||||
protocol_list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Treat this as a cancel, by calling "proto_cancel_cb()".
|
||||
XXX - that'll destroy the Protocols dialog; will that upset
|
||||
a higher-level handler that says "OK, we've been asked to delete
|
||||
this, so destroy it"? */
|
||||
static gboolean proto_delete_cb(GtkWidget *proto_w, gpointer dummy _U_)
|
||||
{
|
||||
proto_cancel_cb(NULL, proto_w);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void proto_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gboolean redissect;
|
||||
|
||||
redissect = set_proto_selection(GTK_WIDGET(parent_w));
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
if (redissect)
|
||||
redissect_packets(&cfile);
|
||||
}
|
||||
|
||||
static void proto_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w)
|
||||
{
|
||||
if (set_proto_selection(GTK_WIDGET(parent_w)))
|
||||
redissect_packets(&cfile);
|
||||
}
|
||||
|
||||
static void proto_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
|
||||
{
|
||||
gboolean redissect;
|
||||
|
||||
redissect = revert_proto_selection();
|
||||
gtk_widget_destroy(GTK_WIDGET(parent_w));
|
||||
if (redissect)
|
||||
redissect_packets(&cfile);
|
||||
}
|
||||
|
||||
static gboolean set_proto_selection(GtkWidget *parent_w)
|
||||
{
|
||||
GSList *entry;
|
||||
gboolean need_redissect = FALSE;
|
||||
|
||||
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
|
||||
GtkWidget *button;
|
||||
protocol_data_t *p = entry->data;
|
||||
|
||||
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
|
||||
p->abbrev);
|
||||
if (proto_is_protocol_enabled(p->hfinfo_index) != GTK_TOGGLE_BUTTON (button)->active) {
|
||||
proto_set_decoding(p->hfinfo_index, GTK_TOGGLE_BUTTON (button)->active);
|
||||
need_redissect = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return need_redissect;
|
||||
|
||||
} /* set_proto_selection */
|
||||
|
||||
static gboolean revert_proto_selection(void)
|
||||
{
|
||||
GSList *entry;
|
||||
gboolean need_redissect = FALSE;
|
||||
|
||||
/*
|
||||
* Undo all the changes we've made to protocol enable flags.
|
||||
*/
|
||||
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
|
||||
protocol_data_t *p = entry->data;
|
||||
|
||||
if (proto_is_protocol_enabled(p->hfinfo_index) != p->was_enabled) {
|
||||
proto_set_decoding(p->hfinfo_index, p->was_enabled);
|
||||
need_redissect = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return need_redissect;
|
||||
|
||||
} /* revert_proto_selection */
|
||||
|
||||
gint protocol_data_compare(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return strcmp(((protocol_data_t *)a)->abbrev,
|
||||
((protocol_data_t *)b)->abbrev);
|
||||
}
|
||||
|
||||
static void show_proto_selection(GtkWidget *main, GtkWidget *container)
|
||||
{
|
||||
|
||||
#define NB_COL 7
|
||||
|
||||
GSList *entry;
|
||||
GtkTooltips *tooltips;
|
||||
GtkWidget *table;
|
||||
int i, t = 0, l = 0, nb_line, nb_proto = 0;
|
||||
void *cookie;
|
||||
protocol_data_t *p;
|
||||
|
||||
/* Iterate over all the protocols */
|
||||
|
||||
for (i = proto_get_first_protocol(&cookie); i != -1;
|
||||
i = proto_get_next_protocol(&cookie)) {
|
||||
if (proto_can_disable_protocol(i)) {
|
||||
p = g_malloc(sizeof(protocol_data_t));
|
||||
p->name = proto_get_protocol_name(i);
|
||||
p->abbrev = proto_get_protocol_filter_name(i);
|
||||
p->hfinfo_index = i;
|
||||
p->was_enabled = proto_is_protocol_enabled(i);
|
||||
protocol_list = g_slist_insert_sorted(protocol_list,
|
||||
p, protocol_data_compare);
|
||||
nb_proto ++;
|
||||
}
|
||||
}
|
||||
|
||||
/* create a table (n x NB_COL) of buttons */
|
||||
|
||||
nb_line = (nb_proto % NB_COL) ? nb_proto / NB_COL + 1 : nb_proto / NB_COL;
|
||||
table = gtk_table_new (nb_line, NB_COL, FALSE);
|
||||
gtk_table_set_row_spacings(GTK_TABLE (table), 1);
|
||||
gtk_table_set_col_spacings(GTK_TABLE (table), 1);
|
||||
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(container), table);
|
||||
gtk_widget_show(table);
|
||||
|
||||
tooltips = gtk_tooltips_new();
|
||||
|
||||
nb_proto = 0;
|
||||
|
||||
for (entry = protocol_list; entry != NULL; entry = g_slist_next(entry)) {
|
||||
GtkWidget *button;
|
||||
|
||||
p = entry->data;
|
||||
/* button label is the protocol abbrev */
|
||||
button = gtk_toggle_button_new_with_label(p->abbrev);
|
||||
/* tip is the complete protocol name */
|
||||
gtk_tooltips_set_tip(tooltips, button, p->name, NULL);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
proto_is_protocol_enabled(p->hfinfo_index));
|
||||
gtk_object_set_data(GTK_OBJECT(main), p->abbrev, button);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), button, l, l+1, t, t+1);
|
||||
gtk_widget_show (button);
|
||||
if (++nb_proto % NB_COL) {
|
||||
l++;
|
||||
}
|
||||
else {
|
||||
l = 0;
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
} /* show_proto_selection */
|
|
@ -0,0 +1,32 @@
|
|||
/* proto_dlg.h
|
||||
*
|
||||
* $Id: proto_dlg.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Laurent Deniel <deniel@worldnet.fr>
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* Copyright 2000 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PROTO_DLG_H__
|
||||
#define __PROTO_DLG_H__
|
||||
|
||||
void proto_cb(GtkWidget *, gpointer);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,70 @@
|
|||
/* proto_draw.h
|
||||
* Definitions for GTK+ packet display structures and routines
|
||||
*
|
||||
* $Id: proto_draw.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GTKPACKET_H__
|
||||
#define __GTKPACKET_H__
|
||||
|
||||
/* Get the current text window for the notebook. */
|
||||
extern GtkWidget *get_notebook_bv_ptr(GtkWidget *nb_ptr);
|
||||
|
||||
/*
|
||||
* Get the data and length for a byte view, given the byte view page.
|
||||
* Return the pointer, or NULL on error, and set "*data_len" to the length.
|
||||
*/
|
||||
extern const guint8 *get_byte_view_data_and_length(GtkWidget *byte_view,
|
||||
guint *data_len);
|
||||
|
||||
/*
|
||||
* Set the current text window for the notebook to the window that
|
||||
* refers to a particular tvbuff.
|
||||
*/
|
||||
extern void set_notebook_page(GtkWidget *nb_ptr, tvbuff_t *tvb);
|
||||
|
||||
/* Redraw a given byte view window. */
|
||||
extern void redraw_hex_dump(GtkWidget *nb, frame_data *fd, field_info *finfo);
|
||||
|
||||
/* Redraw all byte view windows. */
|
||||
extern void redraw_hex_dump_all(void);
|
||||
|
||||
extern GtkWidget *create_byte_view(gint bv_size, GtkWidget *pane);
|
||||
|
||||
extern void add_byte_views(epan_dissect_t *edt, GtkWidget *tree_view,
|
||||
GtkWidget *byte_nb_ptr);
|
||||
|
||||
void packet_hex_print(GtkTextView *, const guint8 *, frame_data *, field_info *,
|
||||
guint);
|
||||
void packet_hex_reprint(GtkTextView *);
|
||||
|
||||
void create_tree_view(gint tv_size, e_prefs *prefs, GtkWidget *pane,
|
||||
GtkWidget **tv_scrollw_p, GtkWidget **tree_view_p);
|
||||
void proto_tree_draw(proto_tree *protocol_tree, GtkWidget *tree_view);
|
||||
void expand_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view);
|
||||
void collapse_all_tree(proto_tree *protocol_tree, GtkWidget *tree_view);
|
||||
|
||||
void set_ptree_sel_browse_all(gboolean);
|
||||
void set_ptree_font_all(PangoFontDescription *font);
|
||||
|
||||
void clear_tree_and_hex_views(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,253 @@
|
|||
/* proto_hier_stats_dlg.c
|
||||
*
|
||||
* $Id: proto_hier_stats_dlg.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "proto_hier_stats.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "ui_util.h"
|
||||
#include "main.h"
|
||||
|
||||
enum {
|
||||
PROTOCOL_COLUMN,
|
||||
PRCT_PKTS_COLUMN,
|
||||
PKTS_COLUMN,
|
||||
BYTES_COLUMN,
|
||||
END_PKTS_COLUMN,
|
||||
END_BYTES_COLUMN,
|
||||
NUM_STAT_COLUMNS /* must be the last */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreeIter *iter;
|
||||
ph_stats_t *ps;
|
||||
|
||||
} draw_info_t;
|
||||
|
||||
|
||||
#define PCT(x,y) (100.0 * (float)(x) / (float)(y))
|
||||
|
||||
static void
|
||||
fill_in_tree_node(GNode *node, gpointer data)
|
||||
{
|
||||
ph_stats_node_t *stats = node->data;
|
||||
draw_info_t *di = data;
|
||||
|
||||
GtkTreeView *tree_view = di->tree_view;
|
||||
GtkTreeIter *iter = di->iter;
|
||||
GtkTreeStore *store;
|
||||
ph_stats_t *ps = di->ps;
|
||||
|
||||
gchar *text[2];
|
||||
gboolean is_leaf;
|
||||
GtkTreeIter new_iter;
|
||||
|
||||
draw_info_t child_di;
|
||||
|
||||
if (g_node_n_children(node) > 0) {
|
||||
is_leaf = FALSE;
|
||||
}
|
||||
else {
|
||||
is_leaf = TRUE;
|
||||
}
|
||||
|
||||
text[0] = stats->hfinfo->name;
|
||||
text[1] = g_strdup_printf("%6.2f%%",
|
||||
PCT(stats->num_pkts_total, ps->tot_packets));
|
||||
|
||||
store = GTK_TREE_STORE(gtk_tree_view_get_model(tree_view));
|
||||
gtk_tree_store_append(store, &new_iter, iter);
|
||||
gtk_tree_store_set(store, &new_iter,
|
||||
PROTOCOL_COLUMN, text[0],
|
||||
PRCT_PKTS_COLUMN, text[1],
|
||||
PKTS_COLUMN, stats->num_pkts_total,
|
||||
BYTES_COLUMN, stats->num_bytes_total,
|
||||
END_PKTS_COLUMN, stats->num_pkts_last,
|
||||
END_BYTES_COLUMN, stats->num_bytes_last,
|
||||
-1);
|
||||
|
||||
g_free(text[1]);
|
||||
|
||||
child_di.tree_view = tree_view;
|
||||
child_di.iter = &new_iter;
|
||||
child_di.ps = ps;
|
||||
|
||||
g_node_children_foreach(node, G_TRAVERSE_ALL,
|
||||
fill_in_tree_node, &child_di);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_in_tree(GtkTreeView *tree, ph_stats_t *ps)
|
||||
{
|
||||
draw_info_t di;
|
||||
|
||||
di.tree_view = tree;
|
||||
di.iter = NULL;
|
||||
di.ps = ps;
|
||||
|
||||
g_node_children_foreach(ps->stats_tree, G_TRAVERSE_ALL,
|
||||
fill_in_tree_node, &di);
|
||||
}
|
||||
|
||||
#define MAX_DLG_HEIGHT 450
|
||||
#define DEF_DLG_WIDTH 600
|
||||
|
||||
static void
|
||||
create_tree(GtkWidget *container, ph_stats_t *ps)
|
||||
{
|
||||
GtkWidget *sw, *tree;
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreeStore *store;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
/* Scrolled Window */
|
||||
sw = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add(GTK_CONTAINER(container), sw);
|
||||
|
||||
store = gtk_tree_store_new(NUM_STAT_COLUMNS, G_TYPE_STRING,
|
||||
G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT,
|
||||
G_TYPE_UINT, G_TYPE_UINT);
|
||||
tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
tree_view = GTK_TREE_VIEW(tree);
|
||||
gtk_tree_view_set_rules_hint(tree_view, TRUE);
|
||||
gtk_tree_view_set_headers_visible(tree_view, TRUE);
|
||||
gtk_tree_view_set_headers_clickable(tree_view, FALSE);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Protocol", renderer,
|
||||
"text", PROTOCOL_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
gtk_tree_view_append_column(tree_view, column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("% Packets", renderer,
|
||||
"text", PRCT_PKTS_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
gtk_tree_view_append_column(tree_view, column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Packets", renderer,
|
||||
"text", PKTS_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
gtk_tree_view_append_column(tree_view, column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("Bytes", renderer,
|
||||
"text", BYTES_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
gtk_tree_view_append_column(tree_view, column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("End Packets",
|
||||
renderer, "text",
|
||||
END_PKTS_COLUMN, NULL);
|
||||
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
gtk_tree_view_append_column(tree_view, column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes("End Bytes", renderer,
|
||||
"text", END_BYTES_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
gtk_tree_view_append_column(tree_view, column);
|
||||
|
||||
/* XXX - get 'pos' to set vertical scroll-bar placement. */
|
||||
|
||||
/* Right justify numeric columns */
|
||||
/* for (i = 1; i <= 5; i++) {
|
||||
gtk_clist_set_column_justification(GTK_CLIST(tree), i,
|
||||
GTK_JUSTIFY_RIGHT);
|
||||
} */
|
||||
|
||||
/* Fill in the data. */
|
||||
fill_in_tree(tree_view, ps);
|
||||
|
||||
gtk_widget_set_size_request(tree, DEF_DLG_WIDTH, MAX_DLG_HEIGHT);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(sw), tree);
|
||||
ph_stats_free(ps);
|
||||
}
|
||||
|
||||
#define WNAME "Protocol Hierarchy Statistics"
|
||||
|
||||
void
|
||||
proto_hier_stats_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
ph_stats_t *ps;
|
||||
GtkWidget *dlg, *bt, *vbox, *frame, *bbox;
|
||||
|
||||
/* Get the statistics. */
|
||||
ps = ph_stats_new();
|
||||
if (ps == NULL) {
|
||||
/* The user gave up before we finished; don't pop up
|
||||
a statistics window. */
|
||||
return;
|
||||
}
|
||||
|
||||
dlg = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(dlg), "Ethereal: " WNAME);
|
||||
g_signal_connect(G_OBJECT(dlg), "realize",
|
||||
G_CALLBACK(window_icon_realize_cb), NULL);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(vbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(dlg), vbox);
|
||||
|
||||
frame = gtk_frame_new(WNAME);
|
||||
/*gtk_container_add(GTK_CONTAINER(vbox), frame);*/
|
||||
gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
|
||||
|
||||
|
||||
/* Data section */
|
||||
create_tree(frame, ps);
|
||||
|
||||
/* Button row. We put it in an HButtonBox to
|
||||
* keep it from expanding to the width of the window. */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
/*gtk_container_add(GTK_CONTAINER(vbox), bbox);*/
|
||||
gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
|
||||
|
||||
/* Close button */
|
||||
bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
|
||||
gtk_signal_connect_object(GTK_OBJECT(bt), "clicked",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(dlg));
|
||||
gtk_container_add(GTK_CONTAINER(bbox), bt);
|
||||
GTK_WIDGET_SET_FLAGS(bt, GTK_CAN_DEFAULT);
|
||||
gtk_widget_grab_default(bt);
|
||||
dlg_set_cancel(dlg, bt);
|
||||
|
||||
gtk_widget_show_all(dlg);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/* proto_hier_stats_dlg.h
|
||||
*
|
||||
* $Id: proto_hier_stats_dlg.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
proto_hier_stats_cb(GtkWidget *w, gpointer d);
|
|
@ -0,0 +1,179 @@
|
|||
/* simple_dialog.c
|
||||
* Simple message dialog box routines.
|
||||
*
|
||||
* $Id: simple_dialog.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef NEED_SNPRINTF_H
|
||||
# include "snprintf.h"
|
||||
#endif
|
||||
|
||||
#include "gtkglobals.h"
|
||||
#include "simple_dialog.h"
|
||||
#include "dlg_utils.h"
|
||||
|
||||
#include "image/eexcl3d64.xpm"
|
||||
#include "image/eicon3d64.xpm"
|
||||
|
||||
static void simple_dialog_cancel_cb(GtkWidget *, gpointer);
|
||||
|
||||
static const gchar bm_key[] = "button mask";
|
||||
|
||||
/* Simple dialog function - Displays a dialog box with the supplied message
|
||||
* text.
|
||||
*
|
||||
* Args:
|
||||
* type : One of ESD_TYPE_*.
|
||||
* btn_mask : The address of a gint. The value passed in determines if
|
||||
* the 'Cancel' button is displayed. The button pressed by the
|
||||
* user is passed back.
|
||||
* msg_format : Sprintf-style format of the text displayed in the dialog.
|
||||
* ... : Argument list for msg_format
|
||||
*
|
||||
*/
|
||||
|
||||
#define ESD_MAX_MSG_LEN 2048
|
||||
void
|
||||
simple_dialog(gint type, gint *btn_mask, gchar *msg_format, ...) {
|
||||
GtkWidget *win, *main_vb, *top_hb, *type_pm, *msg_label,
|
||||
*bbox, *ok_btn, *cancel_btn;
|
||||
GdkPixmap *pixmap;
|
||||
GdkBitmap *mask;
|
||||
GtkStyle *style;
|
||||
GdkColormap *cmap;
|
||||
va_list ap;
|
||||
gchar message[ESD_MAX_MSG_LEN];
|
||||
gchar **icon;
|
||||
|
||||
/* Main window */
|
||||
switch (type & ~ESD_TYPE_MODAL) {
|
||||
case ESD_TYPE_WARN :
|
||||
icon = eexcl3d64_xpm;
|
||||
win = dlg_window_new("Ethereal: Warning");
|
||||
break;
|
||||
case ESD_TYPE_CRIT :
|
||||
icon = eexcl3d64_xpm;
|
||||
win = dlg_window_new("Ethereal: Error");
|
||||
break;
|
||||
case ESD_TYPE_INFO :
|
||||
default :
|
||||
icon = eicon3d64_xpm;
|
||||
win = dlg_window_new("Ethereal: Information");
|
||||
break;
|
||||
}
|
||||
|
||||
if (type & ESD_TYPE_MODAL)
|
||||
gtk_window_set_modal(GTK_WINDOW(win), TRUE);
|
||||
|
||||
gtk_container_border_width(GTK_CONTAINER(win), 7);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(win), bm_key, btn_mask);
|
||||
|
||||
/* Container for our rows */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(win), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* Top row: Icon and message text */
|
||||
top_hb = gtk_hbox_new(FALSE, 10);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), top_hb);
|
||||
gtk_widget_show(top_hb);
|
||||
|
||||
style = gtk_widget_get_style(win);
|
||||
cmap = gdk_colormap_get_system();
|
||||
pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, cmap, &mask,
|
||||
&style->bg[GTK_STATE_NORMAL], icon);
|
||||
type_pm = gtk_pixmap_new(pixmap, mask);
|
||||
gtk_misc_set_alignment (GTK_MISC (type_pm), 0.5, 0.0);
|
||||
gtk_container_add(GTK_CONTAINER(top_hb), type_pm);
|
||||
gtk_widget_show(type_pm);
|
||||
|
||||
/* Load our vararg list into the message string */
|
||||
va_start(ap, msg_format);
|
||||
vsnprintf(message, ESD_MAX_MSG_LEN, msg_format, ap);
|
||||
va_end(ap);
|
||||
|
||||
msg_label = gtk_label_new(message);
|
||||
gtk_label_set_justify(GTK_LABEL(msg_label), GTK_JUSTIFY_FILL);
|
||||
gtk_container_add(GTK_CONTAINER(top_hb), msg_label);
|
||||
gtk_widget_show(msg_label);
|
||||
|
||||
/* Button row */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
ok_btn = gtk_button_new_from_stock(GTK_STOCK_OK);
|
||||
gtk_signal_connect_object(GTK_OBJECT(ok_btn), "clicked",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(win));
|
||||
gtk_container_add(GTK_CONTAINER(bbox), ok_btn);
|
||||
GTK_WIDGET_SET_FLAGS(ok_btn, GTK_CAN_DEFAULT);
|
||||
gtk_widget_grab_default(ok_btn);
|
||||
gtk_widget_show(ok_btn);
|
||||
|
||||
if (btn_mask && *btn_mask == ESD_BTN_CANCEL) {
|
||||
cancel_btn = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(cancel_btn), "clicked",
|
||||
G_CALLBACK(simple_dialog_cancel_cb), (gpointer) win);
|
||||
gtk_container_add(GTK_CONTAINER(bbox), cancel_btn);
|
||||
GTK_WIDGET_SET_FLAGS(cancel_btn, GTK_CAN_DEFAULT);
|
||||
gtk_widget_show(cancel_btn);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Cancel" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(win, cancel_btn);
|
||||
} else {
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "OK" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(win, ok_btn);
|
||||
}
|
||||
|
||||
if (btn_mask)
|
||||
*btn_mask = ESD_BTN_OK;
|
||||
|
||||
gtk_widget_show(win);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_dialog_cancel_cb(GtkWidget *w _U_, gpointer win) {
|
||||
gint *btn_mask = (gint *) gtk_object_get_data(win, bm_key);
|
||||
|
||||
if (btn_mask)
|
||||
*btn_mask = ESD_BTN_CANCEL;
|
||||
gtk_widget_destroy(GTK_WIDGET(win));
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/* stream_prefs.c
|
||||
* Dialog boxes for preferences for the stream window
|
||||
*
|
||||
* $Id: stream_prefs.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "color_utils.h"
|
||||
#include "globals.h"
|
||||
#include "stream_prefs.h"
|
||||
#include "keys.h"
|
||||
#include "print.h"
|
||||
#include "prefs.h"
|
||||
|
||||
static void update_text_color(GtkWidget *, gpointer);
|
||||
static void update_current_color(GtkWidget *, gpointer);
|
||||
|
||||
static GdkColor tcolors[4], *curcolor = NULL;
|
||||
|
||||
#define SAMPLE_CLIENT_TEXT "Sample client text\n"
|
||||
#define SAMPLE_SERVER_TEXT "Sample server text\n"
|
||||
#define CFG_IDX 0
|
||||
#define CBG_IDX 1
|
||||
#define SFG_IDX 2
|
||||
#define SBG_IDX 3
|
||||
#define STREAM_SAMPLE_KEY "stream_entry"
|
||||
#define STREAM_CS_KEY "stream_colorselection"
|
||||
#define CS_RED 0
|
||||
#define CS_GREEN 1
|
||||
#define CS_BLUE 2
|
||||
#define CS_OPACITY 3
|
||||
|
||||
GtkWidget *
|
||||
stream_prefs_show()
|
||||
{
|
||||
GtkWidget *main_vb, *main_tb, *label, *optmenu, *menu, *menuitem;
|
||||
GtkWidget *sample, *colorsel;
|
||||
int width, height, i;
|
||||
gchar *mt[] = { "Client foreground", "Client background",
|
||||
"Server foreground", "Server background" };
|
||||
int mcount = sizeof(mt) / sizeof (gchar *);
|
||||
gdouble scolor[4];
|
||||
GtkTextBuffer *buf;
|
||||
GtkTextIter iter;
|
||||
|
||||
color_t_to_gdkcolor(&tcolors[CFG_IDX], &prefs.st_client_fg);
|
||||
color_t_to_gdkcolor(&tcolors[CBG_IDX], &prefs.st_client_bg);
|
||||
color_t_to_gdkcolor(&tcolors[SFG_IDX], &prefs.st_server_fg);
|
||||
color_t_to_gdkcolor(&tcolors[SBG_IDX], &prefs.st_server_bg);
|
||||
|
||||
curcolor = &tcolors[CFG_IDX];
|
||||
|
||||
scolor[CS_RED] = (gdouble) (curcolor->red) / 65535.0;
|
||||
scolor[CS_GREEN] = (gdouble) (curcolor->green) / 65535.0;
|
||||
scolor[CS_BLUE] = (gdouble) (curcolor->blue) / 65535.0;
|
||||
scolor[CS_OPACITY] = 1.0;
|
||||
|
||||
/* Enclosing containers for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
|
||||
main_tb = gtk_table_new(3, 3, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
gtk_widget_show(main_tb);
|
||||
|
||||
label = gtk_label_new("Set:");
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, 0, 1);
|
||||
gtk_widget_show(label);
|
||||
|
||||
/* We have to create this now, and configure it below. */
|
||||
colorsel = gtk_color_selection_new();
|
||||
|
||||
optmenu = gtk_option_menu_new ();
|
||||
menu = gtk_menu_new ();
|
||||
for (i = 0; i < mcount; i++){
|
||||
menuitem = gtk_menu_item_new_with_label (mt[i]);
|
||||
gtk_object_set_data(GTK_OBJECT(menuitem), STREAM_CS_KEY,
|
||||
(gpointer) colorsel);
|
||||
g_signal_connect(G_OBJECT(menuitem), "activate",
|
||||
G_CALLBACK(update_current_color), &tcolors[i]);
|
||||
gtk_widget_show (menuitem);
|
||||
gtk_menu_append (GTK_MENU (menu), menuitem);
|
||||
}
|
||||
gtk_option_menu_set_menu (GTK_OPTION_MENU (optmenu), menu);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), optmenu, 1, 2, 0, 1);
|
||||
gtk_widget_show(optmenu);
|
||||
|
||||
sample = gtk_text_view_new();
|
||||
height = 2 * (gtk_style_get_font(sample->style)->ascent +
|
||||
gtk_style_get_font(sample->style)->descent);
|
||||
width = gdk_string_width(gtk_style_get_font(sample->style),
|
||||
"Sample server text");
|
||||
gtk_widget_set_size_request(GTK_WIDGET(sample), width, height);
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(sample), FALSE);
|
||||
buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sample));
|
||||
gtk_text_buffer_get_start_iter(buf, &iter);
|
||||
gtk_text_buffer_create_tag(buf, "client",
|
||||
"foreground-gdk", &tcolors[CFG_IDX],
|
||||
"background-gdk", &tcolors[CBG_IDX], NULL);
|
||||
gtk_text_buffer_create_tag(buf, "server",
|
||||
"foreground-gdk", &tcolors[SFG_IDX],
|
||||
"background-gdk", &tcolors[SBG_IDX], NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, SAMPLE_CLIENT_TEXT, -1,
|
||||
"client", NULL);
|
||||
gtk_text_buffer_insert_with_tags_by_name(buf, &iter, SAMPLE_SERVER_TEXT, -1,
|
||||
"server", NULL);
|
||||
gtk_table_attach_defaults(GTK_TABLE(main_tb), sample, 2, 3, 0, 2);
|
||||
gtk_widget_show(sample);
|
||||
|
||||
gtk_color_selection_set_color(GTK_COLOR_SELECTION(colorsel), &scolor[CS_RED]);
|
||||
gtk_table_attach(GTK_TABLE(main_tb), colorsel, 0, 3, 2, 3,
|
||||
GTK_SHRINK, GTK_SHRINK, 0, 0);
|
||||
|
||||
gtk_object_set_data(GTK_OBJECT(colorsel), STREAM_SAMPLE_KEY,
|
||||
(gpointer) sample);
|
||||
g_signal_connect(G_OBJECT(colorsel), "color-changed",
|
||||
G_CALLBACK(update_text_color), NULL);
|
||||
gtk_widget_show(colorsel);
|
||||
|
||||
gtk_widget_show(main_vb);
|
||||
return(main_vb);
|
||||
}
|
||||
|
||||
static void
|
||||
update_text_color(GtkWidget *w, gpointer data _U_) {
|
||||
GtkTextView *sample = gtk_object_get_data(GTK_OBJECT(w), STREAM_SAMPLE_KEY);
|
||||
gdouble scolor[4];
|
||||
GtkTextBuffer *buf;
|
||||
GtkTextTag *tag;
|
||||
|
||||
|
||||
gtk_color_selection_get_color(GTK_COLOR_SELECTION(w), &scolor[CS_RED]);
|
||||
|
||||
curcolor->red = (gushort) (scolor[CS_RED] * 65535.0);
|
||||
curcolor->green = (gushort) (scolor[CS_GREEN] * 65535.0);
|
||||
curcolor->blue = (gushort) (scolor[CS_BLUE] * 65535.0);
|
||||
|
||||
buf = gtk_text_view_get_buffer(sample);
|
||||
tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buf), "client");
|
||||
g_object_set(tag, "foreground-gdk", &tcolors[CFG_IDX], "background-gdk",
|
||||
&tcolors[CBG_IDX], NULL);
|
||||
tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buf), "server");
|
||||
g_object_set(tag, "foreground-gdk", &tcolors[SFG_IDX], "background-gdk",
|
||||
&tcolors[SBG_IDX], NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_color(GtkWidget *w, gpointer data)
|
||||
{
|
||||
GtkColorSelection *colorsel = GTK_COLOR_SELECTION(gtk_object_get_data(GTK_OBJECT(w),
|
||||
STREAM_CS_KEY));
|
||||
gdouble scolor[4];
|
||||
|
||||
curcolor = (GdkColor *) data;
|
||||
|
||||
scolor[CS_RED] = (gdouble) (curcolor->red) / 65535.0;
|
||||
scolor[CS_GREEN] = (gdouble) (curcolor->green) / 65535.0;
|
||||
scolor[CS_BLUE] = (gdouble) (curcolor->blue) / 65535.0;
|
||||
scolor[CS_OPACITY] = 1.0;
|
||||
|
||||
gtk_color_selection_set_color(colorsel, &scolor[CS_RED]);
|
||||
}
|
||||
|
||||
void
|
||||
stream_prefs_fetch(GtkWidget *w _U_)
|
||||
{
|
||||
gdkcolor_to_color_t(&prefs.st_client_fg, &tcolors[CFG_IDX]);
|
||||
gdkcolor_to_color_t(&prefs.st_client_bg, &tcolors[CBG_IDX]);
|
||||
gdkcolor_to_color_t(&prefs.st_server_fg, &tcolors[SFG_IDX]);
|
||||
gdkcolor_to_color_t(&prefs.st_server_bg, &tcolors[SBG_IDX]);
|
||||
}
|
||||
|
||||
/* XXX - "gui_prefs_apply()" handles this, as the "Follow TCP Stream"
|
||||
windows may have to be redrawn due to a font change; this means
|
||||
that calling "stream_prefs_apply()" without calling "gui_prefs_apply()"
|
||||
won't work. */
|
||||
void
|
||||
stream_prefs_apply(GtkWidget *w _U_)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
stream_prefs_destroy(GtkWidget *w _U_)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* stream_prefs.h
|
||||
* Definitions for stream preferences window
|
||||
*
|
||||
* $Id: stream_prefs.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* Copyright 1999 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __STREAM_PREFS_H__
|
||||
#define __STREAM_PREFS_H__
|
||||
|
||||
GtkWidget *stream_prefs_show(void);
|
||||
void stream_prefs_fetch(GtkWidget *w);
|
||||
void stream_prefs_apply(GtkWidget *w);
|
||||
void stream_prefs_destroy(GtkWidget *w);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,231 @@
|
|||
/* summary_dlg.c
|
||||
* Routines for capture file summary window
|
||||
*
|
||||
* $Id: summary_dlg.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wtap.h>
|
||||
|
||||
#ifdef NEED_SNPRINTF_H
|
||||
# include "snprintf.h"
|
||||
#endif
|
||||
|
||||
#include "summary.h"
|
||||
#include "summary_dlg.h"
|
||||
#include "dlg_utils.h"
|
||||
#include "ui_util.h"
|
||||
|
||||
#define SUM_STR_MAX 1024
|
||||
|
||||
|
||||
static void
|
||||
add_string_to_box(gchar *str, GtkWidget *box)
|
||||
{
|
||||
GtkWidget *lb;
|
||||
lb = gtk_label_new(str);
|
||||
gtk_misc_set_alignment(GTK_MISC(lb), 0.0, 0.5);
|
||||
gtk_box_pack_start(GTK_BOX(box), lb,FALSE,FALSE, 0);
|
||||
gtk_widget_show(lb);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
summary_open_cb(GtkWidget *w _U_, gpointer d _U_)
|
||||
{
|
||||
summary_tally summary;
|
||||
GtkWidget *sum_open_w,
|
||||
*main_vb, *file_fr, *data_fr, *capture_fr, *file_box,
|
||||
*data_box, *capture_box, *bbox, *close_bt;
|
||||
|
||||
gchar string_buff[SUM_STR_MAX];
|
||||
|
||||
double seconds;
|
||||
|
||||
/* initialize the tally */
|
||||
summary_fill_in(&summary);
|
||||
|
||||
/* initial compututations */
|
||||
seconds = summary.stop_time - summary.start_time;
|
||||
sum_open_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(sum_open_w), "Ethereal: Summary");
|
||||
g_signal_connect(G_OBJECT(sum_open_w), "realize",
|
||||
G_CALLBACK(window_icon_realize_cb), NULL);
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(sum_open_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
|
||||
/* File frame */
|
||||
file_fr = gtk_frame_new("File");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), file_fr);
|
||||
gtk_widget_show(file_fr);
|
||||
|
||||
file_box = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(file_fr), file_box);
|
||||
gtk_widget_show(file_box);
|
||||
|
||||
/* filename */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Name: %s", summary.filename);
|
||||
add_string_to_box(string_buff, file_box);
|
||||
|
||||
/* length */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Length: %lu", summary.file_length);
|
||||
add_string_to_box(string_buff, file_box);
|
||||
|
||||
/* format */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Format: %s", wtap_file_type_string(summary.encap_type));
|
||||
add_string_to_box(string_buff, file_box);
|
||||
|
||||
if (summary.has_snap) {
|
||||
/* snapshot length */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Snapshot length: %u", summary.snap);
|
||||
add_string_to_box(string_buff, file_box);
|
||||
}
|
||||
|
||||
/* Data frame */
|
||||
data_fr = gtk_frame_new("Data");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), data_fr);
|
||||
gtk_widget_show(data_fr);
|
||||
|
||||
data_box = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(data_fr), data_box);
|
||||
gtk_widget_show(data_box);
|
||||
|
||||
/* seconds */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Elapsed time: %.3f seconds", summary.elapsed_time);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
snprintf(string_buff, SUM_STR_MAX, "Between first and last packet: %.3f seconds", seconds);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
/* Packet count */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Packet count: %i", summary.packet_count);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
/* Filtered Packet count */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Filtered packet count: %i", summary.filtered_count);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
/* Marked Packet count */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Marked packet count: %i", summary.marked_count);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
/* Packets per second */
|
||||
if (seconds > 0){
|
||||
snprintf(string_buff, SUM_STR_MAX, "Avg. packets/sec: %.3f", summary.packet_count/seconds);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
}
|
||||
|
||||
/* Dropped count */
|
||||
if (summary.drops_known) {
|
||||
snprintf(string_buff, SUM_STR_MAX, "Dropped packets: %u", summary.drops);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
}
|
||||
|
||||
/* Byte count */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Bytes of traffic: %d", summary.bytes);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
/* Bytes per second */
|
||||
if (seconds > 0){
|
||||
snprintf(string_buff, SUM_STR_MAX, "Avg. bytes/sec: %.3f", summary.bytes/seconds);
|
||||
add_string_to_box(string_buff, data_box);
|
||||
|
||||
/* MBit per second */
|
||||
snprintf(string_buff, SUM_STR_MAX, "Avg. Mbit/sec: %.3f",
|
||||
summary.bytes * 8.0 / (seconds * 1000.0 * 1000.0));
|
||||
add_string_to_box(string_buff, data_box);
|
||||
}
|
||||
|
||||
/* Capture frame */
|
||||
capture_fr = gtk_frame_new("Capture");
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
|
||||
gtk_widget_show(capture_fr);
|
||||
|
||||
capture_box = gtk_vbox_new(FALSE, 3);
|
||||
gtk_container_add(GTK_CONTAINER(capture_fr), capture_box);
|
||||
gtk_widget_show(capture_box);
|
||||
|
||||
|
||||
/* interface */
|
||||
if (summary.iface) {
|
||||
snprintf(string_buff, SUM_STR_MAX, "Interface: %s", summary.iface);
|
||||
} else {
|
||||
sprintf(string_buff, "Interface: unknown");
|
||||
}
|
||||
add_string_to_box(string_buff, capture_box);
|
||||
|
||||
/* Display filter */
|
||||
if (summary.dfilter) {
|
||||
snprintf(string_buff, SUM_STR_MAX, "Display filter: %s", summary.dfilter);
|
||||
} else {
|
||||
sprintf(string_buff, "Display filter: none");
|
||||
}
|
||||
add_string_to_box(string_buff, capture_box);
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
/* Capture filter */
|
||||
if (summary.cfilter && summary.cfilter[0] != '\0') {
|
||||
snprintf(string_buff, SUM_STR_MAX, "Capture filter: %s", summary.cfilter);
|
||||
} else {
|
||||
sprintf(string_buff, "Capture filter: none");
|
||||
}
|
||||
add_string_to_box(string_buff, capture_box);
|
||||
#endif
|
||||
|
||||
/* Button row: close button.
|
||||
(We put it in an HButtonBox, even though there's only one of them,
|
||||
so that it doesn't expand to the width of the window. */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
/* Create Close Button */
|
||||
close_bt = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
|
||||
gtk_signal_connect_object(GTK_OBJECT(close_bt), "clicked",
|
||||
GTK_SIGNAL_FUNC(gtk_widget_destroy),
|
||||
GTK_OBJECT(sum_open_w));
|
||||
GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), close_bt, FALSE,FALSE, 0);
|
||||
gtk_widget_grab_default(close_bt);
|
||||
gtk_widget_show(close_bt);
|
||||
|
||||
/* Catch the "key_press_event" signal in the window, so that we can catch
|
||||
the ESC key being pressed and act as if the "Close" button had
|
||||
been selected. */
|
||||
dlg_set_cancel(sum_open_w, close_bt);
|
||||
|
||||
gtk_window_set_position(GTK_WINDOW(sum_open_w), GTK_WIN_POS_MOUSE);
|
||||
gtk_widget_show(sum_open_w);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* summary_dlg.h
|
||||
* Routines for capture file summary window
|
||||
*
|
||||
* $Id: summary_dlg.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@zing.org>
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SUMMARY_DLG_H__
|
||||
#define __SUMMARY_DLG_H__
|
||||
|
||||
void summary_open_cb(GtkWidget *w, gpointer d);
|
||||
|
||||
#endif /* __SUMMARY_DLG_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
/* tcp_graph.h
|
||||
* Declarations for TCP graph drawing code
|
||||
* By Pavel Mores <pvl@uh.cz>
|
||||
* Win32 port: rwh@unifiedtech.com
|
||||
*
|
||||
* $Id: tcp_graph.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern void tcp_graph_cb (GtkWidget *, gpointer, guint);
|
|
@ -0,0 +1,205 @@
|
|||
/* ui_util.c
|
||||
* UI utility routines
|
||||
*
|
||||
* $Id: ui_util.c,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gtkglobals.h"
|
||||
#include "ui_util.h"
|
||||
#include "prefs.h"
|
||||
#include "../ui_util.h"
|
||||
#include "image/eicon3d16.xpm"
|
||||
|
||||
|
||||
/* Set the name of the top-level window and its icon to the specified
|
||||
string. */
|
||||
void
|
||||
set_main_window_name(gchar *window_name)
|
||||
{
|
||||
gtk_window_set_title(GTK_WINDOW(top_level), window_name);
|
||||
gdk_window_set_icon_name(top_level->window, window_name);
|
||||
}
|
||||
|
||||
/* Given a pointer to a GtkWidget for a top-level window, raise it and
|
||||
de-iconify it. This routine is used if the user has done something to
|
||||
ask that a window of a certain type be popped up when there can be only
|
||||
one such window and such a window has already been popped up - we
|
||||
pop up the existing one rather than creating a new one.
|
||||
|
||||
XXX - we should request that it be given the input focus, too. Alas,
|
||||
GDK has nothing to do that, e.g. by calling "XSetInputFocus()" in a
|
||||
window in X. Besides, using "XSetInputFocus()" doesn't work anyway,
|
||||
apparently due to the way GTK+/GDK manages the input focus.
|
||||
|
||||
The X Desktop Group's Window Manager Standard specifies, in the section
|
||||
on Root Window Properties, an _NET_ACTIVE_WINDOW client message that
|
||||
can be sent to the root window, containing the window ID of the
|
||||
window to activate; I infer that this might be the way to give the
|
||||
window the input focus - I assume that means it's also de-iconified,
|
||||
but I wouldn't assume it'd raise it.
|
||||
|
||||
XXX - will this do the right thing on window systems other than X? */
|
||||
void
|
||||
reactivate_window(GtkWidget *win)
|
||||
{
|
||||
gdk_window_show(win->window);
|
||||
gdk_window_raise(win->window);
|
||||
}
|
||||
|
||||
/* Set our window icon. The GDK documentation doesn't provide any
|
||||
actual documentation for gdk_window_set_icon(), so we'll steal
|
||||
libgimp/gimpdialog.c:gimp_dialog_realize_callback() from the Gimp
|
||||
sources and assume it's safe.
|
||||
|
||||
XXX - The current icon size is fixed at 16x16 pixels, which looks fine
|
||||
with kwm (KDE 1.x's window manager), Sawfish (the "default" window
|
||||
manager for GNOME?), and under Windows with Exceed putting X windows
|
||||
on the Windows desktop, using Exceed as the window manager, as those
|
||||
window managers put a 16x16 icon on the title bar.
|
||||
|
||||
The window managers in some windowing environments (e.g. dtwm in CDE)
|
||||
and some stand-alone window managers have larger icon sizes (many window
|
||||
managers put the window icon on the desktop, in the Windows 3.x style,
|
||||
rather than in the titlebar, in the Windows 4.x style), so we need to
|
||||
find a way to size our icon appropriately.
|
||||
|
||||
The X11 Inter-Client Communications Conventions Manual, Version 1.1,
|
||||
in X11R5, specifies that "a window manager that wishes to place
|
||||
constraints on the sizes of icon pixmaps and/or windows should
|
||||
place a property called WM_ICON_SIZE on the root"; that property
|
||||
contains minimum width and height, maximum width and height, and
|
||||
width and height increment values. "XGetIconSizes()" retrieves
|
||||
that property; unfortunately, I've yet to find a window manager
|
||||
that sets it on the root window (kwm, AfterStep, and Exceed don't
|
||||
appear to set it).
|
||||
|
||||
The X Desktop Group's Window Manager Standard specifies, in the section
|
||||
on Application Window Properties, an _NET_WM_ICON property, presumably
|
||||
set by the window manager, which is an array of possible icon sizes
|
||||
for the client. There's no API in GTK+ 1.2[.x] for this; there may
|
||||
eventually be one either in GTK+ 2.0 or GNOME 2.0.
|
||||
|
||||
Some window managers can be configured to take the window name
|
||||
specified by the WM_NAME property of a window or the resource
|
||||
or class name specified by the WM_CLASS property and base the
|
||||
choice of icon for the window on one of those; WM_CLASS for
|
||||
Ethereal's windows has a resource name of "ethereal" and a class
|
||||
name of "Ethereal". However, the way that's done is window-manager-
|
||||
specific, and there's no way to determine what size a particular
|
||||
window manager would want, so there's no way to automate this as
|
||||
part of the installation of Ethereal.
|
||||
*/
|
||||
void
|
||||
window_icon_realize_cb (GtkWidget *win, gpointer data _U_)
|
||||
{
|
||||
#ifndef WIN32
|
||||
static GdkPixmap *icon_pmap = NULL;
|
||||
static GdkBitmap *icon_mask = NULL;
|
||||
GtkStyle *style;
|
||||
|
||||
style = gtk_widget_get_style (win);
|
||||
|
||||
if (icon_pmap == NULL) {
|
||||
icon_pmap = gdk_pixmap_create_from_xpm_d (win->window,
|
||||
&icon_mask, &style->bg[GTK_STATE_NORMAL], eicon3d16_xpm);
|
||||
}
|
||||
|
||||
gdk_window_set_icon (win->window, NULL, icon_pmap, icon_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* List of all GtkScrolledWindows, so we can globally set the scrollbar
|
||||
placement of all of them. */
|
||||
static GList *scrolled_windows;
|
||||
|
||||
static void setup_scrolled_window(GtkWidget *scrollw);
|
||||
static void forget_scrolled_window(GtkWidget *scrollw, gpointer data);
|
||||
static void set_scrollbar_placement_scrollw(GtkWidget *scrollw);
|
||||
|
||||
/* Create a GtkScrolledWindow, set its scrollbar placement appropriately,
|
||||
and remember it. */
|
||||
GtkWidget *
|
||||
scrolled_window_new(GtkAdjustment *hadjustment, GtkAdjustment *vadjustment)
|
||||
{
|
||||
GtkWidget *scrollw;
|
||||
|
||||
scrollw = gtk_scrolled_window_new(hadjustment, vadjustment);
|
||||
setup_scrolled_window(scrollw);
|
||||
return scrollw;
|
||||
}
|
||||
|
||||
/* Set a GtkScrolledWindow's scrollbar placement and add it to the list
|
||||
of GtkScrolledWindows. */
|
||||
static void
|
||||
setup_scrolled_window(GtkWidget *scrollw)
|
||||
{
|
||||
set_scrollbar_placement_scrollw(scrollw);
|
||||
|
||||
scrolled_windows = g_list_append(scrolled_windows, scrollw);
|
||||
|
||||
/* Catch the "destroy" event on the widget, so that we remove it from
|
||||
the list when it's destroyed. */
|
||||
g_signal_connect(G_OBJECT(scrollw), "destroy",
|
||||
G_CALLBACK(forget_scrolled_window), NULL);
|
||||
}
|
||||
|
||||
/* Remove a GtkScrolledWindow from the list of GtkScrolledWindows. */
|
||||
static void
|
||||
forget_scrolled_window(GtkWidget *scrollw, gpointer data _U_)
|
||||
{
|
||||
scrolled_windows = g_list_remove(scrolled_windows, scrollw);
|
||||
}
|
||||
|
||||
/* Set the scrollbar placement of a GtkScrolledWindow based upon user
|
||||
preference. */
|
||||
static void
|
||||
set_scrollbar_placement_scrollw(GtkWidget *scrollw)
|
||||
{
|
||||
if (prefs.gui_scrollbar_on_right) {
|
||||
gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
|
||||
GTK_CORNER_TOP_LEFT);
|
||||
} else {
|
||||
gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
|
||||
GTK_CORNER_TOP_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_scrollbar_placement_cb(gpointer data, gpointer user_data _U_)
|
||||
{
|
||||
set_scrollbar_placement_scrollw((GtkWidget *)data);
|
||||
}
|
||||
|
||||
/* Set the scrollbar placement of all GtkScrolledWindows based on
|
||||
user preference. */
|
||||
void
|
||||
set_scrollbar_placement_all(void)
|
||||
{
|
||||
g_list_foreach(scrolled_windows, set_scrollbar_placement_cb, NULL);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* ui_util.h
|
||||
* Definitions for UI utility routines
|
||||
*
|
||||
* $Id: ui_util.h,v 1.1 2002/08/31 09:55:22 oabad Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GTKGUIUI_UTIL_H__
|
||||
#define __GTKGUIUI_UTIL_H__
|
||||
|
||||
/* Given a pointer to a GtkWidget for a top-level window, raise it and
|
||||
de-iconify it. This routine is used if the user has done something to
|
||||
ask that a window of a certain type be popped up when there can be only
|
||||
one such window and such a window has already been popped up - we
|
||||
pop up the existing one rather than creating a new one. */
|
||||
void reactivate_window(GtkWidget *);
|
||||
|
||||
/* Set the window icon to the 16x16 3D icon. */
|
||||
void window_icon_realize_cb (GtkWidget *, gpointer);
|
||||
|
||||
/* Create a GtkScrolledWindow, set its scrollbar placement appropriately,
|
||||
and remember it. */
|
||||
GtkWidget *scrolled_window_new(GtkAdjustment *hadjustment,
|
||||
GtkAdjustment *vadjustment);
|
||||
|
||||
/* Set the scrollbar placement of all scrolled windows based on user
|
||||
preference. */
|
||||
void set_scrollbar_placement_all(void);
|
||||
|
||||
/* Create a GtkCTree, give it the right styles, and remember it. */
|
||||
GtkWidget *ctree_new(gint columns, gint tree_column);
|
||||
GtkWidget *ctree_new_with_titles(gint columns, gint tree_column,
|
||||
gchar *titles[]);
|
||||
|
||||
/* Set the styles of all GtkCTrees based upon user preferences. */
|
||||
void set_ctree_styles_all(void);
|
||||
|
||||
#endif /* __GTKGUIUI_UTIL_H__ */
|
Loading…
Reference in New Issue