In GTK+ 2.x, "gtk_entry_get_text()" returns a "const gchar *"; assign
[obnox/wireshark/wip.git] / gtk / ui_util.c
1 /* ui_util.c
2  * UI utility routines
3  *
4  * $Id: ui_util.c,v 1.14 2002/11/11 15:39:06 oabad Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <gtk/gtk.h>
30
31 #include "gtkglobals.h"
32 #include "ui_util.h"
33 #include "prefs.h"
34 #include "epan/epan.h"
35 #include "../ui_util.h"
36 #include "compat_macros.h"
37
38 #include "image/eicon3d16.xpm"
39
40
41 /* Set the name of the top-level window and its icon to the specified
42    string. */
43 void
44 set_main_window_name(gchar *window_name)
45 {
46   gtk_window_set_title(GTK_WINDOW(top_level), window_name);
47   gdk_window_set_icon_name(top_level->window, window_name);
48 }
49
50 /* Given a pointer to a GtkWidget for a top-level window, raise it and
51    de-iconify it.  This routine is used if the user has done something to
52    ask that a window of a certain type be popped up when there can be only
53    one such window and such a window has already been popped up - we
54    pop up the existing one rather than creating a new one.
55
56    XXX - we should request that it be given the input focus, too.  Alas,
57    GDK has nothing to do that, e.g. by calling "XSetInputFocus()" in a
58    window in X.  Besides, using "XSetInputFocus()" doesn't work anyway,
59    apparently due to the way GTK+/GDK manages the input focus.
60
61    The X Desktop Group's Window Manager Standard specifies, in the section
62    on Root Window Properties, an _NET_ACTIVE_WINDOW client message that
63    can be sent to the root window, containing the window ID of the
64    window to activate; I infer that this might be the way to give the
65    window the input focus - I assume that means it's also de-iconified,
66    but I wouldn't assume it'd raise it.
67
68    XXX - will this do the right thing on window systems other than X? */
69 void
70 reactivate_window(GtkWidget *win)
71 {
72   gdk_window_show(win->window);
73   gdk_window_raise(win->window);
74 }
75
76 /* Set our window icon.  The GDK documentation doesn't provide any
77    actual documentation for gdk_window_set_icon(), so we'll steal
78    libgimp/gimpdialog.c:gimp_dialog_realize_callback() from the Gimp
79    sources and assume it's safe.
80
81    XXX - The current icon size is fixed at 16x16 pixels, which looks fine
82    with kwm (KDE 1.x's window manager), Sawfish (the "default" window
83    manager for GNOME?), and under Windows with Exceed putting X windows
84    on the Windows desktop, using Exceed as the window manager, as those
85    window managers put a 16x16 icon on the title bar.
86
87    The window managers in some windowing environments (e.g. dtwm in CDE)
88    and some stand-alone window managers have larger icon sizes (many window
89    managers put the window icon on the desktop, in the Windows 3.x style,
90    rather than in the titlebar, in the Windows 4.x style), so we need to
91    find a way to size our icon appropriately.
92
93    The X11 Inter-Client Communications Conventions Manual, Version 1.1,
94    in X11R5, specifies that "a window manager that wishes to place
95    constraints on the sizes of icon pixmaps and/or windows should
96    place a property called WM_ICON_SIZE on the root"; that property
97    contains minimum width and height, maximum width and height, and
98    width and height increment values.  "XGetIconSizes()" retrieves
99    that property; unfortunately, I've yet to find a window manager
100    that sets it on the root window (kwm, AfterStep, and Exceed don't
101    appear to set it).
102
103    The X Desktop Group's Window Manager Standard specifies, in the section
104    on Application Window Properties, an _NET_WM_ICON property, presumably
105    set by the window manager, which is an array of possible icon sizes
106    for the client.  There's no API in GTK+ 1.2[.x] for this; there may
107    eventually be one either in GTK+ 2.0 or GNOME 2.0.
108
109    Some window managers can be configured to take the window name
110    specified by the WM_NAME property of a window or the resource
111    or class name specified by the WM_CLASS property and base the
112    choice of icon for the window on one of those; WM_CLASS for
113    Ethereal's windows has a resource name of "ethereal" and a class
114    name of "Ethereal".  However, the way that's done is window-manager-
115    specific, and there's no way to determine what size a particular
116    window manager would want, so there's no way to automate this as
117    part of the installation of Ethereal.
118    */
119 void
120 window_icon_realize_cb (GtkWidget *win, gpointer data _U_)
121 {
122 #ifndef WIN32
123   static GdkPixmap *icon_pmap = NULL;
124   static GdkBitmap *icon_mask = NULL;
125   GtkStyle         *style;
126
127   style = gtk_widget_get_style (win);
128
129   if (icon_pmap == NULL) {
130     icon_pmap = gdk_pixmap_create_from_xpm_d (win->window,
131                 &icon_mask, &style->bg[GTK_STATE_NORMAL], eicon3d16_xpm);
132   }
133
134   gdk_window_set_icon (win->window, NULL, icon_pmap, icon_mask);
135 #endif
136 }
137
138 /* List of all GtkScrolledWindows, so we can globally set the scrollbar
139    placement of all of them. */
140 static GList *scrolled_windows;
141
142 static void setup_scrolled_window(GtkWidget *scrollw);
143 static void forget_scrolled_window(GtkWidget *scrollw, gpointer data);
144 static void set_scrollbar_placement_scrollw(GtkWidget *scrollw);
145
146 /* Create a GtkScrolledWindow, set its scrollbar placement appropriately,
147    and remember it. */
148 GtkWidget *
149 scrolled_window_new(GtkAdjustment *hadjustment, GtkAdjustment *vadjustment)
150 {
151   GtkWidget *scrollw;
152
153   scrollw = gtk_scrolled_window_new(hadjustment, vadjustment);
154   setup_scrolled_window(scrollw);
155   return scrollw;
156 }
157
158 /* Set a GtkScrolledWindow's scrollbar placement and add it to the list
159    of GtkScrolledWindows. */
160 static void
161 setup_scrolled_window(GtkWidget *scrollw)
162 {
163   set_scrollbar_placement_scrollw(scrollw);
164
165   scrolled_windows = g_list_append(scrolled_windows, scrollw);
166
167   /* Catch the "destroy" event on the widget, so that we remove it from
168      the list when it's destroyed. */
169   SIGNAL_CONNECT(scrollw, "destroy", forget_scrolled_window, NULL);
170 }
171
172 /* Remove a GtkScrolledWindow from the list of GtkScrolledWindows. */
173 static void
174 forget_scrolled_window(GtkWidget *scrollw, gpointer data _U_)
175 {
176   scrolled_windows = g_list_remove(scrolled_windows, scrollw);
177 }
178
179 /* Set the scrollbar placement of a GtkScrolledWindow based upon user
180    preference. */
181 static void
182 set_scrollbar_placement_scrollw(GtkWidget *scrollw)
183 {
184   if (prefs.gui_scrollbar_on_right) {
185     gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
186                                       GTK_CORNER_TOP_LEFT);
187   } else {
188     gtk_scrolled_window_set_placement(GTK_SCROLLED_WINDOW(scrollw),
189                                       GTK_CORNER_TOP_RIGHT);
190   }
191 }
192
193 static void
194 set_scrollbar_placement_cb(gpointer data, gpointer user_data _U_)
195 {
196   set_scrollbar_placement_scrollw((GtkWidget *)data);
197 }
198
199 /* Set the scrollbar placement of all GtkScrolledWindows based on
200    user preference. */
201 void
202 set_scrollbar_placement_all(void)
203 {
204   g_list_foreach(scrolled_windows, set_scrollbar_placement_cb, NULL);
205 }
206
207 /* List of all CTrees/TreeViews, so we can globally set the line and
208  * expander style of all of them. */
209 static GList *trees;
210
211 static void setup_tree(GtkWidget *tree);
212 static void forget_tree(GtkWidget *tree, gpointer data);
213 static void set_tree_styles(GtkWidget *tree);
214
215 /* Create a Tree, give it the right styles, and remember it. */
216 #if GTK_MAJOR_VERSION < 2
217 GtkWidget *
218 ctree_new(gint columns, gint tree_column)
219 #else
220 GtkWidget *
221 tree_view_new(GtkTreeModel *model)
222 #endif
223 {
224   GtkWidget *tree;
225
226 #if GTK_MAJOR_VERSION < 2
227   tree = gtk_ctree_new(columns, tree_column);
228 #else
229   tree = gtk_tree_view_new_with_model(model);
230 #endif
231   setup_tree(tree);
232   return tree;
233 }
234
235 #if GTK_MAJOR_VERSION < 2
236 GtkWidget *
237 ctree_new_with_titles(gint columns, gint tree_column, gchar *titles[])
238 {
239   GtkWidget *tree;
240
241   tree = gtk_ctree_new_with_titles(columns, tree_column, titles);
242   setup_tree(tree);
243   return tree;
244 }
245 #endif
246
247 /* Set a Tree's styles and add it to the list of Trees. */
248 static void
249 setup_tree(GtkWidget *tree)
250 {
251   set_tree_styles(tree);
252
253   trees = g_list_append(trees, tree);
254
255   /* Catch the "destroy" event on the widget, so that we remove it from
256      the list when it's destroyed. */
257   SIGNAL_CONNECT(tree, "destroy", forget_tree, NULL);
258 }
259
260 /* Remove a Tree from the list of Trees. */
261 static void
262 forget_tree(GtkWidget *tree, gpointer data _U_)
263 {
264   trees = g_list_remove(trees, tree);
265 }
266
267 /* Set the styles of a Tree based upon user preferences. */
268 static void
269 set_tree_styles(GtkWidget *tree)
270 {
271 #if GTK_MAJOR_VERSION < 2
272   g_assert(prefs.gui_ptree_line_style >= GTK_CTREE_LINES_NONE &&
273            prefs.gui_ptree_line_style <= GTK_CTREE_LINES_TABBED);
274   gtk_ctree_set_line_style(GTK_CTREE(tree), prefs.gui_ptree_line_style);
275   g_assert(prefs.gui_ptree_expander_style >= GTK_CTREE_EXPANDER_NONE &&
276            prefs.gui_ptree_expander_style <= GTK_CTREE_EXPANDER_CIRCULAR);
277   gtk_ctree_set_expander_style(GTK_CTREE(tree),
278       prefs.gui_ptree_expander_style);
279 #else
280   g_assert(prefs.gui_altern_colors >= 0 && prefs.gui_altern_colors <= 1);
281   gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree),
282                                prefs.gui_altern_colors);
283 #endif
284 }
285
286 static void
287 set_tree_styles_cb(gpointer data, gpointer user_data _U_)
288 {
289   set_tree_styles((GtkWidget *)data);
290 }
291
292 /* Set the styles of all Trees based upon style values. */
293 void
294 set_tree_styles_all(void)
295 {
296   g_list_foreach(trees, set_tree_styles_cb, NULL);
297 }