Create a more modular type system for the FT_* types. Put them
[obnox/wireshark/wip.git] / gtk / color_dlg.c
1 /* color_dlg.c
2  * Definitions for dialog boxes for color filters
3  *
4  * $Id: color_dlg.c,v 1.9 2001/02/01 20:21:21 gram Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <gtk/gtk.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include <errno.h>
36
37 #ifdef HAVE_SYS_TYPES_H
38 #include <sys/types.h>
39 #endif
40
41 #include "gtk/main.h"
42 #include "packet.h"
43 #include "colors.h"
44 #include "color_dlg.h"
45 #include "file.h"
46 #include "dfilter/dfilter.h"
47 #include "simple_dialog.h"
48 #include "dlg_utils.h"
49 #include "ui_util.h"
50                 
51 static GtkWidget* colorize_dialog_new(colfilter *filter);
52 static void add_filter_to_clist(gpointer filter_arg, gpointer clist_arg);
53 static void color_filter_up_cb(GtkButton *button, gpointer user_data);
54 static void color_filter_down_cb(GtkButton *button, gpointer user_data);
55 static void remember_selected_row(GtkCList *clist, gint row, gint column,
56                                  GdkEvent *event, gpointer user_data);
57 static void color_destroy_cb(GtkButton *button, gpointer user_data);
58 static void destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy);
59 static void color_new_cb(GtkButton *button, gpointer user_data);
60 static void color_edit_cb(GtkButton *button, gpointer user_data);
61 static void color_delete_cb(GtkWidget *widget, gpointer user_data);
62 static void color_save_cb(GtkButton *button, gpointer user_data);
63 static void color_ok_cb(GtkButton *button, gpointer user_data);
64 static void color_cancel_cb(GtkWidget *widget, gpointer user_data);
65 static void color_apply_cb(GtkButton *button, gpointer user_data);
66
67 static void edit_color_filter_dialog_new(colfilter *filter,
68                                  GtkWidget *color_filters,
69                                  GtkWidget **colorize_filter_name,
70                                  GtkWidget **colorize_filter_text);
71 static void edit_color_filter_destroy_cb(GtkObject *object,
72                                  gpointer user_data);
73 static void edit_color_filter_fg_cb(GtkButton *button, gpointer user_data);
74 static void edit_color_filter_bg_cb(GtkButton *button, gpointer user_data);
75 static void edit_color_filter_ok_cb(GtkButton *button, gpointer user_data);
76 static void edit_color_filter_cancel_cb(GtkObject *object, gpointer user_data);
77
78 static GtkWidget* color_sel_win_new(color_filter_t *colorf, gboolean);
79 static void color_sel_ok_cb(GtkButton *button, gpointer user_data);
80 static void color_sel_cancel_cb(GtkObject *object, gpointer user_data);
81
82 static GtkWidget *colorize_win;
83
84 static gchar *titles[2] = { "Name", "Filter String" };
85
86 #define COLOR_EDIT_LB           "color_edit_lb"
87 #define COLOR_FILTERS_CL        "color_filters_cl"
88 #define COLOR_FILTER            "color_filter"
89 #define COLOR_SELECTION_FG      "color_selection_fg"
90 #define COLOR_SELECTION_BG      "color_selection_bg"
91 #define COLOR_SELECTION_PARENT  "color_selection_parent"
92
93 /* Callback for the "Display:Colorize Display" menu item. */
94 void
95 color_display_cb(GtkWidget *w, gpointer d)
96 {
97   if (colorize_win != NULL) {
98     /* There's already a color dialog box active; reactivate it. */
99     reactivate_window(colorize_win);
100   } else {
101     /* Create a new "Colorize Display" dialog. */
102     colorize_win = colorize_dialog_new(cfile.colors);
103   }
104 }
105
106 /* Create the "Add color to protocols" dialog. */
107 static GtkWidget*
108 colorize_dialog_new (colfilter *filter)
109 {
110   GtkWidget *color_win;
111   GtkWidget *vbox1;
112   GtkWidget *hbox1;
113   GtkWidget *vbox2;
114   GtkWidget *color_filter_up;
115   GtkWidget *label4;
116   GtkWidget *color_filter_down;
117   GtkWidget *scrolledwindow1;
118   GtkWidget *color_filters;
119   GtkWidget *hbox2;
120   GtkWidget *color_new;
121   GtkWidget *color_edit;
122   GtkWidget *color_delete;
123   GtkWidget *color_save;
124   GtkWidget *hbox3;
125   GtkWidget *color_ok;
126   GtkWidget *color_apply;
127   GtkWidget *color_cancel;
128   GtkTooltips *tooltips;
129
130   filter->row_selected = -1; /* no row selected */
131   tooltips = gtk_tooltips_new ();
132
133   color_win = dlg_window_new ("Add color to protocols");
134   gtk_object_set_data (GTK_OBJECT (color_win), "color_win", color_win);
135
136   vbox1 = gtk_vbox_new (FALSE, 0);
137   gtk_widget_ref (vbox1);
138   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox1", vbox1,
139                             (GtkDestroyNotify) gtk_widget_unref);
140   gtk_widget_show (vbox1);
141   gtk_container_add (GTK_CONTAINER (color_win), vbox1);
142
143   hbox1 = gtk_hbox_new (FALSE, 0);
144   gtk_widget_ref (hbox1);
145   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox1", hbox1,
146                             (GtkDestroyNotify) gtk_widget_unref);
147   gtk_widget_show (hbox1);
148   gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
149
150   vbox2 = gtk_vbox_new (TRUE, 0);
151   gtk_widget_ref (vbox2);
152   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox2", vbox2,
153                             (GtkDestroyNotify) gtk_widget_unref);
154   gtk_widget_show (vbox2);
155   gtk_box_pack_start (GTK_BOX (hbox1), vbox2, FALSE, TRUE, 0);
156   gtk_widget_set_usize (vbox2, 150, -2);
157
158   color_filter_up = gtk_button_new_with_label (("Up"));
159   gtk_widget_ref (color_filter_up);
160   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filter_up", color_filter_up,
161                             (GtkDestroyNotify) gtk_widget_unref);
162   gtk_widget_show (color_filter_up);
163   gtk_box_pack_start (GTK_BOX (vbox2), color_filter_up, FALSE, FALSE, 0);
164   gtk_tooltips_set_tip (tooltips, color_filter_up, ("Move filter higher in list"), NULL);
165
166   label4 = gtk_label_new (("Move filter\nup or down\n[List is processed \n"
167                           "in order until\nmatch is found]"));
168   gtk_widget_ref (label4);
169   gtk_object_set_data_full (GTK_OBJECT (color_win), "label4", label4,
170                             (GtkDestroyNotify) gtk_widget_unref);
171   gtk_widget_show (label4);
172   gtk_box_pack_start (GTK_BOX (vbox2), label4, FALSE, FALSE, 0);
173
174   color_filter_down = gtk_button_new_with_label (("Down"));
175   gtk_widget_ref (color_filter_down);
176   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filter_down", color_filter_down,
177                             (GtkDestroyNotify) gtk_widget_unref);
178   gtk_widget_show (color_filter_down);
179   gtk_box_pack_start (GTK_BOX (vbox2), color_filter_down, FALSE, FALSE, 0);
180   gtk_tooltips_set_tip (tooltips, color_filter_down, ("Move filter lower in list"), NULL);
181
182   scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
183   gtk_widget_ref (scrolledwindow1);
184   gtk_object_set_data_full (GTK_OBJECT (color_win), "scrolledwindow1", scrolledwindow1,
185                             (GtkDestroyNotify) gtk_widget_unref);
186   gtk_widget_show (scrolledwindow1);
187   gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
188
189   color_filters = gtk_clist_new_with_titles(2, titles);
190
191 #if 0
192   /* I don't seem to need this, but just in case, I'll if0 it */
193   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filters",
194                             color_filters,
195                             (GtkDestroyNotify) gtk_widget_unref);
196 #endif
197   g_slist_foreach(filter_list, add_filter_to_clist, color_filters);
198
199   gtk_widget_show (color_filters);
200   gtk_container_add (GTK_CONTAINER (scrolledwindow1), color_filters);
201   gtk_widget_set_usize (color_filters, 300, -2);
202   gtk_clist_set_column_width (GTK_CLIST (color_filters), 0, 80);
203   gtk_clist_set_column_width (GTK_CLIST (color_filters), 1, 80);
204   gtk_clist_column_titles_show (GTK_CLIST (color_filters));
205
206   hbox2 = gtk_hbox_new (FALSE, 0);
207   gtk_widget_ref (hbox2);
208   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox2", hbox2,
209                             (GtkDestroyNotify) gtk_widget_unref);
210   gtk_widget_show (hbox2);
211   gtk_box_pack_start (GTK_BOX (vbox1), hbox2, TRUE, FALSE, 5);
212   gtk_widget_set_usize (hbox2, -2, 30);
213
214   color_new = gtk_button_new_with_label (("New"));
215   gtk_widget_ref (color_new);
216   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_new", color_new,
217                             (GtkDestroyNotify) gtk_widget_unref);
218   gtk_widget_show (color_new);
219   gtk_box_pack_start (GTK_BOX (hbox2), color_new, TRUE, FALSE, 5);
220   gtk_widget_set_usize (color_new, 50, 20);
221   gtk_tooltips_set_tip (tooltips, color_new, ("Create a new colorization filter after selected filter"), NULL);
222
223   color_edit = gtk_button_new_with_label (("Edit"));
224   gtk_widget_ref (color_edit);
225   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_edit", color_edit,
226                             (GtkDestroyNotify) gtk_widget_unref);
227   gtk_widget_show (color_edit);
228   gtk_widget_set_usize(color_edit, 50, 20);
229   gtk_box_pack_start (GTK_BOX (hbox2), color_edit, TRUE, FALSE, 5);
230   gtk_tooltips_set_tip (tooltips, color_edit, ("Change color of selected filter"), NULL);
231   gtk_widget_set_sensitive (color_edit,
232       (filter->num_of_filters != 0));
233
234   color_delete = gtk_button_new_with_label (("Delete"));
235   gtk_widget_ref (color_delete);
236   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_delete", color_delete,
237                             (GtkDestroyNotify) gtk_widget_unref);
238   gtk_widget_show (color_delete);
239   gtk_box_pack_start (GTK_BOX (hbox2), color_delete, TRUE, FALSE, 5);
240   gtk_widget_set_usize (color_delete, 50, 20);
241   gtk_tooltips_set_tip (tooltips, color_delete, ("Delete selected colorization filter"), NULL);
242
243   color_save = gtk_button_new_with_label (("Save"));
244   gtk_widget_ref (color_save);
245   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_save", color_save,
246                             (GtkDestroyNotify) gtk_widget_unref);
247   gtk_widget_show (color_save);
248   gtk_box_pack_start (GTK_BOX (hbox2), color_save, TRUE, FALSE, 5);
249   gtk_widget_set_usize (color_save, 50, 20);
250   gtk_tooltips_set_tip (tooltips, color_save, ("Save all filters to disk"), NULL);
251
252   hbox3 = gtk_hbox_new (FALSE, 0);
253   gtk_widget_ref (hbox3);
254   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox3", hbox3,
255                             (GtkDestroyNotify) gtk_widget_unref);
256   gtk_widget_show (hbox3);
257   gtk_box_pack_start (GTK_BOX (vbox1), hbox3, TRUE, FALSE, 5);
258   gtk_widget_set_usize (hbox3, 177, 30);
259
260   color_ok = gtk_button_new_with_label (("OK"));
261   gtk_widget_ref (color_ok);
262   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_ok", color_ok,
263                             (GtkDestroyNotify) gtk_widget_unref);
264   gtk_widget_show (color_ok);
265   gtk_box_pack_start (GTK_BOX (hbox3), color_ok, TRUE, FALSE, 0);
266   gtk_widget_set_usize (color_ok, 50, 20);
267   gtk_tooltips_set_tip (tooltips, color_ok, ("Accept filter list; apply changes"), NULL);
268
269   color_apply = gtk_button_new_with_label (("Apply"));
270   gtk_widget_ref (color_apply);
271   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_apply", color_apply,
272                             (GtkDestroyNotify) gtk_widget_unref);
273   gtk_widget_show (color_apply);
274   gtk_box_pack_start (GTK_BOX (hbox3), color_apply, TRUE, FALSE, 0);
275   gtk_widget_set_usize (color_apply, 50, 20);
276   gtk_tooltips_set_tip (tooltips, color_apply, ("Apply filters in list"), NULL);
277
278   color_cancel = gtk_button_new_with_label (("Cancel"));
279   gtk_widget_ref (color_cancel);
280   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_cancel", color_cancel,
281                             (GtkDestroyNotify) gtk_widget_unref);
282   gtk_widget_show (color_cancel);
283   gtk_box_pack_start (GTK_BOX (hbox3), color_cancel, TRUE, FALSE, 0);
284   gtk_widget_set_usize (color_cancel, 50, 20);
285   gtk_tooltips_set_tip (tooltips, color_cancel, ("No more filter changes; don't apply"), NULL);
286
287   gtk_signal_connect (GTK_OBJECT (color_win), "destroy",
288                       GTK_SIGNAL_FUNC (color_destroy_cb),
289                       NULL);
290   gtk_object_set_data(GTK_OBJECT (color_filter_up), COLOR_FILTERS_CL,
291                       color_filters);
292   gtk_signal_connect (GTK_OBJECT (color_filter_up), "clicked",
293                       GTK_SIGNAL_FUNC (color_filter_up_cb),
294                       filter);
295   gtk_object_set_data(GTK_OBJECT (color_filter_down), COLOR_FILTERS_CL,
296                       color_filters);
297   gtk_signal_connect (GTK_OBJECT (color_filter_down), "clicked",
298                       GTK_SIGNAL_FUNC (color_filter_down_cb),
299                       filter);
300   gtk_signal_connect (GTK_OBJECT (color_filters), "select_row",
301                       GTK_SIGNAL_FUNC (remember_selected_row),
302                       filter);
303   gtk_object_set_data(GTK_OBJECT (color_new), COLOR_EDIT_LB,
304                       color_edit);
305   gtk_object_set_data(GTK_OBJECT (color_new), COLOR_FILTERS_CL,
306                       color_filters);
307   gtk_signal_connect (GTK_OBJECT (color_new), "clicked",
308                       GTK_SIGNAL_FUNC (color_new_cb),
309                       filter);
310   gtk_object_set_data(GTK_OBJECT (color_edit), COLOR_FILTERS_CL,
311                       color_filters);
312   gtk_signal_connect (GTK_OBJECT (color_edit), "clicked",
313                       GTK_SIGNAL_FUNC (color_edit_cb),
314                       filter);
315   gtk_object_set_data(GTK_OBJECT (color_delete), COLOR_EDIT_LB,
316                       color_edit);
317   gtk_object_set_data(GTK_OBJECT (color_delete), COLOR_FILTERS_CL,
318                       color_filters);
319   gtk_signal_connect (GTK_OBJECT (color_delete), "clicked",
320                       GTK_SIGNAL_FUNC (color_delete_cb),
321                       filter);
322   gtk_signal_connect (GTK_OBJECT (color_save), "clicked",
323                       GTK_SIGNAL_FUNC (color_save_cb),
324                       filter);
325   gtk_signal_connect (GTK_OBJECT (color_ok), "clicked",
326                       GTK_SIGNAL_FUNC (color_ok_cb),
327                       NULL);
328   gtk_signal_connect (GTK_OBJECT (color_apply), "clicked",
329                       GTK_SIGNAL_FUNC (color_apply_cb),
330                       filter);
331   gtk_signal_connect (GTK_OBJECT (color_cancel), "clicked",
332                       GTK_SIGNAL_FUNC (color_cancel_cb),
333                       NULL);
334
335   gtk_widget_grab_focus (color_filters);
336   gtk_object_set_data (GTK_OBJECT (color_win), "tooltips", tooltips);
337   gtk_widget_show (color_win);
338
339   dlg_set_cancel(color_win, color_cancel);
340
341   return color_win;
342 }
343
344 static void
345 add_filter_to_clist(gpointer filter_arg, gpointer clist_arg)
346 {
347   color_filter_t *colorf = filter_arg;
348   GtkWidget *color_filters = clist_arg;
349   gchar *data[2];
350   gint row;
351
352   data[0] = colorf->filter_name;
353   data[1] = colorf->filter_text;
354   row = gtk_clist_append(GTK_CLIST(color_filters), data);
355   gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
356   gtk_clist_set_foreground(GTK_CLIST(color_filters), row, &colorf->fg_color);
357   gtk_clist_set_background(GTK_CLIST(color_filters), row, &colorf->bg_color);
358 }
359
360 /* Move the selected filter up in the list */
361 static void
362 color_filter_up_cb                     (GtkButton       *button,
363                                         gpointer         user_data)
364 {
365   colfilter *filter;
366   gint filter_number;
367   GtkWidget *color_filters;
368   color_filter_t *colorf;
369
370   filter = (colfilter *)user_data;
371   filter_number = filter->row_selected;
372
373   /* If it is filter number 0, it cannot be moved, as it's already
374      at the top of the filter.
375      If there's only one filter in the list, it cannot be moved,
376      as there's no place to move it. */
377   if (filter_number != 0 && filter->num_of_filters >= 2) {
378         color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
379                       COLOR_FILTERS_CL);
380         colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters),
381            filter_number);
382         gtk_clist_swap_rows(GTK_CLIST(color_filters), filter_number,
383                         filter_number-1);
384         filter_list = g_slist_remove(filter_list, colorf);
385         filter_list = g_slist_insert(filter_list, colorf, filter_number-1);
386         filter->row_selected--;
387   }
388 }
389
390 /* Move the selected filter down in the list */
391 static void
392 color_filter_down_cb                   (GtkButton       *button,
393                                         gpointer         user_data)
394 {
395   colfilter *filter;
396   gint filter_number;
397   GtkWidget *color_filters;
398   color_filter_t *colorf;
399
400   filter = (colfilter *)user_data;
401   filter_number = filter->row_selected;
402
403   /* If it is the last filter in the list, it cannot be moved, as it's
404      already at the bottom of the filter.
405      If there's only one filter in the list, it cannot be moved,
406      as there's no place to move it. */
407   if (filter_number != filter->num_of_filters-1
408     && filter->num_of_filters >= 2) {
409         color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
410                       COLOR_FILTERS_CL);
411         colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters),
412            filter_number);
413         gtk_clist_swap_rows(GTK_CLIST(color_filters), filter_number+1,
414                         filter_number);
415         filter_list = g_slist_remove(filter_list, colorf);
416         filter_list = g_slist_insert(filter_list, colorf, filter_number+1);
417         filter->row_selected++;
418   }
419 }
420
421 /* Set selected row in cf */
422 static void
423 remember_selected_row                 (GtkCList        *clist,
424                                         gint             row,
425                                         gint             column,
426                                         GdkEvent        *event,
427                                         gpointer         user_data)
428 {
429   colfilter *filter = (colfilter *)user_data;
430
431   filter->row_selected = row;
432 }
433
434 /* Called when the dialog box is being destroyed; destroy any edit
435    dialogs opened from this dialog, and null out the pointer to this
436    dialog. */
437 static void
438 color_destroy_cb                       (GtkButton       *button,
439                                         gpointer         user_data)
440 {
441   /* Destroy any edit dialogs we have open. */
442   g_slist_foreach(filter_list, destroy_edit_dialog_cb, NULL);
443
444   colorize_win = NULL;
445 }
446
447 static void
448 destroy_edit_dialog_cb(gpointer filter_arg, gpointer dummy)
449 {
450   color_filter_t *colorf = (color_filter_t *)filter_arg;
451
452   if (colorf->edit_dialog != NULL)
453     gtk_widget_destroy(colorf->edit_dialog);
454 }
455
456 /* XXX - we don't forbid having more than one "Edit color filter" dialog
457    open, so these shouldn't be static. */
458 static GtkWidget *filt_name_entry;
459 static GtkWidget *filt_text_entry;
460
461 /* Create a new filter in the list, and pop up an "Edit color filter"
462    dialog box to edit it. */
463 static void
464 color_new_cb                          (GtkButton       *button,
465                                         gpointer         user_data)
466 {
467   colfilter *filter;
468   color_filter_t *colorf;
469   GtkWidget *color_filters;
470   gchar *data[2];
471   gint row;
472   GtkWidget *color_edit;
473
474   filter = (colfilter *)user_data;
475   colorf = new_color_filter(filter, "name", "filter"); /* Adds at end! */
476
477   color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
478                       COLOR_FILTERS_CL);
479   data[0] = colorf->filter_name;
480   data[1] = colorf->filter_text;
481   row = gtk_clist_append(GTK_CLIST(color_filters), data);
482   gtk_clist_set_row_data(GTK_CLIST(color_filters), row, colorf);
483
484   /* A row has been added, so we can edit it. */
485   color_edit = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
486                                         COLOR_EDIT_LB);
487   gtk_widget_set_sensitive (color_edit, TRUE);
488
489   /* select the new (last) row */
490   filter->row_selected = filter->num_of_filters;
491   filter->num_of_filters++;
492   gtk_clist_select_row(GTK_CLIST(color_filters), filter->row_selected, -1);
493   edit_color_filter_dialog_new(filter, color_filters, &filt_name_entry,
494                                 &filt_text_entry);
495 }
496
497 /* Pop up an "Edit color filter" dialog box to edit an existing filter. */
498 static void
499 color_edit_cb                        (GtkButton       *button,
500                                       gpointer         user_data)
501 {
502   colfilter *filter;
503   GtkWidget *color_filters;
504
505   filter = (colfilter *)user_data;
506   color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
507                       COLOR_FILTERS_CL);
508   if(filter->row_selected == -1){
509         /* select the first row */
510         filter->row_selected = 0;
511         gtk_clist_select_row(GTK_CLIST(color_filters), filter->row_selected,
512                                 -1);
513   }
514   edit_color_filter_dialog_new(filter, color_filters, &filt_name_entry,
515                                 &filt_text_entry);
516 }
517
518 /* Delete a color from the list. */
519 static void
520 color_delete_cb(GtkWidget *widget, gpointer user_data)
521 {
522   colfilter *filter;
523   GtkWidget *color_filters;
524   color_filter_t *colorf;
525   GtkWidget *color_edit;
526
527   filter = (colfilter *)user_data;
528   if(filter->row_selected != -1){
529         color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
530                       COLOR_FILTERS_CL);
531         colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters),
532            filter->row_selected);
533
534         /* Remove this color filter from the CList displaying the
535            color filters. */
536         gtk_clist_remove(GTK_CLIST(color_filters), filter->row_selected);
537
538         /* Destroy any "Edit color filter" dialog boxes editing it. */
539         if (colorf->edit_dialog != NULL)
540                 gtk_widget_destroy(colorf->edit_dialog);
541
542         /* Remove the color filter from the list of color filters. */
543         delete_color_filter(colorf);
544         filter->num_of_filters--;
545         if(!filter->num_of_filters){
546                 /* No filters any more, so none can be selected... */
547                 filter->row_selected = -1;
548                 color_edit =
549                     (GtkWidget *) gtk_object_get_data(GTK_OBJECT(widget),
550                       COLOR_EDIT_LB);
551
552                 /* ...and none can be edited. */
553                 gtk_widget_set_sensitive (color_edit, FALSE);
554         } else {
555                 filter->row_selected--;
556                 if(filter->row_selected < 0)
557                         filter->row_selected = 0;
558                 gtk_clist_select_row(GTK_CLIST(color_filters),
559                     filter->row_selected, 0);
560         }
561   }
562 }
563
564 /* Save color filters to the color filter file. */
565 static void
566 color_save_cb                          (GtkButton       *button,
567                                         gpointer         user_data)
568 {
569   colfilter *filter = (colfilter *)user_data;
570
571   if (!write_filters(filter))
572         simple_dialog(ESD_TYPE_CRIT, NULL, "Could not open filter file: %s",
573             strerror(errno));
574
575 }
576
577 /* Exit dialog and apply new list of color filters to the capture. */
578 static void
579 color_ok_cb                            (GtkButton       *button,
580                                         gpointer         user_data)
581 {
582   /* colorize list */
583   colorize_packets(&cfile);
584
585   /* Destroy the dialog box. */
586   gtk_widget_destroy(colorize_win);
587 }
588
589 /* Exit dialog without colorizing packets with the new list.
590    XXX - should really undo any changes to the list.... */
591 static void
592 color_cancel_cb                        (GtkWidget       *widget,
593                                         gpointer         user_data)
594 {
595   /* Destroy the dialog box. */
596   gtk_widget_destroy(colorize_win);
597 }
598
599 /* Apply new list of color filters to the capture. */
600 static void
601 color_apply_cb                         (GtkButton       *button,
602                                         gpointer         user_data)
603 {
604   colorize_packets(&cfile);
605 }
606
607 /* Create an "Edit color filter" dialog for a given color filter, and
608    associate it with that color filter. */
609 static void
610 edit_color_filter_dialog_new (colfilter *filter,
611         GtkWidget *color_filters,
612         GtkWidget **colorize_filter_name,
613         GtkWidget **colorize_filter_text)
614 {
615   color_filter_t *colorf;
616   GtkWidget *edit_dialog;
617   GtkWidget *vbox3;
618   GtkWidget *hbox6;
619   GtkWidget *color_filter_name;
620   GtkWidget *hbox7;
621   GtkWidget *color_filter_text;
622   GtkWidget *hbox5;
623   GtkWidget *colorize_filter_fg;
624   GtkWidget *colorize_filter_bg;
625   GtkWidget *hbox4;
626   GtkWidget *edit_color_filter_ok;
627   GtkWidget *edit_color_filter_cancel;
628   GtkTooltips *tooltips;
629   GtkStyle  *style;
630
631   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters),
632            filter->row_selected);
633   if (colorf->edit_dialog != NULL) {
634     /* There's already an edit box open for this filter; reactivate it. */
635     reactivate_window(colorf->edit_dialog);
636     return;
637   }
638
639   tooltips = gtk_tooltips_new ();
640
641   edit_dialog = dlg_window_new ("Edit color filter");
642   gtk_object_set_data (GTK_OBJECT (edit_dialog), "edit_dialog", edit_dialog);
643   colorf->edit_dialog = edit_dialog;
644
645   vbox3 = gtk_vbox_new (FALSE, 0);
646   gtk_widget_ref (vbox3);
647   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "vbox3", vbox3,
648                             (GtkDestroyNotify) gtk_widget_unref);
649   gtk_widget_show (vbox3);
650   gtk_container_add (GTK_CONTAINER (edit_dialog), vbox3);
651
652   hbox6 = gtk_hbox_new (FALSE, 0);
653   gtk_widget_ref (hbox6);
654   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox6", hbox6,
655                             (GtkDestroyNotify) gtk_widget_unref);
656   gtk_widget_show (hbox6);
657   gtk_box_pack_start (GTK_BOX (vbox3), hbox6, TRUE, FALSE, 5);
658
659   color_filter_name = gtk_label_new (("Name: "));
660   gtk_widget_ref (color_filter_name);
661   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "color_filter_name", color_filter_name,
662                             (GtkDestroyNotify) gtk_widget_unref);
663   gtk_widget_show (color_filter_name);
664   gtk_box_pack_start (GTK_BOX (hbox6), color_filter_name, FALSE, FALSE, 0);
665
666   *colorize_filter_name = gtk_entry_new ();
667   gtk_widget_ref (*colorize_filter_name);
668   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "*colorize_filter_name", *colorize_filter_name,
669                             (GtkDestroyNotify) gtk_widget_unref);
670   gtk_entry_set_text(GTK_ENTRY(*colorize_filter_name), colorf->filter_name);
671
672   style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_name));
673   style->base[GTK_STATE_NORMAL] = colorf->bg_color;
674   style->fg[GTK_STATE_NORMAL]   = colorf->fg_color;
675   gtk_widget_set_style(*colorize_filter_name, style);
676
677   gtk_widget_show (*colorize_filter_name);
678   gtk_box_pack_start (GTK_BOX (hbox6), *colorize_filter_name, TRUE, TRUE, 0);
679   gtk_tooltips_set_tip (tooltips, *colorize_filter_name, ("This is the editable name of the filter. (No @ characters allowed.)"), NULL);
680
681   hbox7 = gtk_hbox_new (FALSE, 0);
682   gtk_widget_ref (hbox7);
683   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox7", hbox7,
684                             (GtkDestroyNotify) gtk_widget_unref);
685   gtk_widget_show (hbox7);
686   gtk_box_pack_start (GTK_BOX (vbox3), hbox7, TRUE, FALSE, 5);
687
688   color_filter_text = gtk_label_new (("Filter text:"));
689   gtk_widget_ref (color_filter_text);
690   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "color_filter_text", color_filter_text,
691                             (GtkDestroyNotify) gtk_widget_unref);
692   gtk_widget_show (color_filter_text);
693   gtk_box_pack_start (GTK_BOX (hbox7), color_filter_text, FALSE, FALSE, 0);
694
695   *colorize_filter_text = gtk_entry_new ();
696   gtk_widget_ref (*colorize_filter_text);
697   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "*colorize_filter_text", *colorize_filter_text,
698                             (GtkDestroyNotify) gtk_widget_unref);
699   gtk_entry_set_text(GTK_ENTRY(*colorize_filter_text), colorf->filter_text);
700 #if 0
701   style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_text));
702   style->base[GTK_STATE_NORMAL] = colorf->bg_color;
703   style->fg[GTK_STATE_NORMAL]   = colorf->fg_color;
704 #endif
705   gtk_widget_set_style(*colorize_filter_text, style);
706   gtk_widget_show (*colorize_filter_text);
707   gtk_box_pack_start (GTK_BOX (hbox7), *colorize_filter_text, TRUE, TRUE, 0);
708   gtk_tooltips_set_tip (tooltips, *colorize_filter_text, ("This is the editable text of the filter"), NULL);
709
710   hbox5 = gtk_hbox_new (FALSE, 0);
711   gtk_widget_ref (hbox5);
712   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox5", hbox5,
713                             (GtkDestroyNotify) gtk_widget_unref);
714   gtk_widget_show (hbox5);
715   gtk_box_pack_start (GTK_BOX (vbox3), hbox5, FALSE, FALSE, 5);
716   gtk_widget_set_usize (hbox5, -2, 60);
717
718   colorize_filter_fg = gtk_button_new_with_label (("Choose \nforeground\ncolor"));
719   gtk_widget_ref (colorize_filter_fg);
720   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "colorize_filter_fg", colorize_filter_fg,
721                             (GtkDestroyNotify) gtk_widget_unref);
722   gtk_widget_show (colorize_filter_fg);
723   gtk_box_pack_start (GTK_BOX (hbox5), colorize_filter_fg, TRUE, FALSE, 0);
724   gtk_tooltips_set_tip (tooltips, colorize_filter_fg, ("Select color for data display"), NULL);
725
726   colorize_filter_bg = gtk_button_new_with_label (("Choose\nbackground\ncolor"));
727   gtk_widget_ref (colorize_filter_bg);
728   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "colorize_filter_bg", colorize_filter_bg,
729                             (GtkDestroyNotify) gtk_widget_unref);
730   gtk_widget_show (colorize_filter_bg);
731   gtk_box_pack_start (GTK_BOX (hbox5), colorize_filter_bg, TRUE, FALSE, 0);
732   gtk_tooltips_set_tip (tooltips, colorize_filter_bg, ("Select color for data display"), NULL);
733
734   hbox4 = gtk_hbox_new (FALSE, 0);
735   gtk_widget_ref (hbox4);
736   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "hbox4", hbox4,
737                             (GtkDestroyNotify) gtk_widget_unref);
738   gtk_widget_show (hbox4);
739   gtk_box_pack_start (GTK_BOX (vbox3), hbox4, TRUE, FALSE, 5);
740   gtk_widget_set_usize (hbox4, -2, 30);
741
742   edit_color_filter_ok = gtk_button_new_with_label (("OK"));
743   gtk_widget_ref (edit_color_filter_ok);
744   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "edit_color_filter_ok", edit_color_filter_ok,
745                             (GtkDestroyNotify) gtk_widget_unref);
746   gtk_widget_set_usize (edit_color_filter_ok, 50, 20);
747   gtk_widget_show (edit_color_filter_ok);
748   gtk_box_pack_start (GTK_BOX (hbox4), edit_color_filter_ok, TRUE, FALSE, 0);
749   gtk_tooltips_set_tip (tooltips, edit_color_filter_ok, ("Accept filter color change"), NULL);
750
751   edit_color_filter_cancel = gtk_button_new_with_label (("Cancel"));
752   gtk_widget_ref (edit_color_filter_cancel);
753   gtk_object_set_data_full (GTK_OBJECT (edit_dialog), "edit_color_filter_cancel", edit_color_filter_cancel,
754                             (GtkDestroyNotify) gtk_widget_unref);
755   gtk_widget_set_usize (edit_color_filter_cancel, 50, 20);
756   gtk_widget_show (edit_color_filter_cancel);
757   gtk_box_pack_start (GTK_BOX (hbox4), edit_color_filter_cancel, TRUE, FALSE, 0);
758   gtk_tooltips_set_tip (tooltips, edit_color_filter_cancel, ("Reject filter color change"), NULL);
759   gtk_object_set_data(GTK_OBJECT (edit_dialog), COLOR_FILTER,
760                       colorf);
761   gtk_signal_connect (GTK_OBJECT (edit_dialog), "destroy",
762                       GTK_SIGNAL_FUNC (edit_color_filter_destroy_cb),
763                       NULL);
764   gtk_object_set_data(GTK_OBJECT (colorize_filter_fg), COLOR_FILTER,
765                       colorf);
766   gtk_signal_connect (GTK_OBJECT (colorize_filter_fg), "clicked",
767                       GTK_SIGNAL_FUNC (edit_color_filter_fg_cb),
768                       filter);
769   gtk_object_set_data(GTK_OBJECT (colorize_filter_bg), COLOR_FILTER,
770                       colorf);
771   gtk_signal_connect (GTK_OBJECT (colorize_filter_bg), "clicked",
772                       GTK_SIGNAL_FUNC (edit_color_filter_bg_cb),
773                       filter);
774   gtk_object_set_data(GTK_OBJECT (edit_color_filter_ok), COLOR_FILTERS_CL,
775                       color_filters);
776   gtk_object_set_data(GTK_OBJECT (edit_color_filter_ok), COLOR_FILTER,
777                       colorf);
778   gtk_signal_connect (GTK_OBJECT (edit_color_filter_ok), "clicked",
779                       GTK_SIGNAL_FUNC (edit_color_filter_ok_cb),
780                       edit_dialog);
781   gtk_signal_connect (GTK_OBJECT (edit_color_filter_cancel), "clicked",
782                       GTK_SIGNAL_FUNC (edit_color_filter_cancel_cb),
783                       edit_dialog);
784
785   gtk_object_set_data (GTK_OBJECT (edit_dialog), "tooltips", tooltips);
786
787   dlg_set_cancel(edit_dialog, edit_color_filter_cancel);
788
789   gtk_widget_show (edit_dialog);
790 }
791
792 /* Called when the dialog box is being destroyed; destroy any color
793    selection dialogs opened from this dialog, and null out the pointer
794    to this dialog. */
795 static void
796 edit_color_filter_destroy_cb           (GtkObject       *object,
797                                         gpointer         user_data)
798 {
799   color_filter_t *colorf;
800   GtkWidget *color_sel;
801
802   colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(object),
803                       COLOR_FILTER);
804
805   colorf->edit_dialog = NULL;
806
807   /* Destroy any color selection dialogs this dialog had open. */
808   color_sel = (GtkWidget *) gtk_object_get_data(object, COLOR_SELECTION_FG);
809   if (color_sel != NULL)
810     gtk_widget_destroy(color_sel);
811   color_sel = (GtkWidget *) gtk_object_get_data(object, COLOR_SELECTION_BG);
812   if (color_sel != NULL)
813     gtk_widget_destroy(color_sel);
814 }
815
816 /* Pop up a color selection box to choose the foreground color. */
817 static void
818 edit_color_filter_fg_cb                (GtkButton       *button,
819                                         gpointer         user_data)
820 {
821   colfilter *filter;
822   color_filter_t *colorf;
823   GtkWidget *color_selection_fg;
824
825   filter = (colfilter *)user_data;
826   colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(button),
827                       COLOR_FILTER);
828   /* Do we already have one open for this dialog? */
829   color_selection_fg = gtk_object_get_data(GTK_OBJECT (colorf->edit_dialog),
830       COLOR_SELECTION_FG);
831   if (color_selection_fg != NULL) {
832     /* Yes.  Just reactivate it. */
833     reactivate_window(color_selection_fg);
834   } else {
835     /* No.  Create a new color selection box, and associate it with
836        this dialog. */
837     color_selection_fg = color_sel_win_new(colorf, FALSE);
838     gtk_object_set_data(GTK_OBJECT (colorf->edit_dialog), COLOR_SELECTION_FG,
839                       color_selection_fg);
840     gtk_object_set_data(GTK_OBJECT (color_selection_fg),
841                 COLOR_SELECTION_PARENT, colorf->edit_dialog);
842   }
843 }
844
845 /* Pop up a color selection box to choose the background color. */
846 static void
847 edit_color_filter_bg_cb                (GtkButton       *button,
848                                         gpointer         user_data)
849 {
850   colfilter *filter;
851   color_filter_t *colorf;
852   GtkWidget *color_selection_bg;
853
854   filter = (colfilter *)user_data;
855   colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(button),
856                       COLOR_FILTER);
857
858   /* Do we already have one open for this dialog? */
859   color_selection_bg = gtk_object_get_data(GTK_OBJECT (colorf->edit_dialog),
860       COLOR_SELECTION_BG);
861   if (color_selection_bg != NULL) {
862     /* Yes.  Just reactivate it. */
863     reactivate_window(color_selection_bg);
864   } else {
865     /* No.  Create a new color selection box, and associate it with
866        this dialog. */
867     color_selection_bg = color_sel_win_new(colorf, TRUE);
868     gtk_object_set_data(GTK_OBJECT (colorf->edit_dialog), COLOR_SELECTION_BG,
869                       color_selection_bg);
870     gtk_object_set_data(GTK_OBJECT (color_selection_bg),
871                 COLOR_SELECTION_PARENT, colorf->edit_dialog);
872   }
873 }
874
875 /* accept color (and potential content) change */
876 static void
877 edit_color_filter_ok_cb                (GtkButton       *button,
878                                         gpointer         user_data)
879 {
880   GtkWidget *dialog;
881   GtkStyle *style;
882   GdkColor new_fg_color;
883   GdkColor new_bg_color;
884   gchar *filter_name;
885   gchar *filter_text;
886   color_filter_t *colorf;
887   dfilter_t *compiled_filter;
888   GtkWidget *color_filters;
889
890   dialog = (GtkWidget *)user_data;
891
892   style = gtk_widget_get_style(filt_name_entry);
893   new_bg_color = style->base[GTK_STATE_NORMAL];
894   new_fg_color = style->fg[GTK_STATE_NORMAL];
895
896   filter_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_name_entry)));
897   filter_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_text_entry)));
898
899   if(strchr(filter_name,'@') || strchr(filter_text,'@')){
900         simple_dialog(ESD_TYPE_CRIT, NULL, "Filter names and strings must not"
901           " use the '@' character. Filter unchanged.");
902         g_free(filter_name);
903         g_free(filter_text);
904         return;
905   }
906
907   if(!dfilter_compile(filter_text, &compiled_filter)) {
908         simple_dialog(ESD_TYPE_CRIT, NULL, "Filter \"%s\" did not compile correctly.\n"
909                 " Please try again. Filter unchanged.\n%s\n", filter_name,
910                 dfilter_error_msg);
911   } else {
912         color_filters = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(button),
913                       COLOR_FILTERS_CL);
914         colorf = (color_filter_t *) gtk_object_get_data(GTK_OBJECT(button),
915                       COLOR_FILTER);
916
917         if (colorf->filter_name != NULL)
918             g_free(colorf->filter_name);
919         colorf->filter_name = filter_name;
920         if (colorf->filter_text != NULL)
921             g_free(colorf->filter_text);
922         colorf->filter_text = filter_text;
923         colorf->fg_color = new_fg_color;
924         colorf->bg_color = new_bg_color;
925         gtk_clist_set_foreground(GTK_CLIST(color_filters),
926             cfile.colors->row_selected, &new_fg_color);
927         gtk_clist_set_background(GTK_CLIST(color_filters),
928             cfile.colors->row_selected, &new_bg_color);
929         if(colorf->c_colorfilter != NULL)
930             dfilter_free(colorf->c_colorfilter);
931         colorf->c_colorfilter = compiled_filter;
932         /* gtk_clist_set_text frees old text (if any) and allocates new space */
933         gtk_clist_set_text(GTK_CLIST(color_filters),
934                 cfile.colors->row_selected, 0, filter_name);
935         gtk_clist_set_text(GTK_CLIST(color_filters),
936                 cfile.colors->row_selected, 1, filter_text);
937
938         /* Destroy the dialog box. */
939         gtk_widget_destroy(dialog);
940   }
941 }
942
943 /* Exit dialog and do not process list */
944 static void
945 edit_color_filter_cancel_cb            (GtkObject       *object,
946                                         gpointer         user_data)
947 {
948   GtkWidget *dialog;
949
950   dialog = (GtkWidget *)user_data;
951
952   /* Destroy the dialog box. */
953   gtk_widget_destroy(dialog);
954 }
955
956 static GtkWidget*
957 color_sel_win_new(color_filter_t *colorf, gboolean is_bg)
958 {
959   gint title_len;
960   gchar *title;
961   static const gchar fg_title_format[] = "Choose foreground color for \"%s\"";
962   static const gchar bg_title_format[] = "Choose background color for \"%s\"";
963   GtkWidget *color_sel_win;
964   GdkColor *color;
965   GtkWidget *color_sel_ok;
966   GtkWidget *color_sel_cancel;
967   GtkWidget *color_sel_help;
968
969   if (is_bg) {
970     color = &colorf->bg_color;
971     title_len = strlen(bg_title_format) + strlen(colorf->filter_name);
972     title = g_malloc(title_len + 1);
973     sprintf(title, bg_title_format, colorf->filter_name);
974   } else {
975     color = &colorf->fg_color;
976     title_len = strlen(fg_title_format) + strlen(colorf->filter_name);
977     title = g_malloc(title_len + 1);
978     sprintf(title, fg_title_format, colorf->filter_name);
979   }
980   color_sel_win = gtk_color_selection_dialog_new(title);
981   g_free(title);
982   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_win", color_sel_win);
983   gtk_container_set_border_width (GTK_CONTAINER (color_sel_win), 10);
984
985   if (color != NULL) {
986     gdouble cols[3];
987
988     cols[0] = (gdouble)color->red / 65536.0;
989     cols[1] = (gdouble)color->green / 65536.0;
990     cols[2] = (gdouble)color->blue / 65536.0;
991
992     gtk_color_selection_set_color(
993                     GTK_COLOR_SELECTION(
994                             GTK_COLOR_SELECTION_DIALOG(color_sel_win)->colorsel), cols);
995   }
996
997   color_sel_ok = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->ok_button;
998   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_ok", color_sel_ok);
999   gtk_widget_show (color_sel_ok);
1000   GTK_WIDGET_SET_FLAGS (color_sel_ok, GTK_CAN_DEFAULT);
1001
1002   color_sel_cancel = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->cancel_button;
1003   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_cancel", color_sel_cancel);
1004   gtk_widget_show (color_sel_cancel);
1005   GTK_WIDGET_SET_FLAGS (color_sel_cancel, GTK_CAN_DEFAULT);
1006
1007
1008   color_sel_help = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->help_button;
1009   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_help", color_sel_help);
1010   gtk_widget_show (color_sel_help);
1011
1012
1013   GTK_WIDGET_SET_FLAGS (color_sel_help, GTK_CAN_DEFAULT);
1014   gtk_signal_connect (GTK_OBJECT (color_sel_win), "destroy",
1015                       GTK_SIGNAL_FUNC (color_sel_cancel_cb),
1016                       color_sel_win);
1017
1018   gtk_signal_connect (GTK_OBJECT (color_sel_ok), "clicked",
1019                       GTK_SIGNAL_FUNC (color_sel_ok_cb),
1020                       color_sel_win);
1021   gtk_signal_connect (GTK_OBJECT (color_sel_cancel), "clicked",
1022                       GTK_SIGNAL_FUNC (color_sel_cancel_cb),
1023                       color_sel_win);
1024
1025   gtk_widget_show(color_sel_win);
1026   return color_sel_win;
1027 }
1028
1029 static void
1030 color_sel_win_destroy(GtkWidget *sel_win)
1031 {
1032   GtkWidget *parent;
1033   GtkWidget *color_selection_fg, *color_selection_bg;
1034
1035   /* Find the "Edit color filter" dialog box with which this is associated. */
1036   parent = (GtkWidget *)gtk_object_get_data(GTK_OBJECT (sel_win),
1037       COLOR_SELECTION_PARENT);
1038
1039   /* Find that dialog box's foreground and background color selection
1040      boxes, if any. */
1041   color_selection_fg = gtk_object_get_data(GTK_OBJECT (parent),
1042       COLOR_SELECTION_FG);
1043   color_selection_bg = gtk_object_get_data(GTK_OBJECT (parent),
1044       COLOR_SELECTION_BG);
1045
1046   if (sel_win == color_selection_fg) {
1047     /* This was its foreground color selection box; it isn't, anymore. */
1048     gtk_object_set_data(GTK_OBJECT (parent), COLOR_SELECTION_FG, NULL);
1049   }
1050   if (sel_win == color_selection_bg) {
1051     /* This was its background color selection box; it isn't, anymore. */
1052     gtk_object_set_data(GTK_OBJECT (parent), COLOR_SELECTION_BG, NULL);
1053   }
1054
1055   /* Now destroy it. */
1056   gtk_widget_destroy(sel_win);
1057 }
1058
1059 /* Retrieve selected color */
1060 static void
1061 color_sel_ok_cb                        (GtkButton       *button,
1062                                         gpointer         user_data)
1063 {
1064   GdkColor new_color; /* Color from color selection dialog */
1065   gdouble new_colors[3];
1066   GtkWidget *color_dialog;
1067   GtkStyle  *style;
1068   GtkWidget *parent;
1069   GtkWidget *color_selection_fg, *color_selection_bg;
1070   gboolean is_bg;
1071
1072   color_dialog = (GtkWidget *)user_data;
1073
1074   gtk_color_selection_get_color(GTK_COLOR_SELECTION(
1075    GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), new_colors);
1076
1077   new_color.red   = (guint16)(new_colors[0]*65535.0);
1078   new_color.green = (guint16)(new_colors[1]*65535.0);
1079   new_color.blue  = (guint16)(new_colors[2]*65535.0);
1080
1081   if ( ! get_color(&new_color) ){
1082         simple_dialog(ESD_TYPE_CRIT, NULL, "Could not allocate color.  Try again.");
1083   } else {
1084         /* Find the "Edit color filter" dialog box with which this is
1085            associated. */
1086         parent = (GtkWidget *)gtk_object_get_data(GTK_OBJECT (color_dialog),
1087               COLOR_SELECTION_PARENT);
1088
1089         /* Find that dialog box's foreground and background color selection
1090            boxes, if any. */
1091         color_selection_fg = gtk_object_get_data(GTK_OBJECT (parent),
1092               COLOR_SELECTION_FG);
1093         color_selection_bg = gtk_object_get_data(GTK_OBJECT (parent),
1094               COLOR_SELECTION_BG);
1095         is_bg = (color_dialog == color_selection_bg);
1096
1097         color_sel_win_destroy(color_dialog);
1098
1099         /* now apply the change to the fore/background */
1100         
1101         style = gtk_style_copy(gtk_widget_get_style(filt_name_entry));
1102         if (is_bg)
1103           style->base[GTK_STATE_NORMAL] = new_color;
1104         else
1105           style->fg[GTK_STATE_NORMAL] = new_color;
1106         gtk_widget_set_style(filt_name_entry, style);
1107         gtk_widget_set_style(filt_text_entry, style);   
1108   }
1109 }
1110
1111 /* Don't choose the selected color as the foreground or background
1112    color for the filter. */
1113 static void
1114 color_sel_cancel_cb                    (GtkObject       *object,
1115                                         gpointer         user_data)
1116 {
1117   GtkWidget *color_dialog;
1118   color_dialog = (GtkWidget *)user_data;
1119   /* nothing to change here.  Just get rid of the dialog box. */
1120
1121   color_sel_win_destroy(color_dialog);
1122 }