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