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:
Olivier Abad 2002-08-31 09:55:22 +00:00
parent 2d8152c072
commit 6c5954dac7
74 changed files with 24471 additions and 12 deletions

View File

@ -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 \

View File

@ -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
View File

@ -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
}
}

9
gtk2/.cvsignore Normal file
View File

@ -0,0 +1,9 @@
Makefile
Makefile.in
.deps
stamp-h.in
config.status
aclocal.m4
*.obj
*.lib
*.pdb

101
gtk2/Makefile.am Normal file
View File

@ -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

68
gtk2/Makefile.nmake Normal file
View File

@ -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)

955
gtk2/capture_dlg.c Normal file
View 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 */

32
gtk2/capture_dlg.h Normal file
View File

@ -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 */

167
gtk2/capture_prefs.c Normal file
View File

@ -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 */

33
gtk2/capture_prefs.h Normal file
View File

@ -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

1166
gtk2/color_dlg.c Normal file

File diff suppressed because it is too large Load Diff

31
gtk2/color_dlg.h Normal file
View File

@ -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 */

53
gtk2/color_utils.c Normal file
View File

@ -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;
}

33
gtk2/color_utils.h Normal file
View File

@ -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

291
gtk2/colors.c Normal file
View File

@ -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) );
}

67
gtk2/colors.h Normal file
View File

@ -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

377
gtk2/column_prefs.c Normal file
View File

@ -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));
}

29
gtk2/column_prefs.h Normal file
View File

@ -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 *);

1349
gtk2/decode_as_dlg.c Normal file

File diff suppressed because it is too large Load Diff

33
gtk2/decode_as_dlg.h Normal file
View File

@ -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

1207
gtk2/dfilter_expr_dlg.c Normal file

File diff suppressed because it is too large Load Diff

31
gtk2/dfilter_expr_dlg.h Normal file
View File

@ -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 */

337
gtk2/display_opts.c Normal file
View File

@ -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;
}

31
gtk2/display_opts.h Normal file
View File

@ -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 */

167
gtk2/dlg_utils.c Normal file
View File

@ -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;
}

46
gtk2/dlg_utils.h Normal file
View File

@ -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

647
gtk2/file_dlg.c Normal file
View File

@ -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);
}

42
gtk2/file_dlg.h Normal file
View File

@ -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 */

1178
gtk2/filter_prefs.c Normal file

File diff suppressed because it is too large Load Diff

51
gtk2/filter_prefs.h Normal file
View File

@ -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 */

282
gtk2/find_dlg.c Normal file
View File

@ -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);
}

33
gtk2/find_dlg.h Normal file
View File

@ -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 */

819
gtk2/follow_dlg.c Normal file
View File

@ -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;
}

33
gtk2/follow_dlg.h Normal file
View File

@ -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

169
gtk2/goto_dlg.c Normal file
View File

@ -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));
}

31
gtk2/goto_dlg.h Normal file
View File

@ -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 */

58
gtk2/gtkglobals.h Normal file
View File

@ -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

732
gtk2/gui_prefs.c Normal file
View File

@ -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);
}

34
gtk2/gui_prefs.h Normal file
View File

@ -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

397
gtk2/help_dlg.c Normal file
View File

@ -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);
}
}

35
gtk2/help_dlg.h Normal file
View File

@ -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

48
gtk2/keys.h Normal file
View File

@ -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

2467
gtk2/main.c Normal file

File diff suppressed because it is too large Load Diff

102
gtk2/main.h Normal file
View File

@ -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__ */

527
gtk2/menu.c Normal file
View File

@ -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);
}

43
gtk2/menu.h Normal file
View File

@ -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__ */

129
gtk2/nameres_prefs.c Normal file
View File

@ -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_)
{
}

33
gtk2/nameres_prefs.h Normal file
View File

@ -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

263
gtk2/packet_win.c Normal file
View File

@ -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);
}

39
gtk2/packet_win.h Normal file
View File

@ -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

164
gtk2/plugins_dlg.c Normal file
View File

@ -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

1239
gtk2/prefs_dlg.c Normal file

File diff suppressed because it is too large Load Diff

42
gtk2/prefs_dlg.h Normal file
View File

@ -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

690
gtk2/print_dlg.c Normal file
View File

@ -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
}

202
gtk2/print_mswin.c Normal file
View File

@ -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);
}
}

27
gtk2/print_mswin.h Normal file
View File

@ -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);

250
gtk2/print_prefs.c Normal file
View File

@ -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);
}
}

34
gtk2/print_prefs.h Normal file
View File

@ -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

380
gtk2/progress_dlg.c Normal file
View File

@ -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);
}

412
gtk2/proto_dlg.c Normal file
View File

@ -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 */

32
gtk2/proto_dlg.h Normal file
View File

@ -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

1051
gtk2/proto_draw.c Normal file

File diff suppressed because it is too large Load Diff

70
gtk2/proto_draw.h Normal file
View File

@ -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

253
gtk2/proto_hier_stats_dlg.c Normal file
View File

@ -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);
}

View File

@ -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);

179
gtk2/simple_dialog.c Normal file
View File

@ -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));
}

213
gtk2/stream_prefs.c Normal file
View File

@ -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_)
{
}

34
gtk2/stream_prefs.h Normal file
View File

@ -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

231
gtk2/summary_dlg.c Normal file
View File

@ -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);
}

31
gtk2/summary_dlg.h Normal file
View File

@ -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__ */

3772
gtk2/tcp_graph.c Normal file

File diff suppressed because it is too large Load Diff

27
gtk2/tcp_graph.h Normal file
View File

@ -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);

205
gtk2/ui_util.c Normal file
View File

@ -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);
}

55
gtk2/ui_util.h Normal file
View File

@ -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__ */