Use "strchr()" rather than "index()" - "strchr()" is the ANSI standard
[obnox/wireshark/wip.git] / colors.c
1 /* colors.c
2  * Definitions for color structures and routines
3  *
4  * $Id: colors.c,v 1.2 1999/08/24 18:53:08 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 #include <gtk/gtkwidget.h>
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <glibconfig.h>
37 #include <glib.h>
38
39 #include <gdk/gdkkeysyms.h>
40
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44
45 #include <errno.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49
50 #ifdef HAVE_DIRECT_H
51 #include <direct.h>
52 #endif
53
54 #ifdef HAVE_NETINET_IN_H
55 #include <netinet/in.h>
56 #endif
57
58 #include <signal.h>
59
60 #ifdef NEED_SNPRINTF_H
61 # ifdef HAVE_STDARG_H
62 #  include <stdarg.h>
63 # else
64 #  include <varargs.h>
65 # endif
66 # include "snprintf.h"
67 #endif
68
69 #ifdef NEED_STRERROR_H
70 #include "strerror.h"
71 #endif
72
73 #include "ethereal.h"
74 #include "packet.h"
75 #include "colors.h"
76 #include "file.h"
77 #include "dfilter.h"
78 #include "util.h"
79
80 extern capture_file cf;
81
82 static gboolean read_filters(capture_file *cf);
83
84 GdkColor        proto_colors[MAXCOLORS];
85 GdkColormap*    sys_cmap;
86
87 static gchar *titles[2] = { "Name", "Filter String" };
88 GdkColor        color_light_gray = { 0, 45000, 45000, 45000 };
89 GdkColor        WHITE = { 0,65535, 65535, 65535};
90 GdkColor        BLACK = { 0, 0, 0, 0};
91
92 /* This structure is used to allow you to compile in default colors if
93  * you wish.  They can be later changed by a user.
94  */
95 #ifdef READ_DEFAULT_COLOR_LIST
96 struct _default_colors {
97         gchar* proto;
98         gchar* color; /* background only */
99 } default_colors[]  = {
100         {"arp", "green2"},
101         {"ip",  "light red"},
102         {"tcp",  "light blue"}
103 };
104 #endif
105
106 void
107 colors_init(capture_file *cf)
108 {
109
110 #ifdef READ_DEFAULT_COLOR_LIST
111   gint i;
112   GdkColor color;
113 #endif
114   cf->colors = (colfilter *)g_malloc(sizeof(colfilter));
115   cf->colors->num_of_filters = 0;
116   cf->colors->color_filters = gtk_clist_new_with_titles(2, titles);
117
118   gtk_widget_ref(cf->colors->color_filters); /* so it doesn't go away */
119   /* color_filters will ALWAYS be a GtkCList */
120   sys_cmap = gdk_colormap_get_system();
121
122   /* Allocate "constant" colors. */
123   if( !gdk_colormap_alloc_color(sys_cmap, &WHITE, TRUE, TRUE)){
124         /* oops */
125         simple_dialog(ESD_TYPE_WARN, NULL, "Could not allocate color white.");
126         fprintf(stderr,"Color allocation failed\n");
127         fflush(stderr);
128   }
129
130   if( !gdk_colormap_alloc_color(sys_cmap, &BLACK, TRUE, TRUE)){
131         /* oops */
132         simple_dialog(ESD_TYPE_WARN, NULL, "Could not allocate color black.");
133         fprintf(stderr,"Color allocation failed\n");
134         fflush(stderr);
135   }
136
137 #ifdef READ_DEFAULT_COLOR_LIST
138   /* Now process defaults */
139   for (i = 0 ; i < sizeof default_colors/sizeof (struct _default_colors); i++){
140         gdk_color_parse(default_colors[i].color, &color);
141         
142         if( !gdk_colormap_alloc_color(sys_cmap, &color, TRUE, TRUE)){
143                 /* oops */
144                 simple_dialog(ESD_TYPE_WARN, NULL, "Could not allocate color %s.",
145                     default_colors[i].color);
146                 fprintf(stderr,"Color allocation failed\n");
147                 fflush(stderr);
148         }
149
150         new_color_filter(cf->colors, default_colors[i].proto, default_colors[i].proto);
151         color_filter(cf,i)->bg_color = color;
152
153         color_filter(cf,i)->c_colorfilter = dfilter_new();
154         if(dfilter_compile((color_filter(cf,i)->c_colorfilter),
155           default_colors[i].proto) != 0}{
156                 simple_dialog(ESD_TYPE_WARN, NULL, "Cannot compile default filter %s.\n%s",
157                   default_colors[i].proto, dfilter_error_msg);
158                 /* should reject this filter */
159         }
160         cf->colors->num_of_filters++;
161   }
162 #endif
163   if(!read_filters(cf))
164     /* again, no window because it is not up, yet */
165         fprintf(stderr,"Cound not open filter file\n");
166
167   fprintf(stderr,"Colors initialized\n");
168   fflush(stderr);
169 }
170
171 void
172 set_color_filter_name(capture_file *cf, gint n, gchar *str)
173 {
174         
175         /* gtk_clist_set_text frees old text (if any) and allocates new space */
176         gtk_clist_set_text(GTK_CLIST(cf->colors->color_filters),n,0,str);
177 }
178
179
180 gchar *
181 get_color_filter_name(capture_file *cf, gint n)
182 {
183         gchar *filter_name;
184         gtk_clist_get_text(GTK_CLIST(cf->colors->color_filters),n,0,
185                 (gchar **)&filter_name);
186         return filter_name;
187 }
188
189 void
190 set_color_filter_string(capture_file *cf, gint n, gchar *str)
191 {
192
193         gtk_clist_set_text(GTK_CLIST(cf->colors->color_filters),n,1,str);
194 }
195
196
197 gchar *
198 get_color_filter_string(capture_file *cf, gint n)
199 {
200         gchar *filter_string;
201         gtk_clist_get_text(GTK_CLIST(cf->colors->color_filters),n,1,
202                 (gchar **)&filter_string);
203         return filter_string;
204 }
205
206 color_filter_t *
207 color_filter(capture_file *cf, gint n)
208 {
209         return gtk_clist_get_row_data(GTK_CLIST(cf->colors->color_filters),n);
210 }
211
212 void
213 new_color_filter(colfilter *filters, gchar *name, gchar *filter_string)
214 {
215         color_filter_t *colorf;
216         gchar *data[2];
217         
218         gint row;
219
220         data[0] = g_strdup(name);
221         data[1] = g_strdup(filter_string);
222         row = gtk_clist_append(GTK_CLIST(filters->color_filters), data);
223
224         colorf = (color_filter_t *)g_malloc(sizeof (color_filter_t));
225         colorf->bg_color = WHITE;
226         colorf->fg_color = BLACK;
227         colorf->c_colorfilter = NULL;
228         gtk_clist_set_row_data(GTK_CLIST(filters->color_filters), row, colorf);
229 }
230
231 static gboolean
232 read_filters(capture_file *cf)
233 {
234         /* TODO: Lots more syntax checking on the file */
235         /* I hate these fixed length names! TODO: make more dynamic */
236         gchar name[256],filter[256], buf[1024];
237         guint16 fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
238         GdkColor fg_color, bg_color;
239
240         int i;
241         FILE *f;
242         gchar *path;
243         gchar *fname = PF_DIR "/colorfilters";
244         /* decide what file to open (from dfilter code) */
245
246         /* should only be called by colors_init.
247          * cf->colors->color_filters must exist
248          */
249         if(cf == NULL || cf->colors == NULL || cf->colors->color_filters == NULL)
250                 return FALSE;
251         /* we have a clist */
252
253         path = (gchar *) g_malloc(strlen(getenv("HOME")) + strlen(fname) +  4);
254         sprintf(path, "%s/%s", getenv("HOME"), fname);
255
256         if ((f = fopen(path, "r")) == NULL) {
257           g_free(path);
258           return FALSE;
259         }
260
261         i = 0;
262
263         do{
264           if(!fgets(buf,sizeof buf, f))
265                 break;
266                 
267           if(strspn( buf," \t") == (strchr(buf,'*') - buf)){
268                 /* leading # comment */
269                 continue;
270           }
271
272           /* we get the @ delimiter.  It is not in any strings */
273           if(sscanf(buf," @%[^@]@%[^@]@[%hu,%hu,%hu][%hu,%hu,%hu]",
274                 name, filter, &bg_r, &bg_g, &bg_b, &fg_r, &fg_g, &fg_b) == 8){
275                 /* we got a filter */
276
277             new_color_filter(cf->colors, name, filter);
278             color_filter(cf,i)->c_colorfilter = dfilter_new();
279             if(dfilter_compile((color_filter(cf,i)->c_colorfilter),filter) != 0){
280                 simple_dialog(ESD_TYPE_WARN, NULL,
281                  "Could not compile filter %s from saved filters because\n%s",
282                  name, dfilter_error_msg);
283             }
284             cf->colors->num_of_filters++;
285             fg_color.red = fg_r;
286             fg_color.green = fg_g;
287             fg_color.blue = fg_b;
288             bg_color.red = bg_r;
289             bg_color.green = bg_g;
290             bg_color.blue = bg_b;
291             if( !gdk_colormap_alloc_color(sys_cmap, &fg_color, TRUE, TRUE)){
292                         /* oops */
293                         simple_dialog(ESD_TYPE_WARN, NULL, "Could not allocate fg color specified"
294                             "in input file for %s.", name);
295
296                         fprintf(stderr,"Color allocation failed\n");
297                         fflush(stderr);
298                         i++;
299                         continue;
300             }
301                 if( !gdk_colormap_alloc_color(sys_cmap, &bg_color, TRUE, TRUE)){
302                         /* oops */
303                         simple_dialog(ESD_TYPE_WARN, NULL, "Could not allocate bg color specified"
304                             "in input file for %s.", name);
305                         fprintf(stderr,"Color allocation failed\n");
306                         fflush(stderr);
307                         i++;
308                         continue;
309             }
310
311         color_filter(cf,i)->bg_color = bg_color;
312         color_filter(cf,i)->fg_color = fg_color;
313         gtk_clist_set_foreground(GTK_CLIST(cf->colors->color_filters),
314                         i,&fg_color);
315         gtk_clist_set_background(GTK_CLIST(cf->colors->color_filters),
316                         i,&bg_color);
317
318             i++;
319           }    /* if sscanf */
320         }   while( !feof(f));
321         return TRUE;
322 }
323
324 static gboolean
325 write_filters(capture_file *cf)
326 {
327         int i;
328         FILE *f;
329         gchar *path;
330         gchar *name = PF_DIR "/colorfilters";
331         /* decide what file to open (from dfilter code) */
332         path = (gchar *) g_malloc(strlen(getenv("HOME")) + strlen(name) +  4);
333         sprintf(path, "%s/%s", getenv("HOME"), name);
334
335         if ((f = fopen(path, "w+")) == NULL) {
336           simple_dialog(ESD_TYPE_WARN, NULL, "Could not open\n%s\nfor writing.",
337                 path);
338           g_free(path);
339           return FALSE;
340         }
341         fprintf(f,"# DO NOT EDIT THIS FILE!  It was created by Ethereal\n");
342         for(i = 0; i < cf->colors->num_of_filters; i++){
343           fprintf(f,"@%s@%s@[%d,%d,%d][%d,%d,%d]\n",
344                 get_color_filter_name(cf,i),
345                 get_color_filter_string(cf,i),
346                 color_filter(cf,i)->bg_color.red,
347                 color_filter(cf,i)->bg_color.green,
348                 color_filter(cf,i)->bg_color.blue,
349                 color_filter(cf,i)->fg_color.red,
350                 color_filter(cf,i)->fg_color.green,
351                 color_filter(cf,i)->fg_color.blue);
352         }
353         fclose(f);
354         g_free(path);
355         return TRUE;
356 }
357
358                 
359 /* ===================== USER INTERFACE ====================== */
360 void
361 color_display_cb(GtkWidget *w, gpointer d)
362 {
363   /* cf already exists as a global */
364   /* create the color dialog */
365   create_color_win(&cf);
366
367 }
368
369 void
370 color_cancel_cb                        (GtkWidget       *widget,
371                                         gpointer         user_data)
372 {
373   GtkWidget *win = (GtkWidget *)user_data;
374   /* delete the window */
375   gtk_container_remove(GTK_CONTAINER(GTK_WIDGET(cf.colors->color_filters)->parent),
376         cf.colors->color_filters);
377   gtk_widget_destroy(win);
378 }
379
380 void
381 color_delete_cb(GtkWidget *widget, gpointer user_data)
382 {
383   if(cf.colors->row_selected != -1){
384         gtk_clist_remove(GTK_CLIST(cf.colors->color_filters),
385            cf.colors->row_selected);
386         cf.colors->num_of_filters--;
387         if(!cf.colors->num_of_filters){
388                 cf.colors->row_selected = -1;
389         } else {
390                 cf.colors->row_selected--;
391                 if(cf.colors->row_selected < 0)
392                         cf.colors->row_selected = 0;
393                 gtk_clist_select_row(GTK_CLIST(cf.colors->color_filters),
394                   cf.colors->row_selected,0);
395         }
396   }
397 }
398
399 /* Move the selected filter up in the list */
400 void
401 color_filt_up_cb                       (GtkButton       *button,
402                                         gpointer         user_data)
403 {
404   colfilter *filter;
405   gint filter_number;
406
407   filter = (colfilter *)user_data;
408
409   /* verify filter exists */
410   filter_number = filter->row_selected;
411   /* if it is filter number 0, it cannot be moved */
412   if(filter != NULL &&
413      (filter_number = filter->row_selected)  != 0 &&
414       filter->num_of_filters >= 2){
415         gtk_clist_swap_rows(GTK_CLIST(filter->color_filters),filter_number, filter_number-1);
416         filter->row_selected--;
417       }
418   else {
419         return;
420   }
421
422 }
423
424 /* Move the selected filter down in the list */
425 void
426 color_filter_down_cb                   (GtkButton       *button,
427                                         gpointer         user_data)
428 {
429   colfilter *filter;
430   gint filter_number;
431
432   filter = (colfilter *)user_data;
433   /* verify filter exists */
434   filter_number = filter->row_selected;
435   if(filter != NULL && 
436      (filter_number = filter->row_selected) != filter->num_of_filters-1 && 
437       filter->num_of_filters >= 2){
438         gtk_clist_swap_rows(GTK_CLIST(filter->color_filters),filter_number+1, filter_number);
439         filter->row_selected++;
440   }
441   else
442         return;
443 }
444
445 /* Set selected row in cf */
446 void
447 rembember_selected_row                 (GtkCList        *clist,
448                                         gint             row,
449                                         gint             column,
450                                         GdkEvent        *event,
451                                         gpointer         user_data)
452 {
453   capture_file *cf;
454   cf = (capture_file *) user_data;
455
456   cf->colors->row_selected = row;
457 }
458
459 /* change name to color_new_cb */
460 static GtkWidget *filt_name_entry;
461 static GtkWidget *filt_text_entry;
462
463 /* Create a new filter in the list */
464 void
465 create_new_cb                          (GtkButton       *button,
466                                         gpointer         user_data)
467 {
468   colfilter *filter;
469
470   filter = (colfilter *)user_data;
471   new_color_filter(filter, "name", "filter"); /* Adds at end! */
472   
473   /* select the last row */
474   cf.colors->row_selected = cf.colors->num_of_filters;
475   cf.colors->num_of_filters++;
476   gtk_clist_select_row(GTK_CLIST(cf.colors->color_filters),cf.colors->row_selected,0);
477   /* this is the global cf! */
478   create_colorize_win(&cf, &filt_name_entry, &filt_text_entry);
479 }
480
481 /* Change a filter */
482 /* probably should change name to color_edit_cb */
483 void
484 color_change_cb                        (GtkButton       *button,
485                                         gpointer         user_data)
486 {
487   colfilter *filter;
488   filter = (colfilter *)user_data;
489
490   if(cf.colors->row_selected == -1){
491           /* select the first row */
492           cf.colors->row_selected = 0;
493           gtk_clist_select_row(GTK_CLIST(cf.colors->color_filters),cf.colors->row_selected,0);
494   }
495   /* this is the global cf! */
496   /*Default colors are in cf in the e entry itself.*/
497   create_colorize_win(&cf, &filt_name_entry, &filt_text_entry);
498 }
499
500
501 /* save filters in file */
502 void
503 color_save_cb                          (GtkButton       *button,
504                                         gpointer         user_data)
505 {
506   capture_file *cf;
507   cf = (capture_file *)user_data;
508   if(!write_filters(cf))
509         simple_dialog(ESD_TYPE_WARN, NULL, "Could not open filter file!");
510
511 }
512
513 /* Exit dialog and process list */
514 void
515 color_ok_cb                            (GtkButton       *button,
516                                         gpointer         user_data)
517 {
518   GtkWidget *dialog;
519   dialog = (GtkWidget *)user_data;
520
521   /* colorize list */
522
523   filter_packets(&cf);
524   gtk_container_remove(GTK_CONTAINER(GTK_WIDGET(cf.colors->color_filters)->parent),
525         cf.colors->color_filters);
526   gtk_widget_destroy(dialog);
527
528 }
529
530 /* Process all data by applying filters in list */
531 void
532 color_apply_cb                         (GtkButton       *button,
533                                         gpointer         user_data)
534 {
535   capture_file *cf;
536   cf = (capture_file *)user_data;
537   filter_packets(cf);
538 }
539
540 /* Exit dialog and do not process list */
541 void
542 colorize_cancel_cb                     (GtkObject       *object,
543                                         gpointer         user_data)
544 {
545
546   GtkWidget *dialog;
547   dialog = (GtkWidget *)user_data;
548
549   gtk_widget_destroy(dialog);
550 }
551
552 static gint bg_set_flag; /* 0 -> setting foreground, 1-> setting background */
553 /* Change the foreground color */
554 void
555 colorize_fg_cb                         (GtkButton       *button,
556                                         gpointer         user_data)
557 {
558   colfilter *filter;
559   filter = (colfilter *)user_data; /* UNUSED */
560   create_color_sel_win(&cf);
561   bg_set_flag = 0;
562
563 }
564
565 /* Change the background color */
566 void
567 colorize_bg_cb                         (GtkButton       *button,
568                                         gpointer         user_data)
569 {
570   colfilter *filter;
571   filter = (colfilter *)user_data; /* UNUSED */
572   create_color_sel_win(&cf);
573   bg_set_flag = 1;
574
575 }
576
577 /* accept color (and potential content) change */
578 void
579 colorize_ok_cb                         (GtkButton       *button,
580                                         gpointer         user_data)
581 {
582   GtkWidget *dialog;
583   GtkStyle *style;
584   GdkColor new_fg_color;
585   GdkColor new_bg_color;
586   gchar *filter_name;
587   gchar *filter_text;
588   dfilter *compiled_filter;
589
590   dialog = (GtkWidget *)user_data;
591
592   style = gtk_widget_get_style(filt_name_entry);
593   new_bg_color = style->base[GTK_STATE_NORMAL];
594   new_fg_color = style->fg[GTK_STATE_NORMAL];
595
596   filter_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_name_entry)));
597   filter_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(filt_text_entry)));
598
599   if(strchr(filter_name,'@') || strchr(filter_text,'@')){
600         simple_dialog(ESD_TYPE_WARN,NULL, "Filter names and strings must not"
601           " use the '@' character. Filter unchanged.");
602         g_free(filter_name);
603         g_free(filter_text);
604         return;
605   }
606         
607
608   color_filter(&cf,cf.colors->row_selected)->fg_color = new_fg_color;
609   color_filter(&cf,cf.colors->row_selected)->bg_color = new_bg_color;
610   gtk_clist_set_foreground(GTK_CLIST(cf.colors->color_filters),
611         cf.colors->row_selected, &new_fg_color);
612   gtk_clist_set_background(GTK_CLIST(cf.colors->color_filters),
613         cf.colors->row_selected, &new_bg_color);
614
615
616
617   compiled_filter = dfilter_new();
618   
619   if( dfilter_compile( compiled_filter, filter_text) != 0 ){
620         simple_dialog(ESD_TYPE_WARN, NULL, "Filter \"%s\" did not compile correctly.\n"
621                 " Please try again. Filter unchanged.\n%s\n", filter_name,dfilter_error_msg);
622         dfilter_destroy(compiled_filter);
623   } else {
624
625         if( color_filter(&cf, cf.colors->row_selected)->c_colorfilter != NULL)
626             dfilter_destroy(color_filter(&cf,cf.colors->row_selected)->c_colorfilter);
627         color_filter(&cf,cf.colors->row_selected)->c_colorfilter = compiled_filter;
628         set_color_filter_string(&cf,cf.colors->row_selected,filter_text);
629         set_color_filter_name(&cf,cf.colors->row_selected,filter_name);
630         gtk_widget_destroy(dialog);
631   }
632   g_free(filter_name);
633   g_free(filter_text);
634
635
636 }
637
638 /* Revert to existing colors */
639 void
640 color_cel_cancel_cb                    (GtkObject       *object,
641                                         gpointer         user_data)
642 {
643   GtkWidget *color_dialog;
644   color_dialog = (GtkWidget *)user_data;
645   /* nothing to change here.  Just get rid of the dialog box. */
646
647   gtk_widget_destroy(color_dialog);
648 }
649
650 /* Retrieve selected color */
651 void
652 color_sel_ok_cb                        (GtkButton       *button,
653                                         gpointer         user_data)
654 {
655   GdkColor new_color; /* Color from color selection dialog */
656   gdouble new_colors[3];
657   GtkWidget *color_dialog;
658   GtkStyle  *style;
659
660   color_dialog = (GtkWidget *)user_data;
661
662   gtk_color_selection_get_color(GTK_COLOR_SELECTION(
663    GTK_COLOR_SELECTION_DIALOG(color_dialog)->colorsel), new_colors);
664
665   new_color.red   = (guint16)(new_colors[0]*65535.0);
666   new_color.green = (guint16)(new_colors[1]*65535.0);
667   new_color.blue  = (guint16)(new_colors[2]*65535.0);
668
669   if ( ! gdk_colormap_alloc_color(sys_cmap, &new_color, TRUE, TRUE) ){
670         simple_dialog(ESD_TYPE_WARN, NULL, "Could not allocate color.  Try again.");
671   } else {
672         gtk_widget_destroy(color_dialog);
673
674         /* now apply the change to the fore/background */
675         
676         style = gtk_style_copy(gtk_widget_get_style(filt_name_entry));
677         if( bg_set_flag)
678           style->base[GTK_STATE_NORMAL] = new_color;
679         else
680           style->fg[GTK_STATE_NORMAL] = new_color;
681         gtk_widget_set_style(filt_name_entry, style);
682         gtk_widget_set_style(filt_text_entry, style);   
683   }
684 }
685
686
687
688
689
690 GtkWidget*
691 create_color_win (capture_file *cf)
692 {
693   GtkWidget *color_win;
694   GtkWidget *vbox1;
695   GtkWidget *hbox1;
696   GtkWidget *vbox2;
697   GtkWidget *color_filt_up;
698   GtkWidget *label4;
699   GtkWidget *color_filter_down;
700   GtkWidget *scrolledwindow1;
701   GtkWidget *clist1;
702   GtkWidget *hbox2;
703   GtkWidget *color_new;
704   GtkWidget *color_change_colors;
705   GtkWidget *color_delete;
706   GtkWidget *color_save;
707   GtkWidget *hbox3;
708   GtkWidget *color_ok;
709   GtkWidget *color_apply;
710   GtkWidget *color_cancel;
711   GtkTooltips *tooltips;
712
713   cf->colors->row_selected = -1; /* no row selected */
714   tooltips = gtk_tooltips_new ();
715
716   color_win = gtk_window_new (GTK_WINDOW_DIALOG);
717   gtk_object_set_data (GTK_OBJECT (color_win), "color_win", color_win);
718   gtk_window_set_title (GTK_WINDOW (color_win), ("Add color to protocols"));
719
720   vbox1 = gtk_vbox_new (FALSE, 0);
721   gtk_widget_ref (vbox1);
722   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox1", vbox1,
723                             (GtkDestroyNotify) gtk_widget_unref);
724   gtk_widget_show (vbox1);
725   gtk_container_add (GTK_CONTAINER (color_win), vbox1);
726
727   hbox1 = gtk_hbox_new (FALSE, 0);
728   gtk_widget_ref (hbox1);
729   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox1", hbox1,
730                             (GtkDestroyNotify) gtk_widget_unref);
731   gtk_widget_show (hbox1);
732   gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
733
734   vbox2 = gtk_vbox_new (TRUE, 0);
735   gtk_widget_ref (vbox2);
736   gtk_object_set_data_full (GTK_OBJECT (color_win), "vbox2", vbox2,
737                             (GtkDestroyNotify) gtk_widget_unref);
738   gtk_widget_show (vbox2);
739   gtk_box_pack_start (GTK_BOX (hbox1), vbox2, FALSE, TRUE, 0);
740   gtk_widget_set_usize (vbox2, 150, -2);
741
742   color_filt_up = gtk_button_new_with_label (("Up"));
743   gtk_widget_ref (color_filt_up);
744   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filt_up", color_filt_up,
745                             (GtkDestroyNotify) gtk_widget_unref);
746   gtk_widget_show (color_filt_up);
747   gtk_box_pack_start (GTK_BOX (vbox2), color_filt_up, FALSE, FALSE, 0);
748   gtk_tooltips_set_tip (tooltips, color_filt_up, ("Move filter higher in list"), NULL);
749
750   label4 = gtk_label_new (("Move filter\nup or down\n[List is processed \nin order]"));
751   gtk_widget_ref (label4);
752   gtk_object_set_data_full (GTK_OBJECT (color_win), "label4", label4,
753                             (GtkDestroyNotify) gtk_widget_unref);
754   gtk_widget_show (label4);
755   gtk_box_pack_start (GTK_BOX (vbox2), label4, FALSE, FALSE, 0);
756
757   color_filter_down = gtk_button_new_with_label (("Down"));
758   gtk_widget_ref (color_filter_down);
759   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_filter_down", color_filter_down,
760                             (GtkDestroyNotify) gtk_widget_unref);
761   gtk_widget_show (color_filter_down);
762   gtk_box_pack_start (GTK_BOX (vbox2), color_filter_down, FALSE, FALSE, 0);
763   gtk_tooltips_set_tip (tooltips, color_filter_down, ("Move filter lower in list"), NULL);
764
765   scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
766   gtk_widget_ref (scrolledwindow1);
767   gtk_object_set_data_full (GTK_OBJECT (color_win), "scrolledwindow1", scrolledwindow1,
768                             (GtkDestroyNotify) gtk_widget_unref);
769   gtk_widget_show (scrolledwindow1);
770   gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
771
772
773   /* Do we have a list of filters, yet? */
774   if( cf->colors->color_filters == NULL) {
775         /* no color filters as of now.
776          * This should probably be an assert...
777          */
778         fprintf(stderr,"Null clist\n");
779                 fflush(stderr);
780   }
781
782   clist1 = cf->colors->color_filters;
783   gtk_widget_ref (clist1);
784
785 #if 0
786   /* I don't seem to need this, but just in case, I'll if0 it */
787   gtk_object_set_data_full (GTK_OBJECT (color_win), "clist1", clist1,
788                             (GtkDestroyNotify) gtk_widget_unref);
789 #endif
790
791   gtk_widget_show (clist1);
792   gtk_container_add (GTK_CONTAINER (scrolledwindow1), clist1);
793   gtk_widget_set_usize (clist1, 300, -2);
794   gtk_clist_set_column_width (GTK_CLIST (clist1), 0, 80);
795   gtk_clist_set_column_width (GTK_CLIST (clist1), 1, 80);
796   gtk_clist_column_titles_show (GTK_CLIST (clist1));
797
798   hbox2 = gtk_hbox_new (FALSE, 0);
799   gtk_widget_ref (hbox2);
800   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox2", hbox2,
801                             (GtkDestroyNotify) gtk_widget_unref);
802   gtk_widget_show (hbox2);
803   gtk_box_pack_start (GTK_BOX (vbox1), hbox2, TRUE, FALSE, 5);
804   gtk_widget_set_usize (hbox2, -2, 40);
805
806   color_new = gtk_button_new_with_label (("New"));
807   gtk_widget_ref (color_new);
808   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_new", color_new,
809                             (GtkDestroyNotify) gtk_widget_unref);
810   gtk_widget_show (color_new);
811   gtk_box_pack_start (GTK_BOX (hbox2), color_new, TRUE, FALSE, 5);
812   gtk_widget_set_usize (color_new, 50, 30);
813   gtk_tooltips_set_tip (tooltips, color_new, ("Create a new colorization filter after selected filter"), NULL);
814
815   color_change_colors = gtk_button_new_with_label (("Edit"));
816   gtk_widget_ref (color_change_colors);
817   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_change_colors", color_change_colors,
818                             (GtkDestroyNotify) gtk_widget_unref);
819   gtk_widget_show (color_change_colors);
820   gtk_widget_set_usize(color_change_colors, 50, 30);
821   gtk_box_pack_start (GTK_BOX (hbox2), color_change_colors, TRUE, FALSE, 5);
822   gtk_tooltips_set_tip (tooltips, color_change_colors, ("Change color of selected filter"), NULL);
823
824   color_delete = gtk_button_new_with_label (("Delete"));
825   gtk_widget_ref (color_delete);
826   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_delete", color_delete,
827                             (GtkDestroyNotify) gtk_widget_unref);
828   gtk_widget_show (color_delete);
829   gtk_box_pack_start (GTK_BOX (hbox2), color_delete, TRUE, FALSE, 5);
830   gtk_widget_set_usize (color_delete, 50, 30);
831   gtk_tooltips_set_tip (tooltips, color_delete, ("Delete selected colorization filter"), NULL);
832
833   color_save = gtk_button_new_with_label (("Save"));
834   gtk_widget_ref (color_save);
835   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_save", color_save,
836                             (GtkDestroyNotify) gtk_widget_unref);
837   gtk_widget_show (color_save);
838   gtk_box_pack_start (GTK_BOX (hbox2), color_save, TRUE, FALSE, 5);
839   gtk_widget_set_usize (color_save, 50, 30);
840   gtk_tooltips_set_tip (tooltips, color_save, ("Save all filters to disk"), NULL);
841
842   hbox3 = gtk_hbox_new (FALSE, 0);
843   gtk_widget_ref (hbox3);
844   gtk_object_set_data_full (GTK_OBJECT (color_win), "hbox3", hbox3,
845                             (GtkDestroyNotify) gtk_widget_unref);
846   gtk_widget_show (hbox3);
847   gtk_box_pack_start (GTK_BOX (vbox1), hbox3, TRUE, FALSE, 5);
848   gtk_widget_set_usize (hbox3, 177, 40);
849
850   color_ok = gtk_button_new_with_label (("OK"));
851   gtk_widget_ref (color_ok);
852   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_ok", color_ok,
853                             (GtkDestroyNotify) gtk_widget_unref);
854   gtk_widget_show (color_ok);
855   gtk_box_pack_start (GTK_BOX (hbox3), color_ok, TRUE, FALSE, 0);
856   gtk_widget_set_usize (color_ok, 50, 30);
857   gtk_tooltips_set_tip (tooltips, color_ok, ("Accept filter list; apply changes"), NULL);
858
859   color_apply = gtk_button_new_with_label (("Apply"));
860   gtk_widget_ref (color_apply);
861   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_apply", color_apply,
862                             (GtkDestroyNotify) gtk_widget_unref);
863   gtk_widget_show (color_apply);
864   gtk_box_pack_start (GTK_BOX (hbox3), color_apply, TRUE, FALSE, 0);
865   gtk_widget_set_usize (color_apply, 50, 30);
866   gtk_tooltips_set_tip (tooltips, color_apply, ("Apply filters in list"), NULL);
867
868   color_cancel = gtk_button_new_with_label (("Cancel"));
869   gtk_widget_ref (color_cancel);
870   gtk_object_set_data_full (GTK_OBJECT (color_win), "color_cancel", color_cancel,
871                             (GtkDestroyNotify) gtk_widget_unref);
872   gtk_widget_show (color_cancel);
873   gtk_box_pack_start (GTK_BOX (hbox3), color_cancel, TRUE, FALSE, 0);
874   gtk_widget_set_usize (color_cancel, 50, 30);
875   gtk_tooltips_set_tip (tooltips, color_cancel, ("No more filter changes; don't apply"), NULL);
876
877   gtk_signal_connect (GTK_OBJECT (color_filt_up), "clicked",
878                       GTK_SIGNAL_FUNC (color_filt_up_cb),
879                       cf->colors);
880   gtk_signal_connect (GTK_OBJECT (color_filter_down), "clicked",
881                       GTK_SIGNAL_FUNC (color_filter_down_cb),
882                       cf->colors);
883   gtk_signal_connect (GTK_OBJECT (clist1), "select_row",
884                       GTK_SIGNAL_FUNC (rembember_selected_row),
885                       cf);
886   gtk_signal_connect (GTK_OBJECT (color_new), "clicked",
887                       GTK_SIGNAL_FUNC (create_new_cb),
888                       cf->colors);
889   gtk_signal_connect (GTK_OBJECT (color_change_colors), "clicked",
890                       GTK_SIGNAL_FUNC (color_change_cb),
891                       cf->colors);
892   gtk_signal_connect (GTK_OBJECT (color_delete), "clicked",
893                       GTK_SIGNAL_FUNC (color_delete_cb),
894                       color_delete);
895   gtk_signal_connect (GTK_OBJECT (color_save), "clicked",
896                       GTK_SIGNAL_FUNC (color_save_cb),
897                       cf);
898   gtk_signal_connect (GTK_OBJECT (color_ok), "clicked",
899                       GTK_SIGNAL_FUNC (color_ok_cb),
900                       color_win);
901   gtk_signal_connect (GTK_OBJECT (color_apply), "clicked",
902                       GTK_SIGNAL_FUNC (color_apply_cb),
903                       cf);
904   gtk_signal_connect (GTK_OBJECT (color_cancel), "clicked",
905                       GTK_SIGNAL_FUNC (color_cancel_cb),
906                       color_win);
907
908   gtk_widget_grab_focus (clist1);
909   gtk_object_set_data (GTK_OBJECT (color_win), "tooltips", tooltips);
910   gtk_widget_show (color_win);
911
912   return color_win;
913 }
914
915 GtkWidget*
916 create_colorize_win (capture_file *cf,
917         GtkWidget **colorize_filter_name,
918         GtkWidget **colorize_filter_text)
919         
920 {
921   GtkWidget *colorize_win;
922   GtkWidget *vbox3;
923   GtkWidget *hbox6;
924   GtkWidget *color_filter_name;
925   GtkWidget *hbox7;
926   GtkWidget *color_filter_text;
927   GtkWidget *hbox5;
928   GtkWidget *colorize_filter_fg;
929   GtkWidget *colorize_protocol_bg;
930   GtkWidget *hbox4;
931   GtkWidget *colorize_proto_ok;
932   GtkWidget *colorize_proto_cancel;
933   GtkTooltips *tooltips;
934   GtkStyle  *style;
935
936   tooltips = gtk_tooltips_new ();
937
938   colorize_win = gtk_window_new (GTK_WINDOW_DIALOG);
939   gtk_object_set_data (GTK_OBJECT (colorize_win), "colorize_win", colorize_win);
940   gtk_window_set_title (GTK_WINDOW (colorize_win), ("Edit color filter"));
941
942   vbox3 = gtk_vbox_new (FALSE, 0);
943   gtk_widget_ref (vbox3);
944   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "vbox3", vbox3,
945                             (GtkDestroyNotify) gtk_widget_unref);
946   gtk_widget_show (vbox3);
947   gtk_container_add (GTK_CONTAINER (colorize_win), vbox3);
948
949   hbox6 = gtk_hbox_new (FALSE, 0);
950   gtk_widget_ref (hbox6);
951   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "hbox6", hbox6,
952                             (GtkDestroyNotify) gtk_widget_unref);
953   gtk_widget_show (hbox6);
954   gtk_box_pack_start (GTK_BOX (vbox3), hbox6, TRUE, FALSE, 5);
955
956   color_filter_name = gtk_label_new (("Name: "));
957   gtk_widget_ref (color_filter_name);
958   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "color_filter_name", color_filter_name,
959                             (GtkDestroyNotify) gtk_widget_unref);
960   gtk_widget_show (color_filter_name);
961   gtk_box_pack_start (GTK_BOX (hbox6), color_filter_name, FALSE, FALSE, 0);
962
963   *colorize_filter_name = gtk_entry_new ();
964   gtk_widget_ref (*colorize_filter_name);
965   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "*colorize_filter_name", *colorize_filter_name,
966                             (GtkDestroyNotify) gtk_widget_unref);
967   gtk_entry_set_text(GTK_ENTRY(*colorize_filter_name),
968         get_color_filter_name(cf, cf->colors->row_selected));
969
970   style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_name));
971   style->base[GTK_STATE_NORMAL] = color_filter(cf,cf->colors->row_selected)->bg_color;
972   style->fg[GTK_STATE_NORMAL]   = color_filter(cf,cf->colors->row_selected)->fg_color;
973   gtk_widget_set_style(*colorize_filter_name, style);
974
975   gtk_widget_show (*colorize_filter_name);
976   gtk_box_pack_start (GTK_BOX (hbox6), *colorize_filter_name, TRUE, TRUE, 0);
977   gtk_tooltips_set_tip (tooltips, *colorize_filter_name, ("This is the editable name of the filter. (No @ characters allowed.)"), NULL);
978
979   hbox7 = gtk_hbox_new (FALSE, 0);
980   gtk_widget_ref (hbox7);
981   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "hbox7", hbox7,
982                             (GtkDestroyNotify) gtk_widget_unref);
983   gtk_widget_show (hbox7);
984   gtk_box_pack_start (GTK_BOX (vbox3), hbox7, TRUE, FALSE, 5);
985
986   color_filter_text = gtk_label_new (("Filter text:"));
987   gtk_widget_ref (color_filter_text);
988   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "color_filter_text", color_filter_text,
989                             (GtkDestroyNotify) gtk_widget_unref);
990   gtk_widget_show (color_filter_text);
991   gtk_box_pack_start (GTK_BOX (hbox7), color_filter_text, FALSE, FALSE, 0);
992
993   *colorize_filter_text = gtk_entry_new ();
994   gtk_widget_ref (*colorize_filter_text);
995   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "*colorize_filter_text", *colorize_filter_text,
996                             (GtkDestroyNotify) gtk_widget_unref);
997   gtk_entry_set_text(GTK_ENTRY(*colorize_filter_text),
998         get_color_filter_string(cf, cf->colors->row_selected));
999 #if 0
1000   style = gtk_style_copy(gtk_widget_get_style(*colorize_filter_text));
1001   style->base[GTK_STATE_NORMAL] = color_filter(cf,cf->colors->row_selected)->bg_color;
1002   style->fg[GTK_STATE_NORMAL]   = color_filter(cf,cf->colors->row_selected)->fg_color;
1003 #endif
1004   gtk_widget_set_style(*colorize_filter_text, style);
1005   gtk_widget_show (*colorize_filter_text);
1006   gtk_box_pack_start (GTK_BOX (hbox7), *colorize_filter_text, TRUE, TRUE, 0);
1007   gtk_tooltips_set_tip (tooltips, *colorize_filter_text, ("This is the editable text of the filter"), NULL);
1008
1009   hbox5 = gtk_hbox_new (FALSE, 0);
1010   gtk_widget_ref (hbox5);
1011   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "hbox5", hbox5,
1012                             (GtkDestroyNotify) gtk_widget_unref);
1013   gtk_widget_show (hbox5);
1014   gtk_box_pack_start (GTK_BOX (vbox3), hbox5, FALSE, FALSE, 5);
1015   gtk_widget_set_usize (hbox5, -2, 60);
1016
1017   colorize_filter_fg = gtk_button_new_with_label (("Choose \nforeground\ncolor"));
1018   gtk_widget_ref (colorize_filter_fg);
1019   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "colorize_filter_fg", colorize_filter_fg,
1020                             (GtkDestroyNotify) gtk_widget_unref);
1021   gtk_widget_show (colorize_filter_fg);
1022   gtk_box_pack_start (GTK_BOX (hbox5), colorize_filter_fg, TRUE, FALSE, 0);
1023   gtk_tooltips_set_tip (tooltips, colorize_filter_fg, ("Select color for data display"), NULL);
1024
1025   colorize_protocol_bg = gtk_button_new_with_label (("Choose\nbackground\ncolor"));
1026   gtk_widget_ref (colorize_protocol_bg);
1027   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "colorize_protocol_bg", colorize_protocol_bg,
1028                             (GtkDestroyNotify) gtk_widget_unref);
1029   gtk_widget_show (colorize_protocol_bg);
1030   gtk_box_pack_start (GTK_BOX (hbox5), colorize_protocol_bg, TRUE, FALSE, 0);
1031   gtk_tooltips_set_tip (tooltips, colorize_protocol_bg, ("Select color for data display"), NULL);
1032
1033   hbox4 = gtk_hbox_new (FALSE, 0);
1034   gtk_widget_ref (hbox4);
1035   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "hbox4", hbox4,
1036                             (GtkDestroyNotify) gtk_widget_unref);
1037   gtk_widget_show (hbox4);
1038   gtk_box_pack_start (GTK_BOX (vbox3), hbox4, TRUE, FALSE, 5);
1039   gtk_widget_set_usize (hbox4, -2, 40);
1040
1041   colorize_proto_ok = gtk_button_new_with_label (("OK"));
1042   gtk_widget_ref (colorize_proto_ok);
1043   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "colorize_proto_ok", colorize_proto_ok,
1044                             (GtkDestroyNotify) gtk_widget_unref);
1045   gtk_widget_set_usize (colorize_proto_ok, 50, 30);
1046   gtk_widget_show (colorize_proto_ok);
1047   gtk_box_pack_start (GTK_BOX (hbox4), colorize_proto_ok, TRUE, FALSE, 0);
1048   gtk_tooltips_set_tip (tooltips, colorize_proto_ok, ("Accept filter color change"), NULL);
1049
1050   colorize_proto_cancel = gtk_button_new_with_label (("Cancel"));
1051   gtk_widget_ref (colorize_proto_cancel);
1052   gtk_object_set_data_full (GTK_OBJECT (colorize_win), "colorize_proto_cancel", colorize_proto_cancel,
1053                             (GtkDestroyNotify) gtk_widget_unref);
1054   gtk_widget_set_usize (colorize_proto_cancel, 50, 30);
1055   gtk_widget_show (colorize_proto_cancel);
1056   gtk_box_pack_start (GTK_BOX (hbox4), colorize_proto_cancel, TRUE, FALSE, 0);
1057   gtk_tooltips_set_tip (tooltips, colorize_proto_cancel, ("Reject filter color change"), NULL);
1058 #if 0
1059   gtk_signal_connect (GTK_OBJECT (colorize_win), "destroy",
1060                       GTK_SIGNAL_FUNC (colorize_cancel_cb),
1061                       colorize_win);
1062 #endif
1063   gtk_signal_connect (GTK_OBJECT (colorize_filter_fg), "clicked",
1064                       GTK_SIGNAL_FUNC (colorize_fg_cb),
1065                       cf->colors);
1066   gtk_signal_connect (GTK_OBJECT (colorize_protocol_bg), "clicked",
1067                       GTK_SIGNAL_FUNC (colorize_bg_cb),
1068                       cf->colors);
1069   gtk_signal_connect (GTK_OBJECT (colorize_proto_ok), "clicked",
1070                       GTK_SIGNAL_FUNC (colorize_ok_cb),
1071                       colorize_win);
1072   gtk_signal_connect (GTK_OBJECT (colorize_proto_cancel), "clicked",
1073                       GTK_SIGNAL_FUNC (colorize_cancel_cb),
1074                       colorize_win);
1075
1076   gtk_object_set_data (GTK_OBJECT (colorize_win), "tooltips", tooltips);
1077   gtk_widget_show (colorize_win);
1078   return colorize_win;
1079 }
1080
1081 GtkWidget*
1082 create_color_sel_win (capture_file *cf)
1083 {
1084   GtkWidget *color_sel_win;
1085   GtkWidget *color_sel_ok;
1086   GtkWidget *color_cel_cancel;
1087   GtkWidget *color_sel_help;
1088
1089   color_sel_win = gtk_color_selection_dialog_new (("Choose color"));
1090   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_win", color_sel_win);
1091   gtk_container_set_border_width (GTK_CONTAINER (color_sel_win), 10);
1092
1093   color_sel_ok = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->ok_button;
1094   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_ok", color_sel_ok);
1095   gtk_widget_show (color_sel_ok);
1096   GTK_WIDGET_SET_FLAGS (color_sel_ok, GTK_CAN_DEFAULT);
1097
1098   color_cel_cancel = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->cancel_button;
1099   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_cel_cancel", color_cel_cancel);
1100   gtk_widget_show (color_cel_cancel);
1101   GTK_WIDGET_SET_FLAGS (color_cel_cancel, GTK_CAN_DEFAULT);
1102
1103
1104   color_sel_help = GTK_COLOR_SELECTION_DIALOG (color_sel_win)->help_button;
1105   gtk_object_set_data (GTK_OBJECT (color_sel_win), "color_sel_help", color_sel_help);
1106   gtk_widget_show (color_sel_help);
1107
1108
1109   GTK_WIDGET_SET_FLAGS (color_sel_help, GTK_CAN_DEFAULT);
1110 #if 0
1111   gtk_signal_connect (GTK_OBJECT (color_sel_win), "destroy",
1112                       GTK_SIGNAL_FUNC (color_cel_cancel_cb),
1113                       color_sel_win);
1114 #endif
1115
1116   gtk_signal_connect (GTK_OBJECT (color_sel_ok), "clicked",
1117                       GTK_SIGNAL_FUNC (color_sel_ok_cb),
1118                       color_sel_win);
1119   gtk_signal_connect (GTK_OBJECT (color_cel_cancel), "clicked",
1120                       GTK_SIGNAL_FUNC (color_cel_cancel_cb),
1121                       color_sel_win);
1122
1123   gtk_widget_show(color_sel_win);
1124   return color_sel_win;
1125 }
1126