6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40 #include <gdk/gdkkeysyms.h>
42 #include "gtkglobals.h"
44 #include <epan/prefs.h>
45 #include "epan/epan.h"
46 #include "../ui_util.h"
47 #include "compat_macros.h"
51 #include "image/eicon3d16.xpm"
53 /* XXX - remove this later again, when dlg_xx function cleanup done */
54 #include "dlg_utils.h"
57 #define WINDOW_GEOM_KEY "window_geom"
60 /* load the geometry values for a window from previously saved values */
61 static gboolean window_geom_load(const gchar *name, window_geometry_t *geom);
65 /* Set our window icon. The GDK documentation doesn't provide any
66 actual documentation for gdk_window_set_icon(), so we'll steal
67 libgimp/gimpdialog.c:gimp_dialog_realize_callback() from the Gimp
68 sources and assume it's safe.
70 XXX - The current icon size is fixed at 16x16 pixels, which looks fine
71 with kwm (KDE 1.x's window manager), Sawfish (the "default" window
72 manager for GNOME?), and under Windows with Exceed putting X windows
73 on the Windows desktop, using Exceed as the window manager, as those
74 window managers put a 16x16 icon on the title bar.
76 The window managers in some windowing environments (e.g. dtwm in CDE)
77 and some stand-alone window managers have larger icon sizes (many window
78 managers put the window icon on the desktop, in the Windows 3.x style,
79 rather than in the titlebar, in the Windows 4.x style), so we need to
80 find a way to size our icon appropriately.
82 The X11 Inter-Client Communications Conventions Manual, Version 1.1,
83 in X11R5, specifies that "a window manager that wishes to place
84 constraints on the sizes of icon pixmaps and/or windows should
85 place a property called WM_ICON_SIZE on the root"; that property
86 contains minimum width and height, maximum width and height, and
87 width and height increment values. "XGetIconSizes()" retrieves
88 that property; unfortunately, I've yet to find a window manager
89 that sets it on the root window (kwm, AfterStep, and Exceed don't
92 The X Desktop Group's Window Manager Standard specifies, in the section
93 on Application Window Properties, an _NET_WM_ICON property, presumably
94 set by the window manager, which is an array of possible icon sizes
95 for the client. There's no API in GTK+ 1.2[.x] for this; there may
96 eventually be one either in GTK+ 2.0 or GNOME 2.0.
98 Some window managers can be configured to take the window name
99 specified by the WM_NAME property of a window or the resource
100 or class name specified by the WM_CLASS property and base the
101 choice of icon for the window on one of those; WM_CLASS for
102 Ethereal's windows has a resource name of "ethereal" and a class
103 name of "Ethereal". However, the way that's done is window-manager-
104 specific, and there's no way to determine what size a particular
105 window manager would want, so there's no way to automate this as
106 part of the installation of Ethereal.
109 window_icon_realize_cb (GtkWidget *win, gpointer data _U_)
112 static GdkPixmap *icon_pmap = NULL;
113 static GdkBitmap *icon_mask = NULL;
116 style = gtk_widget_get_style (win);
118 if (icon_pmap == NULL) {
119 icon_pmap = gdk_pixmap_create_from_xpm_d (win->window,
120 &icon_mask, &style->bg[GTK_STATE_NORMAL], eicon3d16_xpm);
123 gdk_window_set_icon (win->window, NULL, icon_pmap, icon_mask);
128 /* Create a new window, of the specified type, with the specified title
129 (if any) and the Ethereal icon. */
131 window_new(GtkWindowType type, const gchar *title)
135 win = gtk_window_new(type);
137 gtk_window_set_title(GTK_WINDOW(win), title);
138 SIGNAL_CONNECT(win, "realize", window_icon_realize_cb, NULL);
140 /* XXX - which one is the correct default policy? or use a preference for this? */
141 /* GTK_WIN_POS_NONE, GTK_WIN_POS_CENTER or GTK_WIN_POS_MOUSE */
142 /* a lot of people dislike GTK_WIN_POS_MOUSE */
144 /* set the initial position (must be done, before show is called!) */
145 #if GTK_MAJOR_VERSION >= 2
146 /* gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER_ON_PARENT);*/
148 /* gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER);*/
150 gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_NONE);
152 #if GTK_MAJOR_VERSION < 2
153 /* allow window to be shrinked by user, as gtk_widget_set_usize() will set minimum size and */
154 /* the user never could shrink the window again */
155 gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, FALSE);
162 /* Same as window_new(), but will keep it's geometry values (size, position, ...).
163 * Be sure to use window_present() and window_destroy() appropriately! */
165 window_new_with_geom(GtkWindowType type, const gchar *title, const gchar *geom_name)
167 window_geometry_t geom;
168 GtkWidget *win = window_new(type, title);
170 OBJECT_SET_DATA(win, WINDOW_GEOM_KEY, geom_name);
172 /* do we have a previously saved size and position of this window? */
174 /* It's a good idea to set the position and size of the window already here,
175 * as it's still invisible and won't "flicker the screen" while initially resizing. */
176 if(window_geom_load(geom_name, &geom)) {
177 /* XXX - use prefs to select which values to set? */
179 geom.set_size = TRUE;
180 geom.set_maximized = FALSE; /* don't maximize until window is shown */
181 window_set_geometry(win, &geom);
189 #if GTK_MAJOR_VERSION < 2
190 /* We can't set the decorations until the window is realized. */
192 window_notitle_realize_cb (GtkWidget *win, gpointer data _U_)
194 gdk_window_set_decorations(win->window, 0);
199 /* Create a new window for a splash screen; it's a main window, with no title,
200 positioned in the center of the screen. */
202 splash_window_new(void)
206 win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
207 #if GTK_MAJOR_VERSION >= 2
208 gtk_window_set_decorated(GTK_WINDOW(win), FALSE);
210 SIGNAL_CONNECT(win, "realize", window_notitle_realize_cb, NULL);
213 /* set the initial position (must be done, before show is called!) */
214 gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER);
220 /* Present the created window on the screen. */
222 window_present(GtkWidget *win)
224 window_geometry_t geom;
227 #if GTK_MAJOR_VERSION >= 2
228 /* present this window */
229 gtk_window_present(GTK_WINDOW(win));
232 /* do we have a previously saved size and position of this window? */
233 name = OBJECT_GET_DATA(win, WINDOW_GEOM_KEY);
235 if(window_geom_load(name, &geom)) {
236 /* XXX - use prefs to select which values to set? */
238 geom.set_size = TRUE;
239 geom.set_maximized = TRUE;
240 window_set_geometry(win, &geom);
247 window_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer cancel_button)
249 g_return_val_if_fail (widget != NULL, FALSE);
250 g_return_val_if_fail (event != NULL, FALSE);
252 if (event->keyval == GDK_Escape) {
253 gtk_widget_activate(GTK_WIDGET(cancel_button));
261 /* Set the "key_press_event" signal for a top-level dialog window to
262 call a routine to activate the "Cancel" button for a dialog box if
263 the key being pressed is the <Esc> key.
265 XXX - there should be a GTK+ widget that'll do that for you, and
266 let you specify a "Cancel" button. It should also not impose
267 a requirement that there be a separator in the dialog box, as
268 the GtkDialog widget does; the visual convention that there's
269 such a separator between the rest of the dialog boxes and buttons
270 such as "OK" and "Cancel" is, for better or worse, not universal
271 (not even in GTK+ - look at the GtkFileSelection dialog!). */
273 window_set_cancel(GtkWidget *widget, GtkWidget *cancel_button)
275 SIGNAL_CONNECT(widget, "key_press_event", window_key_press_cb, cancel_button);
279 /* set the actions needed for the cancel "Close"/"Ok"/"Cancel" button that closes the window */
280 void window_set_cancel_button(GtkWidget *win, GtkWidget *bt, window_cancel_button_fct cb)
283 SIGNAL_CONNECT(bt, "clicked", cb, win);
285 gtk_widget_grab_default(bt);
287 window_set_cancel(win, bt);
291 /* default callback handler for cancel button "clicked" signal */
292 void window_cancel_button_cb(GtkWidget *w _U_, gpointer data)
294 window_destroy(GTK_WIDGET(data));
298 /* default callback handler: the window managers X of the window was clicked (delete_event) */
300 window_delete_event_cb(GtkWidget *win, GdkEvent *event _U_, gpointer user_data _U_)
304 /* event handled, don't do anything else */
309 /* get the geometry of a window from window_new() */
311 window_get_geometry(GtkWidget *widget, window_geometry_t *geom)
314 #if GTK_MAJOR_VERSION >= 2
315 GdkWindowState state;
318 /* Try to grab our geometry.
320 GTK+ provides two routines to get a window's position relative
321 to the X root window. If I understand the documentation correctly,
322 gdk_window_get_deskrelative_origin applies mainly to Enlightenment
323 and gdk_window_get_root_origin applies for all other WMs.
325 The code below tries both routines, and picks the one that returns
326 the upper-left-most coordinates.
330 http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html
331 http://www.gtk.org/faq/#AEN606
334 gdk_window_get_root_origin(widget->window,
337 if (gdk_window_get_deskrelative_origin(widget->window,
339 if (desk_x <= geom->x &&
347 /* XXX - Is this the "approved" method? */
348 gdk_window_get_size(widget->window,
352 #if GTK_MAJOR_VERSION >= 2
353 state = gdk_window_get_state(widget->window);
354 geom->maximized = (state == GDK_WINDOW_STATE_MAXIMIZED);
359 /* set the geometry of a window from window_new() */
361 window_set_geometry(GtkWidget *widget, window_geometry_t *geom)
363 /* as we now have the geometry from the recent file, set it */
365 gtk_widget_set_uposition(widget,
370 if (geom->set_size) {
371 #if GTK_MAJOR_VERSION >= 2
372 gtk_window_resize(GTK_WINDOW(widget),
374 gtk_window_set_default_size(GTK_WINDOW(widget),
377 gtk_widget_set_usize(widget,
379 /*WIDGET_SET_SIZE(widget,*/
384 #if GTK_MAJOR_VERSION >= 2
385 if(geom->set_maximized) {
386 if (geom->maximized) {
387 gdk_window_maximize(widget->window);
389 gdk_window_unmaximize(widget->window);
396 /* the geometry hashtable for all known window classes,
397 * the window name is the key, and the geometry struct is the value */
398 GHashTable *window_geom_hash = NULL;
401 /* save the window and it's current geometry into the geometry hashtable */
403 window_geom_save(const gchar *name, window_geometry_t *geom)
406 window_geometry_t *work;
408 /* init hashtable, if not already done */
409 if(!window_geom_hash) {
410 window_geom_hash = g_hash_table_new (g_str_hash, g_str_equal);
412 /* if we have an old one, remove and free it first */
413 work = g_hash_table_lookup(window_geom_hash, name);
415 g_hash_table_remove(window_geom_hash, name);
420 /* malloc and insert the new one */
421 work = g_malloc(sizeof(*geom));
423 key = g_strdup(name);
425 g_hash_table_insert(window_geom_hash, key, work);
429 /* load the desired geometry for this window from the geometry hashtable */
431 window_geom_load(const gchar *name, window_geometry_t *geom)
433 window_geometry_t *p;
435 /* init hashtable, if not already done */
436 if(!window_geom_hash) {
437 window_geom_hash = g_hash_table_new (g_str_hash, g_str_equal);
440 p = g_hash_table_lookup(window_geom_hash, name);
450 /* read in a single key value pair from the recent file into the geometry hashtable */
452 window_geom_recent_read_pair(const char *name, const char *key, const char *value)
454 window_geometry_t geom;
457 /* find window geometry maybe already in hashtable */
458 if(!window_geom_load(name, &geom)) {
459 /* not in table, init geom with "basic" values */
460 geom.key = g_strdup(name);
461 geom.set_pos = FALSE;
464 geom.set_size = FALSE;
468 geom.set_maximized = FALSE;/* this is valid in GTK2 only */
469 geom.maximized = FALSE; /* this is valid in GTK2 only */
472 if (strcmp(key, "x") == 0) {
473 geom.x = strtol(value, NULL, 10);
475 } else if (strcmp(key, "y") == 0) {
476 geom.y = strtol(value, NULL, 10);
478 } else if (strcmp(key, "width") == 0) {
479 geom.width = strtol(value, NULL, 10);
480 geom.set_size = TRUE;
481 } else if (strcmp(key, "height") == 0) {
482 geom.height = strtol(value, NULL, 10);
483 geom.set_size = TRUE;
484 } else if (strcmp(key, "maximized") == 0) {
485 if (strcasecmp(value, "true") == 0) {
486 geom.maximized = TRUE;
489 geom.maximized = FALSE;
491 geom.set_maximized = TRUE;
493 g_assert_not_reached();
496 /* save / replace geometry in hashtable */
497 window_geom_save(name, &geom);
501 /* write all geometry values of all windows from the hashtable to the recent file */
503 window_geom_recent_write_all(gpointer rf)
505 /* init hashtable, if not already done */
506 if(!window_geom_hash) {
507 window_geom_hash = g_hash_table_new (g_str_hash, g_str_equal);
510 g_hash_table_foreach(window_geom_hash, write_recent_geom, rf);
515 window_destroy(GtkWidget *win)
517 window_geometry_t geom;
520 /* get_geometry must be done *before* destroy is running, as the window geometry
521 * cannot be retrieved at destroy time (so don't use event "destroy" for this) */
522 /* ...and don't do this at all, if we currently have no GdkWindow (e.g. if the
523 * GtkWidget is hidden) */
524 if(!GTK_WIDGET_NO_WINDOW(win) && GTK_WIDGET_VISIBLE(win)) {
525 window_get_geometry(win, &geom);
527 name = OBJECT_GET_DATA(win, WINDOW_GEOM_KEY);
529 window_geom_save(name, &geom);
533 gtk_widget_destroy(win);
537 /* convert an xpm to a GtkWidget, using the window settings from it's parent */
538 /* (be sure that the parent window is already being displayed) */
539 GtkWidget *xpm_to_widget_from_parent(GtkWidget *parent, const char ** xpm) {
540 #if GTK_MAJOR_VERSION < 2
545 icon = gdk_pixmap_create_from_xpm_d(parent->window, &mask, &parent->style->white, (char **) xpm);
546 return gtk_pixmap_new(icon, mask);
553 pixbuf = gdk_pixbuf_new_from_xpm_data(xpm);
554 gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, gtk_widget_get_colormap(parent), &pixmap, &bitmap, 128);
556 return gtk_image_new_from_pixmap (pixmap, bitmap);
561 /* convert an xpm to a GtkWidget, using the top_level window settings */
562 /* (be sure that the top_level window is already being displayed) */
563 GtkWidget *xpm_to_widget(const char ** xpm) {
564 return xpm_to_widget_from_parent(top_level, xpm);
568 /* Set the name of the top-level window and its icon to the specified
571 set_main_window_name(gchar *window_name)
573 gtk_window_set_title(GTK_WINDOW(top_level), window_name);
574 gdk_window_set_icon_name(top_level->window, window_name);
580 /* update the main window */
581 void main_window_update(void)
583 while (gtk_events_pending()) gtk_main_iteration();
586 /* exit the main window */
587 void main_window_exit(void)
592 /* quit a nested main window */
593 void main_window_nested_quit(void)
595 if (gtk_main_level() > 0)
599 /* quit the main window */
600 void main_window_quit(void)
607 typedef struct pipe_input_tag {
611 pipe_input_cb_t input_cb;
617 /* The timer has expired, see if there's stuff to read from the pipe,
618 if so, do the callback */
620 pipe_timer_cb(gpointer data)
624 gboolean result, result1;
626 pipe_input_t *pipe_input = data;
629 /* Oddly enough although Named pipes don't work on win9x,
630 PeekNamedPipe does !!! */
631 handle = (HANDLE) _get_osfhandle (pipe_input->source);
632 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
634 /* Get the child process exit status */
635 result1 = GetExitCodeProcess((HANDLE)*(pipe_input->child_process),
638 /* If the Peek returned an error, or there are bytes to be read
639 or the childwatcher thread has terminated then call the normal
641 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
643 /* avoid reentrancy problems and stack overflow */
644 gtk_timeout_remove(pipe_input->pipe_input_id);
646 /* And call the real handler */
647 if (pipe_input->input_cb(pipe_input->source, pipe_input->user_data)) {
648 /* restore pipe handler */
649 pipe_input->pipe_input_id = gtk_timeout_add(200, pipe_timer_cb, data);
652 /* Return false so that this timer is not run again */
656 /* No data so let timer run again */
663 /* There's stuff to read from the sync pipe, meaning the child has sent
664 us a message, or the sync pipe has closed, meaning the child has
665 closed it (perhaps because it exited). */
667 pipe_input_cb(gpointer data, gint source _U_,
668 GdkInputCondition condition _U_)
670 pipe_input_t *pipe_input = data;
673 /* avoid reentrancy problems and stack overflow */
674 gtk_input_remove(pipe_input->pipe_input_id);
676 if (pipe_input->input_cb(source, pipe_input->user_data)) {
677 /* restore pipe handler */
678 pipe_input->pipe_input_id = gtk_input_add_full (source,
679 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
688 void pipe_input_set_handler(gint source, gpointer user_data, int *child_process, pipe_input_cb_t input_cb)
690 static pipe_input_t pipe_input;
692 pipe_input.source = source;
693 pipe_input.child_process = child_process;
694 pipe_input.user_data = user_data;
695 pipe_input.input_cb = input_cb;
698 /* Tricky to use pipes in win9x, as no concept of wait. NT can
699 do this but that doesn't cover all win32 platforms. GTK can do
700 this but doesn't seem to work over processes. Attempt to do
701 something similar here, start a timer and check for data on every
703 pipe_input.pipe_input_id = gtk_timeout_add(200, pipe_timer_cb, &pipe_input);
705 pipe_input.pipe_input_id = gtk_input_add_full(source,
706 GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
715 #endif /* HAVE_LIBPCAP */
717 /* Given a pointer to a GtkWidget for a top-level window, raise it and
718 de-iconify it. This routine is used if the user has done something to
719 ask that a window of a certain type be popped up when there can be only
720 one such window and such a window has already been popped up - we
721 pop up the existing one rather than creating a new one.
723 XXX - we should request that it be given the input focus, too. Alas,
724 GDK has nothing to do that, e.g. by calling "XSetInputFocus()" in a
725 window in X. Besides, using "XSetInputFocus()" doesn't work anyway,
726 apparently due to the way GTK+/GDK manages the input focus.
728 The X Desktop Group's Window Manager Standard specifies, in the section
729 on Root Window Properties, an _NET_ACTIVE_WINDOW client message that
730 can be sent to the root window, containing the window ID of the
731 window to activate; I infer that this might be the way to give the
732 window the input focus - I assume that means it's also de-iconified,
733 but I wouldn't assume it'd raise it.
735 XXX - will this do the right thing on window systems other than X? */
737 reactivate_window(GtkWidget *win)
739 gdk_window_show(win->window);
740 gdk_window_raise(win->window);
743 /* List of all GtkScrolledWindows, so we can globally set the scrollbar
744 placement of all of them. */
745 static GList *scrolled_windows;
747 static void setup_scrolled_window(GtkWidget *scrollw);
748 static void forget_scrolled_window(GtkWidget *scrollw, gpointer data);
749 static void set_scrollbar_placement_scrollw(GtkWidget *scrollw);
751 /* Create a GtkScrolledWindow, set its scrollbar placement appropriately,
754 scrolled_window_new(GtkAdjustment *hadjustment, GtkAdjustment *vadjustment)
758 scrollw = gtk_scrolled_window_new(hadjustment, vadjustment);
759 setup_scrolled_window(scrollw);
763 /* Set a GtkScrolledWindow's scrollbar placement and add it to the list
764 of GtkScrolledWindows. */
766 setup_scrolled_window(GtkWidget *scrollw)
768 set_scrollbar_placement_scrollw(scrollw);
770 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollw),
771 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
773 scrolled_windows = g_list_append(scrolled_windows, scrollw);
775 /* Catch the "destroy" event on the widget, so that we remove it from
776 the list when it's destroyed. */
777 SIGNAL_CONNECT(scrollw, "destroy", forget_scrolled_window, NULL);
780 /* Remove a GtkScrolledWindow from the list of GtkScrolledWindows. */
782 forget_scrolled_window(GtkWidget *scrollw, gpointer data _U_)
784 scrolled_windows = g_list_remove(scrolled_windows, scrollw);
787 /* Set the scrollbar placement of a GtkScrolledWindow based upon user
790 set_scrollbar_placement_scrollw(GtkWidget *scrollw)
792 if (prefs.gui_scrollbar_on_right) {
793 gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
794 GTK_CORNER_TOP_LEFT);
796 gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
797 GTK_CORNER_TOP_RIGHT);
802 set_scrollbar_placement_cb(gpointer data, gpointer user_data _U_)
804 set_scrollbar_placement_scrollw((GtkWidget *)data);
807 /* Set the scrollbar placement of all GtkScrolledWindows based on
810 set_scrollbar_placement_all(void)
812 g_list_foreach(scrolled_windows, set_scrollbar_placement_cb, NULL);
815 /* List of all CTrees/TreeViews, so we can globally set the line and
816 * expander style of all of them. */
819 static void setup_tree(GtkWidget *tree);
820 static void forget_tree(GtkWidget *tree, gpointer data);
821 static void set_tree_styles(GtkWidget *tree);
823 /* Create a Tree, give it the right styles, and remember it. */
824 #if GTK_MAJOR_VERSION < 2
826 ctree_new(gint columns, gint tree_column)
829 tree_view_new(GtkTreeModel *model)
834 #if GTK_MAJOR_VERSION < 2
835 tree = gtk_ctree_new(columns, tree_column);
837 tree = gtk_tree_view_new_with_model(model);
843 #if GTK_MAJOR_VERSION < 2
845 ctree_new_with_titles(gint columns, gint tree_column, gchar *titles[])
849 tree = gtk_ctree_new_with_titles(columns, tree_column, titles);
855 /* Set a Tree's styles and add it to the list of Trees. */
857 setup_tree(GtkWidget *tree)
859 set_tree_styles(tree);
861 trees = g_list_append(trees, tree);
863 /* Catch the "destroy" event on the widget, so that we remove it from
864 the list when it's destroyed. */
865 SIGNAL_CONNECT(tree, "destroy", forget_tree, NULL);
868 /* Remove a Tree from the list of Trees. */
870 forget_tree(GtkWidget *tree, gpointer data _U_)
872 trees = g_list_remove(trees, tree);
875 /* Set the styles of a Tree based upon user preferences. */
877 set_tree_styles(GtkWidget *tree)
879 #if GTK_MAJOR_VERSION < 2
880 g_assert(prefs.gui_ptree_line_style >= GTK_CTREE_LINES_NONE &&
881 prefs.gui_ptree_line_style <= GTK_CTREE_LINES_TABBED);
882 gtk_ctree_set_line_style(GTK_CTREE(tree), prefs.gui_ptree_line_style);
883 g_assert(prefs.gui_ptree_expander_style >= GTK_CTREE_EXPANDER_NONE &&
884 prefs.gui_ptree_expander_style <= GTK_CTREE_EXPANDER_CIRCULAR);
885 gtk_ctree_set_expander_style(GTK_CTREE(tree),
886 prefs.gui_ptree_expander_style);
888 g_assert(prefs.gui_altern_colors >= 0 && prefs.gui_altern_colors <= 1);
889 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree),
890 prefs.gui_altern_colors);
895 set_tree_styles_cb(gpointer data, gpointer user_data _U_)
897 set_tree_styles((GtkWidget *)data);
900 /* Set the styles of all Trees based upon style values. */
902 set_tree_styles_all(void)
904 g_list_foreach(trees, set_tree_styles_cb, NULL);
910 #if GTK_MAJOR_VERSION < 2
911 /* convert variable argument list of values to array of strings (GTK2 -> GTK1) */
913 simple_list_convert(gchar **ent, va_list ap)
918 while( (i = va_arg(ap, int)) != -1 ) {
919 s = va_arg(ap, char *);
926 /* append a row to the simple list */
927 /* use it like: simple_list_append(list, 0, "first", 1, "second", -1) */
929 simple_list_append(GtkWidget *list, ...)
933 #if GTK_MAJOR_VERSION < 2
934 gchar *ent[10]; /* new entry added in clist */
941 #if GTK_MAJOR_VERSION < 2
942 simple_list_convert(ent, ap);
943 gtk_clist_append(GTK_CLIST(list), ent);
945 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
946 gtk_list_store_append(store, &iter);
947 gtk_list_store_set_valist(store, &iter, ap);
952 /* create a simple list widget */
954 simple_list_new(gint cols, gchar **titles) {
955 GtkWidget *plugins_list;
956 #if GTK_MAJOR_VERSION >= 2
959 GtkCellRenderer *renderer;
960 GtkTreeViewColumn *column;
964 #if GTK_MAJOR_VERSION < 2
965 plugins_list = gtk_clist_new_with_titles(cols, titles);
966 gtk_clist_set_selection_mode(GTK_CLIST(plugins_list), GTK_SELECTION_SINGLE);
967 gtk_clist_column_titles_passive(GTK_CLIST(plugins_list));
969 gtk_clist_column_titles_show(GTK_CLIST(plugins_list));
971 gtk_clist_column_titles_hide(GTK_CLIST(plugins_list));
973 gtk_clist_set_column_auto_resize(GTK_CLIST(plugins_list), 0, TRUE);
974 gtk_clist_set_column_auto_resize(GTK_CLIST(plugins_list), 1, TRUE);
976 g_assert(cols <= 10);
977 store = gtk_list_store_new(cols,
978 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
979 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
980 plugins_list = tree_view_new(GTK_TREE_MODEL(store));
981 g_object_unref(G_OBJECT(store));
982 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(plugins_list), (gboolean) titles);
983 for(i=0; i<cols; i++) {
984 renderer = gtk_cell_renderer_text_new();
985 column = gtk_tree_view_column_new_with_attributes(titles ? titles[i] : "", renderer,
987 gtk_tree_view_column_set_sort_column_id(column, i);
988 gtk_tree_view_append_column(GTK_TREE_VIEW(plugins_list), column);
996 copy_to_clipboard(GString *str)
998 #if (GTK_MAJOR_VERSION >= 2)
1001 cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); /* Get the default clipboard */
1002 gtk_clipboard_set_text(cb, str->str, -1); /* Copy the byte data into the clipboard */
1007 window = window_new (GTK_WINDOW_TOPLEVEL,"");
1008 text = gtk_text_new (NULL, NULL); /* Create the GtkText widget */
1009 gtk_container_add (GTK_CONTAINER (window), text); /* Avoid a GTK assertion */
1010 gtk_widget_realize (text); /* Realizing a widget creates a window for it, ready for us to insert some text */
1011 gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, str->str, -1);
1012 gtk_editable_select_region((GtkEditable *)text, 0, -1); /* Select ALL text */
1013 gtk_editable_copy_clipboard((GtkEditable *)text); /* Copy the byte data into the clipboard */