]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
When popping up the list without any selected items, hack the focus on the
[~andy/gtk] / tests / testgtk.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "config.h"
28
29 #undef  G_LOG_DOMAIN
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <math.h>
36 #include <time.h>
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #define GTK_ENABLE_BROKEN
42 #include "gtk/gtk.h"
43 #include "gdk/gdk.h"
44 #include "gdk/gdkkeysyms.h"
45
46 #ifdef G_OS_WIN32
47 #define sleep(n) _sleep(n)
48 #endif
49
50 #include "prop-editor.h"
51
52 #include "circles.xbm"
53 #include "test.xpm"
54
55 gboolean
56 file_exists (const char *filename)
57 {
58   struct stat statbuf;
59
60   return stat (filename, &statbuf) == 0;
61 }
62
63 GtkWidget *
64 shape_create_icon (GdkScreen *screen,
65                    char      *xpm_file,
66                    gint       x,
67                    gint       y,
68                    gint       px,
69                    gint       py,
70                    gint       window_type);
71
72 static GtkWidget *
73 build_option_menu (gchar           *items[],
74                    gint             num_items,
75                    gint             history,
76                    void           (*func)(GtkWidget *widget, gpointer data),
77                    gpointer         data);
78
79 /* macro, structure and variables used by tree window demos */
80 #define DEFAULT_NUMBER_OF_ITEM  3
81 #define DEFAULT_RECURSION_LEVEL 3
82
83 struct {
84   GSList* selection_mode_group;
85   GtkWidget* single_button;
86   GtkWidget* browse_button;
87   GtkWidget* multiple_button;
88   GtkWidget* draw_line_button;
89   GtkWidget* view_line_button;
90   GtkWidget* no_root_item_button;
91   GtkWidget* nb_item_spinner;
92   GtkWidget* recursion_spinner;
93 } sTreeSampleSelection;
94
95 typedef struct sTreeButtons {
96   guint nb_item_add;
97   GtkWidget* add_button;
98   GtkWidget* remove_button;
99   GtkWidget* subtree_button;
100 } sTreeButtons;
101 /* end of tree section */
102
103 static GtkWidget *
104 build_option_menu (gchar           *items[],
105                    gint             num_items,
106                    gint             history,
107                    void           (*func)(GtkWidget *widget, gpointer data),
108                    gpointer         data)
109 {
110   GtkWidget *omenu;
111   GtkWidget *menu;
112   GtkWidget *menu_item;
113   GSList *group;
114   gint i;
115
116   omenu = gtk_option_menu_new ();
117   g_signal_connect (omenu, "changed",
118                     G_CALLBACK (func), data);
119       
120   menu = gtk_menu_new ();
121   group = NULL;
122   
123   for (i = 0; i < num_items; i++)
124     {
125       menu_item = gtk_radio_menu_item_new_with_label (group, items[i]);
126       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_item));
127       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
128       if (i == history)
129         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
130       gtk_widget_show (menu_item);
131     }
132
133   gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
134   gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), history);
135   
136   return omenu;
137 }
138
139 static void
140 destroy_tooltips (GtkWidget *widget, GtkWindow **window)
141 {
142   GtkTooltips *tt = g_object_get_data (G_OBJECT (*window), "tooltips");
143   g_object_unref (tt);
144   *window = NULL;
145 }
146
147
148 /*
149  * Big windows and guffaw scrolling
150  */
151
152 static gboolean
153 pattern_expose (GtkWidget      *widget,
154                 GdkEventExpose *event,
155                 gpointer        data)
156 {
157   GdkColor *color;
158   GdkWindow *window = event->window;
159
160   color = g_object_get_data (G_OBJECT (window), "pattern-color");
161   if (color)
162     {
163       GdkGC *tmp_gc = gdk_gc_new (window);
164       gdk_gc_set_rgb_fg_color (tmp_gc, color);
165
166       gdk_draw_rectangle (window, tmp_gc, TRUE,
167                           event->area.x, event->area.y,
168                           event->area.width, event->area.height);
169
170       g_object_unref (tmp_gc);
171     }
172
173   return FALSE;
174 }
175
176 static void
177 pattern_set_bg (GtkWidget   *widget,
178                 GdkWindow   *child,
179                 gint         level)
180 {
181   static const GdkColor colors[] = {
182     { 0, 0x4444, 0x4444, 0xffff },
183     { 0, 0x8888, 0x8888, 0xffff },
184     { 0, 0xaaaa, 0xaaaa, 0xffff }
185   };
186     
187   g_object_set_data (G_OBJECT (child), "pattern-color", (gpointer) &colors[level]);
188   gdk_window_set_user_data (child, widget);
189 }
190
191 static void
192 create_pattern (GtkWidget   *widget,
193                 GdkWindow   *parent,
194                 gint         level,
195                 gint         width,
196                 gint         height)
197 {
198   gint h = 1;
199   gint i = 0;
200     
201   GdkWindow *child;
202
203   while (2 * h <= height)
204     {
205       gint w = 1;
206       gint j = 0;
207       
208       while (2 * w <= width)
209         {
210           if ((i + j) % 2 == 0)
211             {
212               gint x = w  - 1;
213               gint y = h - 1;
214               
215               GdkWindowAttr attributes;
216
217               attributes.window_type = GDK_WINDOW_CHILD;
218               attributes.x = x;
219               attributes.y = y;
220               attributes.width = w;
221               attributes.height = h;
222               attributes.wclass = GDK_INPUT_OUTPUT;
223               attributes.event_mask = GDK_EXPOSURE_MASK;
224               attributes.visual = gtk_widget_get_visual (widget);
225               attributes.colormap = gtk_widget_get_colormap (widget);
226               
227               child = gdk_window_new (parent, &attributes,
228                                       GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
229
230               pattern_set_bg (widget, child, level);
231
232               if (level < 2)
233                 create_pattern (widget, child, level + 1, w, h);
234
235               gdk_window_show (child);
236             }
237           j++;
238           w *= 2;
239         }
240       i++;
241       h *= 2;
242     }
243 }
244
245 #define PATTERN_SIZE (1 << 18)
246
247 static void
248 pattern_hadj_changed (GtkAdjustment *adj,
249                       GtkWidget     *darea)
250 {
251   gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value");
252   gint new_value = adj->value;
253
254   if (GTK_WIDGET_REALIZED (darea))
255     {
256       gdk_window_scroll (darea->window, *old_value - new_value, 0);
257       *old_value = new_value;
258     }
259 }
260
261 static void
262 pattern_vadj_changed (GtkAdjustment *adj,
263                       GtkWidget *darea)
264 {
265   gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value");
266   gint new_value = adj->value;
267
268   if (GTK_WIDGET_REALIZED (darea))
269     {
270       gdk_window_scroll (darea->window, 0, *old_value - new_value);
271       *old_value = new_value;
272     }
273 }
274
275 static void
276 pattern_realize (GtkWidget *widget,
277                  gpointer   data)
278 {
279   pattern_set_bg (widget, widget->window, 0);
280   create_pattern (widget, widget->window, 1, PATTERN_SIZE, PATTERN_SIZE);
281 }
282
283 static void 
284 create_big_windows (GtkWidget *widget)
285 {
286   static GtkWidget *window = NULL;
287   GtkWidget *darea, *table, *scrollbar;
288   GtkWidget *eventbox;
289   GtkAdjustment *hadj;
290   GtkAdjustment *vadj;
291   static gint current_x;
292   static gint current_y;
293  
294   if (!window)
295     {
296       current_x = 0;
297       current_y = 0;
298       
299       window = gtk_dialog_new_with_buttons ("Big Windows",
300                                             NULL, 0,
301                                             GTK_STOCK_CLOSE,
302                                             GTK_RESPONSE_NONE,
303                                             NULL);
304  
305       gtk_window_set_screen (GTK_WINDOW (window),
306                              gtk_widget_get_screen (widget));
307
308       gtk_window_set_default_size (GTK_WINDOW (window), 200, 300);
309
310       g_signal_connect (window, "destroy",
311                         G_CALLBACK (gtk_widget_destroyed),
312                         &window);
313
314       g_signal_connect (window, "response",
315                         G_CALLBACK (gtk_widget_destroy),
316                         NULL);
317
318       table = gtk_table_new (2, 2, FALSE);
319       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox),
320                           table, TRUE, TRUE, 0);
321
322       darea = gtk_drawing_area_new ();
323
324       hadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
325       g_signal_connect (hadj, "value_changed",
326                         G_CALLBACK (pattern_hadj_changed), darea);
327       g_object_set_data (G_OBJECT (hadj), "old-value", &current_x);
328       
329       vadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
330       g_signal_connect (vadj, "value_changed",
331                         G_CALLBACK (pattern_vadj_changed), darea);
332       g_object_set_data (G_OBJECT (vadj), "old-value", &current_y);
333       
334       g_signal_connect (darea, "realize",
335                         G_CALLBACK (pattern_realize),
336                         NULL);
337       g_signal_connect (darea, "expose_event",
338                         G_CALLBACK (pattern_expose),
339                         NULL);
340
341       eventbox = gtk_event_box_new ();
342       gtk_table_attach (GTK_TABLE (table), eventbox,
343                         0, 1,                  0, 1,
344                         GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
345                         0,                     0);
346
347       gtk_container_add (GTK_CONTAINER (eventbox), darea);
348
349       scrollbar = gtk_hscrollbar_new (hadj);
350       gtk_table_attach (GTK_TABLE (table), scrollbar,
351                         0, 1,                  1, 2,
352                         GTK_FILL | GTK_EXPAND, GTK_FILL,
353                         0,                     0);
354
355       scrollbar = gtk_vscrollbar_new (vadj);
356       gtk_table_attach (GTK_TABLE (table), scrollbar,
357                         1, 2,                  0, 1,
358                         GTK_FILL,              GTK_EXPAND | GTK_FILL,
359                         0,                     0);
360
361     }
362
363   if (!GTK_WIDGET_VISIBLE (window))
364     gtk_widget_show_all (window);
365   else
366     gtk_widget_hide (window);
367 }
368
369 /*
370  * GtkButton
371  */
372
373 static void
374 button_window (GtkWidget *widget,
375                GtkWidget *button)
376 {
377   if (!GTK_WIDGET_VISIBLE (button))
378     gtk_widget_show (button);
379   else
380     gtk_widget_hide (button);
381 }
382
383 static void
384 create_buttons (GtkWidget *widget)
385 {
386   static GtkWidget *window = NULL;
387   GtkWidget *box1;
388   GtkWidget *box2;
389   GtkWidget *table;
390   GtkWidget *button[10];
391   GtkWidget *separator;
392
393   if (!window)
394     {
395       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
396       gtk_window_set_screen (GTK_WINDOW (window),
397                              gtk_widget_get_screen (widget));
398
399       g_signal_connect (window, "destroy",
400                         G_CALLBACK (gtk_widget_destroyed),
401                         &window);
402
403       gtk_window_set_title (GTK_WINDOW (window), "GtkButton");
404       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
405
406       box1 = gtk_vbox_new (FALSE, 0);
407       gtk_container_add (GTK_CONTAINER (window), box1);
408
409       table = gtk_table_new (3, 3, FALSE);
410       gtk_table_set_row_spacings (GTK_TABLE (table), 5);
411       gtk_table_set_col_spacings (GTK_TABLE (table), 5);
412       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
413       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
414
415       button[0] = gtk_button_new_with_label ("button1");
416       button[1] = gtk_button_new_with_mnemonic ("_button2");
417       button[2] = gtk_button_new_with_mnemonic ("_button3");
418       button[3] = gtk_button_new_from_stock (GTK_STOCK_OK);
419       button[4] = gtk_button_new_with_label ("button5");
420       button[5] = gtk_button_new_with_label ("button6");
421       button[6] = gtk_button_new_with_label ("button7");
422       button[7] = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
423       button[8] = gtk_button_new_with_label ("button9");
424       
425       g_signal_connect (button[0], "clicked",
426                         G_CALLBACK (button_window),
427                         button[1]);
428
429       gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
430                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
431
432       g_signal_connect (button[1], "clicked",
433                         G_CALLBACK (button_window),
434                         button[2]);
435
436       gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
437                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
438
439       g_signal_connect (button[2], "clicked",
440                         G_CALLBACK (button_window),
441                         button[3]);
442       gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
443                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
444
445       g_signal_connect (button[3], "clicked",
446                         G_CALLBACK (button_window),
447                         button[4]);
448       gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
449                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
450
451       g_signal_connect (button[4], "clicked",
452                         G_CALLBACK (button_window),
453                         button[5]);
454       gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
455                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
456
457       g_signal_connect (button[5], "clicked",
458                         G_CALLBACK (button_window),
459                         button[6]);
460       gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
461                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
462
463       g_signal_connect (button[6], "clicked",
464                         G_CALLBACK (button_window),
465                         button[7]);
466       gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
467                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
468
469       g_signal_connect (button[7], "clicked",
470                         G_CALLBACK (button_window),
471                         button[8]);
472       gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
473                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
474
475       g_signal_connect (button[8], "clicked",
476                         G_CALLBACK (button_window),
477                         button[0]);
478       gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
479                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
480
481       separator = gtk_hseparator_new ();
482       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
483
484       box2 = gtk_vbox_new (FALSE, 10);
485       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
486       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
487
488       button[9] = gtk_button_new_with_label ("close");
489       g_signal_connect_swapped (button[9], "clicked",
490                                 G_CALLBACK (gtk_widget_destroy),
491                                 window);
492       gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
493       GTK_WIDGET_SET_FLAGS (button[9], GTK_CAN_DEFAULT);
494       gtk_widget_grab_default (button[9]);
495     }
496
497   if (!GTK_WIDGET_VISIBLE (window))
498     gtk_widget_show_all (window);
499   else
500     gtk_widget_destroy (window);
501 }
502
503 /*
504  * GtkToggleButton
505  */
506
507 static void
508 create_toggle_buttons (GtkWidget *widget)
509 {
510   static GtkWidget *window = NULL;
511   GtkWidget *box1;
512   GtkWidget *box2;
513   GtkWidget *button;
514   GtkWidget *separator;
515
516   if (!window)
517     {
518       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
519       gtk_window_set_screen (GTK_WINDOW (window),
520                              gtk_widget_get_screen (widget));
521
522       g_signal_connect (window, "destroy",
523                         G_CALLBACK (gtk_widget_destroyed),
524                         &window);
525
526       gtk_window_set_title (GTK_WINDOW (window), "GtkToggleButton");
527       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
528
529       box1 = gtk_vbox_new (FALSE, 0);
530       gtk_container_add (GTK_CONTAINER (window), box1);
531
532       box2 = gtk_vbox_new (FALSE, 10);
533       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
534       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
535
536       button = gtk_toggle_button_new_with_label ("button1");
537       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
538
539       button = gtk_toggle_button_new_with_label ("button2");
540       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
541
542       button = gtk_toggle_button_new_with_label ("button3");
543       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
544
545       button = gtk_toggle_button_new_with_label ("inconsistent");
546       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
547       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
548       
549       separator = gtk_hseparator_new ();
550       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
551
552       box2 = gtk_vbox_new (FALSE, 10);
553       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
554       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
555
556       button = gtk_button_new_with_label ("close");
557       g_signal_connect_swapped (button, "clicked",
558                                 G_CALLBACK (gtk_widget_destroy),
559                                 window);
560       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
561       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
562       gtk_widget_grab_default (button);
563     }
564
565   if (!GTK_WIDGET_VISIBLE (window))
566     gtk_widget_show_all (window);
567   else
568     gtk_widget_destroy (window);
569 }
570
571 static GtkWidget *
572 create_widget_grid (GType widget_type)
573 {
574   GtkWidget *table;
575   GtkWidget *group_widget = NULL;
576   gint i, j;
577   
578   table = gtk_table_new (FALSE, 3, 3);
579   
580   for (i = 0; i < 5; i++)
581     {
582       for (j = 0; j < 5; j++)
583         {
584           GtkWidget *widget;
585           char *tmp;
586           
587           if (i == 0 && j == 0)
588             {
589               widget = NULL;
590             }
591           else if (i == 0)
592             {
593               tmp = g_strdup_printf ("%d", j);
594               widget = gtk_label_new (tmp);
595               g_free (tmp);
596             }
597           else if (j == 0)
598             {
599               tmp = g_strdup_printf ("%c", 'A' + i - 1);
600               widget = gtk_label_new (tmp);
601               g_free (tmp);
602             }
603           else
604             {
605               widget = g_object_new (widget_type, NULL);
606               
607               if (g_type_is_a (widget_type, GTK_TYPE_RADIO_BUTTON))
608                 {
609                   if (!group_widget)
610                     group_widget = widget;
611                   else
612                     g_object_set (widget, "group", group_widget, NULL);
613                 }
614             }
615           
616           if (widget)
617             gtk_table_attach (GTK_TABLE (table), widget,
618                               i, i + 1, j, j + 1,
619                               0,        0,
620                               0,        0);
621         }
622     }
623
624   return table;
625 }
626
627 /*
628  * GtkCheckButton
629  */
630
631 static void
632 create_check_buttons (GtkWidget *widget)
633 {
634   static GtkWidget *window = NULL;
635   GtkWidget *box1;
636   GtkWidget *box2;
637   GtkWidget *button;
638   GtkWidget *separator;
639   GtkWidget *table;
640   
641   if (!window)
642     {
643       window = gtk_dialog_new_with_buttons ("Check Buttons",
644                                             NULL, 0,
645                                             GTK_STOCK_CLOSE,
646                                             GTK_RESPONSE_NONE,
647                                             NULL);
648
649       gtk_window_set_screen (GTK_WINDOW (window), 
650                              gtk_widget_get_screen (widget));
651
652       g_signal_connect (window, "destroy",
653                         G_CALLBACK (gtk_widget_destroyed),
654                         &window);
655       g_signal_connect (window, "response",
656                         G_CALLBACK (gtk_widget_destroy),
657                         NULL);
658
659       box1 = GTK_DIALOG (window)->vbox;
660       
661       box2 = gtk_vbox_new (FALSE, 10);
662       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
663       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
664
665       button = gtk_check_button_new_with_mnemonic ("_button1");
666       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
667
668       button = gtk_check_button_new_with_label ("button2");
669       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
670
671       button = gtk_check_button_new_with_label ("button3");
672       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
673
674       button = gtk_check_button_new_with_label ("inconsistent");
675       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
676       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
677
678       separator = gtk_hseparator_new ();
679       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
680
681       table = create_widget_grid (GTK_TYPE_CHECK_BUTTON);
682       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
683       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
684     }
685
686   if (!GTK_WIDGET_VISIBLE (window))
687     gtk_widget_show_all (window);
688   else
689     gtk_widget_destroy (window);
690 }
691
692 /*
693  * GtkRadioButton
694  */
695
696 static void
697 create_radio_buttons (GtkWidget *widget)
698 {
699   static GtkWidget *window = NULL;
700   GtkWidget *box1;
701   GtkWidget *box2;
702   GtkWidget *button;
703   GtkWidget *separator;
704   GtkWidget *table;
705
706   if (!window)
707     {
708       window = gtk_dialog_new_with_buttons ("Radio Buttons",
709                                             NULL, 0,
710                                             GTK_STOCK_CLOSE,
711                                             GTK_RESPONSE_NONE,
712                                             NULL);
713
714       gtk_window_set_screen (GTK_WINDOW (window),
715                              gtk_widget_get_screen (widget));
716
717       g_signal_connect (window, "destroy",
718                         G_CALLBACK (gtk_widget_destroyed),
719                         &window);
720       g_signal_connect (window, "response",
721                         G_CALLBACK (gtk_widget_destroy),
722                         NULL);
723
724       box1 = GTK_DIALOG (window)->vbox;
725
726       box2 = gtk_vbox_new (FALSE, 10);
727       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
728       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
729
730       button = gtk_radio_button_new_with_label (NULL, "button1");
731       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
732
733       button = gtk_radio_button_new_with_label (
734                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
735                  "button2");
736       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
737       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
738
739       button = gtk_radio_button_new_with_label (
740                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
741                  "button3");
742       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
743
744       button = gtk_radio_button_new_with_label (
745                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
746                  "inconsistent");
747       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
748       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
749       
750       separator = gtk_hseparator_new ();
751       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
752
753       box2 = gtk_vbox_new (FALSE, 10);
754       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
755       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
756
757       button = gtk_radio_button_new_with_label (NULL, "button4");
758       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
759       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
760
761       button = gtk_radio_button_new_with_label (
762                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
763                  "button5");
764       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
765       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
766       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
767
768       button = gtk_radio_button_new_with_label (
769                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
770                  "button6");
771       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
772       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
773
774       separator = gtk_hseparator_new ();
775       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
776
777       table = create_widget_grid (GTK_TYPE_RADIO_BUTTON);
778       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
779       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
780     }
781
782   if (!GTK_WIDGET_VISIBLE (window))
783     gtk_widget_show_all (window);
784   else
785     gtk_widget_destroy (window);
786 }
787
788 /*
789  * GtkButtonBox
790  */
791
792 static GtkWidget *
793 create_bbox (gint  horizontal,
794              char* title, 
795              gint  spacing,
796              gint  child_w,
797              gint  child_h,
798              gint  layout)
799 {
800   GtkWidget *frame;
801   GtkWidget *bbox;
802   GtkWidget *button;
803         
804   frame = gtk_frame_new (title);
805
806   if (horizontal)
807     bbox = gtk_hbutton_box_new ();
808   else
809     bbox = gtk_vbutton_box_new ();
810
811   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
812   gtk_container_add (GTK_CONTAINER (frame), bbox);
813
814   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
815   gtk_box_set_spacing (GTK_BOX (bbox), spacing);
816   gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);
817   
818   button = gtk_button_new_with_label ("OK");
819   gtk_container_add (GTK_CONTAINER (bbox), button);
820   
821   button = gtk_button_new_with_label ("Cancel");
822   gtk_container_add (GTK_CONTAINER (bbox), button);
823   
824   button = gtk_button_new_with_label ("Help");
825   gtk_container_add (GTK_CONTAINER (bbox), button);
826
827   return frame;
828 }
829
830 static void
831 create_button_box (GtkWidget *widget)
832 {
833   static GtkWidget* window = NULL;
834   GtkWidget *main_vbox;
835   GtkWidget *vbox;
836   GtkWidget *hbox;
837   GtkWidget *frame_horz;
838   GtkWidget *frame_vert;
839
840   if (!window)
841   {
842     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
843     gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (widget));
844     gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
845     
846     g_signal_connect (window, "destroy",
847                       G_CALLBACK (gtk_widget_destroyed),
848                       &window);
849     
850     gtk_container_set_border_width (GTK_CONTAINER (window), 10);
851
852     main_vbox = gtk_vbox_new (FALSE, 0);
853     gtk_container_add (GTK_CONTAINER (window), main_vbox);
854     
855     frame_horz = gtk_frame_new ("Horizontal Button Boxes");
856     gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz, TRUE, TRUE, 10);
857     
858     vbox = gtk_vbox_new (FALSE, 0);
859     gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
860     gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
861
862     gtk_box_pack_start (GTK_BOX (vbox), 
863            create_bbox (TRUE, "Spread", 40, 85, 20, GTK_BUTTONBOX_SPREAD),
864                         TRUE, TRUE, 0);
865
866     gtk_box_pack_start (GTK_BOX (vbox), 
867            create_bbox (TRUE, "Edge", 40, 85, 20, GTK_BUTTONBOX_EDGE),
868                         TRUE, TRUE, 5);
869
870     gtk_box_pack_start (GTK_BOX (vbox), 
871            create_bbox (TRUE, "Start", 40, 85, 20, GTK_BUTTONBOX_START),
872                         TRUE, TRUE, 5);
873
874     gtk_box_pack_start (GTK_BOX (vbox), 
875            create_bbox (TRUE, "End", 40, 85, 20, GTK_BUTTONBOX_END),
876                         TRUE, TRUE, 5);
877
878     frame_vert = gtk_frame_new ("Vertical Button Boxes");
879     gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert, TRUE, TRUE, 10);
880     
881     hbox = gtk_hbox_new (FALSE, 0);
882     gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
883     gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
884
885     gtk_box_pack_start (GTK_BOX (hbox), 
886            create_bbox (FALSE, "Spread", 30, 85, 20, GTK_BUTTONBOX_SPREAD),
887                         TRUE, TRUE, 0);
888
889     gtk_box_pack_start (GTK_BOX (hbox), 
890            create_bbox (FALSE, "Edge", 30, 85, 20, GTK_BUTTONBOX_EDGE),
891                         TRUE, TRUE, 5);
892
893     gtk_box_pack_start (GTK_BOX (hbox), 
894            create_bbox (FALSE, "Start", 30, 85, 20, GTK_BUTTONBOX_START),
895                         TRUE, TRUE, 5);
896
897     gtk_box_pack_start (GTK_BOX (hbox), 
898            create_bbox (FALSE, "End", 30, 85, 20, GTK_BUTTONBOX_END),
899                         TRUE, TRUE, 5);
900   }
901
902   if (!GTK_WIDGET_VISIBLE (window))
903     gtk_widget_show_all (window);
904   else
905     gtk_widget_destroy (window);
906 }
907
908 /*
909  * GtkToolBar
910  */
911
912 static GtkWidget*
913 new_pixmap (char      *filename,
914             GdkWindow *window,
915             GdkColor  *background)
916 {
917   GtkWidget *wpixmap;
918   GdkPixmap *pixmap;
919   GdkBitmap *mask;
920
921   if (strcmp (filename, "test.xpm") == 0 ||
922       !file_exists (filename))
923     {
924       pixmap = gdk_pixmap_create_from_xpm_d (window, &mask,
925                                              background,
926                                              openfile);
927     }
928   else
929     pixmap = gdk_pixmap_create_from_xpm (window, &mask,
930                                          background,
931                                          filename);
932   
933   wpixmap = gtk_image_new_from_pixmap (pixmap, mask);
934
935   return wpixmap;
936 }
937
938
939 static void
940 set_toolbar_small_stock (GtkWidget *widget,
941                          gpointer   data)
942 {
943   gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_SMALL_TOOLBAR);
944 }
945
946 static void
947 set_toolbar_large_stock (GtkWidget *widget,
948                          gpointer   data)
949 {
950   gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_LARGE_TOOLBAR);
951 }
952
953 static void
954 set_toolbar_horizontal (GtkWidget *widget,
955                         gpointer   data)
956 {
957   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_HORIZONTAL);
958 }
959
960 static void
961 set_toolbar_vertical (GtkWidget *widget,
962                       gpointer   data)
963 {
964   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_VERTICAL);
965 }
966
967 static void
968 set_toolbar_icons (GtkWidget *widget,
969                    gpointer   data)
970 {
971   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
972 }
973
974 static void
975 set_toolbar_text (GtkWidget *widget,
976                   gpointer   data)
977 {
978   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
979 }
980
981 static void
982 set_toolbar_both (GtkWidget *widget,
983                   gpointer   data)
984 {
985   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
986 }
987
988 static void
989 set_toolbar_both_horiz (GtkWidget *widget,
990                         gpointer   data)
991 {
992   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH_HORIZ);
993 }
994
995 static void
996 set_toolbar_enable (GtkWidget *widget,
997                     gpointer   data)
998 {
999   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), TRUE);
1000 }
1001
1002 static void
1003 set_toolbar_disable (GtkWidget *widget,
1004                      gpointer   data)
1005 {
1006   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), FALSE);
1007 }
1008
1009 static void
1010 create_toolbar (GtkWidget *widget)
1011 {
1012   static GtkWidget *window = NULL;
1013   GtkWidget *toolbar;
1014   GtkWidget *entry;
1015
1016   if (!window)
1017     {
1018       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1019       gtk_window_set_screen (GTK_WINDOW (window),
1020                              gtk_widget_get_screen (widget));
1021       
1022       gtk_window_set_title (GTK_WINDOW (window), "Toolbar test");
1023       gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
1024
1025       g_signal_connect (window, "destroy",
1026                         G_CALLBACK (gtk_widget_destroyed),
1027                         &window);
1028
1029       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1030       gtk_widget_realize (window);
1031
1032       toolbar = gtk_toolbar_new ();
1033
1034       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
1035                                 GTK_STOCK_NEW,
1036                                 "Stock icon: New", "Toolbar/New",
1037                                 G_CALLBACK (set_toolbar_small_stock), toolbar, -1);
1038       
1039       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
1040                                 GTK_STOCK_OPEN,
1041                                 "Stock icon: Open", "Toolbar/Open",
1042                                 G_CALLBACK (set_toolbar_large_stock), toolbar, -1);
1043       
1044       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1045                                "Horizontal", "Horizontal toolbar layout", "Toolbar/Horizontal",
1046                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1047                                G_CALLBACK (set_toolbar_horizontal), toolbar);
1048       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1049                                "Vertical", "Vertical toolbar layout", "Toolbar/Vertical",
1050                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1051                                G_CALLBACK (set_toolbar_vertical), toolbar);
1052
1053       gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
1054
1055       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1056                                "Icons", "Only show toolbar icons", "Toolbar/IconsOnly",
1057                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1058                                G_CALLBACK (set_toolbar_icons), toolbar);
1059       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1060                                "Text", "Only show toolbar text", "Toolbar/TextOnly",
1061                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1062                                G_CALLBACK (set_toolbar_text), toolbar);
1063       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1064                                "Both", "Show toolbar icons and text", "Toolbar/Both",
1065                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1066                                G_CALLBACK (set_toolbar_both), toolbar);
1067       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1068                                "Both (horizontal)",
1069                                "Show toolbar icons and text in a horizontal fashion",
1070                                "Toolbar/BothHoriz",
1071                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1072                                G_CALLBACK (set_toolbar_both_horiz), toolbar);
1073                                
1074       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1075
1076       entry = gtk_entry_new ();
1077
1078       gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), entry, "This is an unusable GtkEntry ;)", "Hey don't click me!!!");
1079
1080       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1081
1082
1083       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1084
1085       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1086                                "Enable", "Enable tooltips", NULL,
1087                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1088                                G_CALLBACK (set_toolbar_enable), toolbar);
1089       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1090                                "Disable", "Disable tooltips", NULL,
1091                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1092                                G_CALLBACK (set_toolbar_disable), toolbar);
1093
1094       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1095
1096       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1097                                "Frobate", "Frobate tooltip", NULL,
1098                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1099                                NULL, toolbar);
1100       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1101                                "Baz", "Baz tooltip", NULL,
1102                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1103                                NULL, toolbar);
1104
1105       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1106       
1107       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1108                                "Blah", "Blah tooltip", NULL,
1109                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1110                                NULL, toolbar);
1111       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1112                                "Bar", "Bar tooltip", NULL,
1113                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1114                                NULL, toolbar);
1115
1116       gtk_container_add (GTK_CONTAINER (window), toolbar);
1117     }
1118
1119   if (!GTK_WIDGET_VISIBLE (window))
1120     gtk_widget_show_all (window);
1121   else
1122     gtk_widget_destroy (window);
1123 }
1124
1125 static GtkWidget*
1126 make_toolbar (GtkWidget *window)
1127 {
1128   GtkWidget *toolbar;
1129
1130   if (!GTK_WIDGET_REALIZED (window))
1131     gtk_widget_realize (window);
1132
1133   toolbar = gtk_toolbar_new ();
1134
1135   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1136                            "Horizontal", "Horizontal toolbar layout", NULL,
1137                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1138                            G_CALLBACK (set_toolbar_horizontal), toolbar);
1139   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1140                            "Vertical", "Vertical toolbar layout", NULL,
1141                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1142                            G_CALLBACK (set_toolbar_vertical), toolbar);
1143
1144   gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
1145
1146   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1147                            "Icons", "Only show toolbar icons", NULL,
1148                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1149                            G_CALLBACK (set_toolbar_icons), toolbar);
1150   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1151                            "Text", "Only show toolbar text", NULL,
1152                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1153                            G_CALLBACK (set_toolbar_text), toolbar);
1154   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1155                            "Both", "Show toolbar icons and text", NULL,
1156                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1157                            G_CALLBACK (set_toolbar_both), toolbar);
1158
1159   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1160
1161   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1162                            "Woot", "Woot woot woot", NULL,
1163                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1164                            NULL, toolbar);
1165   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1166                            "Blah", "Blah blah blah", "Toolbar/Big",
1167                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1168                            NULL, toolbar);
1169
1170   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1171
1172   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1173                            "Enable", "Enable tooltips", NULL,
1174                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1175                            G_CALLBACK (set_toolbar_enable), toolbar);
1176   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1177                            "Disable", "Disable tooltips", NULL,
1178                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1179                            G_CALLBACK (set_toolbar_disable), toolbar);
1180
1181   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1182   
1183   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1184                            "Hoo", "Hoo tooltip", NULL,
1185                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1186                            NULL, toolbar);
1187   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1188                            "Woo", "Woo tooltip", NULL,
1189                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1190                            NULL, toolbar);
1191
1192   return toolbar;
1193 }
1194
1195 /*
1196  * GtkStatusBar
1197  */
1198
1199 static guint statusbar_counter = 1;
1200
1201 static void
1202 statusbar_push (GtkWidget *button,
1203                 GtkStatusbar *statusbar)
1204 {
1205   gchar text[1024];
1206
1207   sprintf (text, "something %d", statusbar_counter++);
1208
1209   gtk_statusbar_push (statusbar, 1, text);
1210 }
1211
1212 static void
1213 statusbar_pop (GtkWidget *button,
1214                GtkStatusbar *statusbar)
1215 {
1216   gtk_statusbar_pop (statusbar, 1);
1217 }
1218
1219 static void
1220 statusbar_steal (GtkWidget *button,
1221                  GtkStatusbar *statusbar)
1222 {
1223   gtk_statusbar_remove (statusbar, 1, 4);
1224 }
1225
1226 static void
1227 statusbar_popped (GtkStatusbar  *statusbar,
1228                   guint          context_id,
1229                   const gchar   *text)
1230 {
1231   if (!statusbar->messages)
1232     statusbar_counter = 1;
1233 }
1234
1235 static void
1236 statusbar_contexts (GtkStatusbar *statusbar)
1237 {
1238   gchar *string;
1239
1240   string = "any context";
1241   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1242            string,
1243            gtk_statusbar_get_context_id (statusbar, string));
1244   
1245   string = "idle messages";
1246   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1247            string,
1248            gtk_statusbar_get_context_id (statusbar, string));
1249   
1250   string = "some text";
1251   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1252            string,
1253            gtk_statusbar_get_context_id (statusbar, string));
1254
1255   string = "hit the mouse";
1256   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1257            string,
1258            gtk_statusbar_get_context_id (statusbar, string));
1259
1260   string = "hit the mouse2";
1261   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1262            string,
1263            gtk_statusbar_get_context_id (statusbar, string));
1264 }
1265
1266 static void
1267 create_statusbar (GtkWidget *widget)
1268 {
1269   static GtkWidget *window = NULL;
1270   GtkWidget *box1;
1271   GtkWidget *box2;
1272   GtkWidget *button;
1273   GtkWidget *separator;
1274   GtkWidget *statusbar;
1275
1276   if (!window)
1277     {
1278       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1279       gtk_window_set_screen (GTK_WINDOW (window),
1280                              gtk_widget_get_screen (widget));
1281
1282       g_signal_connect (window, "destroy",
1283                         G_CALLBACK (gtk_widget_destroyed),
1284                         &window);
1285
1286       gtk_window_set_title (GTK_WINDOW (window), "statusbar");
1287       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1288
1289       box1 = gtk_vbox_new (FALSE, 0);
1290       gtk_container_add (GTK_CONTAINER (window), box1);
1291
1292       box2 = gtk_vbox_new (FALSE, 10);
1293       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1294       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1295
1296       statusbar = gtk_statusbar_new ();
1297       gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
1298       g_signal_connect (statusbar,
1299                         "text_popped",
1300                         G_CALLBACK (statusbar_popped),
1301                         NULL);
1302
1303       button = gtk_widget_new (gtk_button_get_type (),
1304                                "label", "push something",
1305                                "visible", TRUE,
1306                                "parent", box2,
1307                                NULL);
1308       g_object_connect (button,
1309                         "signal::clicked", statusbar_push, statusbar,
1310                         NULL);
1311
1312       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1313                                                  "label", "pop",
1314                                                  "visible", TRUE,
1315                                                  "parent", box2,
1316                                                  NULL),
1317                                  "signal_after::clicked", statusbar_pop, statusbar,
1318                                  NULL);
1319
1320       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1321                                                  "label", "steal #4",
1322                                                  "visible", TRUE,
1323                                                  "parent", box2,
1324                                                  NULL),
1325                                  "signal_after::clicked", statusbar_steal, statusbar,
1326                                  NULL);
1327
1328       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1329                                                  "label", "test contexts",
1330                                                  "visible", TRUE,
1331                                                  "parent", box2,
1332                                                  NULL),
1333                                  "swapped_signal_after::clicked", statusbar_contexts, statusbar,
1334                                  NULL);
1335       
1336       separator = gtk_hseparator_new ();
1337       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1338
1339       box2 = gtk_vbox_new (FALSE, 10);
1340       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1341       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1342
1343       button = gtk_button_new_with_label ("close");
1344       g_signal_connect_swapped (button, "clicked",
1345                                 G_CALLBACK (gtk_widget_destroy),
1346                                 window);
1347       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1348       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1349       gtk_widget_grab_default (button);
1350     }
1351
1352   if (!GTK_WIDGET_VISIBLE (window))
1353     gtk_widget_show_all (window);
1354   else
1355     gtk_widget_destroy (window);
1356 }
1357
1358 /*
1359  * GtkTree
1360  */
1361
1362 static void
1363 cb_tree_destroy_event(GtkWidget* w)
1364 {
1365   sTreeButtons* tree_buttons;
1366
1367   /* free buttons structure associate at this tree */
1368   tree_buttons = g_object_get_data (G_OBJECT (w), "user_data");
1369   g_free (tree_buttons);
1370 }
1371
1372 static void
1373 cb_add_new_item(GtkWidget* w, GtkTree* tree)
1374 {
1375   sTreeButtons* tree_buttons;
1376   GList* selected_list;
1377   GtkWidget* selected_item;
1378   GtkWidget* subtree;
1379   GtkWidget* item_new;
1380   char buffer[255];
1381
1382   tree_buttons = g_object_get_data (G_OBJECT (tree), "user_data");
1383
1384   selected_list = GTK_TREE_SELECTION_OLD(tree);
1385
1386   if(selected_list == NULL)
1387     {
1388       /* there is no item in tree */
1389       subtree = GTK_WIDGET(tree);
1390     }
1391   else
1392     {
1393       /* list can have only one element */
1394       selected_item = GTK_WIDGET(selected_list->data);
1395       
1396       subtree = GTK_TREE_ITEM_SUBTREE(selected_item);
1397
1398       if(subtree == NULL)
1399         {
1400           /* current selected item have not subtree ... create it */
1401           subtree = gtk_tree_new();
1402           gtk_tree_item_set_subtree(GTK_TREE_ITEM(selected_item), 
1403                                     subtree);
1404         }
1405     }
1406
1407   /* at this point, we know which subtree will be used to add new item */
1408   /* create a new item */
1409   sprintf(buffer, "item add %d", tree_buttons->nb_item_add);
1410   item_new = gtk_tree_item_new_with_label(buffer);
1411   gtk_tree_append(GTK_TREE(subtree), item_new);
1412   gtk_widget_show(item_new);
1413
1414   tree_buttons->nb_item_add++;
1415 }
1416
1417 static void
1418 cb_remove_item(GtkWidget*w, GtkTree* tree)
1419 {
1420   GList* selected_list;
1421   GList* clear_list;
1422   
1423   selected_list = GTK_TREE_SELECTION_OLD(tree);
1424
1425   clear_list = NULL;
1426     
1427   while (selected_list) 
1428     {
1429       clear_list = g_list_prepend (clear_list, selected_list->data);
1430       selected_list = selected_list->next;
1431     }
1432   
1433   clear_list = g_list_reverse (clear_list);
1434   gtk_tree_remove_items(tree, clear_list);
1435
1436   g_list_free (clear_list);
1437 }
1438
1439 static void
1440 cb_remove_subtree(GtkWidget*w, GtkTree* tree)
1441 {
1442   GList* selected_list;
1443   GtkTreeItem *item;
1444   
1445   selected_list = GTK_TREE_SELECTION_OLD(tree);
1446
1447   if (selected_list)
1448     {
1449       item = GTK_TREE_ITEM (selected_list->data);
1450       if (item->subtree)
1451         gtk_tree_item_remove_subtree (item);
1452     }
1453 }
1454
1455 static void
1456 cb_tree_changed(GtkTree* tree)
1457 {
1458   sTreeButtons* tree_buttons;
1459   GList* selected_list;
1460   guint nb_selected;
1461
1462   tree_buttons = g_object_get_data (G_OBJECT (tree), "user_data");
1463
1464   selected_list = GTK_TREE_SELECTION_OLD(tree);
1465   nb_selected = g_list_length(selected_list);
1466
1467   if(nb_selected == 0) 
1468     {
1469       if(tree->children == NULL)
1470         gtk_widget_set_sensitive(tree_buttons->add_button, TRUE);
1471       else
1472         gtk_widget_set_sensitive(tree_buttons->add_button, FALSE);
1473       gtk_widget_set_sensitive(tree_buttons->remove_button, FALSE);
1474       gtk_widget_set_sensitive(tree_buttons->subtree_button, FALSE);
1475     } 
1476   else 
1477     {
1478       gtk_widget_set_sensitive(tree_buttons->remove_button, TRUE);
1479       gtk_widget_set_sensitive(tree_buttons->add_button, (nb_selected == 1));
1480       gtk_widget_set_sensitive(tree_buttons->subtree_button, (nb_selected == 1));
1481     }  
1482 }
1483
1484 static void 
1485 create_subtree(GtkWidget* item, guint level, guint nb_item_max, guint recursion_level_max)
1486 {
1487   GtkWidget* item_subtree;
1488   GtkWidget* item_new;
1489   guint nb_item;
1490   char buffer[255];
1491   int no_root_item;
1492
1493   if(level == recursion_level_max) return;
1494
1495   if(level == -1)
1496     {
1497       /* query with no root item */
1498       level = 0;
1499       item_subtree = item;
1500       no_root_item = 1;
1501     }
1502   else
1503     {
1504       /* query with no root item */
1505       /* create subtree and associate it with current item */
1506       item_subtree = gtk_tree_new();
1507       no_root_item = 0;
1508     }
1509   
1510   for(nb_item = 0; nb_item < nb_item_max; nb_item++)
1511     {
1512       sprintf(buffer, "item %d-%d", level, nb_item);
1513       item_new = gtk_tree_item_new_with_label(buffer);
1514       gtk_tree_append(GTK_TREE(item_subtree), item_new);
1515       create_subtree(item_new, level+1, nb_item_max, recursion_level_max);
1516       gtk_widget_show(item_new);
1517     }
1518
1519   if(!no_root_item)
1520     gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), item_subtree);
1521 }
1522
1523 static void
1524 create_tree_sample(GdkScreen *screen, guint selection_mode, 
1525                    guint draw_line, guint view_line, guint no_root_item,
1526                    guint nb_item_max, guint recursion_level_max) 
1527 {
1528   GtkWidget* window;
1529   GtkWidget* box1;
1530   GtkWidget* box2;
1531   GtkWidget* separator;
1532   GtkWidget* button;
1533   GtkWidget* scrolled_win;
1534   GtkWidget* root_tree;
1535   GtkWidget* root_item;
1536   sTreeButtons* tree_buttons;
1537
1538   /* create tree buttons struct */
1539   if ((tree_buttons = g_malloc (sizeof (sTreeButtons))) == NULL)
1540     {
1541       g_error("can't allocate memory for tree structure !\n");
1542       return;
1543     }
1544   tree_buttons->nb_item_add = 0;
1545
1546   /* create top level window */
1547   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1548   gtk_window_set_screen (GTK_WINDOW (window), screen);
1549   gtk_window_set_title(GTK_WINDOW(window), "Tree Sample");
1550   g_signal_connect (window, "destroy",
1551                     G_CALLBACK (cb_tree_destroy_event), NULL);
1552   g_object_set_data (G_OBJECT (window), "user_data", tree_buttons);
1553
1554   box1 = gtk_vbox_new(FALSE, 0);
1555   gtk_container_add(GTK_CONTAINER(window), box1);
1556   gtk_widget_show(box1);
1557
1558   /* create tree box */
1559   box2 = gtk_vbox_new(FALSE, 0);
1560   gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
1561   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1562   gtk_widget_show(box2);
1563
1564   /* create scrolled window */
1565   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1566   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
1567                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1568   gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
1569   gtk_widget_set_size_request (scrolled_win, 200, 200);
1570   gtk_widget_show (scrolled_win);
1571   
1572   /* create root tree widget */
1573   root_tree = gtk_tree_new();
1574   g_signal_connect (root_tree, "selection_changed",
1575                     G_CALLBACK (cb_tree_changed),
1576                     NULL);
1577   g_object_set_data (G_OBJECT (root_tree), "user_data", tree_buttons);
1578   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), root_tree);
1579   gtk_tree_set_selection_mode(GTK_TREE(root_tree), selection_mode);
1580   gtk_tree_set_view_lines(GTK_TREE(root_tree), draw_line);
1581   gtk_tree_set_view_mode(GTK_TREE(root_tree), !view_line);
1582   gtk_widget_show(root_tree);
1583
1584   if ( no_root_item )
1585     {
1586       /* set root tree to subtree function with root item variable */
1587       root_item = GTK_WIDGET(root_tree);
1588     }
1589   else
1590     {
1591       /* create root tree item widget */
1592       root_item = gtk_tree_item_new_with_label("root item");
1593       gtk_tree_append(GTK_TREE(root_tree), root_item);
1594       gtk_widget_show(root_item);
1595      }
1596   create_subtree(root_item, -no_root_item, nb_item_max, recursion_level_max);
1597
1598   box2 = gtk_vbox_new(FALSE, 0);
1599   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1600   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1601   gtk_widget_show(box2);
1602
1603   button = gtk_button_new_with_label("Add Item");
1604   gtk_widget_set_sensitive(button, FALSE);
1605   g_signal_connect (button, "clicked",
1606                     G_CALLBACK (cb_add_new_item),
1607                     root_tree);
1608   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1609   gtk_widget_show(button);
1610   tree_buttons->add_button = button;
1611
1612   button = gtk_button_new_with_label("Remove Item(s)");
1613   gtk_widget_set_sensitive(button, FALSE);
1614   g_signal_connect (button, "clicked",
1615                     G_CALLBACK (cb_remove_item),
1616                     root_tree);
1617   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1618   gtk_widget_show(button);
1619   tree_buttons->remove_button = button;
1620
1621   button = gtk_button_new_with_label("Remove Subtree");
1622   gtk_widget_set_sensitive(button, FALSE);
1623   g_signal_connect (button, "clicked",
1624                     G_CALLBACK (cb_remove_subtree),
1625                     root_tree);
1626   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1627   gtk_widget_show(button);
1628   tree_buttons->subtree_button = button;
1629
1630   /* create separator */
1631   separator = gtk_hseparator_new();
1632   gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
1633   gtk_widget_show(separator);
1634
1635   /* create button box */
1636   box2 = gtk_vbox_new(FALSE, 0);
1637   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1638   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1639   gtk_widget_show(box2);
1640
1641   button = gtk_button_new_with_label("Close");
1642   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1643   g_signal_connect_swapped (button, "clicked",
1644                             G_CALLBACK (gtk_widget_destroy),
1645                             window);
1646   gtk_widget_show(button);
1647
1648   gtk_widget_show(window);
1649 }
1650
1651 static void
1652 cb_create_tree(GtkWidget* w)
1653 {
1654   guint selection_mode = GTK_SELECTION_SINGLE;
1655   guint view_line;
1656   guint draw_line;
1657   guint no_root_item;
1658   guint nb_item;
1659   guint recursion_level;
1660
1661   /* get selection mode choice */
1662   if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.single_button)->active)
1663     selection_mode = GTK_SELECTION_SINGLE;
1664   else
1665     if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.browse_button)->active)
1666       selection_mode = GTK_SELECTION_BROWSE;
1667     else
1668       selection_mode = GTK_SELECTION_MULTIPLE;
1669
1670   /* get options choice */
1671   draw_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.draw_line_button)->active;
1672   view_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.view_line_button)->active;
1673   no_root_item = GTK_TOGGLE_BUTTON(sTreeSampleSelection.no_root_item_button)->active;
1674     
1675   /* get levels */
1676   nb_item = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.nb_item_spinner));
1677   recursion_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.recursion_spinner));
1678
1679   if (pow (nb_item, recursion_level) > 10000)
1680     {
1681       g_print ("%g total items? That will take a very long time. Try less\n",
1682                pow (nb_item, recursion_level));
1683       return;
1684     }
1685
1686   create_tree_sample(gtk_widget_get_screen (w),
1687                      selection_mode, draw_line, 
1688                      view_line, no_root_item, nb_item, recursion_level);
1689 }
1690
1691 void 
1692 create_tree_mode_window(GtkWidget *widget)
1693 {
1694   static GtkWidget* window;
1695   GtkWidget* box1;
1696   GtkWidget* box2;
1697   GtkWidget* box3;
1698   GtkWidget* box4;
1699   GtkWidget* box5;
1700   GtkWidget* button;
1701   GtkWidget* frame;
1702   GtkWidget* separator;
1703   GtkWidget* label;
1704   GtkWidget* spinner;
1705   GtkAdjustment *adj;
1706
1707   if (!window)
1708     {
1709       /* create toplevel window  */
1710       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1711       gtk_window_set_screen (GTK_WINDOW (window),
1712                              gtk_widget_get_screen (widget));
1713       gtk_window_set_title(GTK_WINDOW(window), "Set Tree Parameters");
1714       g_signal_connect (window, "destroy",
1715                         G_CALLBACK (gtk_widget_destroyed),
1716                         &window);
1717       box1 = gtk_vbox_new(FALSE, 0);
1718       gtk_container_add(GTK_CONTAINER(window), box1);
1719
1720       /* create upper box - selection box */
1721       box2 = gtk_vbox_new(FALSE, 5);
1722       gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
1723       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1724
1725       box3 = gtk_hbox_new(FALSE, 5);
1726       gtk_box_pack_start(GTK_BOX(box2), box3, TRUE, TRUE, 0);
1727
1728       /* create selection mode frame */
1729       frame = gtk_frame_new("Selection Mode");
1730       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
1731
1732       box4 = gtk_vbox_new(FALSE, 0);
1733       gtk_container_add(GTK_CONTAINER(frame), box4);
1734       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1735
1736       /* create radio button */  
1737       button = gtk_radio_button_new_with_label(NULL, "SINGLE");
1738       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1739       sTreeSampleSelection.single_button = button;
1740
1741       button = gtk_radio_button_new_with_label(gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1742                                                "BROWSE");
1743       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1744       sTreeSampleSelection.browse_button = button;
1745
1746       button = gtk_radio_button_new_with_label(gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1747                                                "MULTIPLE");
1748       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1749       sTreeSampleSelection.multiple_button = button;
1750
1751       sTreeSampleSelection.selection_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
1752
1753       /* create option mode frame */
1754       frame = gtk_frame_new("Options");
1755       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
1756
1757       box4 = gtk_vbox_new(FALSE, 0);
1758       gtk_container_add(GTK_CONTAINER(frame), box4);
1759       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1760
1761       /* create check button */
1762       button = gtk_check_button_new_with_label("Draw line");
1763       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1764       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
1765       sTreeSampleSelection.draw_line_button = button;
1766   
1767       button = gtk_check_button_new_with_label("View Line mode");
1768       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1769       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
1770       sTreeSampleSelection.view_line_button = button;
1771   
1772       button = gtk_check_button_new_with_label("Without Root item");
1773       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1774       sTreeSampleSelection.no_root_item_button = button;
1775
1776       /* create recursion parameter */
1777       frame = gtk_frame_new("Size Parameters");
1778       gtk_box_pack_start(GTK_BOX(box2), frame, TRUE, TRUE, 0);
1779
1780       box4 = gtk_hbox_new(FALSE, 5);
1781       gtk_container_add(GTK_CONTAINER(frame), box4);
1782       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1783
1784       /* create number of item spin button */
1785       box5 = gtk_hbox_new(FALSE, 5);
1786       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
1787
1788       label = gtk_label_new("Number of items : ");
1789       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1790       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
1791
1792       adj = (GtkAdjustment *) gtk_adjustment_new (DEFAULT_NUMBER_OF_ITEM, 1.0, 255.0, 1.0,
1793                                                   5.0, 0.0);
1794       spinner = gtk_spin_button_new (adj, 0, 0);
1795       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
1796       sTreeSampleSelection.nb_item_spinner = spinner;
1797   
1798       /* create recursion level spin button */
1799       box5 = gtk_hbox_new(FALSE, 5);
1800       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
1801
1802       label = gtk_label_new("Depth : ");
1803       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1804       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
1805
1806       adj = (GtkAdjustment *) gtk_adjustment_new (DEFAULT_RECURSION_LEVEL, 0.0, 255.0, 1.0,
1807                                                   5.0, 0.0);
1808       spinner = gtk_spin_button_new (adj, 0, 0);
1809       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
1810       sTreeSampleSelection.recursion_spinner = spinner;
1811   
1812       /* create horizontal separator */
1813       separator = gtk_hseparator_new();
1814       gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
1815
1816       /* create bottom button box */
1817       box2 = gtk_hbox_new(TRUE, 10);
1818       gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1819       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1820
1821       button = gtk_button_new_with_label("Create Tree");
1822       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1823       g_signal_connect (button, "clicked",
1824                         G_CALLBACK (cb_create_tree), NULL);
1825
1826       button = gtk_button_new_with_label("Close");
1827       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1828       g_signal_connect_swapped (button, "clicked",
1829                                 G_CALLBACK (gtk_widget_destroy),
1830                                 window);
1831     }
1832   if (!GTK_WIDGET_VISIBLE (window))
1833     gtk_widget_show_all (window);
1834   else
1835     gtk_widget_destroy (window);
1836 }
1837
1838 /*
1839  * Gridded geometry
1840  */
1841 #define GRID_SIZE 20
1842 #define DEFAULT_GEOMETRY "10x10"
1843
1844 static gboolean
1845 gridded_geometry_expose (GtkWidget      *widget,
1846                          GdkEventExpose *event)
1847 {
1848   int i, j;
1849
1850   gdk_draw_rectangle (widget->window, widget->style->base_gc[widget->state], TRUE,
1851                       0, 0, widget->allocation.width, widget->allocation.height);
1852   
1853   for (i = 0 ; i * GRID_SIZE < widget->allocation.width; i++)
1854     for (j = 0 ; j * GRID_SIZE < widget->allocation.height; j++)
1855       {
1856         if ((i + j) % 2 == 0)
1857           gdk_draw_rectangle (widget->window, widget->style->text_gc[widget->state], TRUE,
1858                               i * GRID_SIZE, j * GRID_SIZE, GRID_SIZE, GRID_SIZE);
1859       }
1860
1861   return FALSE;
1862 }
1863
1864 static void
1865 gridded_geometry_subresponse (GtkDialog *dialog,
1866                               gint       response_id,
1867                               gchar     *geometry_string)
1868 {
1869   if (response_id == GTK_RESPONSE_NONE)
1870     {
1871       gtk_widget_destroy (GTK_WIDGET (dialog));
1872     }
1873   else
1874     {
1875       if (!gtk_window_parse_geometry (GTK_WINDOW (dialog), geometry_string))
1876         {
1877           g_print ("Can't parse geometry string %s\n", geometry_string);
1878           gtk_window_parse_geometry (GTK_WINDOW (dialog), DEFAULT_GEOMETRY);
1879         }
1880     }
1881 }
1882
1883 static void
1884 gridded_geometry_response (GtkDialog *dialog,
1885                            gint       response_id,
1886                            GtkEntry  *entry)
1887 {
1888   if (response_id == GTK_RESPONSE_NONE)
1889     {
1890       gtk_widget_destroy (GTK_WIDGET (dialog));
1891     }
1892   else
1893     {
1894       gchar *geometry_string = g_strdup (gtk_entry_get_text (entry));
1895       gchar *title = g_strdup_printf ("Gridded window at: %s", geometry_string);
1896       GtkWidget *window;
1897       GtkWidget *drawing_area;
1898       GtkWidget *box;
1899       GdkGeometry geometry;
1900       
1901       window = gtk_dialog_new_with_buttons (title,
1902                                             NULL, 0,
1903                                             "Reset", 1,
1904                                             GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
1905                                             NULL);
1906
1907       gtk_window_set_screen (GTK_WINDOW (window), 
1908                              gtk_widget_get_screen (GTK_WIDGET (dialog)));
1909       g_free (title);
1910       g_signal_connect (window, "response",
1911                         G_CALLBACK (gridded_geometry_subresponse), geometry_string);
1912
1913       box = gtk_vbox_new (FALSE, 0);
1914       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), box, TRUE, TRUE, 0);
1915       
1916       gtk_container_set_border_width (GTK_CONTAINER (box), 7);
1917       
1918       drawing_area = gtk_drawing_area_new ();
1919       g_signal_connect (drawing_area, "expose_event",
1920                         G_CALLBACK (gridded_geometry_expose), NULL);
1921       gtk_box_pack_start (GTK_BOX (box), drawing_area, TRUE, TRUE, 0);
1922
1923       /* Gross hack to work around bug 68668... if we set the size request
1924        * large enough, then  the current
1925        *
1926        *   request_of_window - request_of_geometry_widget
1927        *
1928        * method of getting the base size works more or less works.
1929        */
1930       gtk_widget_set_size_request (drawing_area, 2000, 2000);
1931
1932       geometry.base_width = 0;
1933       geometry.base_height = 0;
1934       geometry.min_width = 2 * GRID_SIZE;
1935       geometry.min_height = 2 * GRID_SIZE;
1936       geometry.width_inc = GRID_SIZE;
1937       geometry.height_inc = GRID_SIZE;
1938
1939       gtk_window_set_geometry_hints (GTK_WINDOW (window), drawing_area,
1940                                      &geometry,
1941                                      GDK_HINT_BASE_SIZE | GDK_HINT_MIN_SIZE | GDK_HINT_RESIZE_INC);
1942
1943       if (!gtk_window_parse_geometry (GTK_WINDOW (window), geometry_string))
1944         {
1945           g_print ("Can't parse geometry string %s\n", geometry_string);
1946           gtk_window_parse_geometry (GTK_WINDOW (window), DEFAULT_GEOMETRY);
1947         }
1948
1949       gtk_widget_show_all (window);
1950     }
1951 }
1952
1953 static void 
1954 create_gridded_geometry (GtkWidget *widget)
1955 {
1956   static GtkWidget *window = NULL;
1957   GtkWidget *entry;
1958   GtkWidget *label;
1959
1960   if (!window)
1961     {
1962       window = gtk_dialog_new_with_buttons ("Gridded Geometry",
1963                                             NULL, 0,
1964                                             "Create", 1,
1965                                             GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
1966                                             NULL);
1967       
1968       gtk_window_set_screen (GTK_WINDOW (window),
1969                              gtk_widget_get_screen (widget));
1970
1971       label = gtk_label_new ("Geometry string:");
1972       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label, FALSE, FALSE, 0);
1973
1974       entry = gtk_entry_new ();
1975       gtk_entry_set_text (GTK_ENTRY (entry), DEFAULT_GEOMETRY);
1976       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), entry, FALSE, FALSE, 0);
1977
1978       g_signal_connect (window, "response",
1979                         G_CALLBACK (gridded_geometry_response), entry);
1980       g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
1981
1982       gtk_widget_show_all (window);
1983     }
1984   else
1985     gtk_widget_destroy (window);
1986 }
1987
1988 /*
1989  * GtkHandleBox
1990  */
1991
1992 static void
1993 handle_box_child_signal (GtkHandleBox *hb,
1994                          GtkWidget    *child,
1995                          const gchar  *action)
1996 {
1997   printf ("%s: child <%s> %sed\n",
1998           g_type_name (G_OBJECT_TYPE (hb)),
1999           g_type_name (G_OBJECT_TYPE (child)),
2000           action);
2001 }
2002
2003 static void
2004 create_handle_box (GtkWidget *widget)
2005 {
2006   static GtkWidget* window = NULL;
2007   GtkWidget *handle_box;
2008   GtkWidget *handle_box2;
2009   GtkWidget *vbox;
2010   GtkWidget *hbox;
2011   GtkWidget *toolbar;
2012   GtkWidget *label;
2013   GtkWidget *separator;
2014
2015   if (!window)
2016   {
2017     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2018     
2019     gtk_window_set_screen (GTK_WINDOW (window),
2020                            gtk_widget_get_screen (widget));
2021
2022     gtk_window_set_title (GTK_WINDOW (window),
2023                           "Handle Box Test");
2024     gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
2025     
2026     g_signal_connect (window, "destroy",
2027                       G_CALLBACK (gtk_widget_destroyed),
2028                       &window);
2029     
2030     gtk_container_set_border_width (GTK_CONTAINER (window), 20);
2031
2032     vbox = gtk_vbox_new (FALSE, 0);
2033     gtk_container_add (GTK_CONTAINER (window), vbox);
2034     gtk_widget_show (vbox);
2035
2036     label = gtk_label_new ("Above");
2037     gtk_container_add (GTK_CONTAINER (vbox), label);
2038     gtk_widget_show (label);
2039
2040     separator = gtk_hseparator_new ();
2041     gtk_container_add (GTK_CONTAINER (vbox), separator);
2042     gtk_widget_show (separator);
2043     
2044     hbox = gtk_hbox_new (FALSE, 10);
2045     gtk_container_add (GTK_CONTAINER (vbox), hbox);
2046     gtk_widget_show (hbox);
2047
2048     separator = gtk_hseparator_new ();
2049     gtk_container_add (GTK_CONTAINER (vbox), separator);
2050     gtk_widget_show (separator);
2051
2052     label = gtk_label_new ("Below");
2053     gtk_container_add (GTK_CONTAINER (vbox), label);
2054     gtk_widget_show (label);
2055
2056     handle_box = gtk_handle_box_new ();
2057     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
2058     g_signal_connect (handle_box,
2059                       "child_attached",
2060                       G_CALLBACK (handle_box_child_signal),
2061                       "attached");
2062     g_signal_connect (handle_box,
2063                       "child_detached",
2064                       G_CALLBACK (handle_box_child_signal),
2065                       "detached");
2066     gtk_widget_show (handle_box);
2067
2068     toolbar = make_toolbar (window);
2069     
2070     gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
2071     gtk_widget_show (toolbar);
2072
2073     handle_box = gtk_handle_box_new ();
2074     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
2075     g_signal_connect (handle_box,
2076                       "child_attached",
2077                       G_CALLBACK (handle_box_child_signal),
2078                       "attached");
2079     g_signal_connect (handle_box,
2080                       "child_detached",
2081                       G_CALLBACK (handle_box_child_signal),
2082                       "detached");
2083     gtk_widget_show (handle_box);
2084
2085     handle_box2 = gtk_handle_box_new ();
2086     gtk_container_add (GTK_CONTAINER (handle_box), handle_box2);
2087     g_signal_connect (handle_box2,
2088                       "child_attached",
2089                       G_CALLBACK (handle_box_child_signal),
2090                       "attached");
2091     g_signal_connect (handle_box2,
2092                       "child_detached",
2093                       G_CALLBACK (handle_box_child_signal),
2094                       "detached");
2095     gtk_widget_show (handle_box2);
2096
2097     label = gtk_label_new ("Fooo!");
2098     gtk_container_add (GTK_CONTAINER (handle_box2), label);
2099     gtk_widget_show (label);
2100   }
2101
2102   if (!GTK_WIDGET_VISIBLE (window))
2103     gtk_widget_show (window);
2104   else
2105     gtk_widget_destroy (window);
2106 }
2107
2108 /*
2109  * Test for getting an image from a drawable
2110  */
2111
2112 struct GetImageData
2113 {
2114   GtkWidget *src;
2115   GtkWidget *snap;
2116   GtkWidget *sw;
2117 };
2118
2119 static void
2120 take_snapshot (GtkWidget *button,
2121                gpointer data)
2122 {
2123   struct GetImageData *gid = data;
2124   GdkRectangle visible;
2125   int width_fraction;
2126   int height_fraction;
2127   GdkGC *gc;
2128   GdkGC *black_gc;
2129   GdkColor color = { 0, 30000, 0, 0 };
2130   GdkRectangle target;
2131   GdkImage *shot;
2132   
2133   /* Do some begin_paint_rect on some random rects, draw some
2134    * distinctive stuff into those rects, then take the snapshot.
2135    * figure out whether any rects were overlapped and report to
2136    * user.
2137    */
2138
2139   visible = gid->sw->allocation;
2140
2141   visible.x = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (gid->sw))->value;
2142   visible.y = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (gid->sw))->value;
2143   
2144   width_fraction = visible.width / 4;
2145   height_fraction = visible.height / 4;
2146
2147   gc = gdk_gc_new (gid->src->window);
2148   black_gc = gid->src->style->black_gc;
2149   
2150   gdk_gc_set_rgb_fg_color (gc, &color);
2151
2152     
2153   target.x = visible.x + width_fraction;
2154   target.y = visible.y + height_fraction * 3;
2155   target.width = width_fraction;
2156   target.height = height_fraction / 2;
2157   
2158   gdk_window_begin_paint_rect (gid->src->window,
2159                                &target);
2160
2161   gdk_draw_rectangle (gid->src->window,
2162                       gc,
2163                       TRUE,
2164                       target.x, target.y,
2165                       target.width, target.height);
2166
2167   gdk_draw_rectangle (gid->src->window,
2168                       black_gc,
2169                       FALSE,
2170                       target.x + 10, target.y + 10,
2171                       target.width - 20, target.height - 20);
2172   
2173   target.x = visible.x + width_fraction;
2174   target.y = visible.y + height_fraction;
2175   target.width = width_fraction;
2176   target.height = height_fraction;
2177   
2178   gdk_window_begin_paint_rect (gid->src->window,
2179                                &target);
2180
2181   gdk_draw_rectangle (gid->src->window,
2182                       gc,
2183                       TRUE,
2184                       target.x, target.y,
2185                       target.width, target.height);
2186
2187   gdk_draw_rectangle (gid->src->window,
2188                       black_gc,
2189                       FALSE,
2190                       target.x + 10, target.y + 10,
2191                       target.width - 20, target.height - 20);
2192   
2193   target.x = visible.x + width_fraction * 3;
2194   target.y = visible.y + height_fraction;
2195   target.width = width_fraction / 2;
2196   target.height = height_fraction;
2197   
2198   gdk_window_begin_paint_rect (gid->src->window,
2199                                &target);
2200
2201   gdk_draw_rectangle (gid->src->window,
2202                       gc,
2203                       TRUE,
2204                       target.x, target.y,
2205                       target.width, target.height);
2206
2207   gdk_draw_rectangle (gid->src->window,
2208                       black_gc,
2209                       FALSE,
2210                       target.x + 10, target.y + 10,
2211                       target.width - 20, target.height - 20);
2212   
2213   target.x = visible.x + width_fraction * 2;
2214   target.y = visible.y + height_fraction * 2;
2215   target.width = width_fraction / 4;
2216   target.height = height_fraction / 4;
2217   
2218   gdk_window_begin_paint_rect (gid->src->window,
2219                                &target);
2220
2221   gdk_draw_rectangle (gid->src->window,
2222                       gc,
2223                       TRUE,
2224                       target.x, target.y,
2225                       target.width, target.height);
2226
2227   gdk_draw_rectangle (gid->src->window,
2228                       black_gc,
2229                       FALSE,
2230                       target.x + 10, target.y + 10,
2231                       target.width - 20, target.height - 20);  
2232
2233   target.x += target.width / 2;
2234   target.y += target.width / 2;
2235   
2236   gdk_window_begin_paint_rect (gid->src->window,
2237                                &target);
2238
2239   gdk_draw_rectangle (gid->src->window,
2240                       gc,
2241                       TRUE,
2242                       target.x, target.y,
2243                       target.width, target.height);
2244
2245   gdk_draw_rectangle (gid->src->window,
2246                       black_gc,
2247                       FALSE,
2248                       target.x + 10, target.y + 10,
2249                       target.width - 20, target.height - 20);
2250   
2251   /* Screen shot area */
2252
2253   target.x = visible.x + width_fraction * 1.5;
2254   target.y = visible.y + height_fraction * 1.5;
2255   target.width = width_fraction * 2;
2256   target.height = height_fraction * 2;  
2257
2258   shot = gdk_drawable_get_image (gid->src->window,
2259                                  target.x, target.y,
2260                                  target.width, target.height);
2261
2262   gtk_image_set_from_image (GTK_IMAGE (gid->snap),
2263                             shot, NULL);
2264
2265   g_object_unref (shot);
2266   
2267   gdk_window_end_paint (gid->src->window);
2268   gdk_window_end_paint (gid->src->window);
2269   gdk_window_end_paint (gid->src->window);
2270   gdk_window_end_paint (gid->src->window);
2271   gdk_window_end_paint (gid->src->window);
2272
2273   gdk_draw_rectangle (gid->src->window,
2274                       gid->src->style->black_gc,
2275                       FALSE,
2276                       target.x, target.y,
2277                       target.width, target.height);
2278   
2279   g_object_unref (gc);
2280 }
2281
2282 static gint
2283 image_source_expose (GtkWidget *da,
2284                      GdkEventExpose *event,
2285                      gpointer data)
2286 {
2287   int x = event->area.x;
2288   GdkColor red = { 0, 65535, 0, 0 };
2289   GdkColor green = { 0, 0, 65535, 0 };
2290   GdkColor blue = { 0, 0, 0, 65535 };
2291   GdkGC *gc;
2292
2293   gc = gdk_gc_new (event->window);
2294   
2295   while (x < (event->area.x + event->area.width))
2296     {
2297       switch (x % 7)
2298         {
2299         case 0:
2300         case 1:
2301         case 2:
2302           gdk_gc_set_rgb_fg_color (gc, &red);
2303           break;
2304
2305         case 3:
2306         case 4:
2307         case 5:
2308           gdk_gc_set_rgb_fg_color (gc, &green);
2309           break;
2310
2311         case 6:
2312         case 7:
2313         case 8:
2314           gdk_gc_set_rgb_fg_color (gc, &blue);
2315           break;
2316
2317         default:
2318           g_assert_not_reached ();
2319           break;
2320         }
2321
2322       gdk_draw_line (event->window,
2323                      gc,
2324                      x, event->area.y,
2325                      x, event->area.y + event->area.height);
2326       
2327       ++x;
2328     }
2329
2330   g_object_unref (gc);
2331   
2332   return TRUE;
2333 }
2334
2335 static void
2336 create_get_image (GtkWidget *widget)
2337 {
2338   static GtkWidget *window = NULL;
2339
2340   if (window)
2341     gtk_widget_destroy (window);
2342   else
2343     {
2344       GtkWidget *sw;
2345       GtkWidget *src;
2346       GtkWidget *snap;
2347       GtkWidget *vbox;
2348       GtkWidget *hbox;
2349       GtkWidget *button;
2350       struct GetImageData *gid;
2351
2352       gid = g_new (struct GetImageData, 1);
2353       
2354       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2355       
2356       gtk_window_set_screen (GTK_WINDOW (window),
2357                              gtk_widget_get_screen (widget));
2358
2359       g_signal_connect (window,
2360                         "destroy",
2361                         G_CALLBACK (gtk_widget_destroyed),
2362                         &window);
2363
2364       g_object_set_data_full (G_OBJECT (window),
2365                               "testgtk-get-image-data",
2366                               gid,
2367                               g_free);
2368       
2369       vbox = gtk_vbox_new (FALSE, 0);
2370       
2371       gtk_container_add (GTK_CONTAINER (window), vbox);
2372       
2373       sw = gtk_scrolled_window_new (NULL, NULL);
2374       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
2375                                       GTK_POLICY_AUTOMATIC,
2376                                       GTK_POLICY_AUTOMATIC);
2377
2378       gid->sw = sw;
2379
2380       gtk_widget_set_size_request (sw, 400, 400);
2381       
2382       src = gtk_drawing_area_new ();
2383       gtk_widget_set_size_request (src, 10000, 10000);
2384
2385       g_signal_connect (src,
2386                         "expose_event",
2387                         G_CALLBACK (image_source_expose),
2388                         gid);
2389       
2390       gid->src = src;
2391       
2392       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
2393                                              src);
2394       
2395       gtk_box_pack_start (GTK_BOX (vbox),
2396                           sw, TRUE, TRUE, 0);                          
2397
2398
2399       hbox = gtk_hbox_new (FALSE, 3);
2400
2401       snap = gtk_widget_new (GTK_TYPE_IMAGE, NULL);
2402
2403       gid->snap = snap;
2404
2405       sw = gtk_scrolled_window_new (NULL, NULL);
2406       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
2407                                       GTK_POLICY_AUTOMATIC,
2408                                       GTK_POLICY_AUTOMATIC);
2409       gtk_widget_set_size_request (sw, 300, 300);
2410       
2411       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), snap);
2412
2413       gtk_box_pack_end (GTK_BOX (hbox), sw, FALSE, FALSE, 5);
2414
2415       button = gtk_button_new_with_label ("Get image from drawable");
2416
2417       g_signal_connect (button,
2418                         "clicked",
2419                         G_CALLBACK (take_snapshot),
2420                         gid);
2421       
2422       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
2423
2424       gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2425       
2426       gtk_widget_show_all (window);
2427     }
2428 }
2429
2430 /* 
2431  * Label Demo
2432  */
2433 static void
2434 sensitivity_toggled (GtkWidget *toggle,
2435                      GtkWidget *widget)
2436 {
2437   gtk_widget_set_sensitive (widget,  GTK_TOGGLE_BUTTON (toggle)->active);  
2438 }
2439
2440 static GtkWidget*
2441 create_sensitivity_control (GtkWidget *widget)
2442 {
2443   GtkWidget *button;
2444
2445   button = gtk_toggle_button_new_with_label ("Sensitive");  
2446
2447   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
2448                                 GTK_WIDGET_IS_SENSITIVE (widget));
2449   
2450   g_signal_connect (button,
2451                     "toggled",
2452                     G_CALLBACK (sensitivity_toggled),
2453                     widget);
2454   
2455   gtk_widget_show_all (button);
2456
2457   return button;
2458 }
2459
2460 static void
2461 set_selectable_recursive (GtkWidget *widget,
2462                           gboolean   setting)
2463 {
2464   if (GTK_IS_CONTAINER (widget))
2465     {
2466       GList *children;
2467       GList *tmp;
2468       
2469       children = gtk_container_get_children (GTK_CONTAINER (widget));
2470       tmp = children;
2471       while (tmp)
2472         {
2473           set_selectable_recursive (tmp->data, setting);
2474
2475           tmp = tmp->next;
2476         }
2477       g_list_free (children);
2478     }
2479   else if (GTK_IS_LABEL (widget))
2480     {
2481       gtk_label_set_selectable (GTK_LABEL (widget), setting);
2482     }
2483 }
2484
2485 static void
2486 selectable_toggled (GtkWidget *toggle,
2487                     GtkWidget *widget)
2488 {
2489   set_selectable_recursive (widget,
2490                             GTK_TOGGLE_BUTTON (toggle)->active);
2491 }
2492
2493 static GtkWidget*
2494 create_selectable_control (GtkWidget *widget)
2495 {
2496   GtkWidget *button;
2497
2498   button = gtk_toggle_button_new_with_label ("Selectable");  
2499
2500   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
2501                                 FALSE);
2502   
2503   g_signal_connect (button,
2504                     "toggled",
2505                     G_CALLBACK (selectable_toggled),
2506                     widget);
2507   
2508   gtk_widget_show_all (button);
2509
2510   return button;
2511 }
2512
2513 void create_labels (GtkWidget *widget)
2514 {
2515   static GtkWidget *window = NULL;
2516   GtkWidget *hbox;
2517   GtkWidget *vbox;
2518   GtkWidget *frame;
2519   GtkWidget *label;
2520   GtkWidget *button;
2521
2522   if (!window)
2523     {
2524       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2525
2526       gtk_window_set_screen (GTK_WINDOW (window),
2527                              gtk_widget_get_screen (widget));
2528
2529       g_signal_connect (window, "destroy",
2530                         G_CALLBACK (gtk_widget_destroyed),
2531                         &window);
2532
2533       gtk_window_set_title (GTK_WINDOW (window), "Label");
2534
2535       vbox = gtk_vbox_new (FALSE, 5);
2536       
2537       hbox = gtk_hbox_new (FALSE, 5);
2538       gtk_container_add (GTK_CONTAINER (window), vbox);
2539
2540       gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2541
2542       button = create_sensitivity_control (hbox);
2543
2544       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2545
2546       button = create_selectable_control (hbox);
2547
2548       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2549       
2550       vbox = gtk_vbox_new (FALSE, 5);
2551       
2552       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2553       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
2554
2555       frame = gtk_frame_new ("Normal Label");
2556       label = gtk_label_new ("This is a Normal label");
2557       gtk_container_add (GTK_CONTAINER (frame), label);
2558       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2559
2560       frame = gtk_frame_new ("Multi-line Label");
2561       label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
2562       gtk_container_add (GTK_CONTAINER (frame), label);
2563       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2564
2565       frame = gtk_frame_new ("Left Justified Label");
2566       label = gtk_label_new ("This is a Left-Justified\nMulti-line label.\nThird      line");
2567       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2568       gtk_container_add (GTK_CONTAINER (frame), label);
2569       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2570
2571       frame = gtk_frame_new ("Right Justified Label");
2572       label = gtk_label_new ("This is a Right-Justified\nMulti-line label.\nFourth line, (j/k)");
2573       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
2574       gtk_container_add (GTK_CONTAINER (frame), label);
2575       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2576
2577       frame = gtk_frame_new ("Internationalized Label");
2578       label = gtk_label_new (NULL);
2579       gtk_label_set_markup (GTK_LABEL (label),
2580                             "French (Français) Bonjour, Salut\n"
2581                             "Korean (한글)   안녕하세요, 안녕하십니까\n"
2582                             "Russian (Русский) Здравствуйте!\n"
2583                             "Chinese (Simplified) <span lang=\"zh-cn\">元气   开发</span>\n"
2584                             "Chinese (Traditional) <span lang=\"zh-tw\">元氣  開發</span>\n"
2585                             "Japanese <span lang=\"ja\">元気  開発</span>");
2586       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2587       gtk_container_add (GTK_CONTAINER (frame), label);
2588       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2589
2590       frame = gtk_frame_new ("Bidirection Label");
2591       label = gtk_label_new ("Arabic    السلام عليكم\n"
2592                              "Hebrew    שלום");
2593       gtk_widget_set_direction (label, GTK_TEXT_DIR_RTL);
2594       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
2595       gtk_container_add (GTK_CONTAINER (frame), label);
2596       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2597
2598       vbox = gtk_vbox_new (FALSE, 5);
2599       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2600       frame = gtk_frame_new ("Line wrapped label");
2601       label = gtk_label_new ("This is an example of a line-wrapped label.  It should not be taking "\
2602                              "up the entire             "/* big space to test spacing */\
2603                              "width allocated to it, but automatically wraps the words to fit.  "\
2604                              "The time has come, for all good men, to come to the aid of their party.  "\
2605                              "The sixth sheik's six sheep's sick.\n"\
2606                              "     It supports multiple paragraphs correctly, and  correctly   adds "\
2607                              "many          extra  spaces. ");
2608
2609       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2610       gtk_container_add (GTK_CONTAINER (frame), label);
2611       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2612
2613       frame = gtk_frame_new ("Filled, wrapped label");
2614       label = gtk_label_new ("This is an example of a line-wrapped, filled label.  It should be taking "\
2615                              "up the entire              width allocated to it.  Here is a seneance to prove "\
2616                              "my point.  Here is another sentence. "\
2617                              "Here comes the sun, do de do de do.\n"\
2618                              "    This is a new paragraph.\n"\
2619                              "    This is another newer, longer, better paragraph.  It is coming to an end, "\
2620                              "unfortunately.");
2621       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_FILL);
2622       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2623       gtk_container_add (GTK_CONTAINER (frame), label);
2624       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2625
2626       frame = gtk_frame_new ("Underlined label");
2627       label = gtk_label_new ("This label is underlined!\n"
2628                              "This one is underlined (こんにちは) in quite a funky fashion");
2629       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2630       gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __  ___ ____ _____");
2631       gtk_container_add (GTK_CONTAINER (frame), label);
2632       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2633
2634       frame = gtk_frame_new ("Markup label");
2635       label = gtk_label_new (NULL);
2636
2637       /* There's also a gtk_label_set_markup() without accel if you
2638        * don't have an accelerator key
2639        */
2640       gtk_label_set_markup_with_mnemonic (GTK_LABEL (label),
2641                                           "This <span foreground=\"blue\" background=\"orange\">label</span> has "
2642                                           "<b>markup</b> _such as "
2643                                           "<big><i>Big Italics</i></big>\n"
2644                                           "<tt>Monospace font</tt>\n"
2645                                           "<u>Underline!</u>\n"
2646                                           "foo\n"
2647                                           "<span foreground=\"green\" background=\"red\">Ugly colors</span>\n"
2648                                           "and nothing on this line,\n"
2649                                           "or this.\n"
2650                                           "or this either\n"
2651                                           "or even on this one\n"
2652                                           "la <big>la <big>la <big>la <big>la</big></big></big></big>\n"
2653                                           "but this _word is <span foreground=\"purple\"><big>purple</big></span>\n"
2654                                           "<span underline=\"double\">We like <sup>superscript</sup> and <sub>subscript</sub> too</span>");
2655
2656       g_assert (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)) == GDK_s);
2657       
2658       gtk_container_add (GTK_CONTAINER (frame), label);
2659       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2660     }
2661   
2662   if (!GTK_WIDGET_VISIBLE (window))
2663     gtk_widget_show_all (window);
2664   else
2665     gtk_widget_destroy (window);
2666 }
2667
2668 /*
2669  * Reparent demo
2670  */
2671
2672 static void
2673 reparent_label (GtkWidget *widget,
2674                 GtkWidget *new_parent)
2675 {
2676   GtkWidget *label;
2677
2678   label = g_object_get_data (G_OBJECT (widget), "user_data");
2679
2680   gtk_widget_reparent (label, new_parent);
2681 }
2682
2683 static void
2684 set_parent_signal (GtkWidget *child,
2685                    GtkWidget *old_parent,
2686                    gpointer   func_data)
2687 {
2688   g_print ("set_parent for \"%s\": new parent: \"%s\", old parent: \"%s\", data: %d\n",
2689            g_type_name (G_OBJECT_TYPE (child)),
2690            child->parent ? g_type_name (G_OBJECT_TYPE (child->parent)) : "NULL",
2691            old_parent ? g_type_name (G_OBJECT_TYPE (old_parent)) : "NULL",
2692            GPOINTER_TO_INT (func_data));
2693 }
2694
2695 static void
2696 create_reparent (GtkWidget *widget)
2697 {
2698   static GtkWidget *window = NULL;
2699   GtkWidget *box1;
2700   GtkWidget *box2;
2701   GtkWidget *box3;
2702   GtkWidget *frame;
2703   GtkWidget *button;
2704   GtkWidget *label;
2705   GtkWidget *separator;
2706   GtkWidget *event_box;
2707
2708   if (!window)
2709     {
2710       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2711
2712       gtk_window_set_screen (GTK_WINDOW (window),
2713                              gtk_widget_get_screen (widget));
2714
2715       g_signal_connect (window, "destroy",
2716                         G_CALLBACK (gtk_widget_destroyed),
2717                         &window);
2718
2719       gtk_window_set_title (GTK_WINDOW (window), "reparent");
2720       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2721
2722       box1 = gtk_vbox_new (FALSE, 0);
2723       gtk_container_add (GTK_CONTAINER (window), box1);
2724
2725       box2 = gtk_hbox_new (FALSE, 5);
2726       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2727       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2728
2729       label = gtk_label_new ("Hello World");
2730
2731       frame = gtk_frame_new ("Frame 1");
2732       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
2733
2734       box3 = gtk_vbox_new (FALSE, 5);
2735       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
2736       gtk_container_add (GTK_CONTAINER (frame), box3);
2737
2738       button = gtk_button_new_with_label ("switch");
2739       g_object_set_data (G_OBJECT (button), "user_data", label);
2740       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
2741
2742       event_box = gtk_event_box_new ();
2743       gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
2744       gtk_container_add (GTK_CONTAINER (event_box), label);
2745                          
2746       g_signal_connect (button, "clicked",
2747                         G_CALLBACK (reparent_label),
2748                         event_box);
2749       
2750       g_signal_connect (label, "parent_set",
2751                         G_CALLBACK (set_parent_signal),
2752                         GINT_TO_POINTER (42));
2753
2754       frame = gtk_frame_new ("Frame 2");
2755       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
2756
2757       box3 = gtk_vbox_new (FALSE, 5);
2758       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
2759       gtk_container_add (GTK_CONTAINER (frame), box3);
2760
2761       button = gtk_button_new_with_label ("switch");
2762       g_object_set_data (G_OBJECT (button), "user_data", label);
2763       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
2764       
2765       event_box = gtk_event_box_new ();
2766       gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
2767
2768       g_signal_connect (button, "clicked",
2769                         G_CALLBACK (reparent_label),
2770                         event_box);
2771
2772       separator = gtk_hseparator_new ();
2773       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2774
2775       box2 = gtk_vbox_new (FALSE, 10);
2776       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2777       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2778
2779       button = gtk_button_new_with_label ("close");
2780       g_signal_connect_swapped (button, "clicked",
2781                                 G_CALLBACK (gtk_widget_destroy), window);
2782       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2783       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2784       gtk_widget_grab_default (button);
2785     }
2786
2787   if (!GTK_WIDGET_VISIBLE (window))
2788     gtk_widget_show_all (window);
2789   else
2790     gtk_widget_destroy (window);
2791 }
2792
2793 /*
2794  * Saved Position
2795  */
2796 gint upositionx = 0;
2797 gint upositiony = 0;
2798
2799 static gint
2800 uposition_configure (GtkWidget *window)
2801 {
2802   GtkLabel *lx;
2803   GtkLabel *ly;
2804   gchar buffer[64];
2805
2806   lx = g_object_get_data (G_OBJECT (window), "x");
2807   ly = g_object_get_data (G_OBJECT (window), "y");
2808
2809   gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
2810   sprintf (buffer, "%d", upositionx);
2811   gtk_label_set_text (lx, buffer);
2812   sprintf (buffer, "%d", upositiony);
2813   gtk_label_set_text (ly, buffer);
2814
2815   return FALSE;
2816 }
2817
2818 static void
2819 uposition_stop_configure (GtkToggleButton *toggle,
2820                           GtkObject       *window)
2821 {
2822   if (toggle->active)
2823     g_signal_handlers_block_by_func (window, G_CALLBACK (uposition_configure), NULL);
2824   else
2825     g_signal_handlers_unblock_by_func (window, G_CALLBACK (uposition_configure), NULL);
2826 }
2827
2828 static void
2829 create_saved_position (GtkWidget *widget)
2830 {
2831   static GtkWidget *window = NULL;
2832
2833   if (!window)
2834     {
2835       GtkWidget *hbox;
2836       GtkWidget *main_vbox;
2837       GtkWidget *vbox;
2838       GtkWidget *x_label;
2839       GtkWidget *y_label;
2840       GtkWidget *button;
2841       GtkWidget *label;
2842       GtkWidget *any;
2843
2844       window = g_object_connect (gtk_widget_new (GTK_TYPE_WINDOW,
2845                                                  "type", GTK_WINDOW_TOPLEVEL,
2846                                                  "x", upositionx,
2847                                                  "y", upositiony,
2848                                                  "title", "Saved Position",
2849                                                  NULL),
2850                                  "signal::configure_event", uposition_configure, NULL,
2851                                  NULL);
2852
2853       gtk_window_set_screen (GTK_WINDOW (window),
2854                              gtk_widget_get_screen (widget));
2855       
2856
2857       g_signal_connect (window, "destroy",
2858                         G_CALLBACK (gtk_widget_destroyed),
2859                         &window);
2860
2861       main_vbox = gtk_vbox_new (FALSE, 5);
2862       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
2863       gtk_container_add (GTK_CONTAINER (window), main_vbox);
2864
2865       vbox =
2866         gtk_widget_new (gtk_vbox_get_type (),
2867                         "GtkBox::homogeneous", FALSE,
2868                         "GtkBox::spacing", 5,
2869                         "GtkContainer::border_width", 10,
2870                         "GtkWidget::parent", main_vbox,
2871                         "GtkWidget::visible", TRUE,
2872                         "child", g_object_connect (gtk_widget_new (GTK_TYPE_TOGGLE_BUTTON,
2873                                                                    "label", "Stop Events",
2874                                                                    "active", FALSE,
2875                                                                    "visible", TRUE,
2876                                                                    NULL),
2877                                                    "signal::clicked", uposition_stop_configure, window,
2878                                                    NULL),
2879                         NULL);
2880
2881       hbox = gtk_hbox_new (FALSE, 0);
2882       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2883       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2884
2885       label = gtk_label_new ("X Origin : ");
2886       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2887       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2888
2889       x_label = gtk_label_new ("");
2890       gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
2891       g_object_set_data (G_OBJECT (window), "x", x_label);
2892
2893       hbox = gtk_hbox_new (FALSE, 0);
2894       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2895       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2896
2897       label = gtk_label_new ("Y Origin : ");
2898       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2899       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2900
2901       y_label = gtk_label_new ("");
2902       gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
2903       g_object_set_data (G_OBJECT (window), "y", y_label);
2904
2905       any =
2906         gtk_widget_new (gtk_hseparator_get_type (),
2907                         "GtkWidget::visible", TRUE,
2908                         NULL);
2909       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
2910
2911       hbox = gtk_hbox_new (FALSE, 0);
2912       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
2913       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
2914
2915       button = gtk_button_new_with_label ("Close");
2916       g_signal_connect_swapped (button, "clicked",
2917                                 G_CALLBACK (gtk_widget_destroy),
2918                                 window);
2919       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
2920       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2921       gtk_widget_grab_default (button);
2922       
2923       gtk_widget_show_all (window);
2924     }
2925   else
2926     gtk_widget_destroy (window);
2927 }
2928
2929 /*
2930  * GtkPixmap
2931  */
2932
2933 static void
2934 create_pixmap (GtkWidget *widget)
2935 {
2936   static GtkWidget *window = NULL;
2937   GtkWidget *box1;
2938   GtkWidget *box2;
2939   GtkWidget *box3;
2940   GtkWidget *button;
2941   GtkWidget *label;
2942   GtkWidget *separator;
2943   GtkWidget *pixmapwid;
2944
2945   if (!window)
2946     {
2947       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2948
2949       gtk_window_set_screen (GTK_WINDOW (window),
2950                              gtk_widget_get_screen (widget));
2951
2952       g_signal_connect (window, "destroy",
2953                         G_CALLBACK (gtk_widget_destroyed),
2954                         &window);
2955
2956       gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
2957       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2958       gtk_widget_realize(window);
2959
2960       box1 = gtk_vbox_new (FALSE, 0);
2961       gtk_container_add (GTK_CONTAINER (window), box1);
2962
2963       box2 = gtk_vbox_new (FALSE, 10);
2964       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2965       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2966
2967       button = gtk_button_new ();
2968       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2969
2970       pixmapwid = new_pixmap ("test.xpm", window->window, NULL);
2971
2972       label = gtk_label_new ("Pixmap\ntest");
2973       box3 = gtk_hbox_new (FALSE, 0);
2974       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2975       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
2976       gtk_container_add (GTK_CONTAINER (box3), label);
2977       gtk_container_add (GTK_CONTAINER (button), box3);
2978
2979       button = gtk_button_new ();
2980       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2981       
2982       pixmapwid = new_pixmap ("test.xpm", window->window, NULL);
2983
2984       label = gtk_label_new ("Pixmap\ntest");
2985       box3 = gtk_hbox_new (FALSE, 0);
2986       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2987       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
2988       gtk_container_add (GTK_CONTAINER (box3), label);
2989       gtk_container_add (GTK_CONTAINER (button), box3);
2990
2991       gtk_widget_set_sensitive (button, FALSE);
2992       
2993       separator = gtk_hseparator_new ();
2994       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2995
2996       box2 = gtk_vbox_new (FALSE, 10);
2997       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2998       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2999
3000       button = gtk_button_new_with_label ("close");
3001       g_signal_connect_swapped (button, "clicked",
3002                                 G_CALLBACK (gtk_widget_destroy),
3003                                 window);
3004       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3005       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3006       gtk_widget_grab_default (button);
3007     }
3008
3009   if (!GTK_WIDGET_VISIBLE (window))
3010     gtk_widget_show_all (window);
3011   else
3012     gtk_widget_destroy (window);
3013 }
3014
3015 static void
3016 tips_query_widget_entered (GtkTipsQuery   *tips_query,
3017                            GtkWidget      *widget,
3018                            const gchar    *tip_text,
3019                            const gchar    *tip_private,
3020                            GtkWidget      *toggle)
3021 {
3022   if (GTK_TOGGLE_BUTTON (toggle)->active)
3023     {
3024       gtk_label_set_text (GTK_LABEL (tips_query), tip_text ? "There is a Tip!" : "There is no Tip!");
3025       /* don't let GtkTipsQuery reset its label */
3026       g_signal_stop_emission_by_name (tips_query, "widget_entered");
3027     }
3028 }
3029
3030 static gint
3031 tips_query_widget_selected (GtkWidget      *tips_query,
3032                             GtkWidget      *widget,
3033                             const gchar    *tip_text,
3034                             const gchar    *tip_private,
3035                             GdkEventButton *event,
3036                             gpointer        func_data)
3037 {
3038   if (widget)
3039     g_print ("Help \"%s\" requested for <%s>\n",
3040              tip_private ? tip_private : "None",
3041              g_type_name (G_OBJECT_TYPE (widget)));
3042   return TRUE;
3043 }
3044
3045 static void
3046 create_tooltips (GtkWidget *widget)
3047 {
3048   static GtkWidget *window = NULL;
3049   GtkWidget *box1;
3050   GtkWidget *box2;
3051   GtkWidget *box3;
3052   GtkWidget *button;
3053   GtkWidget *toggle;
3054   GtkWidget *frame;
3055   GtkWidget *tips_query;
3056   GtkWidget *separator;
3057   GtkTooltips *tooltips;
3058
3059   if (!window)
3060     {
3061       window =
3062         gtk_widget_new (gtk_window_get_type (),
3063                         "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
3064                         "GtkContainer::border_width", 0,
3065                         "GtkWindow::title", "Tooltips",
3066                         "GtkWindow::allow_shrink", TRUE,
3067                         "GtkWindow::allow_grow", FALSE,
3068                         NULL);
3069
3070       gtk_window_set_screen (GTK_WINDOW (window),
3071                              gtk_widget_get_screen (widget));
3072
3073       g_signal_connect (window, "destroy",
3074                         G_CALLBACK (destroy_tooltips),
3075                         &window);
3076
3077       tooltips=gtk_tooltips_new();
3078       g_object_ref (tooltips);
3079       gtk_object_sink (GTK_OBJECT (tooltips));
3080       g_object_set_data (G_OBJECT (window), "tooltips", tooltips);
3081       
3082       box1 = gtk_vbox_new (FALSE, 0);
3083       gtk_container_add (GTK_CONTAINER (window), box1);
3084
3085       box2 = gtk_vbox_new (FALSE, 10);
3086       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3087       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3088
3089       button = gtk_toggle_button_new_with_label ("button1");
3090       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3091
3092       gtk_tooltips_set_tip (tooltips,
3093                             button,
3094                             "This is button 1",
3095                             "ContextHelp/buttons/1");
3096
3097       button = gtk_toggle_button_new_with_label ("button2");
3098       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3099
3100       gtk_tooltips_set_tip (tooltips,
3101                             button,
3102                             "This is button 2. This is also a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly.",
3103                             "ContextHelp/buttons/2_long");
3104
3105       toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
3106       gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
3107
3108       gtk_tooltips_set_tip (tooltips,
3109                             toggle,
3110                             "Toggle TipsQuery view.",
3111                             "Hi msw! ;)");
3112
3113       box3 =
3114         gtk_widget_new (gtk_vbox_get_type (),
3115                         "homogeneous", FALSE,
3116                         "spacing", 5,
3117                         "border_width", 5,
3118                         "visible", TRUE,
3119                         NULL);
3120
3121       tips_query = gtk_tips_query_new ();
3122
3123       button =
3124         gtk_widget_new (gtk_button_get_type (),
3125                         "label", "[?]",
3126                         "visible", TRUE,
3127                         "parent", box3,
3128                         NULL);
3129       g_object_connect (button,
3130                         "swapped_signal::clicked", gtk_tips_query_start_query, tips_query,
3131                         NULL);
3132       gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
3133       gtk_tooltips_set_tip (tooltips,
3134                             button,
3135                             "Start the Tooltips Inspector",
3136                             "ContextHelp/buttons/?");
3137       
3138       
3139       g_object_set (g_object_connect (tips_query,
3140                                       "signal::widget_entered", tips_query_widget_entered, toggle,
3141                                       "signal::widget_selected", tips_query_widget_selected, NULL,
3142                                       NULL),
3143                     "visible", TRUE,
3144                     "parent", box3,
3145                     "caller", button,
3146                     NULL);
3147       
3148       frame = gtk_widget_new (gtk_frame_get_type (),
3149                               "label", "ToolTips Inspector",
3150                               "label_xalign", (double) 0.5,
3151                               "border_width", 0,
3152                               "visible", TRUE,
3153                               "parent", box2,
3154                               "child", box3,
3155                               NULL);
3156       gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
3157
3158       separator = gtk_hseparator_new ();
3159       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3160
3161       box2 = gtk_vbox_new (FALSE, 10);
3162       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3163       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3164
3165       button = gtk_button_new_with_label ("close");
3166       g_signal_connect_swapped (button, "clicked",
3167                                 G_CALLBACK (gtk_widget_destroy),
3168                                 window);
3169       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3170       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3171       gtk_widget_grab_default (button);
3172
3173       gtk_tooltips_set_tip (tooltips, button, "Push this button to close window", "ContextHelp/buttons/Close");
3174     }
3175
3176   if (!GTK_WIDGET_VISIBLE (window))
3177     gtk_widget_show_all (window);
3178   else
3179     gtk_widget_destroy (window);
3180 }
3181
3182 /*
3183  * GtkImage
3184  */
3185
3186 static void
3187 pack_image (GtkWidget *box,
3188             const gchar *text,
3189             GtkWidget *image)
3190 {
3191   gtk_box_pack_start (GTK_BOX (box),
3192                       gtk_label_new (text),
3193                       FALSE, FALSE, 0);
3194
3195   gtk_box_pack_start (GTK_BOX (box),
3196                       image,
3197                       TRUE, TRUE, 0);  
3198 }
3199
3200 static void
3201 create_image (GtkWidget *widget)
3202 {
3203   static GtkWidget *window = NULL;
3204
3205   if (window == NULL)
3206     {
3207       GtkWidget *vbox;
3208       GdkPixmap *pixmap;
3209       GdkBitmap *mask;
3210         
3211       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3212       
3213       gtk_window_set_screen (GTK_WINDOW (window),
3214                              gtk_widget_get_screen (widget));
3215
3216       /* this is bogus for testing drawing when allocation < request,
3217        * don't copy into real code
3218        */
3219       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
3220       
3221       g_signal_connect (window, "destroy",
3222                         G_CALLBACK (gtk_widget_destroyed),
3223                         &window);
3224
3225       vbox = gtk_vbox_new (FALSE, 5);
3226
3227       gtk_container_add (GTK_CONTAINER (window), vbox);
3228
3229       pack_image (vbox, "Stock Warning Dialog",
3230                   gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
3231                                             GTK_ICON_SIZE_DIALOG));
3232
3233       pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
3234                                                       gtk_widget_get_colormap (window),
3235                                                       &mask,
3236                                                       NULL,
3237                                                       openfile);
3238       
3239       pack_image (vbox, "Pixmap",
3240                   gtk_image_new_from_pixmap (pixmap, mask));
3241     }
3242
3243   if (!GTK_WIDGET_VISIBLE (window))
3244     gtk_widget_show_all (window);
3245   else
3246     gtk_widget_destroy (window);
3247 }
3248      
3249 /*
3250  * Menu demo
3251  */
3252
3253 static GtkWidget*
3254 create_menu (GdkScreen *screen, gint depth, gint length, gboolean tearoff)
3255 {
3256   GtkWidget *menu;
3257   GtkWidget *menuitem;
3258   GtkWidget *image;
3259   GSList *group;
3260   char buf[32];
3261   int i, j;
3262
3263   if (depth < 1)
3264     return NULL;
3265
3266   menu = gtk_menu_new ();
3267   gtk_menu_set_screen (GTK_MENU (menu), screen);
3268
3269   group = NULL;
3270
3271   if (tearoff)
3272     {
3273       menuitem = gtk_tearoff_menu_item_new ();
3274       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3275       gtk_widget_show (menuitem);
3276     }
3277
3278   image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
3279                                     GTK_ICON_SIZE_MENU);
3280   gtk_widget_show (image);
3281   menuitem = gtk_image_menu_item_new_with_label ("Image item");
3282   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3283   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3284   gtk_widget_show (menuitem);
3285   
3286   for (i = 0, j = 1; i < length; i++, j++)
3287     {
3288       sprintf (buf, "item %2d - %d", depth, j);
3289
3290       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
3291       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
3292
3293 #if 0
3294       if (depth % 2)
3295         gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
3296 #endif
3297
3298       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3299       gtk_widget_show (menuitem);
3300       if (i == 3)
3301         gtk_widget_set_sensitive (menuitem, FALSE);
3302
3303       if (i == 5)
3304         gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (menuitem),
3305                                               TRUE);
3306
3307       if (i < 5)
3308         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), 
3309                                    create_menu (screen, depth - 1, 5,  TRUE));
3310     }
3311
3312   return menu;
3313 }
3314
3315 static void
3316 create_menus (GtkWidget *widget)
3317 {
3318   static GtkWidget *window = NULL;
3319   GtkWidget *box1;
3320   GtkWidget *box2;
3321   GtkWidget *button;
3322   GtkWidget *optionmenu;
3323   GtkWidget *separator;
3324   
3325   if (!window)
3326     {
3327       GtkWidget *menubar;
3328       GtkWidget *menu;
3329       GtkWidget *menuitem;
3330       GtkAccelGroup *accel_group;
3331       GtkWidget *image;
3332       GdkScreen *screen = gtk_widget_get_screen (widget);
3333       
3334       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3335
3336       gtk_window_set_screen (GTK_WINDOW (window), screen);
3337       
3338       g_signal_connect (window, "destroy",
3339                         G_CALLBACK (gtk_widget_destroyed),
3340                         &window);
3341       g_signal_connect (window, "delete-event",
3342                         G_CALLBACK (gtk_true),
3343                         NULL);
3344       
3345       accel_group = gtk_accel_group_new ();
3346       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3347
3348       gtk_window_set_title (GTK_WINDOW (window), "menus");
3349       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3350       
3351       
3352       box1 = gtk_vbox_new (FALSE, 0);
3353       gtk_container_add (GTK_CONTAINER (window), box1);
3354       gtk_widget_show (box1);
3355       
3356       menubar = gtk_menu_bar_new ();
3357       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3358       gtk_widget_show (menubar);
3359       
3360       menu = create_menu (screen, 2, 50, TRUE);
3361       
3362       menuitem = gtk_menu_item_new_with_label ("test\nline2");
3363       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3364       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3365       gtk_widget_show (menuitem);
3366       
3367       menuitem = gtk_menu_item_new_with_label ("foo");
3368       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE));
3369       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3370       gtk_widget_show (menuitem);
3371
3372       image = gtk_image_new_from_stock (GTK_STOCK_HELP,
3373                                         GTK_ICON_SIZE_MENU);
3374       gtk_widget_show (image);
3375       menuitem = gtk_image_menu_item_new_with_label ("Help");
3376       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3377       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 4, 5, TRUE));
3378       gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
3379       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3380       gtk_widget_show (menuitem);
3381       
3382       menubar = gtk_menu_bar_new ();
3383       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3384       gtk_widget_show (menubar);
3385       
3386       menu = create_menu (screen, 2, 10, TRUE);
3387       
3388       menuitem = gtk_menu_item_new_with_label ("Second menu bar");
3389       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3390       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3391       gtk_widget_show (menuitem);
3392       
3393       box2 = gtk_vbox_new (FALSE, 10);
3394       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3395       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3396       gtk_widget_show (box2);
3397       
3398       menu = create_menu (screen, 1, 5, FALSE);
3399       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
3400
3401       menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
3402       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3403       gtk_widget_show (menuitem);
3404       
3405       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
3406       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3407       gtk_widget_show (menuitem);
3408       gtk_widget_add_accelerator (menuitem,
3409                                   "activate",
3410                                   accel_group,
3411                                   GDK_F1,
3412                                   0,
3413                                   GTK_ACCEL_VISIBLE);
3414       menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
3415       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3416       gtk_widget_show (menuitem);
3417       gtk_widget_add_accelerator (menuitem,
3418                                   "activate",
3419                                   accel_group,
3420                                   GDK_F2,
3421                                   0,
3422                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3423       menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
3424       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3425       gtk_widget_show (menuitem);
3426       gtk_widget_add_accelerator (menuitem,
3427                                   "activate",
3428                                   accel_group,
3429                                   GDK_F2,
3430                                   0,
3431                                   GTK_ACCEL_VISIBLE);
3432       gtk_widget_add_accelerator (menuitem,
3433                                   "activate",
3434                                   accel_group,
3435                                   GDK_F3,
3436                                   0,
3437                                   GTK_ACCEL_VISIBLE);
3438       
3439       optionmenu = gtk_option_menu_new ();
3440       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
3441       gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 3);
3442       gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
3443       gtk_widget_show (optionmenu);
3444
3445       separator = gtk_hseparator_new ();
3446       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3447       gtk_widget_show (separator);
3448
3449       box2 = gtk_vbox_new (FALSE, 10);
3450       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3451       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3452       gtk_widget_show (box2);
3453
3454       button = gtk_button_new_with_label ("close");
3455       g_signal_connect_swapped (button, "clicked",
3456                                 G_CALLBACK (gtk_widget_destroy),
3457                                 window);
3458       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3459       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3460       gtk_widget_grab_default (button);
3461       gtk_widget_show (button);
3462     }
3463
3464   if (!GTK_WIDGET_VISIBLE (window))
3465     gtk_widget_show (window);
3466   else
3467     gtk_widget_destroy (window);
3468 }
3469
3470 static void
3471 gtk_ifactory_cb (gpointer             callback_data,
3472                  guint                callback_action,
3473                  GtkWidget           *widget)
3474 {
3475   g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
3476 }
3477
3478 /* This file was automatically generated by the make-inline-pixbuf program.
3479  * It contains inline RGB image data.
3480  */
3481 static const guchar apple[] =
3482 {
3483   /* File magic (1197763408) */
3484   0x47, 0x64, 0x6b, 0x50,
3485   /* Format of following stuff (0) */
3486   0x00, 0x00, 0x00, 0x00,
3487   /* Rowstride (64) */
3488   0x00, 0x00, 0x00, 0x40,
3489   /* Width (16) */
3490   0x00, 0x00, 0x00, 0x10,
3491   /* Height (16) */
3492   0x00, 0x00, 0x00, 0x10,
3493   /* Has an alpha channel (TRUE) */
3494   0x01,
3495   /* Colorspace (0 == RGB, no other options implemented) (0) */
3496   0x00, 0x00, 0x00, 0x00,
3497   /* Number of channels (4) */
3498   0x00, 0x00, 0x00, 0x04,
3499   /* Bits per sample (8) */
3500   0x00, 0x00, 0x00, 0x08,
3501   /* Image data */
3502   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3503   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3504   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3505   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3506   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3507   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3508   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3509   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x16, 0x14, 0x0f, 0x04,
3510   0x00, 0x00, 0x00, 0x01,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3511   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3512   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3513   0x00, 0x00, 0x00, 0x00,  0x61, 0x6d, 0x5b, 0x2b,  0x6e, 0x7c, 0x61, 0xd9,
3514   0x71, 0x80, 0x63, 0xd7,  0x5f, 0x6b, 0x5b, 0x35,  0x00, 0x00, 0x00, 0x00,
3515   0x3a, 0x35, 0x28, 0x8f,  0x00, 0x00, 0x00, 0x32,  0x00, 0x00, 0x00, 0x00,
3516   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3517   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3518   0x00, 0x00, 0x00, 0x00,  0x60, 0x6c, 0x5c, 0x07,  0x6d, 0x7b, 0x61, 0xd8,
3519   0x75, 0x84, 0x65, 0xf6,  0x76, 0x86, 0x66, 0xf7,  0x6a, 0x77, 0x60, 0xec,
3520   0x5e, 0x6a, 0x58, 0x47,  0x1c, 0x1a, 0x13, 0xa2,  0x4b, 0x47, 0x30, 0x07,
3521   0x55, 0x4e, 0x33, 0x21,  0x48, 0x3e, 0x2a, 0x08,  0xd0, 0xb8, 0x84, 0x00,
3522   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3523   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x69, 0x76, 0x5f, 0x74,
3524   0x75, 0x84, 0x65, 0xf3,  0x67, 0x75, 0x5e, 0xc4,  0x69, 0x62, 0x55, 0x75,
3525   0x94, 0x50, 0x50, 0x69,  0x75, 0x5c, 0x52, 0xb2,  0x69, 0x38, 0x34, 0xa2,
3526   0xa7, 0x5b, 0x53, 0xea,  0xa3, 0x52, 0x4f, 0xff,  0x90, 0x47, 0x42, 0xfa,
3527   0x76, 0x44, 0x36, 0xb9,  0x59, 0x38, 0x29, 0x3c,  0x00, 0x00, 0x00, 0x00,
3528   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x5f, 0x6b, 0x5a, 0x09,
3529   0x69, 0x76, 0x5e, 0xb0,  0x5f, 0x6b, 0x59, 0x57,  0x9a, 0x4b, 0x4d, 0x5b,
3530   0xb8, 0x5f, 0x63, 0xfa,  0xcc, 0x7d, 0x7e, 0xff,  0xc5, 0x69, 0x68, 0xff,
3531   0xc7, 0x6b, 0x67, 0xff,  0xc5, 0x6f, 0x67, 0xff,  0xba, 0x5e, 0x5a, 0xff,
3532   0xb1, 0x4d, 0x4d, 0xff,  0x92, 0x4b, 0x42, 0xff,  0x6a, 0x3e, 0x30, 0xfc,
3533   0x5c, 0x3b, 0x27, 0x6d,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3534   0x5d, 0x69, 0x57, 0x09,  0x5d, 0x69, 0x57, 0x09,  0x92, 0x47, 0x46, 0x1e,
3535   0xba, 0x65, 0x64, 0xf4,  0xe7, 0xbf, 0xc0, 0xff,  0xdf, 0xa5, 0xa3, 0xff,
3536   0xd4, 0x84, 0x81, 0xff,  0xd1, 0x7c, 0x76, 0xff,  0xc9, 0x78, 0x6d, 0xff,
3537   0xbb, 0x6a, 0x5d, 0xff,  0xb3, 0x5a, 0x52, 0xff,  0x9f, 0x4b, 0x47, 0xff,
3538   0x78, 0x45, 0x35, 0xff,  0x5f, 0x3c, 0x28, 0xfa,  0x53, 0x5a, 0x38, 0x24,
3539   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3540   0xa1, 0x54, 0x4d, 0x8c,  0xcf, 0x8e, 0x89, 0xff,  0xe3, 0xb1, 0xae, 0xff,
3541   0xd8, 0x94, 0x8e, 0xff,  0xd3, 0x8a, 0x82, 0xff,  0xcf, 0x80, 0x76, 0xff,
3542   0xc4, 0x75, 0x67, 0xff,  0xb7, 0x6c, 0x5c, 0xff,  0xab, 0x5e, 0x51, 0xff,
3543   0x9c, 0x4c, 0x46, 0xff,  0x7e, 0x4a, 0x3a, 0xff,  0x5c, 0x3c, 0x26, 0xff,
3544   0x58, 0x3d, 0x28, 0x55,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3545   0x00, 0x00, 0x00, 0x00,  0xa2, 0x59, 0x4f, 0xc3,  0xcd, 0x8e, 0x88, 0xff,
3546   0xd3, 0x93, 0x8c, 0xff,  0xd0, 0x8c, 0x83, 0xff,  0xcc, 0x84, 0x79, 0xff,
3547   0xc7, 0x7c, 0x6e, 0xff,  0xbc, 0x73, 0x61, 0xff,  0xb1, 0x6b, 0x59, 0xff,
3548   0xa3, 0x5f, 0x4f, 0xff,  0x93, 0x50, 0x44, 0xff,  0x78, 0x48, 0x35, 0xff,
3549   0x59, 0x3b, 0x25, 0xff,  0x4f, 0x3d, 0x28, 0x4f,  0x00, 0x00, 0x00, 0x00,
3550   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x9b, 0x5b, 0x4d, 0xbc,
3551   0xbd, 0x7e, 0x72, 0xff,  0xc6, 0x86, 0x7a, 0xff,  0xc5, 0x7f, 0x72, 0xff,
3552   0xc2, 0x7b, 0x6c, 0xff,  0xbf, 0x77, 0x63, 0xff,  0xb7, 0x72, 0x5b, 0xff,
3553   0xa9, 0x6b, 0x53, 0xff,  0x9a, 0x60, 0x4b, 0xff,  0x8b, 0x56, 0x41, 0xff,
3554   0x6a, 0x44, 0x2e, 0xff,  0x53, 0x38, 0x21, 0xfd,  0x42, 0x4b, 0x2e, 0x1a,
3555   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3556   0x8e, 0x57, 0x48, 0x6e,  0xa6, 0x6b, 0x5a, 0xff,  0xb3, 0x74, 0x62, 0xff,
3557   0xb8, 0x75, 0x61, 0xff,  0xba, 0x76, 0x61, 0xff,  0xb7, 0x74, 0x5c, 0xff,
3558   0xae, 0x6e, 0x54, 0xff,  0x9f, 0x67, 0x4c, 0xff,  0x90, 0x5d, 0x43, 0xff,
3559   0x79, 0x4d, 0x38, 0xff,  0x5c, 0x3d, 0x25, 0xff,  0x50, 0x39, 0x23, 0xb8,
3560   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3561   0x00, 0x00, 0x00, 0x00,  0x78, 0x52, 0x43, 0x07,  0x92, 0x5c, 0x47, 0xdc,
3562   0x9e, 0x64, 0x4e, 0xff,  0xa8, 0x6b, 0x52, 0xff,  0xaa, 0x6d, 0x53, 0xff,
3563   0xa7, 0x6d, 0x50, 0xff,  0x9c, 0x67, 0x4a, 0xff,  0x8e, 0x5d, 0x41, 0xff,
3564   0x7d, 0x54, 0x3a, 0xff,  0x6a, 0x4b, 0x32, 0xff,  0x51, 0x39, 0x23, 0xff,
3565   0x28, 0x20, 0x12, 0x77,  0x00, 0x00, 0x00, 0x12,  0x00, 0x00, 0x00, 0x01,
3566   0x00, 0x00, 0x00, 0x03,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3567   0x6f, 0x4a, 0x37, 0x2a,  0x81, 0x54, 0x3d, 0xec,  0x8b, 0x5a, 0x41, 0xff,
3568   0x8b, 0x5a, 0x3f, 0xff,  0x85, 0x56, 0x3c, 0xff,  0x7d, 0x52, 0x38, 0xff,
3569   0x77, 0x51, 0x33, 0xff,  0x6f, 0x4e, 0x34, 0xff,  0x5f, 0x45, 0x2c, 0xff,
3570   0x2e, 0x21, 0x14, 0xff,  0x00, 0x00, 0x00, 0xf8,  0x00, 0x00, 0x00, 0x92,
3571   0x00, 0x00, 0x00, 0x0e,  0x00, 0x00, 0x00, 0x04,  0x00, 0x00, 0x00, 0x00,
3572   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x14,  0x11, 0x0b, 0x08, 0xb4,
3573   0x50, 0x37, 0x25, 0xfe,  0x6d, 0x49, 0x2f, 0xff,  0x52, 0x37, 0x22, 0xff,
3574   0x50, 0x37, 0x21, 0xff,  0x66, 0x45, 0x2b, 0xff,  0x60, 0x46, 0x2c, 0xff,
3575   0x2d, 0x22, 0x16, 0xff,  0x00, 0x00, 0x00, 0xfe,  0x00, 0x00, 0x00, 0xd2,
3576   0x00, 0x00, 0x00, 0x63,  0x00, 0x00, 0x00, 0x07,  0x00, 0x00, 0x00, 0x00,
3577   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x02,
3578   0x00, 0x00, 0x00, 0x22,  0x00, 0x00, 0x00, 0x64,  0x09, 0x0a, 0x07, 0xa4,
3579   0x00, 0x00, 0x00, 0xbd,  0x00, 0x00, 0x00, 0xbe,  0x00, 0x00, 0x00, 0xc4,
3580   0x00, 0x00, 0x00, 0xb8,  0x00, 0x00, 0x00, 0x9d,  0x00, 0x00, 0x00, 0x6c,
3581   0x00, 0x00, 0x00, 0x2c,  0x00, 0x00, 0x00, 0x07,  0x00, 0x00, 0x00, 0x00,
3582   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3583   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x01,
3584   0x00, 0x00, 0x00, 0x05,  0x00, 0x00, 0x00, 0x0b,  0x00, 0x00, 0x00, 0x0d,
3585   0x00, 0x00, 0x00, 0x0b,  0x00, 0x00, 0x00, 0x08,  0x00, 0x00, 0x00, 0x06,
3586   0x00, 0x00, 0x00, 0x02,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
3587   0x00, 0x00, 0x00, 0x00
3588 };
3589
3590
3591 static void
3592 dump_accels (gpointer             callback_data,
3593              guint                callback_action,
3594              GtkWidget           *widget)
3595 {
3596   gtk_accel_map_save_fd (1 /* stdout */);
3597 }
3598     
3599 static GtkItemFactoryEntry menu_items[] =
3600 {
3601   { "/_File",                  NULL,         0,                     0, "<Branch>" },
3602   { "/File/tearoff1",          NULL,         gtk_ifactory_cb,       0, "<Tearoff>" },
3603   { "/File/_New",              NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_NEW },
3604   { "/File/_Open",             NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_OPEN },
3605   { "/File/_Save",             NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
3606   { "/File/Save _As...",       "<control>A", gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
3607   { "/File/_Dump \"_Accels\"",  NULL,        dump_accels,           0 },
3608   { "/File/\\/Test__Escaping/And\\/\n\tWei\\\\rdly",
3609                                 NULL,        gtk_ifactory_cb,       0 },
3610   { "/File/sep1",        NULL,               gtk_ifactory_cb,       0, "<Separator>" },
3611   { "/File/_Quit",       NULL,               gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_QUIT },
3612
3613   { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
3614   { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
3615   { "/_Preferences/Color/_Red",         NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
3616   { "/_Preferences/Color/_Green",       NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
3617   { "/_Preferences/Color/_Blue",        NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
3618   { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
3619   { "/_Preferences/Shape/_Square",      NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
3620   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
3621   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
3622   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
3623   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
3624   { "/_Preferences/Shape/_Image",       NULL, gtk_ifactory_cb, 0, "<ImageItem>", apple },
3625
3626   /* For testing deletion of menus */
3627   { "/_Preferences/Should_NotAppear",          NULL, 0,               0, "<Branch>" },
3628   { "/Preferences/ShouldNotAppear/SubItem1",   NULL, gtk_ifactory_cb, 0 },
3629   { "/Preferences/ShouldNotAppear/SubItem2",   NULL, gtk_ifactory_cb, 0 },
3630
3631   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
3632   { "/Help/_Help",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_HELP},
3633   { "/Help/_About",      NULL,         gtk_ifactory_cb,       0 },
3634 };
3635
3636
3637 static int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
3638
3639 static void
3640 create_item_factory (GtkWidget *widget)
3641 {
3642   static GtkWidget *window = NULL;
3643   
3644   if (!window)
3645     {
3646       GtkWidget *box1;
3647       GtkWidget *box2;
3648       GtkWidget *separator;
3649       GtkWidget *label;
3650       GtkWidget *button;
3651       GtkAccelGroup *accel_group;
3652       GtkItemFactory *item_factory;
3653       GtkTooltips *tooltips;
3654       
3655       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3656       
3657       gtk_window_set_screen (GTK_WINDOW (window),
3658                              gtk_widget_get_screen (widget));
3659       
3660       g_signal_connect (window, "destroy",
3661                         G_CALLBACK(gtk_widget_destroyed),
3662                         &window);
3663       g_signal_connect (window, "delete-event",
3664                         G_CALLBACK (gtk_true),
3665                         NULL);
3666       
3667       accel_group = gtk_accel_group_new ();
3668       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
3669       g_object_set_data_full (G_OBJECT (window),
3670                               "<main>",
3671                               item_factory,
3672                               g_object_unref);
3673       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3674       gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
3675       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3676       gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
3677
3678       /* preselect /Preferences/Shape/Oval over the other radios
3679        */
3680       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory,
3681                                                                                       "/Preferences/Shape/Oval")),
3682                                       TRUE);
3683
3684       /* Test how tooltips (ugh) work on menu items
3685        */
3686       tooltips = gtk_tooltips_new ();
3687       g_object_ref (tooltips);
3688       gtk_object_sink (GTK_OBJECT (tooltips));
3689       g_object_set_data_full (G_OBJECT (window), "testgtk-tooltips",
3690                               tooltips, (GDestroyNotify)g_object_unref);
3691       
3692       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/New"),
3693                             "Create a new file", NULL);
3694       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/Open"),
3695                             "Open a file", NULL);
3696       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/Save"),
3697                             "Safe file", NULL);
3698       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/Preferences/Color"),
3699                             "Modify color", NULL);
3700
3701       box1 = gtk_vbox_new (FALSE, 0);
3702       gtk_container_add (GTK_CONTAINER (window), box1);
3703       
3704       gtk_box_pack_start (GTK_BOX (box1),
3705                           gtk_item_factory_get_widget (item_factory, "<main>"),
3706                           FALSE, FALSE, 0);
3707
3708       label = gtk_label_new ("Type\n<alt>\nto start");
3709       gtk_widget_set_size_request (label, 200, 200);
3710       gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
3711       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
3712
3713
3714       separator = gtk_hseparator_new ();
3715       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3716
3717
3718       box2 = gtk_vbox_new (FALSE, 10);
3719       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3720       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3721
3722       button = gtk_button_new_with_label ("close");
3723       g_signal_connect_swapped (button, "clicked",
3724                                 G_CALLBACK (gtk_widget_destroy),
3725                                 window);
3726       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3727       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3728       gtk_widget_grab_default (button);
3729
3730       gtk_item_factory_delete_item (item_factory, "/Preferences/ShouldNotAppear");
3731       
3732       gtk_widget_show_all (window);
3733     }
3734   else
3735     gtk_widget_destroy (window);
3736 }
3737
3738 static GtkWidget *
3739 accel_button_new (GtkAccelGroup *accel_group,
3740                   const gchar   *text,
3741                   const gchar   *accel)
3742 {
3743   guint keyval;
3744   GdkModifierType modifiers;
3745   GtkWidget *button;
3746   GtkWidget *label;
3747
3748   gtk_accelerator_parse (accel, &keyval, &modifiers);
3749   g_assert (keyval);
3750
3751   button = gtk_button_new ();
3752   gtk_widget_add_accelerator (button, "activate", accel_group,
3753                               keyval, modifiers, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3754
3755   label = gtk_accel_label_new (text);
3756   gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), button);
3757   gtk_widget_show (label);
3758   
3759   gtk_container_add (GTK_CONTAINER (button), label);
3760
3761   return button;
3762 }
3763
3764 static void
3765 create_key_lookup (GtkWidget *widget)
3766 {
3767   static GtkWidget *window = NULL;
3768
3769   if (!window)
3770     {
3771       GtkAccelGroup *accel_group = gtk_accel_group_new ();
3772       GtkWidget *button;
3773       
3774       window = gtk_dialog_new_with_buttons ("Key Lookup", NULL, 0,
3775                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
3776                                             NULL);
3777
3778       gtk_window_set_screen (GTK_WINDOW (window),
3779                              gtk_widget_get_screen (widget));
3780
3781       /* We have to expand it so the accel labels will draw their labels
3782        */
3783       gtk_window_set_default_size (GTK_WINDOW (window), 300, -1);
3784       
3785       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3786       
3787       button = gtk_button_new_with_mnemonic ("Button 1 (_a)");
3788       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3789       button = gtk_button_new_with_mnemonic ("Button 2 (_A)");
3790       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3791       button = gtk_button_new_with_mnemonic ("Button 3 (_ф)");
3792       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3793       button = gtk_button_new_with_mnemonic ("Button 4 (_Ф)");
3794       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3795       button = gtk_button_new_with_mnemonic ("Button 6 (_b)");
3796       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3797       button = accel_button_new (accel_group, "Button 7", "<Alt><Shift>b");
3798       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3799       button = accel_button_new (accel_group, "Button 8", "<Alt>d");
3800       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3801       button = accel_button_new (accel_group, "Button 9", "<Alt>Cyrillic_ve");
3802       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3803       button = gtk_button_new_with_mnemonic ("Button 10 (_1)");
3804       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3805       button = gtk_button_new_with_mnemonic ("Button 11 (_!)");
3806       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3807       
3808       g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
3809       g_signal_connect (window, "response", G_CALLBACK (gtk_object_destroy), NULL);
3810
3811       gtk_widget_show_all (window);
3812     }
3813   else
3814     gtk_widget_destroy (window);
3815 }
3816
3817
3818 /*
3819  create_modal_window
3820  */
3821
3822 static gboolean
3823 cmw_destroy_cb(GtkWidget *widget)
3824 {
3825   /* This is needed to get out of gtk_main */
3826   gtk_main_quit ();
3827
3828   return FALSE;
3829 }
3830
3831 static void
3832 cmw_color (GtkWidget *widget, GtkWidget *parent)
3833 {
3834     GtkWidget *csd;
3835
3836     csd = gtk_color_selection_dialog_new ("This is a modal color selection dialog");
3837
3838     gtk_window_set_screen (GTK_WINDOW (csd), gtk_widget_get_screen (parent));
3839
3840     gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (csd)->colorsel),
3841                                          TRUE);
3842     
3843     /* Set as modal */
3844     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
3845
3846     /* And mark it as a transient dialog */
3847     gtk_window_set_transient_for (GTK_WINDOW (csd), GTK_WINDOW (parent));
3848     
3849     g_signal_connect (csd, "destroy",
3850                       G_CALLBACK (cmw_destroy_cb), NULL);
3851
3852     g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (csd)->ok_button,
3853                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
3854     g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (csd)->cancel_button,
3855                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
3856     
3857     /* wait until destroy calls gtk_main_quit */
3858     gtk_widget_show (csd);    
3859     gtk_main ();
3860 }
3861
3862 static void
3863 cmw_file (GtkWidget *widget, GtkWidget *parent)
3864 {
3865     GtkWidget *fs;
3866
3867     fs = gtk_file_selection_new("This is a modal file selection dialog");
3868
3869     gtk_window_set_screen (GTK_WINDOW (fs), gtk_widget_get_screen (parent));
3870
3871     /* Set as modal */
3872     gtk_window_set_modal (GTK_WINDOW(fs),TRUE);
3873
3874     /* And mark it as a transient dialog */
3875     gtk_window_set_transient_for (GTK_WINDOW (fs), GTK_WINDOW (parent));
3876
3877     g_signal_connect (fs, "destroy",
3878                       G_CALLBACK (cmw_destroy_cb), NULL);
3879
3880     g_signal_connect_swapped (GTK_FILE_SELECTION (fs)->ok_button,
3881                               "clicked", G_CALLBACK (gtk_widget_destroy), fs);
3882     g_signal_connect_swapped (GTK_FILE_SELECTION (fs)->cancel_button,
3883                               "clicked", G_CALLBACK (gtk_widget_destroy), fs);
3884     
3885     /* wait until destroy calls gtk_main_quit */
3886     gtk_widget_show (fs);
3887     
3888     gtk_main();
3889 }
3890
3891
3892 static void
3893 create_modal_window (GtkWidget *widget)
3894 {
3895   GtkWidget *window = NULL;
3896   GtkWidget *box1,*box2;
3897   GtkWidget *frame1;
3898   GtkWidget *btnColor,*btnFile,*btnClose;
3899
3900   /* Create modal window (Here you can use any window descendent )*/
3901   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3902   gtk_window_set_screen (GTK_WINDOW (window),
3903                          gtk_widget_get_screen (widget));
3904
3905   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
3906
3907   /* Set window as modal */
3908   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
3909
3910   /* Create widgets */
3911   box1 = gtk_vbox_new (FALSE,5);
3912   frame1 = gtk_frame_new ("Standard dialogs in modal form");
3913   box2 = gtk_vbox_new (TRUE,5);
3914   btnColor = gtk_button_new_with_label ("Color");
3915   btnFile = gtk_button_new_with_label ("File Selection");
3916   btnClose = gtk_button_new_with_label ("Close");
3917
3918   /* Init widgets */
3919   gtk_container_set_border_width (GTK_CONTAINER (box1), 3);
3920   gtk_container_set_border_width (GTK_CONTAINER (box2), 3);
3921     
3922   /* Pack widgets */
3923   gtk_container_add (GTK_CONTAINER (window), box1);
3924   gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
3925   gtk_container_add (GTK_CONTAINER (frame1), box2);
3926   gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
3927   gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
3928   gtk_box_pack_start (GTK_BOX (box1), gtk_hseparator_new (), FALSE, FALSE, 4);
3929   gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
3930    
3931   /* connect signals */
3932   g_signal_connect_swapped (btnClose, "clicked",
3933                             G_CALLBACK (gtk_widget_destroy), window);
3934
3935   g_signal_connect (window, "destroy",
3936                     G_CALLBACK (cmw_destroy_cb), NULL);
3937   
3938   g_signal_connect (btnColor, "clicked",
3939                     G_CALLBACK (cmw_color), window);
3940   g_signal_connect (btnFile, "clicked",
3941                     G_CALLBACK (cmw_file), window);
3942
3943   /* Show widgets */
3944   gtk_widget_show_all (window);
3945
3946   /* wait until dialog get destroyed */
3947   gtk_main();
3948 }
3949
3950 /*
3951  * GtkMessageDialog
3952  */
3953
3954 static void
3955 make_message_dialog (GdkScreen *screen,
3956                      GtkWidget **dialog,
3957                      GtkMessageType  type,
3958                      GtkButtonsType  buttons,
3959                      guint           default_response)
3960 {
3961   if (*dialog)
3962     {
3963       gtk_widget_destroy (*dialog);
3964
3965       return;
3966     }
3967
3968   *dialog = gtk_message_dialog_new (NULL, 0, type, buttons,
3969                                     "This is a message dialog; it can wrap long lines. This is a long line. La la la. Look this line is wrapped. Blah blah blah blah blah blah. (Note: testgtk has a nonstandard gtkrc that changes some of the message dialog icons.)");
3970
3971   gtk_window_set_screen (GTK_WINDOW (*dialog), screen);
3972
3973   g_signal_connect_swapped (*dialog,
3974                             "response",
3975                             G_CALLBACK (gtk_widget_destroy),
3976                             *dialog);
3977   
3978   g_signal_connect (*dialog,
3979                     "destroy",
3980                     G_CALLBACK (gtk_widget_destroyed),
3981                     dialog);
3982
3983   gtk_dialog_set_default_response (GTK_DIALOG (*dialog), default_response);
3984
3985   gtk_widget_show (*dialog);
3986 }
3987
3988 static void
3989 create_message_dialog (GtkWidget *widget)
3990 {
3991   static GtkWidget *info = NULL;
3992   static GtkWidget *warning = NULL;
3993   static GtkWidget *error = NULL;
3994   static GtkWidget *question = NULL;
3995   GdkScreen *screen = gtk_widget_get_screen (widget);
3996
3997   make_message_dialog (screen, &info, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, GTK_RESPONSE_OK);
3998   make_message_dialog (screen, &warning, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_OK);
3999   make_message_dialog (screen, &error, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK);
4000   make_message_dialog (screen, &question, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, GTK_RESPONSE_YES);
4001 }
4002
4003 /*
4004  * GtkScrolledWindow
4005  */
4006
4007 static GtkWidget *sw_parent = NULL;
4008 static GtkWidget *sw_float_parent;
4009 static guint sw_destroyed_handler = 0;
4010
4011 static gboolean
4012 scrolled_windows_delete_cb (GtkWidget *widget, GdkEventAny *event, GtkWidget *scrollwin)
4013 {
4014   gtk_widget_reparent (scrollwin, sw_parent);
4015   
4016   g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
4017   sw_float_parent = NULL;
4018   sw_parent = NULL;
4019   sw_destroyed_handler = 0;
4020
4021   return FALSE;
4022 }
4023
4024 static void
4025 scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
4026 {
4027   gtk_widget_destroy (sw_float_parent);
4028
4029   sw_float_parent = NULL;
4030   sw_parent = NULL;
4031   sw_destroyed_handler = 0;
4032 }
4033
4034 static void
4035 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
4036 {
4037   if (sw_parent)
4038     {
4039       gtk_widget_reparent (scrollwin, sw_parent);
4040       gtk_widget_destroy (sw_float_parent);
4041
4042       g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
4043       sw_float_parent = NULL;
4044       sw_parent = NULL;
4045       sw_destroyed_handler = 0;
4046     }
4047   else
4048     {
4049       sw_parent = scrollwin->parent;
4050       sw_float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4051       gtk_window_set_screen (GTK_WINDOW (sw_float_parent),
4052                              gtk_widget_get_screen (widget));
4053       
4054       gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), 200, 200);
4055       
4056       gtk_widget_reparent (scrollwin, sw_float_parent);
4057       gtk_widget_show (sw_float_parent);
4058
4059       sw_destroyed_handler =
4060         g_signal_connect (sw_parent, "destroy",
4061                           G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
4062       g_signal_connect (sw_float_parent, "delete_event",
4063                         G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
4064     }
4065 }
4066
4067 static void
4068 create_scrolled_windows (GtkWidget *widget)
4069 {
4070   static GtkWidget *window;
4071   GtkWidget *scrolled_window;
4072   GtkWidget *table;
4073   GtkWidget *button;
4074   char buffer[32];
4075   int i, j;
4076
4077   if (!window)
4078     {
4079       window = gtk_dialog_new ();
4080
4081       gtk_window_set_screen (GTK_WINDOW (window),
4082                              gtk_widget_get_screen (widget));
4083
4084       g_signal_connect (window, "destroy",
4085                         G_CALLBACK (gtk_widget_destroyed),
4086                         &window);
4087
4088       gtk_window_set_title (GTK_WINDOW (window), "dialog");
4089       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4090
4091
4092       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
4093       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
4094       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
4095                                       GTK_POLICY_AUTOMATIC,
4096                                       GTK_POLICY_AUTOMATIC);
4097       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
4098                           scrolled_window, TRUE, TRUE, 0);
4099       gtk_widget_show (scrolled_window);
4100
4101       table = gtk_table_new (20, 20, FALSE);
4102       gtk_table_set_row_spacings (GTK_TABLE (table), 10);
4103       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
4104       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
4105       gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
4106                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
4107       gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
4108                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
4109       gtk_widget_show (table);
4110
4111       for (i = 0; i < 20; i++)
4112         for (j = 0; j < 20; j++)
4113           {
4114             sprintf (buffer, "button (%d,%d)\n", i, j);
4115             button = gtk_toggle_button_new_with_label (buffer);
4116             gtk_table_attach_defaults (GTK_TABLE (table), button,
4117                                        i, i+1, j, j+1);
4118             gtk_widget_show (button);
4119           }
4120
4121
4122       button = gtk_button_new_with_label ("Close");
4123       g_signal_connect_swapped (button, "clicked",
4124                                 G_CALLBACK (gtk_widget_destroy),
4125                                 window);
4126       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4127       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
4128                           button, TRUE, TRUE, 0);
4129       gtk_widget_grab_default (button);
4130       gtk_widget_show (button);
4131
4132       button = gtk_button_new_with_label ("Reparent Out");
4133       g_signal_connect (button, "clicked",
4134                         G_CALLBACK (scrolled_windows_remove),
4135                         scrolled_window);
4136       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4137       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
4138                           button, TRUE, TRUE, 0);
4139       gtk_widget_grab_default (button);
4140       gtk_widget_show (button);
4141
4142       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
4143     }
4144
4145   if (!GTK_WIDGET_VISIBLE (window))
4146     gtk_widget_show (window);
4147   else
4148     gtk_widget_destroy (window);
4149 }
4150
4151 /*
4152  * GtkEntry
4153  */
4154
4155 static void
4156 entry_toggle_frame (GtkWidget *checkbutton,
4157                     GtkWidget *entry)
4158 {
4159    gtk_entry_set_has_frame (GTK_ENTRY(entry),
4160                             GTK_TOGGLE_BUTTON(checkbutton)->active);
4161 }
4162
4163 static void
4164 entry_toggle_sensitive (GtkWidget *checkbutton,
4165                         GtkWidget *entry)
4166 {
4167    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
4168 }
4169
4170 static void
4171 entry_props_clicked (GtkWidget *button,
4172                      GObject   *entry)
4173 {
4174   GtkWidget *window = create_prop_editor (entry, 0);
4175
4176   gtk_window_set_title (GTK_WINDOW (window), "Entry Properties");
4177 }
4178
4179 static void
4180 create_entry (GtkWidget *widget)
4181 {
4182   static GtkWidget *window = NULL;
4183   GtkWidget *box1;
4184   GtkWidget *box2;
4185   GtkWidget *hbox;
4186   GtkWidget *has_frame_check;
4187   GtkWidget *sensitive_check;
4188   GtkWidget *entry, *cb;
4189   GtkWidget *button;
4190   GtkWidget *separator;
4191   GList *cbitems = NULL;
4192
4193   if (!window)
4194     {
4195       cbitems = g_list_append(cbitems, "item0");
4196       cbitems = g_list_append(cbitems, "item1 item1");
4197       cbitems = g_list_append(cbitems, "item2 item2 item2");
4198       cbitems = g_list_append(cbitems, "item3 item3 item3 item3");
4199       cbitems = g_list_append(cbitems, "item4 item4 item4 item4 item4");
4200       cbitems = g_list_append(cbitems, "item5 item5 item5 item5 item5 item5");
4201       cbitems = g_list_append(cbitems, "item6 item6 item6 item6 item6");
4202       cbitems = g_list_append(cbitems, "item7 item7 item7 item7");
4203       cbitems = g_list_append(cbitems, "item8 item8 item8");
4204       cbitems = g_list_append(cbitems, "item9 item9");
4205
4206       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4207       gtk_window_set_screen (GTK_WINDOW (window),
4208                              gtk_widget_get_screen (widget));
4209
4210       g_signal_connect (window, "destroy",
4211                         G_CALLBACK (gtk_widget_destroyed),
4212                         &window);
4213
4214       gtk_window_set_title (GTK_WINDOW (window), "entry");
4215       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4216
4217
4218       box1 = gtk_vbox_new (FALSE, 0);
4219       gtk_container_add (GTK_CONTAINER (window), box1);
4220
4221
4222       box2 = gtk_vbox_new (FALSE, 10);
4223       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4224       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4225
4226       hbox = gtk_hbox_new (FALSE, 5);
4227       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
4228       
4229       entry = gtk_entry_new ();
4230       gtk_entry_set_text (GTK_ENTRY (entry), "hello world السلام عليكم");
4231       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
4232       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
4233
4234       button = gtk_button_new_with_mnemonic ("_Props");
4235       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4236       g_signal_connect (button, "clicked",
4237                         G_CALLBACK (entry_props_clicked),
4238                         entry);
4239
4240       cb = gtk_combo_new ();
4241       gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
4242       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO(cb)->entry), "hello world \n\n\n foo");
4243       gtk_editable_select_region (GTK_EDITABLE (GTK_COMBO(cb)->entry),
4244                                   0, -1);
4245       gtk_box_pack_start (GTK_BOX (box2), cb, TRUE, TRUE, 0);
4246
4247       sensitive_check = gtk_check_button_new_with_label("Sensitive");
4248       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
4249       g_signal_connect (sensitive_check, "toggled",
4250                         G_CALLBACK (entry_toggle_sensitive), entry);
4251       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
4252
4253       has_frame_check = gtk_check_button_new_with_label("Has Frame");
4254       gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
4255       g_signal_connect (has_frame_check, "toggled",
4256                         G_CALLBACK (entry_toggle_frame), entry);
4257       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
4258       
4259       separator = gtk_hseparator_new ();
4260       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4261
4262       box2 = gtk_vbox_new (FALSE, 10);
4263       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4264       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4265
4266       button = gtk_button_new_with_label ("close");
4267       g_signal_connect_swapped (button, "clicked",
4268                                 G_CALLBACK (gtk_widget_destroy),
4269                                 window);
4270       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4271       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4272       gtk_widget_grab_default (button);
4273     }
4274
4275   if (!GTK_WIDGET_VISIBLE (window))
4276     gtk_widget_show_all (window);
4277   else
4278     gtk_widget_destroy (window);
4279 }
4280
4281 /*
4282  * GtkSizeGroup
4283  */
4284
4285 #define SIZE_GROUP_INITIAL_SIZE 50
4286
4287 static void
4288 size_group_hsize_changed (GtkSpinButton *spin_button,
4289                           GtkWidget     *button)
4290 {
4291   gtk_widget_set_size_request (GTK_BIN (button)->child,
4292                                gtk_spin_button_get_value_as_int (spin_button),
4293                                -1);
4294 }
4295
4296 static void
4297 size_group_vsize_changed (GtkSpinButton *spin_button,
4298                           GtkWidget     *button)
4299 {
4300   gtk_widget_set_size_request (GTK_BIN (button)->child,
4301                                -1,
4302                                gtk_spin_button_get_value_as_int (spin_button));
4303 }
4304
4305 static GtkWidget *
4306 create_size_group_window (GdkScreen    *screen,
4307                           GtkSizeGroup *master_size_group)
4308 {
4309   GtkWidget *window;
4310   GtkWidget *table;
4311   GtkWidget *main_button;
4312   GtkWidget *button;
4313   GtkWidget *spin_button;
4314   GtkWidget *hbox;
4315   GtkSizeGroup *hgroup1;
4316   GtkSizeGroup *hgroup2;
4317   GtkSizeGroup *vgroup1;
4318   GtkSizeGroup *vgroup2;
4319
4320   window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
4321                                         NULL, 0,
4322                                         GTK_STOCK_CLOSE,
4323                                         GTK_RESPONSE_NONE,
4324                                         NULL);
4325
4326   gtk_window_set_screen (GTK_WINDOW (window), screen);
4327
4328   gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
4329
4330   g_signal_connect (window, "response",
4331                     G_CALLBACK (gtk_widget_destroy),
4332                     NULL);
4333
4334   table = gtk_table_new (2, 2, FALSE);
4335   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), table, TRUE, TRUE, 0);
4336
4337   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
4338   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
4339   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
4340   gtk_widget_set_size_request (table, 250, 250);
4341
4342   hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4343   hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4344   vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4345   vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4346
4347   main_button = gtk_button_new_with_label ("X");
4348   
4349   gtk_table_attach (GTK_TABLE (table), main_button,
4350                     0, 1,       0, 1,
4351                     GTK_EXPAND, GTK_EXPAND,
4352                     0,          0);
4353   gtk_size_group_add_widget (master_size_group, main_button);
4354   gtk_size_group_add_widget (hgroup1, main_button);
4355   gtk_size_group_add_widget (vgroup1, main_button);
4356   gtk_widget_set_size_request (GTK_BIN (main_button)->child,
4357                                SIZE_GROUP_INITIAL_SIZE,
4358                                SIZE_GROUP_INITIAL_SIZE);
4359
4360   button = gtk_button_new ();
4361   gtk_table_attach (GTK_TABLE (table), button,
4362                     1, 2,       0, 1,
4363                     GTK_EXPAND, GTK_EXPAND,
4364                     0,          0);
4365   gtk_size_group_add_widget (vgroup1, button);
4366   gtk_size_group_add_widget (vgroup2, button);
4367
4368   button = gtk_button_new ();
4369   gtk_table_attach (GTK_TABLE (table), button,
4370                     0, 1,       1, 2,
4371                     GTK_EXPAND, GTK_EXPAND,
4372                     0,          0);
4373   gtk_size_group_add_widget (hgroup1, button);
4374   gtk_size_group_add_widget (hgroup2, button);
4375
4376   button = gtk_button_new ();
4377   gtk_table_attach (GTK_TABLE (table), button,
4378                     1, 2,       1, 2,
4379                     GTK_EXPAND, GTK_EXPAND,
4380                     0,          0);
4381   gtk_size_group_add_widget (hgroup2, button);
4382   gtk_size_group_add_widget (vgroup2, button);
4383
4384   g_object_unref (hgroup1);
4385   g_object_unref (hgroup2);
4386   g_object_unref (vgroup1);
4387   g_object_unref (vgroup2);
4388   
4389   hbox = gtk_hbox_new (FALSE, 5);
4390   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox, FALSE, FALSE, 0);
4391   
4392   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4393   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4394   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4395   g_signal_connect (spin_button, "value_changed",
4396                     G_CALLBACK (size_group_hsize_changed), main_button);
4397
4398   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4399   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4400   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4401   g_signal_connect (spin_button, "value_changed",
4402                     G_CALLBACK (size_group_vsize_changed), main_button);
4403
4404   return window;
4405 }
4406
4407 static void
4408 create_size_groups (GtkWidget *widget)
4409 {
4410   static GtkWidget *window1 = NULL;
4411   static GtkWidget *window2 = NULL;
4412   static GtkSizeGroup *master_size_group;
4413
4414   if (!master_size_group)
4415     master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
4416
4417   if (!window1)
4418     {
4419       window1 = create_size_group_window (gtk_widget_get_screen (widget),
4420                                           master_size_group);
4421
4422       g_signal_connect (window1, "destroy",
4423                         G_CALLBACK (gtk_widget_destroyed),
4424                         &window1);
4425     }
4426
4427   if (!window2)
4428     {
4429       window2 = create_size_group_window (gtk_widget_get_screen (widget),
4430                                           master_size_group);
4431
4432       g_signal_connect (window2, "destroy",
4433                         G_CALLBACK (gtk_widget_destroyed),
4434                         &window2);
4435     }
4436
4437   if (GTK_WIDGET_VISIBLE (window1) && GTK_WIDGET_VISIBLE (window2))
4438     {
4439       gtk_widget_destroy (window1);
4440       gtk_widget_destroy (window2);
4441     }
4442   else
4443     {
4444       if (!GTK_WIDGET_VISIBLE (window1))
4445         gtk_widget_show_all (window1);
4446       if (!GTK_WIDGET_VISIBLE (window2))
4447         gtk_widget_show_all (window2);
4448     }
4449 }
4450
4451 /*
4452  * GtkSpinButton
4453  */
4454
4455 static GtkWidget *spinner1;
4456
4457 static void
4458 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
4459 {
4460   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
4461 }
4462
4463 static void
4464 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
4465 {
4466   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
4467 }
4468
4469 static void
4470 change_digits (GtkWidget *widget, GtkSpinButton *spin)
4471 {
4472   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
4473                               gtk_spin_button_get_value_as_int (spin));
4474 }
4475
4476 static void
4477 get_value (GtkWidget *widget, gpointer data)
4478 {
4479   gchar buf[32];
4480   GtkLabel *label;
4481   GtkSpinButton *spin;
4482
4483   spin = GTK_SPIN_BUTTON (spinner1);
4484   label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
4485   if (GPOINTER_TO_INT (data) == 1)
4486     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
4487   else
4488     sprintf (buf, "%0.*f", spin->digits, gtk_spin_button_get_value (spin));
4489   gtk_label_set_text (label, buf);
4490 }
4491
4492 static void
4493 get_spin_value (GtkWidget *widget, gpointer data)
4494 {
4495   gchar *buffer;
4496   GtkLabel *label;
4497   GtkSpinButton *spin;
4498
4499   spin = GTK_SPIN_BUTTON (widget);
4500   label = GTK_LABEL (data);
4501
4502   buffer = g_strdup_printf ("%0.*f", spin->digits,
4503                             gtk_spin_button_get_value (spin));
4504   gtk_label_set_text (label, buffer);
4505
4506   g_free (buffer);
4507 }
4508
4509 static gint
4510 spin_button_time_output_func (GtkSpinButton *spin_button)
4511 {
4512   static gchar buf[6];
4513   gdouble hours;
4514   gdouble minutes;
4515
4516   hours = spin_button->adjustment->value / 60.0;
4517   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
4518   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
4519   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4520     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4521   return TRUE;
4522 }
4523
4524 static gint
4525 spin_button_month_input_func (GtkSpinButton *spin_button,
4526                               gdouble       *new_val)
4527 {
4528   gint i;
4529   static gchar *month[12] = { "January", "February", "March", "April",
4530                               "May", "June", "July", "August",
4531                               "September", "October", "November", "December" };
4532   gchar *tmp1, *tmp2;
4533   gboolean found = FALSE;
4534
4535   for (i = 1; i <= 12; i++)
4536     {
4537       tmp1 = g_ascii_strup (month[i - 1], -1);
4538       tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
4539       if (strstr (tmp1, tmp2) == tmp1)
4540         found = TRUE;
4541       g_free (tmp1);
4542       g_free (tmp2);
4543       if (found)
4544         break;
4545     }
4546   if (!found)
4547     {
4548       *new_val = 0.0;
4549       return GTK_INPUT_ERROR;
4550     }
4551   *new_val = (gdouble) i;
4552   return TRUE;
4553 }
4554
4555 static gint
4556 spin_button_month_output_func (GtkSpinButton *spin_button)
4557 {
4558   gint i;
4559   static gchar *month[12] = { "January", "February", "March", "April",
4560                               "May", "June", "July", "August", "September",
4561                               "October", "November", "December" };
4562
4563   for (i = 1; i <= 12; i++)
4564     if (fabs (spin_button->adjustment->value - (double)i) < 1e-5)
4565       {
4566         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
4567           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
4568       }
4569   return TRUE;
4570 }
4571
4572 static gint
4573 spin_button_hex_input_func (GtkSpinButton *spin_button,
4574                             gdouble       *new_val)
4575 {
4576   const gchar *buf;
4577   gchar *err;
4578   gdouble res;
4579
4580   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
4581   res = strtol(buf, &err, 16);
4582   *new_val = res;
4583   if (*err)
4584     return GTK_INPUT_ERROR;
4585   else
4586     return TRUE;
4587 }
4588
4589 static gint
4590 spin_button_hex_output_func (GtkSpinButton *spin_button)
4591 {
4592   static gchar buf[7];
4593   gint val;
4594
4595   val = (gint) spin_button->adjustment->value;
4596   if (fabs (val) < 1e-5)
4597     sprintf (buf, "0x00");
4598   else
4599     sprintf (buf, "0x%.2X", val);
4600   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4601     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4602   return TRUE;
4603 }
4604
4605 static void
4606 create_spins (GtkWidget *widget)
4607 {
4608   static GtkWidget *window = NULL;
4609   GtkWidget *frame;
4610   GtkWidget *hbox;
4611   GtkWidget *main_vbox;
4612   GtkWidget *vbox;
4613   GtkWidget *vbox2;
4614   GtkWidget *spinner2;
4615   GtkWidget *spinner;
4616   GtkWidget *button;
4617   GtkWidget *label;
4618   GtkWidget *val_label;
4619   GtkAdjustment *adj;
4620
4621   if (!window)
4622     {
4623       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4624       gtk_window_set_screen (GTK_WINDOW (window),
4625                              gtk_widget_get_screen (widget));
4626       
4627       g_signal_connect (window, "destroy",
4628                         G_CALLBACK (gtk_widget_destroyed),
4629                         &window);
4630       
4631       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
4632       
4633       main_vbox = gtk_vbox_new (FALSE, 5);
4634       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
4635       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4636       
4637       frame = gtk_frame_new ("Not accelerated");
4638       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4639       
4640       vbox = gtk_vbox_new (FALSE, 0);
4641       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4642       gtk_container_add (GTK_CONTAINER (frame), vbox);
4643       
4644       /* Time, month, hex spinners */
4645       
4646       hbox = gtk_hbox_new (FALSE, 0);
4647       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
4648       
4649       vbox2 = gtk_vbox_new (FALSE, 0);
4650       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4651       
4652       label = gtk_label_new ("Time :");
4653       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4654       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4655       
4656       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
4657       spinner = gtk_spin_button_new (adj, 0, 0);
4658       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
4659       g_signal_connect (spinner,
4660                         "output",
4661                         G_CALLBACK (spin_button_time_output_func),
4662                         NULL);
4663       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4664       gtk_widget_set_size_request (spinner, 55, -1);
4665       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4666
4667       vbox2 = gtk_vbox_new (FALSE, 0);
4668       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4669       
4670       label = gtk_label_new ("Month :");
4671       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4672       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4673       
4674       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
4675                                                   5.0, 0.0);
4676       spinner = gtk_spin_button_new (adj, 0, 0);
4677       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
4678                                          GTK_UPDATE_IF_VALID);
4679       g_signal_connect (spinner,
4680                         "input",
4681                         G_CALLBACK (spin_button_month_input_func),
4682                         NULL);
4683       g_signal_connect (spinner,
4684                         "output",
4685                         G_CALLBACK (spin_button_month_output_func),
4686                         NULL);
4687       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4688       gtk_widget_set_size_request (spinner, 85, -1);
4689       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4690       
4691       vbox2 = gtk_vbox_new (FALSE, 0);
4692       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4693
4694       label = gtk_label_new ("Hex :");
4695       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4696       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4697
4698       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 255, 1, 16, 0);
4699       spinner = gtk_spin_button_new (adj, 0, 0);
4700       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
4701       g_signal_connect (spinner,
4702                         "input",
4703                         G_CALLBACK (spin_button_hex_input_func),
4704                         NULL);
4705       g_signal_connect (spinner,
4706                         "output",
4707                         G_CALLBACK (spin_button_hex_output_func),
4708                         NULL);
4709       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4710       gtk_widget_set_size_request (spinner, 55, -1);
4711       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4712
4713       frame = gtk_frame_new ("Accelerated");
4714       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4715   
4716       vbox = gtk_vbox_new (FALSE, 0);
4717       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4718       gtk_container_add (GTK_CONTAINER (frame), vbox);
4719       
4720       hbox = gtk_hbox_new (FALSE, 0);
4721       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4722       
4723       vbox2 = gtk_vbox_new (FALSE, 0);
4724       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4725       
4726       label = gtk_label_new ("Value :");
4727       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4728       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4729
4730       adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,
4731                                                   0.5, 100.0, 0.0);
4732       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
4733       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
4734       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
4735
4736       vbox2 = gtk_vbox_new (FALSE, 0);
4737       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4738
4739       label = gtk_label_new ("Digits :");
4740       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4741       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4742
4743       adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 15, 1, 1, 0);
4744       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
4745       g_signal_connect (adj, "value_changed",
4746                         G_CALLBACK (change_digits),
4747                         spinner2);
4748       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
4749
4750       hbox = gtk_hbox_new (FALSE, 0);
4751       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4752
4753       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
4754       g_signal_connect (button, "clicked",
4755                         G_CALLBACK (toggle_snap),
4756                         spinner1);
4757       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4758       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4759
4760       button = gtk_check_button_new_with_label ("Numeric only input mode");
4761       g_signal_connect (button, "clicked",
4762                         G_CALLBACK (toggle_numeric),
4763                         spinner1);
4764       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4765       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4766
4767       val_label = gtk_label_new ("");
4768
4769       hbox = gtk_hbox_new (FALSE, 0);
4770       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4771
4772       button = gtk_button_new_with_label ("Value as Int");
4773       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4774       g_signal_connect (button, "clicked",
4775                         G_CALLBACK (get_value),
4776                         GINT_TO_POINTER (1));
4777       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4778
4779       button = gtk_button_new_with_label ("Value as Float");
4780       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4781       g_signal_connect (button, "clicked",
4782                         G_CALLBACK (get_value),
4783                         GINT_TO_POINTER (2));
4784       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4785
4786       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
4787       gtk_label_set_text (GTK_LABEL (val_label), "0");
4788
4789       frame = gtk_frame_new ("Using Convenience Constructor");
4790       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4791   
4792       hbox = gtk_hbox_new (FALSE, 0);
4793       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4794       gtk_container_add (GTK_CONTAINER (frame), hbox);
4795       
4796       val_label = gtk_label_new ("0.0");
4797
4798       spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
4799       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
4800       g_signal_connect (spinner, "value_changed",
4801                         G_CALLBACK (get_spin_value), val_label);
4802       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
4803       gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
4804
4805       hbox = gtk_hbox_new (FALSE, 0);
4806       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4807   
4808       button = gtk_button_new_with_label ("Close");
4809       g_signal_connect_swapped (button, "clicked",
4810                                 G_CALLBACK (gtk_widget_destroy),
4811                                 window);
4812       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4813     }
4814
4815   if (!GTK_WIDGET_VISIBLE (window))
4816     gtk_widget_show_all (window);
4817   else
4818     gtk_widget_destroy (window);
4819 }
4820
4821
4822 /*
4823  * Cursors
4824  */
4825
4826 static gint
4827 cursor_expose_event (GtkWidget *widget,
4828                      GdkEvent  *event,
4829                      gpointer   user_data)
4830 {
4831   GtkDrawingArea *darea;
4832   GdkDrawable *drawable;
4833   GdkGC *black_gc;
4834   GdkGC *gray_gc;
4835   GdkGC *white_gc;
4836   guint max_width;
4837   guint max_height;
4838
4839   g_return_val_if_fail (widget != NULL, TRUE);
4840   g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE);
4841
4842   darea = GTK_DRAWING_AREA (widget);
4843   drawable = widget->window;
4844   white_gc = widget->style->white_gc;
4845   gray_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
4846   black_gc = widget->style->black_gc;
4847   max_width = widget->allocation.width;
4848   max_height = widget->allocation.height;
4849
4850   gdk_draw_rectangle (drawable, white_gc,
4851                       TRUE,
4852                       0,
4853                       0,
4854                       max_width,
4855                       max_height / 2);
4856
4857   gdk_draw_rectangle (drawable, black_gc,
4858                       TRUE,
4859                       0,
4860                       max_height / 2,
4861                       max_width,
4862                       max_height / 2);
4863
4864   gdk_draw_rectangle (drawable, gray_gc,
4865                       TRUE,
4866                       max_width / 3,
4867                       max_height / 3,
4868                       max_width / 3,
4869                       max_height / 3);
4870
4871   return TRUE;
4872 }
4873
4874 static void
4875 set_cursor (GtkWidget *spinner,
4876             GtkWidget *widget)
4877 {
4878   guint c;
4879   GdkCursor *cursor;
4880   GtkWidget *label;
4881   GEnumClass *class;
4882   GEnumValue *vals;
4883
4884   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
4885   c &= 0xfe;
4886
4887   label = g_object_get_data (G_OBJECT (spinner), "user_data");
4888   
4889   class = gtk_type_class (GDK_TYPE_CURSOR_TYPE);
4890   vals = class->values;
4891
4892   while (vals && vals->value != c)
4893     vals++;
4894   if (vals)
4895     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
4896   else
4897     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
4898
4899   cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), c);
4900   gdk_window_set_cursor (widget->window, cursor);
4901   gdk_cursor_unref (cursor);
4902 }
4903
4904 static gint
4905 cursor_event (GtkWidget          *widget,
4906               GdkEvent           *event,
4907               GtkSpinButton      *spinner)
4908 {
4909   if ((event->type == GDK_BUTTON_PRESS) &&
4910       ((event->button.button == 1) ||
4911        (event->button.button == 3)))
4912     {
4913       gtk_spin_button_spin (spinner, event->button.button == 1 ?
4914                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
4915       return TRUE;
4916     }
4917
4918   return FALSE;
4919 }
4920
4921 static void
4922 create_cursors (GtkWidget *widget)
4923 {
4924   static GtkWidget *window = NULL;
4925   GtkWidget *frame;
4926   GtkWidget *hbox;
4927   GtkWidget *main_vbox;
4928   GtkWidget *vbox;
4929   GtkWidget *darea;
4930   GtkWidget *spinner;
4931   GtkWidget *button;
4932   GtkWidget *label;
4933   GtkWidget *any;
4934   GtkAdjustment *adj;
4935
4936   if (!window)
4937     {
4938       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4939       gtk_window_set_screen (GTK_WINDOW (window), 
4940                              gtk_widget_get_screen (widget));
4941       
4942       g_signal_connect (window, "destroy",
4943                         G_CALLBACK (gtk_widget_destroyed),
4944                         &window);
4945       
4946       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
4947       
4948       main_vbox = gtk_vbox_new (FALSE, 5);
4949       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
4950       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4951
4952       vbox =
4953         gtk_widget_new (gtk_vbox_get_type (),
4954                         "GtkBox::homogeneous", FALSE,
4955                         "GtkBox::spacing", 5,
4956                         "GtkContainer::border_width", 10,
4957                         "GtkWidget::parent", main_vbox,
4958                         "GtkWidget::visible", TRUE,
4959                         NULL);
4960
4961       hbox = gtk_hbox_new (FALSE, 0);
4962       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4963       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4964       
4965       label = gtk_label_new ("Cursor Value : ");
4966       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4967       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4968       
4969       adj = (GtkAdjustment *) gtk_adjustment_new (0,
4970                                                   0, 152,
4971                                                   2,
4972                                                   10, 0);
4973       spinner = gtk_spin_button_new (adj, 0, 0);
4974       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
4975
4976       frame =
4977         gtk_widget_new (gtk_frame_get_type (),
4978                         "GtkFrame::shadow", GTK_SHADOW_ETCHED_IN,
4979                         "GtkFrame::label_xalign", 0.5,
4980                         "GtkFrame::label", "Cursor Area",
4981                         "GtkContainer::border_width", 10,
4982                         "GtkWidget::parent", vbox,
4983                         "GtkWidget::visible", TRUE,
4984                         NULL);
4985
4986       darea = gtk_drawing_area_new ();
4987       gtk_widget_set_size_request (darea, 80, 80);
4988       gtk_container_add (GTK_CONTAINER (frame), darea);
4989       g_signal_connect (darea,
4990                         "expose_event",
4991                         G_CALLBACK (cursor_expose_event),
4992                         NULL);
4993       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
4994       g_signal_connect (darea,
4995                         "button_press_event",
4996                         G_CALLBACK (cursor_event),
4997                         spinner);
4998       gtk_widget_show (darea);
4999
5000       g_signal_connect (spinner, "changed",
5001                         G_CALLBACK (set_cursor),
5002                         darea);
5003
5004       label = gtk_widget_new (GTK_TYPE_LABEL,
5005                               "visible", TRUE,
5006                               "label", "XXX",
5007                               "parent", vbox,
5008                               NULL);
5009       gtk_container_child_set (GTK_CONTAINER (vbox), label,
5010                                "expand", FALSE,
5011                                NULL);
5012       g_object_set_data (G_OBJECT (spinner), "user_data", label);
5013
5014       any =
5015         gtk_widget_new (gtk_hseparator_get_type (),
5016                         "GtkWidget::visible", TRUE,
5017                         NULL);
5018       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
5019   
5020       hbox = gtk_hbox_new (FALSE, 0);
5021       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
5022       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
5023
5024       button = gtk_button_new_with_label ("Close");
5025       g_signal_connect_swapped (button, "clicked",
5026                                 G_CALLBACK (gtk_widget_destroy),
5027                                 window);
5028       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5029
5030       gtk_widget_show_all (window);
5031
5032       set_cursor (spinner, darea);
5033     }
5034   else
5035     gtk_widget_destroy (window);
5036 }
5037
5038 /*
5039  * GtkList
5040  */
5041
5042 static void
5043 list_add (GtkWidget *widget,
5044           GtkWidget *list)
5045 {
5046   static int i = 1;
5047   gchar buffer[64];
5048   GtkWidget *list_item;
5049   GtkContainer *container;
5050
5051   container = GTK_CONTAINER (list);
5052
5053   sprintf (buffer, "added item %d", i++);
5054   list_item = gtk_list_item_new_with_label (buffer);
5055   gtk_widget_show (list_item);
5056
5057   gtk_container_add (container, list_item);
5058 }
5059
5060 static void
5061 list_remove (GtkWidget *widget,
5062              GtkList   *list)
5063 {
5064   GList *clear_list = NULL;
5065   GList *sel_row = NULL;
5066   GList *work = NULL;
5067
5068   if (list->selection_mode == GTK_SELECTION_EXTENDED)
5069     {
5070       GtkWidget *item;
5071
5072       item = GTK_CONTAINER (list)->focus_child;
5073       if (!item && list->selection)
5074         item = list->selection->data;
5075
5076       if (item)
5077         {
5078           work = g_list_find (list->children, item);
5079           for (sel_row = work; sel_row; sel_row = sel_row->next)
5080             if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
5081               break;
5082
5083           if (!sel_row)
5084             {
5085               for (sel_row = work; sel_row; sel_row = sel_row->prev)
5086                 if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
5087                   break;
5088             }
5089         }
5090     }
5091
5092   for (work = list->selection; work; work = work->next)
5093     clear_list = g_list_prepend (clear_list, work->data);
5094
5095   clear_list = g_list_reverse (clear_list);
5096   gtk_list_remove_items (GTK_LIST (list), clear_list);
5097   g_list_free (clear_list);
5098
5099   if (list->selection_mode == GTK_SELECTION_EXTENDED && sel_row)
5100     gtk_list_select_child (list, GTK_WIDGET(sel_row->data));
5101 }
5102
5103 static void
5104 list_clear (GtkWidget *widget,
5105             GtkWidget *list)
5106 {
5107   gtk_list_clear_items (GTK_LIST (list), 0, -1);
5108 }
5109
5110 static gchar *selection_mode_items[] =
5111 {
5112   "Single",
5113   "Browse",
5114   "Multiple"
5115 };
5116
5117 static const GtkSelectionMode selection_modes[] = {
5118   GTK_SELECTION_SINGLE,
5119   GTK_SELECTION_BROWSE,
5120   GTK_SELECTION_MULTIPLE
5121 };
5122
5123 static GtkWidget *list_omenu;
5124
5125 static void 
5126 list_toggle_sel_mode (GtkWidget *widget, gpointer data)
5127 {
5128   GtkList *list;
5129   gint i;
5130
5131   list = GTK_LIST (data);
5132
5133   if (!GTK_WIDGET_MAPPED (widget))
5134     return;
5135
5136   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
5137
5138   gtk_list_set_selection_mode (list, selection_modes[i]);
5139 }
5140
5141 static void
5142 create_list (GtkWidget *widget)
5143 {
5144   static GtkWidget *window = NULL;
5145
5146   if (!window)
5147     {
5148       GtkWidget *cbox;
5149       GtkWidget *vbox;
5150       GtkWidget *hbox;
5151       GtkWidget *label;
5152       GtkWidget *scrolled_win;
5153       GtkWidget *list;
5154       GtkWidget *button;
5155       GtkWidget *separator;
5156       FILE *infile;
5157
5158       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5159
5160       gtk_window_set_screen (GTK_WINDOW (window),
5161                              gtk_widget_get_screen (widget));
5162
5163       g_signal_connect (window, "destroy",
5164                         G_CALLBACK (gtk_widget_destroyed),
5165                         &window);
5166
5167       gtk_window_set_title (GTK_WINDOW (window), "list");
5168       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5169
5170       vbox = gtk_vbox_new (FALSE, 0);
5171       gtk_container_add (GTK_CONTAINER (window), vbox);
5172
5173       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
5174       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
5175       gtk_widget_set_size_request (scrolled_win, -1, 300);
5176       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
5177       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
5178                                       GTK_POLICY_AUTOMATIC,
5179                                       GTK_POLICY_AUTOMATIC);
5180
5181       list = gtk_list_new ();
5182       gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
5183       gtk_scrolled_window_add_with_viewport
5184         (GTK_SCROLLED_WINDOW (scrolled_win), list);
5185       gtk_container_set_focus_vadjustment
5186         (GTK_CONTAINER (list),
5187          gtk_scrolled_window_get_vadjustment
5188          (GTK_SCROLLED_WINDOW (scrolled_win)));
5189       gtk_container_set_focus_hadjustment
5190         (GTK_CONTAINER (list),
5191          gtk_scrolled_window_get_hadjustment
5192          (GTK_SCROLLED_WINDOW (scrolled_win)));
5193
5194       if ((infile = fopen("../gtk/gtkenums.h", "r")))
5195         {
5196           char buffer[256];
5197           char *pos;
5198           GtkWidget *item;
5199
5200           while (fgets (buffer, 256, infile))
5201             {
5202               if ((pos = strchr (buffer, '\n')))
5203                 *pos = 0;
5204               item = gtk_list_item_new_with_label (buffer);
5205               gtk_container_add (GTK_CONTAINER (list), item);
5206             }
5207           
5208           fclose (infile);
5209         }
5210
5211
5212       hbox = gtk_hbox_new (TRUE, 5);
5213       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5214       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5215
5216       button = gtk_button_new_with_label ("Insert Row");
5217       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5218       g_signal_connect (button, "clicked",
5219                         G_CALLBACK (list_add),
5220                         list);
5221
5222       button = gtk_button_new_with_label ("Clear List");
5223       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5224       g_signal_connect (button, "clicked",
5225                         G_CALLBACK (list_clear),
5226                         list);
5227
5228       button = gtk_button_new_with_label ("Remove Selection");
5229       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5230       g_signal_connect (button, "clicked",
5231                         G_CALLBACK (list_remove),
5232                         list);
5233
5234       cbox = gtk_hbox_new (FALSE, 0);
5235       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
5236
5237       hbox = gtk_hbox_new (FALSE, 5);
5238       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5239       gtk_box_pack_start (GTK_BOX (cbox), hbox, TRUE, FALSE, 0);
5240
5241       label = gtk_label_new ("Selection Mode :");
5242       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5243
5244       list_omenu = build_option_menu (selection_mode_items, 3, 3, 
5245                                       list_toggle_sel_mode,
5246                                       list);
5247       gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
5248
5249       separator = gtk_hseparator_new ();
5250       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
5251
5252       cbox = gtk_hbox_new (FALSE, 0);
5253       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
5254
5255       button = gtk_button_new_with_label ("close");
5256       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5257       gtk_box_pack_start (GTK_BOX (cbox), button, TRUE, TRUE, 0);
5258       g_signal_connect_swapped (button, "clicked",
5259                                 G_CALLBACK (gtk_widget_destroy),
5260                                 window);
5261
5262       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5263       gtk_widget_grab_default (button);
5264     }
5265
5266   if (!GTK_WIDGET_VISIBLE (window))
5267     gtk_widget_show_all (window);
5268   else
5269     gtk_widget_destroy (window);
5270 }
5271
5272 /*
5273  * GtkCList
5274  */
5275
5276 static char * book_open_xpm[] = {
5277 "16 16 4 1",
5278 "       c None s None",
5279 ".      c black",
5280 "X      c #808080",
5281 "o      c white",
5282 "                ",
5283 "  ..            ",
5284 " .Xo.    ...    ",
5285 " .Xoo. ..oo.    ",
5286 " .Xooo.Xooo...  ",
5287 " .Xooo.oooo.X.  ",
5288 " .Xooo.Xooo.X.  ",
5289 " .Xooo.oooo.X.  ",
5290 " .Xooo.Xooo.X.  ",
5291 " .Xooo.oooo.X.  ",
5292 "  .Xoo.Xoo..X.  ",
5293 "   .Xo.o..ooX.  ",
5294 "    .X..XXXXX.  ",
5295 "    ..X.......  ",
5296 "     ..         ",
5297 "                "};
5298
5299 static char * book_closed_xpm[] = {
5300 "16 16 6 1",
5301 "       c None s None",
5302 ".      c black",
5303 "X      c red",
5304 "o      c yellow",
5305 "O      c #808080",
5306 "#      c white",
5307 "                ",
5308 "       ..       ",
5309 "     ..XX.      ",
5310 "   ..XXXXX.     ",
5311 " ..XXXXXXXX.    ",
5312 ".ooXXXXXXXXX.   ",
5313 "..ooXXXXXXXXX.  ",
5314 ".X.ooXXXXXXXXX. ",
5315 ".XX.ooXXXXXX..  ",
5316 " .XX.ooXXX..#O  ",
5317 "  .XX.oo..##OO. ",
5318 "   .XX..##OO..  ",
5319 "    .X.#OO..    ",
5320 "     ..O..      ",
5321 "      ..        ",
5322 "                "};
5323
5324 static char * mini_page_xpm[] = {
5325 "16 16 4 1",
5326 "       c None s None",
5327 ".      c black",
5328 "X      c white",
5329 "o      c #808080",
5330 "                ",
5331 "   .......      ",
5332 "   .XXXXX..     ",
5333 "   .XoooX.X.    ",
5334 "   .XXXXX....   ",
5335 "   .XooooXoo.o  ",
5336 "   .XXXXXXXX.o  ",
5337 "   .XooooooX.o  ",
5338 "   .XXXXXXXX.o  ",
5339 "   .XooooooX.o  ",
5340 "   .XXXXXXXX.o  ",
5341 "   .XooooooX.o  ",
5342 "   .XXXXXXXX.o  ",
5343 "   ..........o  ",
5344 "    oooooooooo  ",
5345 "                "};
5346
5347 static char * gtk_mini_xpm[] = {
5348 "15 20 17 1",
5349 "       c None",
5350 ".      c #14121F",
5351 "+      c #278828",
5352 "@      c #9B3334",
5353 "#      c #284C72",
5354 "$      c #24692A",
5355 "%      c #69282E",
5356 "&      c #37C539",
5357 "*      c #1D2F4D",
5358 "=      c #6D7076",
5359 "-      c #7D8482",
5360 ";      c #E24A49",
5361 ">      c #515357",
5362 ",      c #9B9C9B",
5363 "'      c #2FA232",
5364 ")      c #3CE23D",
5365 "!      c #3B6CCB",
5366 "               ",
5367 "      ***>     ",
5368 "    >.*!!!*    ",
5369 "   ***....#*=  ",
5370 "  *!*.!!!**!!# ",
5371 " .!!#*!#*!!!!# ",
5372 " @%#!.##.*!!$& ",
5373 " @;%*!*.#!#')) ",
5374 " @;;@%!!*$&)'' ",
5375 " @%.%@%$'&)$+' ",
5376 " @;...@$'*'*)+ ",
5377 " @;%..@$+*.')$ ",
5378 " @;%%;;$+..$)# ",
5379 " @;%%;@$$$'.$# ",
5380 " %;@@;;$$+))&* ",
5381 "  %;;;@+$&)&*  ",
5382 "   %;;@'))+>   ",
5383 "    %;@'&#     ",
5384 "     >%$$      ",
5385 "      >=       "};
5386
5387 #define TESTGTK_CLIST_COLUMNS 12
5388 static gint clist_rows = 0;
5389 static GtkWidget *clist_omenu;
5390
5391 static void
5392 add1000_clist (GtkWidget *widget, gpointer data)
5393 {
5394   gint i, row;
5395   char text[TESTGTK_CLIST_COLUMNS][50];
5396   char *texts[TESTGTK_CLIST_COLUMNS];
5397   GdkBitmap *mask;
5398   GdkPixmap *pixmap;
5399   GtkCList  *clist;
5400
5401   clist = GTK_CLIST (data);
5402
5403   pixmap = gdk_pixmap_create_from_xpm_d (clist->clist_window,
5404                                          &mask, 
5405                                          &GTK_WIDGET (data)->style->white,
5406                                          gtk_mini_xpm);
5407
5408   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5409     {
5410       texts[i] = text[i];
5411       sprintf (text[i], "Column %d", i);
5412     }
5413   
5414   texts[3] = NULL;
5415   sprintf (text[1], "Right");
5416   sprintf (text[2], "Center");
5417   
5418   gtk_clist_freeze (GTK_CLIST (data));
5419   for (i = 0; i < 1000; i++)
5420     {
5421       sprintf (text[0], "CListRow %d", rand() % 10000);
5422       row = gtk_clist_append (clist, texts);
5423       gtk_clist_set_pixtext (clist, row, 3, "gtk+", 5, pixmap, mask);
5424     }
5425
5426   gtk_clist_thaw (GTK_CLIST (data));
5427
5428   g_object_unref (pixmap);
5429   g_object_unref (mask);
5430 }
5431
5432 static void
5433 add10000_clist (GtkWidget *widget, gpointer data)
5434 {
5435   gint i;
5436   char text[TESTGTK_CLIST_COLUMNS][50];
5437   char *texts[TESTGTK_CLIST_COLUMNS];
5438
5439   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5440     {
5441       texts[i] = text[i];
5442       sprintf (text[i], "Column %d", i);
5443     }
5444   
5445   sprintf (text[1], "Right");
5446   sprintf (text[2], "Center");
5447   
5448   gtk_clist_freeze (GTK_CLIST (data));
5449   for (i = 0; i < 10000; i++)
5450     {
5451       sprintf (text[0], "CListRow %d", rand() % 10000);
5452       gtk_clist_append (GTK_CLIST (data), texts);
5453     }
5454   gtk_clist_thaw (GTK_CLIST (data));
5455 }
5456
5457 void
5458 clear_clist (GtkWidget *widget, gpointer data)
5459 {
5460   gtk_clist_clear (GTK_CLIST (data));
5461   clist_rows = 0;
5462 }
5463
5464 void clist_remove_selection (GtkWidget *widget, GtkCList *clist)
5465 {
5466   gtk_clist_freeze (clist);
5467
5468   while (clist->selection)
5469     {
5470       gint row;
5471
5472       clist_rows--;
5473       row = GPOINTER_TO_INT (clist->selection->data);
5474
5475       gtk_clist_remove (clist, row);
5476
5477       if (clist->selection_mode == GTK_SELECTION_BROWSE)
5478         break;
5479     }
5480
5481   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
5482       clist->focus_row >= 0)
5483     gtk_clist_select_row (clist, clist->focus_row, -1);
5484
5485   gtk_clist_thaw (clist);
5486 }
5487
5488 void toggle_title_buttons (GtkWidget *widget, GtkCList *clist)
5489 {
5490   if (GTK_TOGGLE_BUTTON (widget)->active)
5491     gtk_clist_column_titles_show (clist);
5492   else
5493     gtk_clist_column_titles_hide (clist);
5494 }
5495
5496 void toggle_reorderable (GtkWidget *widget, GtkCList *clist)
5497 {
5498   gtk_clist_set_reorderable (clist, GTK_TOGGLE_BUTTON (widget)->active);
5499 }
5500
5501 static void
5502 insert_row_clist (GtkWidget *widget, gpointer data)
5503 {
5504   static char *text[] =
5505   {
5506     "This", "is an", "inserted", "row.",
5507     "This", "is an", "inserted", "row.",
5508     "This", "is an", "inserted", "row."
5509   };
5510
5511   static GtkStyle *style1 = NULL;
5512   static GtkStyle *style2 = NULL;
5513   static GtkStyle *style3 = NULL;
5514   gint row;
5515   
5516   if (GTK_CLIST (data)->focus_row >= 0)
5517     row = gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row,
5518                             text);
5519   else
5520     row = gtk_clist_prepend (GTK_CLIST (data), text);
5521
5522   if (!style1)
5523     {
5524       GdkColor col1;
5525       GdkColor col2;
5526
5527       col1.red   = 0;
5528       col1.green = 56000;
5529       col1.blue  = 0;
5530       col2.red   = 32000;
5531       col2.green = 0;
5532       col2.blue  = 56000;
5533
5534       style1 = gtk_style_copy (GTK_WIDGET (data)->style);
5535       style1->base[GTK_STATE_NORMAL] = col1;
5536       style1->base[GTK_STATE_SELECTED] = col2;
5537
5538       style2 = gtk_style_copy (GTK_WIDGET (data)->style);
5539       style2->fg[GTK_STATE_NORMAL] = col1;
5540       style2->fg[GTK_STATE_SELECTED] = col2;
5541
5542       style3 = gtk_style_copy (GTK_WIDGET (data)->style);
5543       style3->fg[GTK_STATE_NORMAL] = col1;
5544       style3->base[GTK_STATE_NORMAL] = col2;
5545       pango_font_description_free (style3->font_desc);
5546       style3->font_desc = pango_font_description_from_string ("courier 12");
5547     }
5548
5549   gtk_clist_set_cell_style (GTK_CLIST (data), row, 3, style1);
5550   gtk_clist_set_cell_style (GTK_CLIST (data), row, 4, style2);
5551   gtk_clist_set_cell_style (GTK_CLIST (data), row, 0, style3);
5552
5553   clist_rows++;
5554 }
5555
5556 static void
5557 clist_warning_test (GtkWidget *button,
5558                     GtkWidget *clist)
5559 {
5560   GtkWidget *child;
5561   static gboolean add_remove = FALSE;
5562
5563   add_remove = !add_remove;
5564
5565   child = gtk_label_new ("Test");
5566   g_object_ref (child);
5567   gtk_object_sink (GTK_OBJECT (child));
5568
5569   if (add_remove)
5570     gtk_container_add (GTK_CONTAINER (clist), child);
5571   else
5572     {
5573       child->parent = clist;
5574       gtk_container_remove (GTK_CONTAINER (clist), child);
5575       child->parent = NULL;
5576     }
5577
5578   gtk_widget_destroy (child);
5579   gtk_widget_unref (child);
5580 }
5581
5582 static void
5583 undo_selection (GtkWidget *button, GtkCList *clist)
5584 {
5585   gtk_clist_undo_selection (clist);
5586 }
5587
5588 static void 
5589 clist_toggle_sel_mode (GtkWidget *widget, gpointer data)
5590 {
5591   GtkCList *clist;
5592   gint i;
5593
5594   clist = GTK_CLIST (data);
5595
5596   if (!GTK_WIDGET_MAPPED (widget))
5597     return;
5598
5599   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
5600
5601   gtk_clist_set_selection_mode (clist, selection_modes[i]);
5602 }
5603
5604 static void 
5605 clist_click_column (GtkCList *clist, gint column, gpointer data)
5606 {
5607   if (column == 4)
5608     gtk_clist_set_column_visibility (clist, column, FALSE);
5609   else if (column == clist->sort_column)
5610     {
5611       if (clist->sort_type == GTK_SORT_ASCENDING)
5612         clist->sort_type = GTK_SORT_DESCENDING;
5613       else
5614         clist->sort_type = GTK_SORT_ASCENDING;
5615     }
5616   else
5617     gtk_clist_set_sort_column (clist, column);
5618
5619   gtk_clist_sort (clist);
5620 }
5621
5622 static void
5623 create_clist (GtkWidget *widget)
5624 {
5625   gint i;
5626   static GtkWidget *window = NULL;
5627
5628   static char *titles[] =
5629   {
5630     "auto resize", "not resizeable", "max width 100", "min width 50",
5631     "hide column", "Title 5", "Title 6", "Title 7",
5632     "Title 8",  "Title 9",  "Title 10", "Title 11"
5633   };
5634
5635   char text[TESTGTK_CLIST_COLUMNS][50];
5636   char *texts[TESTGTK_CLIST_COLUMNS];
5637
5638   GtkWidget *vbox;
5639   GtkWidget *hbox;
5640   GtkWidget *clist;
5641   GtkWidget *button;
5642   GtkWidget *separator;
5643   GtkWidget *scrolled_win;
5644   GtkWidget *check;
5645
5646   GtkWidget *undo_button;
5647   GtkWidget *label;
5648
5649   GtkStyle *style;
5650   GdkColor col1;
5651   GdkColor col2;
5652
5653   if (!window)
5654     {
5655       clist_rows = 0;
5656       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5657       gtk_window_set_screen (GTK_WINDOW (window), 
5658                              gtk_widget_get_screen (widget));
5659
5660       g_signal_connect (window, "destroy",
5661                         G_CALLBACK (gtk_widget_destroyed), &window);
5662
5663       gtk_window_set_title (GTK_WINDOW (window), "clist");
5664       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5665
5666       vbox = gtk_vbox_new (FALSE, 0);
5667       gtk_container_add (GTK_CONTAINER (window), vbox);
5668
5669       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
5670       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
5671       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
5672                                       GTK_POLICY_AUTOMATIC, 
5673                                       GTK_POLICY_AUTOMATIC);
5674
5675       /* create GtkCList here so we have a pointer to throw at the 
5676        * button callbacks -- more is done with it later */
5677       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
5678       gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
5679       g_signal_connect (clist, "click_column",
5680                         G_CALLBACK (clist_click_column), NULL);
5681
5682       /* control buttons */
5683       hbox = gtk_hbox_new (FALSE, 5);
5684       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5685       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5686
5687       button = gtk_button_new_with_label ("Insert Row");
5688       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5689       g_signal_connect (button, "clicked",
5690                         G_CALLBACK (insert_row_clist), clist);
5691
5692       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
5693       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5694       g_signal_connect (button, "clicked",
5695                         G_CALLBACK (add1000_clist), clist);
5696
5697       button = gtk_button_new_with_label ("Add 10,000 Rows");
5698       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5699       g_signal_connect (button, "clicked",
5700                         G_CALLBACK (add10000_clist), clist);
5701
5702       /* second layer of buttons */
5703       hbox = gtk_hbox_new (FALSE, 5);
5704       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5705       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5706
5707       button = gtk_button_new_with_label ("Clear List");
5708       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5709       g_signal_connect (button, "clicked",
5710                         G_CALLBACK (clear_clist), clist);
5711
5712       button = gtk_button_new_with_label ("Remove Selection");
5713       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5714       g_signal_connect (button, "clicked",
5715                         G_CALLBACK (clist_remove_selection), clist);
5716
5717       undo_button = gtk_button_new_with_label ("Undo Selection");
5718       gtk_box_pack_start (GTK_BOX (hbox), undo_button, TRUE, TRUE, 0);
5719       g_signal_connect (undo_button, "clicked",
5720                         G_CALLBACK (undo_selection), clist);
5721
5722       button = gtk_button_new_with_label ("Warning Test");
5723       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5724       g_signal_connect (button, "clicked",
5725                         G_CALLBACK (clist_warning_test), clist);
5726
5727       /* third layer of buttons */
5728       hbox = gtk_hbox_new (FALSE, 5);
5729       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5730       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5731
5732       check = gtk_check_button_new_with_label ("Show Title Buttons");
5733       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5734       g_signal_connect (check, "clicked",
5735                         G_CALLBACK (toggle_title_buttons), clist);
5736       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5737
5738       check = gtk_check_button_new_with_label ("Reorderable");
5739       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5740       g_signal_connect (check, "clicked",
5741                         G_CALLBACK (toggle_reorderable), clist);
5742       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5743
5744       label = gtk_label_new ("Selection Mode :");
5745       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5746
5747       clist_omenu = build_option_menu (selection_mode_items, 3, 3, 
5748                                        clist_toggle_sel_mode,
5749                                        clist);
5750       gtk_box_pack_start (GTK_BOX (hbox), clist_omenu, FALSE, TRUE, 0);
5751
5752       /* 
5753        * the rest of the clist configuration
5754        */
5755
5756       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
5757       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
5758       gtk_widget_set_size_request (clist, -1, 300);
5759
5760       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
5761         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
5762
5763       gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
5764       gtk_clist_set_column_resizeable (GTK_CLIST (clist), 1, FALSE);
5765       gtk_clist_set_column_max_width (GTK_CLIST (clist), 2, 100);
5766       gtk_clist_set_column_min_width (GTK_CLIST (clist), 3, 50);
5767       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
5768       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
5769                                           GTK_JUSTIFY_RIGHT);
5770       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
5771                                           GTK_JUSTIFY_CENTER);
5772       
5773       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5774         {
5775           texts[i] = text[i];
5776           sprintf (text[i], "Column %d", i);
5777         }
5778
5779       sprintf (text[1], "Right");
5780       sprintf (text[2], "Center");
5781
5782       col1.red   = 56000;
5783       col1.green = 0;
5784       col1.blue  = 0;
5785       col2.red   = 0;
5786       col2.green = 56000;
5787       col2.blue  = 32000;
5788
5789       style = gtk_style_new ();
5790       style->fg[GTK_STATE_NORMAL] = col1;
5791       style->base[GTK_STATE_NORMAL] = col2;
5792
5793       pango_font_description_set_size (style->font_desc, 14 * PANGO_SCALE);
5794       pango_font_description_set_weight (style->font_desc, PANGO_WEIGHT_BOLD);
5795
5796       for (i = 0; i < 10; i++)
5797         {
5798           sprintf (text[0], "CListRow %d", clist_rows++);
5799           gtk_clist_append (GTK_CLIST (clist), texts);
5800
5801           switch (i % 4)
5802             {
5803             case 2:
5804               gtk_clist_set_row_style (GTK_CLIST (clist), i, style);
5805               break;
5806             default:
5807               gtk_clist_set_cell_style (GTK_CLIST (clist), i, i % 4, style);
5808               break;
5809             }
5810         }
5811
5812       gtk_style_unref (style);
5813       
5814       separator = gtk_hseparator_new ();
5815       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
5816
5817       hbox = gtk_hbox_new (FALSE, 0);
5818       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5819
5820       button = gtk_button_new_with_label ("close");
5821       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5822       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5823       g_signal_connect_swapped (button, "clicked",
5824                                 G_CALLBACK (gtk_widget_destroy),
5825                                 window);
5826
5827       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5828       gtk_widget_grab_default (button);
5829     }
5830
5831   if (!GTK_WIDGET_VISIBLE (window))
5832     gtk_widget_show_all (window);
5833   else
5834     {
5835       clist_rows = 0;
5836       gtk_widget_destroy (window);
5837     }
5838 }
5839
5840 /*
5841  * GtkCTree
5842  */
5843
5844 typedef struct 
5845 {
5846   GdkPixmap *pixmap1;
5847   GdkPixmap *pixmap2;
5848   GdkPixmap *pixmap3;
5849   GdkBitmap *mask1;
5850   GdkBitmap *mask2;
5851   GdkBitmap *mask3;
5852 } CTreePixmaps;
5853
5854 static gint books = 0;
5855 static gint pages = 0;
5856
5857 static GtkWidget *book_label;
5858 static GtkWidget *page_label;
5859 static GtkWidget *sel_label;
5860 static GtkWidget *vis_label;
5861 static GtkWidget *omenu1;
5862 static GtkWidget *omenu2;
5863 static GtkWidget *omenu3;
5864 static GtkWidget *omenu4;
5865 static GtkWidget *spin1;
5866 static GtkWidget *spin2;
5867 static GtkWidget *spin3;
5868 static gint line_style;
5869
5870
5871 static CTreePixmaps *
5872 get_ctree_pixmaps (GtkCTree *ctree)
5873 {
5874   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (ctree));
5875   CTreePixmaps *pixmaps = g_object_get_data (G_OBJECT (screen), "ctree-pixmaps");
5876
5877   if (!pixmaps)
5878     {
5879       GdkColormap *colormap = gdk_screen_get_rgb_colormap (screen);
5880       pixmaps = g_new (CTreePixmaps, 1);
5881       
5882       pixmaps->pixmap1 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5883                                                                 &pixmaps->mask1, 
5884                                                                 NULL, book_closed_xpm);
5885       pixmaps->pixmap2 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5886                                                                 &pixmaps->mask2, 
5887                                                                 NULL, book_open_xpm);
5888       pixmaps->pixmap3 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5889                                                                 &pixmaps->mask3,
5890                                                                 NULL, mini_page_xpm);
5891       
5892       g_object_set_data (G_OBJECT (screen), "ctree-pixmaps", pixmaps);
5893     }
5894
5895   return pixmaps;
5896 }
5897
5898 void after_press (GtkCTree *ctree, gpointer data)
5899 {
5900   char buf[80];
5901
5902   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
5903   gtk_label_set_text (GTK_LABEL (sel_label), buf);
5904
5905   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
5906   gtk_label_set_text (GTK_LABEL (vis_label), buf);
5907
5908   sprintf (buf, "%d", books);
5909   gtk_label_set_text (GTK_LABEL (book_label), buf);
5910
5911   sprintf (buf, "%d", pages);
5912   gtk_label_set_text (GTK_LABEL (page_label), buf);
5913 }
5914
5915 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
5916                  GtkCTreeNode *sibling, gpointer data)
5917 {
5918   char *source;
5919   char *target1;
5920   char *target2;
5921
5922   gtk_ctree_get_node_info (ctree, child, &source, 
5923                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5924   if (parent)
5925     gtk_ctree_get_node_info (ctree, parent, &target1, 
5926                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5927   if (sibling)
5928     gtk_ctree_get_node_info (ctree, sibling, &target2, 
5929                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5930
5931   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
5932            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
5933 }
5934
5935 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
5936 {
5937   if (GTK_CTREE_ROW (list)->is_leaf)
5938     pages--;
5939   else
5940     books--;
5941 }
5942
5943 void expand_all (GtkWidget *widget, GtkCTree *ctree)
5944 {
5945   gtk_ctree_expand_recursive (ctree, NULL);
5946   after_press (ctree, NULL);
5947 }
5948
5949 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
5950 {
5951   gtk_ctree_collapse_recursive (ctree, NULL);
5952   after_press (ctree, NULL);
5953 }
5954
5955 void select_all (GtkWidget *widget, GtkCTree *ctree)
5956 {
5957   gtk_ctree_select_recursive (ctree, NULL);
5958   after_press (ctree, NULL);
5959 }
5960
5961 void change_style (GtkWidget *widget, GtkCTree *ctree)
5962 {
5963   static GtkStyle *style1 = NULL;
5964   static GtkStyle *style2 = NULL;
5965
5966   GtkCTreeNode *node;
5967   GdkColor col1;
5968   GdkColor col2;
5969
5970   if (GTK_CLIST (ctree)->focus_row >= 0)
5971     node = GTK_CTREE_NODE
5972       (g_list_nth (GTK_CLIST (ctree)->row_list,GTK_CLIST (ctree)->focus_row));
5973   else
5974     node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
5975
5976   if (!node)
5977     return;
5978
5979   if (!style1)
5980     {
5981       col1.red   = 0;
5982       col1.green = 56000;
5983       col1.blue  = 0;
5984       col2.red   = 32000;
5985       col2.green = 0;
5986       col2.blue  = 56000;
5987
5988       style1 = gtk_style_new ();
5989       style1->base[GTK_STATE_NORMAL] = col1;
5990       style1->fg[GTK_STATE_SELECTED] = col2;
5991
5992       style2 = gtk_style_new ();
5993       style2->base[GTK_STATE_SELECTED] = col2;
5994       style2->fg[GTK_STATE_NORMAL] = col1;
5995       style2->base[GTK_STATE_NORMAL] = col2;
5996       pango_font_description_free (style2->font_desc);
5997       style2->font_desc = pango_font_description_from_string ("courier 30");
5998     }
5999
6000   gtk_ctree_node_set_cell_style (ctree, node, 1, style1);
6001   gtk_ctree_node_set_cell_style (ctree, node, 0, style2);
6002
6003   if (GTK_CTREE_ROW (node)->children)
6004     gtk_ctree_node_set_row_style (ctree, GTK_CTREE_ROW (node)->children,
6005                                   style2);
6006 }
6007
6008 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
6009 {
6010   gtk_ctree_unselect_recursive (ctree, NULL);
6011   after_press (ctree, NULL);
6012 }
6013
6014 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
6015 {
6016   GtkCList *clist;
6017   GtkCTreeNode *node;
6018
6019   clist = GTK_CLIST (ctree);
6020
6021   gtk_clist_freeze (clist);
6022
6023   while (clist->selection)
6024     {
6025       node = clist->selection->data;
6026
6027       if (GTK_CTREE_ROW (node)->is_leaf)
6028         pages--;
6029       else
6030         gtk_ctree_post_recursive (ctree, node,
6031                                   (GtkCTreeFunc) count_items, NULL);
6032
6033       gtk_ctree_remove_node (ctree, node);
6034
6035       if (clist->selection_mode == GTK_SELECTION_BROWSE)
6036         break;
6037     }
6038
6039   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
6040       clist->focus_row >= 0)
6041     {
6042       node = gtk_ctree_node_nth (ctree, clist->focus_row);
6043
6044       if (node)
6045         gtk_ctree_select (ctree, node);
6046     }
6047     
6048   gtk_clist_thaw (clist);
6049   after_press (ctree, NULL);
6050 }
6051
6052 struct _ExportStruct {
6053   gchar *tree;
6054   gchar *info;
6055   gboolean is_leaf;
6056 };
6057
6058 typedef struct _ExportStruct ExportStruct;
6059
6060 gboolean
6061 gnode2ctree (GtkCTree   *ctree,
6062              guint       depth,
6063              GNode        *gnode,
6064              GtkCTreeNode *cnode,
6065              gpointer    data)
6066 {
6067   ExportStruct *es;
6068   GdkPixmap *pixmap_closed;
6069   GdkBitmap *mask_closed;
6070   GdkPixmap *pixmap_opened;
6071   GdkBitmap *mask_opened;
6072   CTreePixmaps *pixmaps;
6073
6074   if (!cnode || !gnode || (!(es = gnode->data)))
6075     return FALSE;
6076
6077   pixmaps = get_ctree_pixmaps (ctree);
6078
6079   if (es->is_leaf)
6080     {
6081       pixmap_closed = pixmaps->pixmap3;
6082       mask_closed = pixmaps->mask3;
6083       pixmap_opened = NULL;
6084       mask_opened = NULL;
6085     }
6086   else
6087     {
6088       pixmap_closed = pixmaps->pixmap1;
6089       mask_closed = pixmaps->mask1;
6090       pixmap_opened = pixmaps->pixmap2;
6091       mask_opened = pixmaps->mask2;
6092     }
6093
6094   gtk_ctree_set_node_info (ctree, cnode, es->tree, 2, pixmap_closed,
6095                            mask_closed, pixmap_opened, mask_opened,
6096                            es->is_leaf, (depth < 3));
6097   gtk_ctree_node_set_text (ctree, cnode, 1, es->info);
6098   g_free (es);
6099   gnode->data = NULL;
6100
6101   return TRUE;
6102 }
6103
6104 gboolean
6105 ctree2gnode (GtkCTree   *ctree,
6106              guint       depth,
6107              GNode        *gnode,
6108              GtkCTreeNode *cnode,
6109              gpointer    data)
6110 {
6111   ExportStruct *es;
6112
6113   if (!cnode || !gnode)
6114     return FALSE;
6115   
6116   es = g_new (ExportStruct, 1);
6117   gnode->data = es;
6118   es->is_leaf = GTK_CTREE_ROW (cnode)->is_leaf;
6119   es->tree = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[0])->text;
6120   es->info = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[1])->text;
6121   return TRUE;
6122 }
6123
6124 void export_ctree (GtkWidget *widget, GtkCTree *ctree)
6125 {
6126   char *title[] = { "Tree" , "Info" };
6127   static GtkWidget *export_window = NULL;
6128   static GtkCTree *export_ctree;
6129   GtkWidget *vbox;
6130   GtkWidget *scrolled_win;
6131   GtkWidget *button;
6132   GtkWidget *sep;
6133   GNode *gnode;
6134   GtkCTreeNode *node;
6135
6136   if (!export_window)
6137     {
6138       export_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6139
6140       gtk_window_set_screen (GTK_WINDOW (export_window),
6141                              gtk_widget_get_screen (widget));
6142   
6143       g_signal_connect (export_window, "destroy",
6144                         G_CALLBACK (gtk_widget_destroyed),
6145                         &export_window);
6146
6147       gtk_window_set_title (GTK_WINDOW (export_window), "exported ctree");
6148       gtk_container_set_border_width (GTK_CONTAINER (export_window), 5);
6149
6150       vbox = gtk_vbox_new (FALSE, 0);
6151       gtk_container_add (GTK_CONTAINER (export_window), vbox);
6152       
6153       button = gtk_button_new_with_label ("Close");
6154       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, TRUE, 0);
6155
6156       g_signal_connect_swapped (button, "clicked",
6157                                 G_CALLBACK (gtk_widget_destroy),
6158                                 export_window);
6159
6160       sep = gtk_hseparator_new ();
6161       gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, TRUE, 10);
6162
6163       export_ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
6164       gtk_ctree_set_line_style (export_ctree, GTK_CTREE_LINES_DOTTED);
6165
6166       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6167       gtk_container_add (GTK_CONTAINER (scrolled_win),
6168                          GTK_WIDGET (export_ctree));
6169       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6170                                       GTK_POLICY_AUTOMATIC,
6171                                       GTK_POLICY_AUTOMATIC);
6172       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6173       gtk_clist_set_selection_mode (GTK_CLIST (export_ctree),
6174                                     GTK_SELECTION_EXTENDED);
6175       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 0, 200);
6176       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 1, 200);
6177       gtk_widget_set_size_request (GTK_WIDGET (export_ctree), 300, 200);
6178     }
6179
6180   if (!GTK_WIDGET_VISIBLE (export_window))
6181     gtk_widget_show_all (export_window);
6182       
6183   gtk_clist_clear (GTK_CLIST (export_ctree));
6184
6185   node = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list,
6186                                      GTK_CLIST (ctree)->focus_row));
6187   if (!node)
6188     return;
6189
6190   gnode = gtk_ctree_export_to_gnode (ctree, NULL, NULL, node,
6191                                      ctree2gnode, NULL);
6192   if (gnode)
6193     {
6194       gtk_ctree_insert_gnode (export_ctree, NULL, NULL, gnode,
6195                               gnode2ctree, NULL);
6196       g_node_destroy (gnode);
6197     }
6198 }
6199
6200 void change_indent (GtkWidget *widget, GtkCTree *ctree)
6201 {
6202   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
6203 }
6204
6205 void change_spacing (GtkWidget *widget, GtkCTree *ctree)
6206 {
6207   gtk_ctree_set_spacing (ctree, GTK_ADJUSTMENT (widget)->value);
6208 }
6209
6210 void change_row_height (GtkWidget *widget, GtkCList *clist)
6211 {
6212   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
6213 }
6214
6215 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
6216 {
6217   GtkStyle *style = NULL;
6218   
6219   if (!node)
6220     return;
6221   
6222   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
6223     {
6224       if (!GTK_CTREE_ROW (node)->is_leaf)
6225         style = GTK_CTREE_ROW (node)->row.data;
6226       else if (GTK_CTREE_ROW (node)->parent)
6227         style = GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data;
6228     }
6229
6230   gtk_ctree_node_set_row_style (ctree, node, style);
6231 }
6232
6233 void 
6234 ctree_toggle_line_style (GtkWidget *widget, gpointer data)
6235 {
6236   GtkCTree *ctree;
6237   gint i;
6238
6239   ctree = GTK_CTREE (data);
6240
6241   if (!GTK_WIDGET_MAPPED (widget))
6242     return;
6243
6244   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6245
6246   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
6247        ((GtkCTreeLineStyle) i) != GTK_CTREE_LINES_TABBED) ||
6248       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
6249        ((GtkCTreeLineStyle) i) == GTK_CTREE_LINES_TABBED))
6250     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
6251   gtk_ctree_set_line_style (ctree, i);
6252   line_style = i;
6253 }
6254
6255 void 
6256 ctree_toggle_expander_style (GtkWidget *widget, gpointer data)
6257 {
6258   GtkCTree *ctree;
6259   gint i;
6260
6261   ctree = GTK_CTREE (data);
6262
6263   if (!GTK_WIDGET_MAPPED (widget))
6264     return;
6265   
6266   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6267   
6268   gtk_ctree_set_expander_style (ctree, (GtkCTreeExpanderStyle) i);
6269 }
6270
6271 void 
6272 ctree_toggle_justify (GtkWidget *widget, gpointer data)
6273 {
6274   GtkCTree *ctree;
6275   gint i;
6276
6277   ctree = GTK_CTREE (data);
6278
6279   if (!GTK_WIDGET_MAPPED (widget))
6280     return;
6281
6282   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6283
6284   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
6285                                       (GtkJustification) i);
6286 }
6287
6288 void 
6289 ctree_toggle_sel_mode (GtkWidget *widget, gpointer data)
6290 {
6291   GtkCTree *ctree;
6292   gint i;
6293
6294   ctree = GTK_CTREE (data);
6295
6296   if (!GTK_WIDGET_MAPPED (widget))
6297     return;
6298
6299   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6300
6301   gtk_clist_set_selection_mode (GTK_CLIST (ctree), selection_modes[i]);
6302   after_press (ctree, NULL);
6303 }
6304     
6305 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
6306                       gint num_books, gint num_pages, GtkCTreeNode *parent)
6307 {
6308   gchar *text[2];
6309   gchar buf1[60];
6310   gchar buf2[60];
6311   GtkCTreeNode *sibling;
6312   CTreePixmaps *pixmaps;
6313   gint i;
6314
6315   text[0] = buf1;
6316   text[1] = buf2;
6317   sibling = NULL;
6318
6319   pixmaps = get_ctree_pixmaps (ctree);
6320
6321   for (i = num_pages + num_books; i > num_books; i--)
6322     {
6323       pages++;
6324       sprintf (buf1, "Page %02d", (gint) rand() % 100);
6325       sprintf (buf2, "Item %d-%d", cur_depth, i);
6326       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
6327                                        pixmaps->pixmap3, pixmaps->mask3, NULL, NULL,
6328                                        TRUE, FALSE);
6329
6330       if (parent && ctree->line_style == GTK_CTREE_LINES_TABBED)
6331         gtk_ctree_node_set_row_style (ctree, sibling,
6332                                       GTK_CTREE_ROW (parent)->row.style);
6333     }
6334
6335   if (cur_depth == depth)
6336     return;
6337
6338   for (i = num_books; i > 0; i--)
6339     {
6340       GtkStyle *style;
6341
6342       books++;
6343       sprintf (buf1, "Book %02d", (gint) rand() % 100);
6344       sprintf (buf2, "Item %d-%d", cur_depth, i);
6345       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
6346                                        pixmaps->pixmap1, pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2,
6347                                        FALSE, FALSE);
6348
6349       style = gtk_style_new ();
6350       switch (cur_depth % 3)
6351         {
6352         case 0:
6353           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
6354           style->base[GTK_STATE_NORMAL].green = 0;
6355           style->base[GTK_STATE_NORMAL].blue  = 65535 - ((i * 10000) % 65535);
6356           break;
6357         case 1:
6358           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
6359           style->base[GTK_STATE_NORMAL].green = 65535 - ((i * 10000) % 65535);
6360           style->base[GTK_STATE_NORMAL].blue  = 0;
6361           break;
6362         default:
6363           style->base[GTK_STATE_NORMAL].red   = 65535 - ((i * 10000) % 65535);
6364           style->base[GTK_STATE_NORMAL].green = 0;
6365           style->base[GTK_STATE_NORMAL].blue  = 10000 * (cur_depth % 6);
6366           break;
6367         }
6368       gtk_ctree_node_set_row_data_full (ctree, sibling, style,
6369                                         (GtkDestroyNotify) gtk_style_unref);
6370
6371       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
6372         gtk_ctree_node_set_row_style (ctree, sibling, style);
6373
6374       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
6375                        sibling);
6376     }
6377 }
6378
6379 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
6380 {
6381   gchar *text [2];
6382   gchar label1[] = "Root";
6383   gchar label2[] = "";
6384   GtkCTreeNode *parent;
6385   GtkStyle *style;
6386   guint b, d, p, n;
6387   CTreePixmaps *pixmaps;
6388
6389   pixmaps = get_ctree_pixmaps (ctree);
6390
6391   text[0] = label1;
6392   text[1] = label2;
6393   
6394   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
6395   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
6396   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
6397
6398   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
6399
6400   if (n > 100000)
6401     {
6402       g_print ("%d total items? Try less\n",n);
6403       return;
6404     }
6405
6406   gtk_clist_freeze (GTK_CLIST (ctree));
6407   gtk_clist_clear (GTK_CLIST (ctree));
6408
6409   books = 1;
6410   pages = 0;
6411
6412   parent = gtk_ctree_insert_node (ctree, NULL, NULL, text, 5, pixmaps->pixmap1,
6413                                   pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2, FALSE, TRUE);
6414
6415   style = gtk_style_new ();
6416   style->base[GTK_STATE_NORMAL].red   = 0;
6417   style->base[GTK_STATE_NORMAL].green = 45000;
6418   style->base[GTK_STATE_NORMAL].blue  = 55000;
6419   gtk_ctree_node_set_row_data_full (ctree, parent, style,
6420                                     (GtkDestroyNotify) gtk_style_unref);
6421
6422   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
6423     gtk_ctree_node_set_row_style (ctree, parent, style);
6424
6425   build_recursive (ctree, 1, d, b, p, parent);
6426   gtk_clist_thaw (GTK_CLIST (ctree));
6427   after_press (ctree, NULL);
6428 }
6429
6430 static void 
6431 ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
6432 {
6433   GtkCList *clist;
6434
6435   clist = GTK_CLIST (ctree);
6436
6437   if (column == clist->sort_column)
6438     {
6439       if (clist->sort_type == GTK_SORT_ASCENDING)
6440         clist->sort_type = GTK_SORT_DESCENDING;
6441       else
6442         clist->sort_type = GTK_SORT_ASCENDING;
6443     }
6444   else
6445     gtk_clist_set_sort_column (clist, column);
6446
6447   gtk_ctree_sort_recursive (ctree, NULL);
6448 }
6449
6450 void create_ctree (GtkWidget *widget)
6451 {
6452   static GtkWidget *window = NULL;
6453   GtkTooltips *tooltips;
6454   GtkCTree *ctree;
6455   GtkWidget *scrolled_win;
6456   GtkWidget *vbox;
6457   GtkWidget *bbox;
6458   GtkWidget *mbox;
6459   GtkWidget *hbox;
6460   GtkWidget *hbox2;
6461   GtkWidget *frame;
6462   GtkWidget *label;
6463   GtkWidget *button;
6464   GtkWidget *check;
6465   GtkAdjustment *adj;
6466   GtkWidget *spinner;
6467
6468   char *title[] = { "Tree" , "Info" };
6469   char buf[80];
6470
6471   static gchar *items1[] =
6472   {
6473     "No lines",
6474     "Solid",
6475     "Dotted",
6476     "Tabbed"
6477   };
6478
6479   static gchar *items2[] =
6480   {
6481     "None",
6482     "Square",
6483     "Triangle",
6484     "Circular"
6485   };
6486
6487   static gchar *items3[] =
6488   {
6489     "Left",
6490     "Right"
6491   };
6492   
6493   if (!window)
6494     {
6495       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6496       gtk_window_set_screen (GTK_WINDOW (window), 
6497                              gtk_widget_get_screen (widget));
6498
6499       g_signal_connect (window, "destroy",
6500                         G_CALLBACK (gtk_widget_destroyed),
6501                         &window);
6502
6503       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
6504       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6505
6506       tooltips = gtk_tooltips_new ();
6507       g_object_ref (tooltips);
6508       gtk_object_sink (GTK_OBJECT (tooltips));
6509
6510       g_object_set_data_full (G_OBJECT (window), "tooltips", tooltips,
6511                               g_object_unref);
6512
6513       vbox = gtk_vbox_new (FALSE, 0);
6514       gtk_container_add (GTK_CONTAINER (window), vbox);
6515
6516       hbox = gtk_hbox_new (FALSE, 5);
6517       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6518       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
6519       
6520       label = gtk_label_new ("Depth :");
6521       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6522       
6523       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
6524       spin1 = gtk_spin_button_new (adj, 0, 0);
6525       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
6526   
6527       label = gtk_label_new ("Books :");
6528       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6529       
6530       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
6531       spin2 = gtk_spin_button_new (adj, 0, 0);
6532       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
6533
6534       label = gtk_label_new ("Pages :");
6535       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6536       
6537       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
6538       spin3 = gtk_spin_button_new (adj, 0, 0);
6539       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
6540
6541       button = gtk_button_new_with_label ("Close");
6542       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6543
6544       g_signal_connect_swapped (button, "clicked",
6545                                 G_CALLBACK (gtk_widget_destroy),
6546                                 window);
6547
6548       button = gtk_button_new_with_label ("Rebuild Tree");
6549       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6550
6551       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6552       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
6553       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6554                                       GTK_POLICY_AUTOMATIC,
6555                                       GTK_POLICY_ALWAYS);
6556       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6557
6558       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
6559       gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
6560
6561       gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
6562       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
6563       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
6564       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
6565       line_style = GTK_CTREE_LINES_DOTTED;
6566
6567       g_signal_connect (button, "clicked",
6568                         G_CALLBACK (rebuild_tree), ctree);
6569       g_signal_connect (ctree, "click_column",
6570                         G_CALLBACK (ctree_click_column), NULL);
6571
6572       g_signal_connect_after (ctree, "button_press_event",
6573                               G_CALLBACK (after_press), NULL);
6574       g_signal_connect_after (ctree, "button_release_event",
6575                               G_CALLBACK (after_press), NULL);
6576       g_signal_connect_after (ctree, "tree_move",
6577                               G_CALLBACK (after_move), NULL);
6578       g_signal_connect_after (ctree, "end_selection",
6579                               G_CALLBACK (after_press), NULL);
6580       g_signal_connect_after (ctree, "toggle_focus_row",
6581                               G_CALLBACK (after_press), NULL);
6582       g_signal_connect_after (ctree, "select_all",
6583                               G_CALLBACK (after_press), NULL);
6584       g_signal_connect_after (ctree, "unselect_all",
6585                               G_CALLBACK (after_press), NULL);
6586       g_signal_connect_after (ctree, "scroll_vertical",
6587                               G_CALLBACK (after_press), NULL);
6588
6589       bbox = gtk_hbox_new (FALSE, 5);
6590       gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
6591       gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, TRUE, 0);
6592
6593       mbox = gtk_vbox_new (TRUE, 5);
6594       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6595
6596       label = gtk_label_new ("Row Height :");
6597       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6598
6599       label = gtk_label_new ("Indent :");
6600       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6601
6602       label = gtk_label_new ("Spacing :");
6603       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6604
6605       mbox = gtk_vbox_new (TRUE, 5);
6606       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6607
6608       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
6609       spinner = gtk_spin_button_new (adj, 0, 0);
6610       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6611       gtk_tooltips_set_tip (tooltips, spinner,
6612                             "Row height of list items", NULL);
6613       g_signal_connect (adj, "value_changed",
6614                         G_CALLBACK (change_row_height), ctree);
6615       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
6616
6617       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
6618       spinner = gtk_spin_button_new (adj, 0, 0);
6619       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6620       gtk_tooltips_set_tip (tooltips, spinner, "Tree Indentation.", NULL);
6621       g_signal_connect (adj, "value_changed",
6622                         G_CALLBACK (change_indent), ctree);
6623
6624       adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 60, 1, 10, 0);
6625       spinner = gtk_spin_button_new (adj, 0, 0);
6626       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6627       gtk_tooltips_set_tip (tooltips, spinner, "Tree Spacing.", NULL);
6628       g_signal_connect (adj, "value_changed",
6629                         G_CALLBACK (change_spacing), ctree);
6630
6631       mbox = gtk_vbox_new (TRUE, 5);
6632       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6633
6634       hbox = gtk_hbox_new (FALSE, 5);
6635       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6636
6637       button = gtk_button_new_with_label ("Expand All");
6638       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6639       g_signal_connect (button, "clicked",
6640                         G_CALLBACK (expand_all), ctree);
6641
6642       button = gtk_button_new_with_label ("Collapse All");
6643       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6644       g_signal_connect (button, "clicked",
6645                         G_CALLBACK (collapse_all), ctree);
6646
6647       button = gtk_button_new_with_label ("Change Style");
6648       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6649       g_signal_connect (button, "clicked",
6650                         G_CALLBACK (change_style), ctree);
6651
6652       button = gtk_button_new_with_label ("Export Tree");
6653       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6654       g_signal_connect (button, "clicked",
6655                         G_CALLBACK (export_ctree), ctree);
6656
6657       hbox = gtk_hbox_new (FALSE, 5);
6658       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6659
6660       button = gtk_button_new_with_label ("Select All");
6661       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6662       g_signal_connect (button, "clicked",
6663                         G_CALLBACK (select_all), ctree);
6664
6665       button = gtk_button_new_with_label ("Unselect All");
6666       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6667       g_signal_connect (button, "clicked",
6668                         G_CALLBACK (unselect_all), ctree);
6669
6670       button = gtk_button_new_with_label ("Remove Selection");
6671       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6672       g_signal_connect (button, "clicked",
6673                         G_CALLBACK (remove_selection), ctree);
6674
6675       check = gtk_check_button_new_with_label ("Reorderable");
6676       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
6677       gtk_tooltips_set_tip (tooltips, check,
6678                             "Tree items can be reordered by dragging.", NULL);
6679       g_signal_connect (check, "clicked",
6680                         G_CALLBACK (toggle_reorderable), ctree);
6681       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
6682
6683       hbox = gtk_hbox_new (TRUE, 5);
6684       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6685
6686       omenu1 = build_option_menu (items1, 4, 2, 
6687                                   ctree_toggle_line_style,
6688                                   ctree);
6689       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
6690       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
6691
6692       omenu2 = build_option_menu (items2, 4, 1, 
6693                                   ctree_toggle_expander_style,
6694                                   ctree);
6695       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
6696       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's expander style.",
6697                             NULL);
6698
6699       omenu3 = build_option_menu (items3, 2, 0, 
6700                                   ctree_toggle_justify, ctree);
6701       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
6702       gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.",
6703                             NULL);
6704
6705       omenu4 = build_option_menu (selection_mode_items, 3, 3, 
6706                                   ctree_toggle_sel_mode, ctree);
6707       gtk_box_pack_start (GTK_BOX (hbox), omenu4, FALSE, TRUE, 0);
6708       gtk_tooltips_set_tip (tooltips, omenu4, "The list's selection mode.",
6709                             NULL);
6710
6711       gtk_widget_realize (window);
6712       
6713       gtk_widget_set_size_request (GTK_WIDGET (ctree), -1, 300);
6714
6715       frame = gtk_frame_new (NULL);
6716       gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
6717       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
6718       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
6719
6720       hbox = gtk_hbox_new (TRUE, 2);
6721       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
6722       gtk_container_add (GTK_CONTAINER (frame), hbox);
6723
6724       frame = gtk_frame_new (NULL);
6725       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6726       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6727
6728       hbox2 = gtk_hbox_new (FALSE, 0);
6729       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6730       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6731
6732       label = gtk_label_new ("Books :");
6733       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6734
6735       sprintf (buf, "%d", books);
6736       book_label = gtk_label_new (buf);
6737       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
6738
6739       frame = gtk_frame_new (NULL);
6740       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6741       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6742
6743       hbox2 = gtk_hbox_new (FALSE, 0);
6744       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6745       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6746
6747       label = gtk_label_new ("Pages :");
6748       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6749
6750       sprintf (buf, "%d", pages);
6751       page_label = gtk_label_new (buf);
6752       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
6753
6754       frame = gtk_frame_new (NULL);
6755       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6756       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6757
6758       hbox2 = gtk_hbox_new (FALSE, 0);
6759       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6760       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6761
6762       label = gtk_label_new ("Selected :");
6763       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6764
6765       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
6766       sel_label = gtk_label_new (buf);
6767       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
6768
6769       frame = gtk_frame_new (NULL);
6770       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6771       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6772
6773       hbox2 = gtk_hbox_new (FALSE, 0);
6774       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6775       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6776
6777       label = gtk_label_new ("Visible :");
6778       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6779
6780       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
6781       vis_label = gtk_label_new (buf);
6782       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
6783
6784       rebuild_tree (NULL, ctree);
6785     }
6786
6787   if (!GTK_WIDGET_VISIBLE (window))
6788     gtk_widget_show_all (window);
6789   else
6790     gtk_widget_destroy (window);
6791 }
6792
6793 /*
6794  * GtkColorSelection
6795  */
6796
6797 void
6798 color_selection_ok (GtkWidget               *w,
6799                     GtkColorSelectionDialog *cs)
6800 {
6801   GtkColorSelection *colorsel;
6802   gdouble color[4];
6803
6804   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
6805
6806   gtk_color_selection_get_color(colorsel,color);
6807   gtk_color_selection_set_color(colorsel,color);
6808 }
6809
6810 void
6811 color_selection_changed (GtkWidget *w,
6812                          GtkColorSelectionDialog *cs)
6813 {
6814   GtkColorSelection *colorsel;
6815   gdouble color[4];
6816
6817   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
6818   gtk_color_selection_get_color(colorsel,color);
6819 }
6820
6821 static void
6822 opacity_toggled_cb (GtkWidget *w,
6823                     GtkColorSelectionDialog *cs)
6824 {
6825   GtkColorSelection *colorsel;
6826
6827   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
6828   gtk_color_selection_set_has_opacity_control (colorsel,
6829                                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
6830 }
6831
6832 static void
6833 palette_toggled_cb (GtkWidget *w,
6834                     GtkColorSelectionDialog *cs)
6835 {
6836   GtkColorSelection *colorsel;
6837
6838   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
6839   gtk_color_selection_set_has_palette (colorsel,
6840                                        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
6841 }
6842
6843 void
6844 create_color_selection (GtkWidget *widget)
6845 {
6846   static GtkWidget *window = NULL;
6847
6848   if (!window)
6849     {
6850       GtkWidget *options_hbox;
6851       GtkWidget *check_button;
6852       
6853       window = gtk_color_selection_dialog_new ("color selection dialog");
6854       gtk_window_set_screen (GTK_WINDOW (window), 
6855                              gtk_widget_get_screen (widget));
6856                              
6857       gtk_widget_show (GTK_COLOR_SELECTION_DIALOG (window)->help_button);
6858
6859       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
6860
6861       g_signal_connect (window, "destroy",
6862                         G_CALLBACK(gtk_widget_destroyed),
6863                         &window);
6864
6865       options_hbox = gtk_hbox_new (FALSE, 0);
6866       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), options_hbox, FALSE, FALSE, 0);
6867       gtk_container_set_border_width (GTK_CONTAINER (options_hbox), 10);
6868       
6869       check_button = gtk_check_button_new_with_label ("Show Opacity");
6870       gtk_box_pack_start (GTK_BOX (options_hbox), check_button, FALSE, FALSE, 0);
6871       g_signal_connect (check_button, "toggled",
6872                         G_CALLBACK (opacity_toggled_cb), window);
6873
6874       check_button = gtk_check_button_new_with_label ("Show Palette");
6875       gtk_box_pack_end (GTK_BOX (options_hbox), check_button, FALSE, FALSE, 0);
6876       g_signal_connect (check_button, "toggled",
6877                         G_CALLBACK (palette_toggled_cb), window);
6878
6879       g_signal_connect (GTK_COLOR_SELECTION_DIALOG (window)->colorsel,
6880                         "color_changed",
6881                         G_CALLBACK (color_selection_changed),
6882                         window);
6883
6884       g_signal_connect (GTK_COLOR_SELECTION_DIALOG (window)->ok_button,
6885                         "clicked",
6886                         G_CALLBACK (color_selection_ok),
6887                         window);
6888
6889       g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button,
6890                                 "clicked",
6891                                 G_CALLBACK (gtk_widget_destroy),
6892                                 window);
6893     }
6894
6895   if (!GTK_WIDGET_VISIBLE (window))
6896     gtk_widget_show_all (window);
6897   else
6898     gtk_widget_destroy (window);
6899 }
6900
6901 /*
6902  * GtkFileSelection
6903  */
6904
6905 void
6906 show_fileops (GtkWidget        *widget,
6907               GtkFileSelection *fs)
6908 {
6909   gboolean show_ops;
6910
6911   show_ops = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6912
6913   if (show_ops)
6914     gtk_file_selection_show_fileop_buttons (fs);
6915   else
6916     gtk_file_selection_hide_fileop_buttons (fs);
6917 }
6918
6919 void
6920 select_multiple (GtkWidget        *widget,
6921                  GtkFileSelection *fs)
6922 {
6923   gboolean select_multiple;
6924
6925   select_multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6926   gtk_file_selection_set_select_multiple (fs, select_multiple);
6927 }
6928
6929 void
6930 file_selection_ok (GtkFileSelection *fs)
6931 {
6932   int i;
6933   gchar **selections;
6934
6935   selections = gtk_file_selection_get_selections (fs);
6936
6937   for (i = 0; selections[i] != NULL; i++)
6938     g_print ("%s\n", selections[i]);
6939
6940   g_strfreev (selections);
6941
6942   gtk_widget_destroy (GTK_WIDGET (fs));
6943 }
6944
6945 void
6946 create_file_selection (GtkWidget *widget)
6947 {
6948   static GtkWidget *window = NULL;
6949   GtkWidget *button;
6950
6951   if (!window)
6952     {
6953       window = gtk_file_selection_new ("file selection dialog");
6954       gtk_window_set_screen (GTK_WINDOW (window),
6955                              gtk_widget_get_screen (widget));
6956
6957       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
6958
6959       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
6960
6961       g_signal_connect (window, "destroy",
6962                         G_CALLBACK (gtk_widget_destroyed),
6963                         &window);
6964
6965       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->ok_button,
6966                                 "clicked",
6967                                 G_CALLBACK (file_selection_ok),
6968                                 window);
6969       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->cancel_button,
6970                                 "clicked",
6971                                 G_CALLBACK (gtk_widget_destroy),
6972                                 window);
6973       
6974       button = gtk_check_button_new_with_label ("Show Fileops");
6975       g_signal_connect (button, "toggled",
6976                         G_CALLBACK (show_fileops),
6977                         window);
6978       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
6979                           button, FALSE, FALSE, 0);
6980       gtk_widget_show (button);
6981
6982       button = gtk_check_button_new_with_label ("Select Multiple");
6983       g_signal_connect (button, "clicked",
6984                         G_CALLBACK (select_multiple),
6985                         window);
6986       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
6987                           button, FALSE, FALSE, 0);
6988       gtk_widget_show (button);
6989     }
6990   
6991   if (!GTK_WIDGET_VISIBLE (window))
6992     gtk_widget_show (window);
6993   else
6994     gtk_widget_destroy (window);
6995 }
6996
6997 void
6998 flipping_toggled_cb (GtkWidget *widget, gpointer data)
6999 {
7000   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
7001   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
7002
7003   gtk_widget_set_default_direction (new_direction);
7004 }
7005
7006 static void
7007 set_direction_recurse (GtkWidget *widget,
7008                        gpointer   data)
7009 {
7010   GtkTextDirection *dir = data;
7011   
7012   gtk_widget_set_direction (widget, *dir);
7013   if (GTK_IS_CONTAINER (widget))
7014     gtk_container_foreach (GTK_CONTAINER (widget),
7015                            set_direction_recurse,
7016                            data);
7017 }
7018
7019 static GtkWidget *
7020 create_forward_back (const char       *title,
7021                      GtkTextDirection  text_dir)
7022 {
7023   GtkWidget *frame = gtk_frame_new (title);
7024   GtkWidget *bbox = gtk_hbutton_box_new ();
7025   GtkWidget *back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
7026   GtkWidget *forward_button = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
7027
7028   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
7029   
7030   gtk_container_add (GTK_CONTAINER (frame), bbox);
7031   gtk_container_add (GTK_CONTAINER (bbox), back_button);
7032   gtk_container_add (GTK_CONTAINER (bbox), forward_button);
7033
7034   set_direction_recurse (frame, &text_dir);
7035
7036   return frame;
7037 }
7038
7039 void
7040 create_flipping (GtkWidget *widget)
7041 {
7042   static GtkWidget *window = NULL;
7043   GtkWidget *check_button, *button;
7044
7045   if (!window)
7046     {
7047       window = gtk_dialog_new ();
7048
7049       gtk_window_set_screen (GTK_WINDOW (window),
7050                              gtk_widget_get_screen (widget));
7051
7052       g_signal_connect (window, "destroy",
7053                         G_CALLBACK (gtk_widget_destroyed),
7054                         &window);
7055
7056       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
7057
7058       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
7059       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7060                           check_button, TRUE, TRUE, 0);
7061
7062       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7063                           create_forward_back ("Default", GTK_TEXT_DIR_NONE),
7064                           TRUE, TRUE, 0);
7065
7066       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7067                           create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
7068                           TRUE, TRUE, 0);
7069
7070       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7071                           create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
7072                           TRUE, TRUE, 0);
7073
7074       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
7075         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
7076
7077       g_signal_connect (check_button, "toggled",
7078                         G_CALLBACK (flipping_toggled_cb), FALSE);
7079
7080       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
7081       
7082       button = gtk_button_new_with_label ("Close");
7083       g_signal_connect_swapped (button, "clicked",
7084                                 G_CALLBACK (gtk_widget_destroy), window);
7085       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7086                           button, TRUE, TRUE, 0);
7087     }
7088   
7089   if (!GTK_WIDGET_VISIBLE (window))
7090     gtk_widget_show_all (window);
7091   else
7092     gtk_widget_destroy (window);
7093 }
7094
7095 /*
7096  * Focus test
7097  */
7098
7099 static GtkWidget*
7100 make_focus_table (GList **list)
7101 {
7102   GtkWidget *table;
7103   gint i, j;
7104   
7105   table = gtk_table_new (5, 5, FALSE);
7106
7107   i = 0;
7108   j = 0;
7109
7110   while (i < 5)
7111     {
7112       j = 0;
7113       while (j < 5)
7114         {
7115           GtkWidget *widget;
7116           
7117           if ((i + j) % 2)
7118             widget = gtk_entry_new ();
7119           else
7120             widget = gtk_button_new_with_label ("Foo");
7121
7122           *list = g_list_prepend (*list, widget);
7123           
7124           gtk_table_attach (GTK_TABLE (table),
7125                             widget,
7126                             i, i + 1,
7127                             j, j + 1,
7128                             GTK_EXPAND | GTK_FILL,
7129                             GTK_EXPAND | GTK_FILL,
7130                             5, 5);
7131           
7132           ++j;
7133         }
7134
7135       ++i;
7136     }
7137
7138   *list = g_list_reverse (*list);
7139   
7140   return table;
7141 }
7142
7143 static void
7144 create_focus (GtkWidget *widget)
7145 {
7146   static GtkWidget *window = NULL;
7147   
7148   if (!window)
7149     {
7150       GtkWidget *table;
7151       GtkWidget *frame;
7152       GList *list = NULL;
7153       
7154       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
7155                                             NULL, 0,
7156                                             GTK_STOCK_CLOSE,
7157                                             GTK_RESPONSE_NONE,
7158                                             NULL);
7159
7160       gtk_window_set_screen (GTK_WINDOW (window),
7161                              gtk_widget_get_screen (widget));
7162
7163       g_signal_connect (window, "destroy",
7164                         G_CALLBACK (gtk_widget_destroyed),
7165                         &window);
7166
7167       g_signal_connect (window, "response",
7168                         G_CALLBACK (gtk_widget_destroy),
7169                         NULL);
7170       
7171       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
7172
7173       frame = gtk_frame_new ("Weird tab focus chain");
7174
7175       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7176                           frame, TRUE, TRUE, 0);
7177       
7178       table = make_focus_table (&list);
7179
7180       gtk_container_add (GTK_CONTAINER (frame), table);
7181
7182       gtk_container_set_focus_chain (GTK_CONTAINER (table),
7183                                      list);
7184
7185       g_list_free (list);
7186       
7187       frame = gtk_frame_new ("Default tab focus chain");
7188
7189       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7190                           frame, TRUE, TRUE, 0);
7191
7192       list = NULL;
7193       table = make_focus_table (&list);
7194
7195       g_list_free (list);
7196       
7197       gtk_container_add (GTK_CONTAINER (frame), table);      
7198     }
7199   
7200   if (!GTK_WIDGET_VISIBLE (window))
7201     gtk_widget_show_all (window);
7202   else
7203     gtk_widget_destroy (window);
7204 }
7205
7206 /*
7207  * GtkFontSelection
7208  */
7209
7210 void
7211 font_selection_ok (GtkWidget              *w,
7212                    GtkFontSelectionDialog *fs)
7213 {
7214   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
7215
7216   g_print ("%s\n", s);
7217   g_free (s);
7218   gtk_widget_destroy (GTK_WIDGET (fs));
7219 }
7220
7221 void
7222 create_font_selection (GtkWidget *widget)
7223 {
7224   static GtkWidget *window = NULL;
7225
7226   if (!window)
7227     {
7228       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
7229       
7230       gtk_window_set_screen (GTK_WINDOW (window),
7231                              gtk_widget_get_screen (widget));
7232
7233       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
7234
7235       g_signal_connect (window, "destroy",
7236                         G_CALLBACK (gtk_widget_destroyed),
7237                         &window);
7238
7239       g_signal_connect (GTK_FONT_SELECTION_DIALOG (window)->ok_button,
7240                         "clicked", G_CALLBACK (font_selection_ok),
7241                         GTK_FONT_SELECTION_DIALOG (window));
7242       g_signal_connect_swapped (GTK_FONT_SELECTION_DIALOG (window)->cancel_button,
7243                                 "clicked", G_CALLBACK (gtk_widget_destroy),
7244                                 window);
7245     }
7246   
7247   if (!GTK_WIDGET_VISIBLE (window))
7248     gtk_widget_show (window);
7249   else
7250     gtk_widget_destroy (window);
7251 }
7252
7253 /*
7254  * GtkDialog
7255  */
7256
7257 static GtkWidget *dialog_window = NULL;
7258
7259 static void
7260 label_toggle (GtkWidget  *widget,
7261               GtkWidget **label)
7262 {
7263   if (!(*label))
7264     {
7265       *label = gtk_label_new ("Dialog Test");
7266       g_signal_connect (*label,
7267                         "destroy",
7268                         G_CALLBACK (gtk_widget_destroyed),
7269                         label);
7270       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
7271       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7272                           *label, TRUE, TRUE, 0);
7273       gtk_widget_show (*label);
7274     }
7275   else
7276     gtk_widget_destroy (*label);
7277 }
7278
7279 #define RESPONSE_TOGGLE_SEPARATOR 1
7280
7281 static void
7282 print_response (GtkWidget *dialog,
7283                 gint       response_id,
7284                 gpointer   data)
7285 {
7286   g_print ("response signal received (%d)\n", response_id);
7287
7288   if (response_id == RESPONSE_TOGGLE_SEPARATOR)
7289     {
7290       gtk_dialog_set_has_separator (GTK_DIALOG (dialog),
7291                                     !gtk_dialog_get_has_separator (GTK_DIALOG (dialog)));
7292     }
7293 }
7294
7295 static void
7296 create_dialog (GtkWidget *widget)
7297 {
7298   static GtkWidget *label;
7299   GtkWidget *button;
7300
7301   if (!dialog_window)
7302     {
7303       /* This is a terrible example; it's much simpler to create
7304        * dialogs than this. Don't use testgtk for example code,
7305        * use gtk-demo ;-)
7306        */
7307       
7308       dialog_window = gtk_dialog_new ();
7309       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7310                              gtk_widget_get_screen (widget));
7311
7312       g_signal_connect (dialog_window,
7313                         "response",
7314                         G_CALLBACK (print_response),
7315                         NULL);
7316       
7317       g_signal_connect (dialog_window, "destroy",
7318                         G_CALLBACK (gtk_widget_destroyed),
7319                         &dialog_window);
7320
7321       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
7322       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7323
7324       button = gtk_button_new_with_label ("OK");
7325       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7326       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
7327                           button, TRUE, TRUE, 0);
7328       gtk_widget_grab_default (button);
7329       gtk_widget_show (button);
7330
7331       button = gtk_button_new_with_label ("Toggle");
7332       g_signal_connect (button, "clicked",
7333                         G_CALLBACK (label_toggle),
7334                         &label);
7335       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7336       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7337                           button, TRUE, TRUE, 0);
7338       gtk_widget_show (button);
7339
7340       label = NULL;
7341       
7342       button = gtk_button_new_with_label ("Separator");
7343
7344       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7345
7346       gtk_dialog_add_action_widget (GTK_DIALOG (dialog_window),
7347                                     button,
7348                                     RESPONSE_TOGGLE_SEPARATOR);
7349       gtk_widget_show (button);
7350     }
7351
7352   if (!GTK_WIDGET_VISIBLE (dialog_window))
7353     gtk_widget_show (dialog_window);
7354   else
7355     gtk_widget_destroy (dialog_window);
7356 }
7357
7358 /* Display & Screen test 
7359  */
7360
7361 typedef struct 
7362
7363   GtkEntry *entry;
7364   GtkWidget *radio_dpy;
7365   GtkWidget *toplevel; 
7366   GtkWidget *dialog_window;
7367   GList *valid_display_list;
7368 } ScreenDisplaySelection;
7369
7370 static gint
7371 display_name_cmp (gconstpointer a,
7372                   gconstpointer b)
7373 {
7374   return g_ascii_strcasecmp (a,b);
7375 }
7376
7377 static void
7378 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
7379 {
7380   char *display_name;
7381   GdkDisplay *display = gtk_widget_get_display (widget);
7382   GtkWidget *dialog;
7383   GdkScreen *new_screen = NULL;
7384   GdkScreen *current_screen = gtk_widget_get_screen (widget);
7385   
7386   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
7387     {
7388       display_name = g_strdup (gtk_entry_get_text (data->entry));
7389       display = gdk_display_open (display_name);
7390       
7391       if (!display)
7392         {
7393           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
7394                                            GTK_DIALOG_DESTROY_WITH_PARENT,
7395                                            GTK_MESSAGE_ERROR,
7396                                            GTK_BUTTONS_OK,
7397                                            "The display :\n%s\ncannot be opened",
7398                                            display_name);
7399           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
7400           gtk_widget_show (dialog);
7401           g_signal_connect (dialog, "response",
7402                             G_CALLBACK (gtk_widget_destroy),
7403                             NULL);
7404         }
7405       else
7406         {
7407           if (!g_list_find_custom (data->valid_display_list, 
7408                                    display_name,
7409                                    display_name_cmp))
7410             data->valid_display_list = g_list_append (data->valid_display_list,
7411                                                       display_name);
7412           
7413           new_screen = gdk_display_get_default_screen (display);
7414         }
7415     }
7416   else
7417     {
7418       gint number_of_screens = gdk_display_get_n_screens (display);
7419       gint screen_num = gdk_screen_get_number (current_screen);
7420       if ((screen_num +1) < number_of_screens)
7421         new_screen = gdk_display_get_screen (display, screen_num + 1);
7422       else
7423         new_screen = gdk_display_get_screen (display, 0);
7424     }
7425   
7426   if (new_screen) 
7427     {
7428       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
7429       gtk_widget_destroy (data->dialog_window);
7430     }
7431 }
7432
7433 void
7434 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
7435 {
7436   gtk_widget_destroy (data);
7437 }
7438
7439 void
7440 create_display_screen (GtkWidget *widget)
7441 {
7442   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
7443   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
7444   GtkWidget *bbox;
7445   ScreenDisplaySelection *scr_dpy_data;
7446   GdkScreen *screen = gtk_widget_get_screen (widget);
7447   static GList *valid_display_list = NULL;
7448   
7449   GdkDisplay *display = gdk_screen_get_display (screen);
7450
7451   window = gtk_widget_new (gtk_window_get_type (),
7452                            "screen", screen,
7453                            "user_data", NULL,
7454                            "type", GTK_WINDOW_TOPLEVEL,
7455                            "title",
7456                            "Screen or Display selection",
7457                            "border_width", 10, NULL);
7458   g_signal_connect (window, "destroy", 
7459                     G_CALLBACK (gtk_widget_destroy), NULL);
7460
7461   vbox = gtk_vbox_new (FALSE, 3);
7462   gtk_container_add (GTK_CONTAINER (window), vbox);
7463   
7464   frame = gtk_frame_new ("Select screen or display");
7465   gtk_container_add (GTK_CONTAINER (vbox), frame);
7466   
7467   table = gtk_table_new (2, 2, TRUE);
7468   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
7469   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
7470
7471   gtk_container_add (GTK_CONTAINER (frame), table);
7472
7473   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
7474   if (gdk_display_get_n_screens(display) > 1)
7475     radio_scr = gtk_radio_button_new_with_label 
7476     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
7477   else
7478     {    
7479       radio_scr = gtk_radio_button_new_with_label 
7480         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
7481          "only one screen on the current display");
7482       gtk_widget_set_sensitive (radio_scr, FALSE);
7483     }
7484   combo_dpy = gtk_combo_new ();
7485   if (!valid_display_list)
7486     valid_display_list = g_list_append (valid_display_list, "diabolo:0.0");
7487     
7488   gtk_combo_set_popdown_strings (GTK_COMBO (combo_dpy), valid_display_list);
7489     
7490   gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo_dpy)->entry), 
7491                       "<hostname>:<X Server Num>.<Screen Num>");
7492
7493   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
7494   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
7495   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
7496
7497   bbox = gtk_hbutton_box_new ();
7498   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
7499   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
7500   
7501   gtk_container_add (GTK_CONTAINER (vbox), bbox);
7502
7503   gtk_container_add (GTK_CONTAINER (bbox), applyb);
7504   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
7505
7506   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
7507
7508   scr_dpy_data->entry = GTK_ENTRY (GTK_COMBO (combo_dpy)->entry);
7509   scr_dpy_data->radio_dpy = radio_dpy;
7510   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
7511   scr_dpy_data->dialog_window = window;
7512   scr_dpy_data->valid_display_list = valid_display_list;
7513
7514   g_signal_connect (cancelb, "clicked", 
7515                     G_CALLBACK (screen_display_destroy_diag), window);
7516   g_signal_connect (applyb, "clicked", 
7517                     G_CALLBACK (screen_display_check), scr_dpy_data);
7518   gtk_widget_show_all (window);
7519 }
7520
7521 /* Event Watcher
7522  */
7523 static gboolean event_watcher_enter_id = 0;
7524 static gboolean event_watcher_leave_id = 0;
7525
7526 static gboolean
7527 event_watcher (GSignalInvocationHint *ihint,
7528                guint                  n_param_values,
7529                const GValue          *param_values,
7530                gpointer               data)
7531 {
7532   g_print ("Watch: \"%s\" emitted for %s\n",
7533            g_signal_name (ihint->signal_id),
7534            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
7535
7536   return TRUE;
7537 }
7538
7539 static void
7540 event_watcher_down (void)
7541 {
7542   if (event_watcher_enter_id)
7543     {
7544       guint signal_id;
7545
7546       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7547       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
7548       event_watcher_enter_id = 0;
7549       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7550       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
7551       event_watcher_leave_id = 0;
7552     }
7553 }
7554
7555 static void
7556 event_watcher_toggle (void)
7557 {
7558   if (event_watcher_enter_id)
7559     event_watcher_down ();
7560   else
7561     {
7562       guint signal_id;
7563
7564       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7565       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7566       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7567       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7568     }
7569 }
7570
7571 static void
7572 create_event_watcher (GtkWidget *widget)
7573 {
7574   GtkWidget *button;
7575
7576   if (!dialog_window)
7577     {
7578       dialog_window = gtk_dialog_new ();
7579       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7580                              gtk_widget_get_screen (widget));
7581
7582       g_signal_connect (dialog_window, "destroy",
7583                         G_CALLBACK (gtk_widget_destroyed),
7584                         &dialog_window);
7585       g_signal_connect (dialog_window, "destroy",
7586                         G_CALLBACK (event_watcher_down),
7587                         NULL);
7588
7589       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
7590       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7591       gtk_widget_set_size_request (dialog_window, 200, 110);
7592
7593       button = gtk_toggle_button_new_with_label ("Activate Watch");
7594       g_signal_connect (button, "clicked",
7595                         G_CALLBACK (event_watcher_toggle),
7596                         NULL);
7597       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
7598       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7599                           button, TRUE, TRUE, 0);
7600       gtk_widget_show (button);
7601
7602       button = gtk_button_new_with_label ("Close");
7603       g_signal_connect_swapped (button, "clicked",
7604                                 G_CALLBACK (gtk_widget_destroy),
7605                                 dialog_window);
7606       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7607       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7608                           button, TRUE, TRUE, 0);
7609       gtk_widget_grab_default (button);
7610       gtk_widget_show (button);
7611     }
7612
7613   if (!GTK_WIDGET_VISIBLE (dialog_window))
7614     gtk_widget_show (dialog_window);
7615   else
7616     gtk_widget_destroy (dialog_window);
7617 }
7618
7619 /*
7620  * GtkRange
7621  */
7622
7623 static gchar*
7624 reformat_value (GtkScale *scale,
7625                 gdouble   value)
7626 {
7627   return g_strdup_printf ("-->%0.*g<--",
7628                           gtk_scale_get_digits (scale), value);
7629 }
7630
7631 static void
7632 create_range_controls (GtkWidget *widget)
7633 {
7634   static GtkWidget *window = NULL;
7635   GtkWidget *box1;
7636   GtkWidget *box2;
7637   GtkWidget *button;
7638   GtkWidget *scrollbar;
7639   GtkWidget *scale;
7640   GtkWidget *separator;
7641   GtkObject *adjustment;
7642   GtkWidget *hbox;
7643
7644   if (!window)
7645     {
7646       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7647
7648       gtk_window_set_screen (GTK_WINDOW (window),
7649                              gtk_widget_get_screen (widget));
7650
7651       g_signal_connect (window, "destroy",
7652                         G_CALLBACK (gtk_widget_destroyed),
7653                         &window);
7654
7655       gtk_window_set_title (GTK_WINDOW (window), "range controls");
7656       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7657
7658
7659       box1 = gtk_vbox_new (FALSE, 0);
7660       gtk_container_add (GTK_CONTAINER (window), box1);
7661       gtk_widget_show (box1);
7662
7663
7664       box2 = gtk_vbox_new (FALSE, 10);
7665       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7666       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7667       gtk_widget_show (box2);
7668
7669
7670       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
7671
7672       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7673       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
7674       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
7675       gtk_scale_set_digits (GTK_SCALE (scale), 1);
7676       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7677       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7678       gtk_widget_show (scale);
7679
7680       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
7681       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
7682                                    GTK_UPDATE_CONTINUOUS);
7683       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
7684       gtk_widget_show (scrollbar);
7685
7686       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7687       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7688       g_signal_connect (scale,
7689                         "format_value",
7690                         G_CALLBACK (reformat_value),
7691                         NULL);
7692       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7693       gtk_widget_show (scale);
7694       
7695       hbox = gtk_hbox_new (FALSE, 0);
7696
7697       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7698       gtk_widget_set_size_request (scale, -1, 200);
7699       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7700       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7701       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7702       gtk_widget_show (scale);
7703
7704       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7705       gtk_widget_set_size_request (scale, -1, 200);
7706       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7707       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7708       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
7709       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7710       gtk_widget_show (scale);
7711
7712       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7713       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7714       g_signal_connect (scale,
7715                         "format_value",
7716                         G_CALLBACK (reformat_value),
7717                         NULL);
7718       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7719       gtk_widget_show (scale);
7720
7721       
7722       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
7723       gtk_widget_show (hbox);
7724       
7725       separator = gtk_hseparator_new ();
7726       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7727       gtk_widget_show (separator);
7728
7729
7730       box2 = gtk_vbox_new (FALSE, 10);
7731       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7732       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7733       gtk_widget_show (box2);
7734
7735
7736       button = gtk_button_new_with_label ("close");
7737       g_signal_connect_swapped (button, "clicked",
7738                                 G_CALLBACK (gtk_widget_destroy),
7739                                 window);
7740       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7741       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7742       gtk_widget_grab_default (button);
7743       gtk_widget_show (button);
7744     }
7745
7746   if (!GTK_WIDGET_VISIBLE (window))
7747     gtk_widget_show (window);
7748   else
7749     gtk_widget_destroy (window);
7750 }
7751
7752 /*
7753  * GtkRulers
7754  */
7755
7756 void
7757 create_rulers (GtkWidget *widget)
7758 {
7759   static GtkWidget *window = NULL;
7760   GtkWidget *table;
7761   GtkWidget *ruler;
7762
7763   if (!window)
7764     {
7765       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7766
7767       gtk_window_set_screen (GTK_WINDOW (window),
7768                              gtk_widget_get_screen (widget));
7769
7770       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
7771
7772       g_signal_connect (window, "destroy",
7773                         G_CALLBACK (gtk_widget_destroyed),
7774                         &window);
7775
7776       gtk_window_set_title (GTK_WINDOW (window), "rulers");
7777       gtk_widget_set_size_request (window, 300, 300);
7778       gtk_widget_set_events (window, 
7779                              GDK_POINTER_MOTION_MASK 
7780                              | GDK_POINTER_MOTION_HINT_MASK);
7781       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7782
7783       table = gtk_table_new (2, 2, FALSE);
7784       gtk_container_add (GTK_CONTAINER (window), table);
7785       gtk_widget_show (table);
7786
7787       ruler = gtk_hruler_new ();
7788       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
7789       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
7790
7791       g_signal_connect_swapped (window, 
7792                                 "motion_notify_event",
7793                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7794                                 ruler);
7795       
7796       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
7797                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
7798       gtk_widget_show (ruler);
7799
7800
7801       ruler = gtk_vruler_new ();
7802       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
7803
7804       g_signal_connect_swapped (window, 
7805                                 "motion_notify_event",
7806                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7807                                 ruler);
7808       
7809       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
7810                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
7811       gtk_widget_show (ruler);
7812     }
7813
7814   if (!GTK_WIDGET_VISIBLE (window))
7815     gtk_widget_show (window);
7816   else
7817     gtk_widget_destroy (window);
7818 }
7819
7820 static void
7821 text_toggle_editable (GtkWidget *checkbutton,
7822                        GtkWidget *text)
7823 {
7824    gtk_text_set_editable(GTK_TEXT(text),
7825                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7826 }
7827
7828 static void
7829 text_toggle_word_wrap (GtkWidget *checkbutton,
7830                        GtkWidget *text)
7831 {
7832    gtk_text_set_word_wrap(GTK_TEXT(text),
7833                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7834 }
7835
7836 struct {
7837   GdkColor color;
7838   gchar *name;
7839 } text_colors[] = {
7840  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
7841  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
7842  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
7843  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
7844  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
7845  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
7846  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
7847  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
7848 };
7849
7850 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
7851
7852 /*
7853  * GtkText
7854  */
7855 void
7856 text_insert_random (GtkWidget *w, GtkText *text)
7857 {
7858   int i;
7859   char c;
7860    for (i=0; i<10; i++)
7861     {
7862       c = 'A' + rand() % ('Z' - 'A');
7863       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
7864       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
7865     }
7866 }
7867
7868 void
7869 create_text (GtkWidget *widget)
7870 {
7871   int i, j;
7872
7873   static GtkWidget *window = NULL;
7874   GtkWidget *box1;
7875   GtkWidget *box2;
7876   GtkWidget *hbox;
7877   GtkWidget *button;
7878   GtkWidget *check;
7879   GtkWidget *separator;
7880   GtkWidget *scrolled_window;
7881   GtkWidget *text;
7882
7883   FILE *infile;
7884
7885   if (!window)
7886     {
7887       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7888       gtk_window_set_screen (GTK_WINDOW (window),
7889                              gtk_widget_get_screen (widget));
7890
7891       gtk_widget_set_name (window, "text window");
7892       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
7893       gtk_widget_set_size_request (window, 500, 500);
7894
7895       g_signal_connect (window, "destroy",
7896                         G_CALLBACK (gtk_widget_destroyed),
7897                         &window);
7898
7899       gtk_window_set_title (GTK_WINDOW (window), "test");
7900       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7901
7902
7903       box1 = gtk_vbox_new (FALSE, 0);
7904       gtk_container_add (GTK_CONTAINER (window), box1);
7905       gtk_widget_show (box1);
7906
7907
7908       box2 = gtk_vbox_new (FALSE, 10);
7909       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7910       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7911       gtk_widget_show (box2);
7912
7913
7914       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
7915       gtk_box_pack_start (GTK_BOX (box2), scrolled_window, TRUE, TRUE, 0);
7916       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
7917                                       GTK_POLICY_NEVER,
7918                                       GTK_POLICY_ALWAYS);
7919       gtk_widget_show (scrolled_window);
7920
7921       text = gtk_text_new (NULL, NULL);
7922       gtk_text_set_editable (GTK_TEXT (text), TRUE);
7923       gtk_container_add (GTK_CONTAINER (scrolled_window), text);
7924       gtk_widget_grab_focus (text);
7925       gtk_widget_show (text);
7926
7927
7928       gtk_text_freeze (GTK_TEXT (text));
7929
7930       for (i=0; i<ntext_colors; i++)
7931         {
7932           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, 
7933                            text_colors[i].name, -1);
7934           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\t", -1);
7935
7936           for (j=0; j<ntext_colors; j++)
7937             {
7938               gtk_text_insert (GTK_TEXT (text), NULL,
7939                                &text_colors[j].color, &text_colors[i].color,
7940                                "XYZ", -1);
7941             }
7942           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
7943         }
7944
7945       infile = fopen("testgtk.c", "r");
7946       
7947       if (infile)
7948         {
7949           char *buffer;
7950           int nbytes_read, nbytes_alloc;
7951           
7952           nbytes_read = 0;
7953           nbytes_alloc = 1024;
7954           buffer = g_new (char, nbytes_alloc);
7955           while (1)
7956             {
7957               int len;
7958               if (nbytes_alloc < nbytes_read + 1024)
7959                 {
7960                   nbytes_alloc *= 2;
7961                   buffer = g_realloc (buffer, nbytes_alloc);
7962                 }
7963               len = fread (buffer + nbytes_read, 1, 1024, infile);
7964               nbytes_read += len;
7965               if (len < 1024)
7966                 break;
7967             }
7968           
7969           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
7970                            NULL, buffer, nbytes_read);
7971           g_free(buffer);
7972           fclose (infile);
7973         }
7974       
7975       gtk_text_thaw (GTK_TEXT (text));
7976
7977       hbox = gtk_hbutton_box_new ();
7978       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
7979       gtk_widget_show (hbox);
7980
7981       check = gtk_check_button_new_with_label("Editable");
7982       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
7983       g_signal_connect (check, "toggled",
7984                         G_CALLBACK (text_toggle_editable), text);
7985       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
7986       gtk_widget_show (check);
7987
7988       check = gtk_check_button_new_with_label("Wrap Words");
7989       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
7990       g_signal_connect (check, "toggled",
7991                         G_CALLBACK (text_toggle_word_wrap), text);
7992       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
7993       gtk_widget_show (check);
7994
7995       separator = gtk_hseparator_new ();
7996       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7997       gtk_widget_show (separator);
7998
7999
8000       box2 = gtk_vbox_new (FALSE, 10);
8001       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8002       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8003       gtk_widget_show (box2);
8004
8005
8006       button = gtk_button_new_with_label ("insert random");
8007       g_signal_connect (button, "clicked",
8008                         G_CALLBACK (text_insert_random),
8009                         text);
8010       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8011       gtk_widget_show (button);
8012
8013       button = gtk_button_new_with_label ("close");
8014       g_signal_connect_swapped (button, "clicked",
8015                                 G_CALLBACK (gtk_widget_destroy),
8016                                 window);
8017       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8018       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8019       gtk_widget_grab_default (button);
8020       gtk_widget_show (button);
8021     }
8022
8023   if (!GTK_WIDGET_VISIBLE (window))
8024     gtk_widget_show (window);
8025   else
8026     gtk_widget_destroy (window);
8027 }
8028
8029 /*
8030  * GtkNotebook
8031  */
8032
8033 GdkPixbuf *book_open;
8034 GdkPixbuf *book_closed;
8035 GtkWidget *sample_notebook;
8036
8037 static void
8038 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
8039 {
8040   GtkWidget *page_widget;
8041   GtkWidget *pixwid;
8042
8043   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
8044
8045   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
8046   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
8047   
8048   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
8049   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
8050 }
8051
8052 static void
8053 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
8054 {
8055   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
8056   gint old_page_num = gtk_notebook_get_current_page (notebook);
8057  
8058   if (page_num == old_page_num)
8059     return;
8060
8061   set_page_image (notebook, page_num, book_open);
8062
8063   if (old_page_num != -1)
8064     set_page_image (notebook, old_page_num, book_closed);
8065 }
8066
8067 static void
8068 tab_fill (GtkToggleButton *button, GtkWidget *child)
8069 {
8070   gboolean expand;
8071   GtkPackType pack_type;
8072
8073   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8074                                         &expand, NULL, &pack_type);
8075   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8076                                       expand, button->active, pack_type);
8077 }
8078
8079 static void
8080 tab_expand (GtkToggleButton *button, GtkWidget *child)
8081 {
8082   gboolean fill;
8083   GtkPackType pack_type;
8084
8085   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8086                                         NULL, &fill, &pack_type);
8087   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8088                                       button->active, fill, pack_type);
8089 }
8090
8091 static void
8092 tab_pack (GtkToggleButton *button, GtkWidget *child)
8093           
8094
8095   gboolean expand;
8096   gboolean fill;
8097
8098   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8099                                         &expand, &fill, NULL);
8100   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8101                                       expand, fill, button->active);
8102 }
8103
8104 static void
8105 create_pages (GtkNotebook *notebook, gint start, gint end)
8106 {
8107   GtkWidget *child = NULL;
8108   GtkWidget *button;
8109   GtkWidget *label;
8110   GtkWidget *hbox;
8111   GtkWidget *vbox;
8112   GtkWidget *label_box;
8113   GtkWidget *menu_box;
8114   GtkWidget *pixwid;
8115   gint i;
8116   char buffer[32];
8117   char accel_buffer[32];
8118
8119   for (i = start; i <= end; i++)
8120     {
8121       sprintf (buffer, "Page %d", i);
8122       sprintf (accel_buffer, "Page _%d", i);
8123
8124       child = gtk_frame_new (buffer);
8125       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
8126
8127       vbox = gtk_vbox_new (TRUE,0);
8128       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8129       gtk_container_add (GTK_CONTAINER (child), vbox);
8130
8131       hbox = gtk_hbox_new (TRUE,0);
8132       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
8133
8134       button = gtk_check_button_new_with_label ("Fill Tab");
8135       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8136       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8137       g_signal_connect (button, "toggled",
8138                         G_CALLBACK (tab_fill), child);
8139
8140       button = gtk_check_button_new_with_label ("Expand Tab");
8141       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8142       g_signal_connect (button, "toggled",
8143                         G_CALLBACK (tab_expand), child);
8144
8145       button = gtk_check_button_new_with_label ("Pack end");
8146       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8147       g_signal_connect (button, "toggled",
8148                         G_CALLBACK (tab_pack), child);
8149
8150       button = gtk_button_new_with_label ("Hide Page");
8151       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
8152       g_signal_connect_swapped (button, "clicked",
8153                                 G_CALLBACK (gtk_widget_hide),
8154                                 child);
8155
8156       gtk_widget_show_all (child);
8157
8158       label_box = gtk_hbox_new (FALSE, 0);
8159       pixwid = gtk_image_new_from_pixbuf (book_closed);
8160       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
8161                            
8162       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
8163       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8164       label = gtk_label_new_with_mnemonic (accel_buffer);
8165       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
8166       gtk_widget_show_all (label_box);
8167       
8168                                        
8169       menu_box = gtk_hbox_new (FALSE, 0);
8170       pixwid = gtk_image_new_from_pixbuf (book_closed);
8171       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
8172       
8173       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
8174       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8175       label = gtk_label_new (buffer);
8176       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
8177       gtk_widget_show_all (menu_box);
8178
8179       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
8180     }
8181 }
8182
8183 static void
8184 rotate_notebook (GtkButton   *button,
8185                  GtkNotebook *notebook)
8186 {
8187   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
8188 }
8189
8190 static void
8191 show_all_pages (GtkButton   *button,
8192                 GtkNotebook *notebook)
8193 {  
8194   gtk_container_foreach (GTK_CONTAINER (notebook),
8195                          (GtkCallback) gtk_widget_show, NULL);
8196 }
8197
8198 static void
8199 notebook_type_changed (GtkWidget *optionmenu,
8200                        gpointer   data)
8201 {
8202   GtkNotebook *notebook;
8203   gint i, c;
8204
8205   enum {
8206     STANDARD,
8207     NOTABS,
8208     BORDERLESS,
8209     SCROLLABLE
8210   };
8211
8212   notebook = GTK_NOTEBOOK (data);
8213
8214   c = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu));
8215
8216   switch (c)
8217     {
8218     case STANDARD:
8219       /* standard notebook */
8220       gtk_notebook_set_show_tabs (notebook, TRUE);
8221       gtk_notebook_set_show_border (notebook, TRUE);
8222       gtk_notebook_set_scrollable (notebook, FALSE);
8223       break;
8224
8225     case NOTABS:
8226       /* notabs notebook */
8227       gtk_notebook_set_show_tabs (notebook, FALSE);
8228       gtk_notebook_set_show_border (notebook, TRUE);
8229       break;
8230
8231     case BORDERLESS:
8232       /* borderless */
8233       gtk_notebook_set_show_tabs (notebook, FALSE);
8234       gtk_notebook_set_show_border (notebook, FALSE);
8235       break;
8236
8237     case SCROLLABLE:  
8238       /* scrollable */
8239       gtk_notebook_set_show_tabs (notebook, TRUE);
8240       gtk_notebook_set_show_border (notebook, TRUE);
8241       gtk_notebook_set_scrollable (notebook, TRUE);
8242       if (g_list_length (notebook->children) == 5)
8243         create_pages (notebook, 6, 15);
8244       
8245       return;
8246       break;
8247     }
8248   
8249   if (g_list_length (notebook->children) == 15)
8250     for (i = 0; i < 10; i++)
8251       gtk_notebook_remove_page (notebook, 5);
8252 }
8253
8254 static void
8255 notebook_popup (GtkToggleButton *button,
8256                 GtkNotebook     *notebook)
8257 {
8258   if (button->active)
8259     gtk_notebook_popup_enable (notebook);
8260   else
8261     gtk_notebook_popup_disable (notebook);
8262 }
8263
8264 static void
8265 notebook_homogeneous (GtkToggleButton *button,
8266                       GtkNotebook     *notebook)
8267 {
8268   g_object_set (G_OBJECT (notebook), "homogeneous", button->active, NULL);
8269 }
8270
8271 static void
8272 create_notebook (GtkWidget *widget)
8273 {
8274   static GtkWidget *window = NULL;
8275   GtkWidget *box1;
8276   GtkWidget *box2;
8277   GtkWidget *button;
8278   GtkWidget *separator;
8279   GtkWidget *omenu;
8280   GtkWidget *label;
8281
8282   static gchar *items[] =
8283   {
8284     "Standard",
8285     "No tabs",
8286     "Borderless",
8287     "Scrollable"
8288   };
8289   
8290   if (!window)
8291     {
8292       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8293       gtk_window_set_screen (GTK_WINDOW (window),
8294                              gtk_widget_get_screen (widget));
8295
8296       g_signal_connect (window, "destroy",
8297                         G_CALLBACK (gtk_widget_destroyed),
8298                         &window);
8299
8300       gtk_window_set_title (GTK_WINDOW (window), "notebook");
8301       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8302
8303       box1 = gtk_vbox_new (FALSE, 0);
8304       gtk_container_add (GTK_CONTAINER (window), box1);
8305
8306       sample_notebook = gtk_notebook_new ();
8307       g_signal_connect (sample_notebook, "switch_page",
8308                         G_CALLBACK (page_switch), NULL);
8309       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
8310       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
8311       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
8312
8313       gtk_widget_realize (sample_notebook);
8314
8315       if (!book_open)
8316         book_open = gdk_pixbuf_new_from_xpm_data ((const char **)book_open_xpm);
8317                                                   
8318       if (!book_closed)
8319         book_closed = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
8320
8321       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
8322
8323       separator = gtk_hseparator_new ();
8324       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
8325       
8326       box2 = gtk_hbox_new (FALSE, 5);
8327       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8328       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8329
8330       button = gtk_check_button_new_with_label ("popup menu");
8331       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8332       g_signal_connect (button, "clicked",
8333                         G_CALLBACK (notebook_popup),
8334                         sample_notebook);
8335
8336       button = gtk_check_button_new_with_label ("homogeneous tabs");
8337       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8338       g_signal_connect (button, "clicked",
8339                         G_CALLBACK (notebook_homogeneous),
8340                         sample_notebook);
8341
8342       box2 = gtk_hbox_new (FALSE, 5);
8343       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8344       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8345
8346       label = gtk_label_new ("Notebook Style :");
8347       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
8348
8349       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
8350                                  notebook_type_changed,
8351                                  sample_notebook);
8352       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
8353
8354       button = gtk_button_new_with_label ("Show all Pages");
8355       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
8356       g_signal_connect (button, "clicked",
8357                         G_CALLBACK (show_all_pages), sample_notebook);
8358
8359       box2 = gtk_hbox_new (TRUE, 10);
8360       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8361       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8362
8363       button = gtk_button_new_with_label ("prev");
8364       g_signal_connect_swapped (button, "clicked",
8365                                 G_CALLBACK (gtk_notebook_prev_page),
8366                                 sample_notebook);
8367       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8368
8369       button = gtk_button_new_with_label ("next");
8370       g_signal_connect_swapped (button, "clicked",
8371                                 G_CALLBACK (gtk_notebook_next_page),
8372                                 sample_notebook);
8373       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8374
8375       button = gtk_button_new_with_label ("rotate");
8376       g_signal_connect (button, "clicked",
8377                         G_CALLBACK (rotate_notebook), sample_notebook);
8378       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8379
8380       separator = gtk_hseparator_new ();
8381       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
8382
8383       button = gtk_button_new_with_label ("close");
8384       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
8385       g_signal_connect_swapped (button, "clicked",
8386                                 G_CALLBACK (gtk_widget_destroy),
8387                                 window);
8388       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
8389       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8390       gtk_widget_grab_default (button);
8391     }
8392
8393   if (!GTK_WIDGET_VISIBLE (window))
8394     gtk_widget_show_all (window);
8395   else
8396     gtk_widget_destroy (window);
8397 }
8398
8399 /*
8400  * GtkPanes
8401  */
8402
8403 void
8404 toggle_resize (GtkWidget *widget, GtkWidget *child)
8405 {
8406   GtkPaned *paned = GTK_PANED (child->parent);
8407   gboolean is_child1 = (child == paned->child1);
8408   gboolean resize, shrink;
8409
8410   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8411   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8412
8413   gtk_widget_ref (child);
8414   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8415   if (is_child1)
8416     gtk_paned_pack1 (paned, child, !resize, shrink);
8417   else
8418     gtk_paned_pack2 (paned, child, !resize, shrink);
8419   gtk_widget_unref (child);
8420 }
8421
8422 void
8423 toggle_shrink (GtkWidget *widget, GtkWidget *child)
8424 {
8425   GtkPaned *paned = GTK_PANED (child->parent);
8426   gboolean is_child1 = (child == paned->child1);
8427   gboolean resize, shrink;
8428
8429   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8430   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8431
8432   gtk_widget_ref (child);
8433   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8434   if (is_child1)
8435     gtk_paned_pack1 (paned, child, resize, !shrink);
8436   else
8437     gtk_paned_pack2 (paned, child, resize, !shrink);
8438   gtk_widget_unref (child);
8439 }
8440
8441 static void
8442 paned_props_clicked (GtkWidget *button,
8443                      GObject   *paned)
8444 {
8445   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
8446   
8447   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
8448 }
8449
8450 GtkWidget *
8451 create_pane_options (GtkPaned    *paned,
8452                      const gchar *frame_label,
8453                      const gchar *label1,
8454                      const gchar *label2)
8455 {
8456   GtkWidget *frame;
8457   GtkWidget *table;
8458   GtkWidget *label;
8459   GtkWidget *button;
8460   GtkWidget *check_button;
8461   
8462   frame = gtk_frame_new (frame_label);
8463   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
8464   
8465   table = gtk_table_new (4, 2, 4);
8466   gtk_container_add (GTK_CONTAINER (frame), table);
8467   
8468   label = gtk_label_new (label1);
8469   gtk_table_attach_defaults (GTK_TABLE (table), label,
8470                              0, 1, 0, 1);
8471   
8472   check_button = gtk_check_button_new_with_label ("Resize");
8473   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8474                              0, 1, 1, 2);
8475   g_signal_connect (check_button, "toggled",
8476                     G_CALLBACK (toggle_resize),
8477                     paned->child1);
8478   
8479   check_button = gtk_check_button_new_with_label ("Shrink");
8480   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8481                              0, 1, 2, 3);
8482   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8483                                TRUE);
8484   g_signal_connect (check_button, "toggled",
8485                     G_CALLBACK (toggle_shrink),
8486                     paned->child1);
8487   
8488   label = gtk_label_new (label2);
8489   gtk_table_attach_defaults (GTK_TABLE (table), label,
8490                              1, 2, 0, 1);
8491   
8492   check_button = gtk_check_button_new_with_label ("Resize");
8493   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8494                              1, 2, 1, 2);
8495   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8496                                TRUE);
8497   g_signal_connect (check_button, "toggled",
8498                     G_CALLBACK (toggle_resize),
8499                     paned->child2);
8500   
8501   check_button = gtk_check_button_new_with_label ("Shrink");
8502   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8503                              1, 2, 2, 3);
8504   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8505                                TRUE);
8506   g_signal_connect (check_button, "toggled",
8507                     G_CALLBACK (toggle_shrink),
8508                     paned->child2);
8509
8510   button = gtk_button_new_with_mnemonic ("_Properties");
8511   gtk_table_attach_defaults (GTK_TABLE (table), button,
8512                              0, 2, 3, 4);
8513   g_signal_connect (button, "clicked",
8514                     G_CALLBACK (paned_props_clicked),
8515                     paned);
8516
8517   return frame;
8518 }
8519
8520 void
8521 create_panes (GtkWidget *widget)
8522 {
8523   static GtkWidget *window = NULL;
8524   GtkWidget *frame;
8525   GtkWidget *hpaned;
8526   GtkWidget *vpaned;
8527   GtkWidget *button;
8528   GtkWidget *vbox;
8529
8530   if (!window)
8531     {
8532       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8533
8534       gtk_window_set_screen (GTK_WINDOW (window),
8535                              gtk_widget_get_screen (widget));
8536       
8537       g_signal_connect (window, "destroy",
8538                         G_CALLBACK (gtk_widget_destroyed),
8539                         &window);
8540
8541       gtk_window_set_title (GTK_WINDOW (window), "Panes");
8542       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8543
8544       vbox = gtk_vbox_new (FALSE, 0);
8545       gtk_container_add (GTK_CONTAINER (window), vbox);
8546       
8547       vpaned = gtk_vpaned_new ();
8548       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
8549       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
8550
8551       hpaned = gtk_hpaned_new ();
8552       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
8553
8554       frame = gtk_frame_new (NULL);
8555       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8556       gtk_widget_set_size_request (frame, 60, 60);
8557       gtk_paned_add1 (GTK_PANED (hpaned), frame);
8558       
8559       button = gtk_button_new_with_label ("Hi there");
8560       gtk_container_add (GTK_CONTAINER(frame), button);
8561
8562       frame = gtk_frame_new (NULL);
8563       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8564       gtk_widget_set_size_request (frame, 80, 60);
8565       gtk_paned_add2 (GTK_PANED (hpaned), frame);
8566
8567       frame = gtk_frame_new (NULL);
8568       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8569       gtk_widget_set_size_request (frame, 60, 80);
8570       gtk_paned_add2 (GTK_PANED (vpaned), frame);
8571
8572       /* Now create toggle buttons to control sizing */
8573
8574       gtk_box_pack_start (GTK_BOX (vbox),
8575                           create_pane_options (GTK_PANED (hpaned),
8576                                                "Horizontal",
8577                                                "Left",
8578                                                "Right"),
8579                           FALSE, FALSE, 0);
8580
8581       gtk_box_pack_start (GTK_BOX (vbox),
8582                           create_pane_options (GTK_PANED (vpaned),
8583                                                "Vertical",
8584                                                "Top",
8585                                                "Bottom"),
8586                           FALSE, FALSE, 0);
8587
8588       gtk_widget_show_all (vbox);
8589     }
8590
8591   if (!GTK_WIDGET_VISIBLE (window))
8592     gtk_widget_show (window);
8593   else
8594     gtk_widget_destroy (window);
8595 }
8596
8597 /*
8598  * Paned keyboard navigation
8599  */
8600
8601 static GtkWidget*
8602 paned_keyboard_window1 (GtkWidget *widget)
8603 {
8604   GtkWidget *window1;
8605   GtkWidget *hpaned1;
8606   GtkWidget *frame1;
8607   GtkWidget *vbox1;
8608   GtkWidget *button7;
8609   GtkWidget *button8;
8610   GtkWidget *button9;
8611   GtkWidget *vpaned1;
8612   GtkWidget *frame2;
8613   GtkWidget *frame5;
8614   GtkWidget *hbox1;
8615   GtkWidget *button5;
8616   GtkWidget *button6;
8617   GtkWidget *frame3;
8618   GtkWidget *frame4;
8619   GtkWidget *table1;
8620   GtkWidget *button1;
8621   GtkWidget *button2;
8622   GtkWidget *button3;
8623   GtkWidget *button4;
8624
8625   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8626   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
8627   gtk_window_set_screen (GTK_WINDOW (window1), 
8628                          gtk_widget_get_screen (widget));
8629
8630   hpaned1 = gtk_hpaned_new ();
8631   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
8632
8633   frame1 = gtk_frame_new (NULL);
8634   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
8635   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
8636
8637   vbox1 = gtk_vbox_new (FALSE, 0);
8638   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
8639
8640   button7 = gtk_button_new_with_label ("button7");
8641   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
8642
8643   button8 = gtk_button_new_with_label ("button8");
8644   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
8645
8646   button9 = gtk_button_new_with_label ("button9");
8647   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
8648
8649   vpaned1 = gtk_vpaned_new ();
8650   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
8651
8652   frame2 = gtk_frame_new (NULL);
8653   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
8654   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
8655
8656   frame5 = gtk_frame_new (NULL);
8657   gtk_container_add (GTK_CONTAINER (frame2), frame5);
8658
8659   hbox1 = gtk_hbox_new (FALSE, 0);
8660   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
8661
8662   button5 = gtk_button_new_with_label ("button5");
8663   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
8664
8665   button6 = gtk_button_new_with_label ("button6");
8666   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
8667
8668   frame3 = gtk_frame_new (NULL);
8669   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
8670   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
8671
8672   frame4 = gtk_frame_new ("Buttons");
8673   gtk_container_add (GTK_CONTAINER (frame3), frame4);
8674   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
8675
8676   table1 = gtk_table_new (2, 2, FALSE);
8677   gtk_container_add (GTK_CONTAINER (frame4), table1);
8678   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
8679
8680   button1 = gtk_button_new_with_label ("button1");
8681   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
8682                     (GtkAttachOptions) (GTK_FILL),
8683                     (GtkAttachOptions) (0), 0, 0);
8684
8685   button2 = gtk_button_new_with_label ("button2");
8686   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
8687                     (GtkAttachOptions) (GTK_FILL),
8688                     (GtkAttachOptions) (0), 0, 0);
8689
8690   button3 = gtk_button_new_with_label ("button3");
8691   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
8692                     (GtkAttachOptions) (GTK_FILL),
8693                     (GtkAttachOptions) (0), 0, 0);
8694
8695   button4 = gtk_button_new_with_label ("button4");
8696   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
8697                     (GtkAttachOptions) (GTK_FILL),
8698                     (GtkAttachOptions) (0), 0, 0);
8699
8700   return window1;
8701 }
8702
8703 static GtkWidget*
8704 paned_keyboard_window2 (GtkWidget *widget)
8705 {
8706   GtkWidget *window2;
8707   GtkWidget *hpaned2;
8708   GtkWidget *frame6;
8709   GtkWidget *button13;
8710   GtkWidget *hbox2;
8711   GtkWidget *vpaned2;
8712   GtkWidget *frame7;
8713   GtkWidget *button12;
8714   GtkWidget *frame8;
8715   GtkWidget *button11;
8716   GtkWidget *button10;
8717
8718   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8719   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
8720
8721   gtk_window_set_screen (GTK_WINDOW (window2), 
8722                          gtk_widget_get_screen (widget));
8723
8724   hpaned2 = gtk_hpaned_new ();
8725   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
8726
8727   frame6 = gtk_frame_new (NULL);
8728   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
8729   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
8730
8731   button13 = gtk_button_new_with_label ("button13");
8732   gtk_container_add (GTK_CONTAINER (frame6), button13);
8733
8734   hbox2 = gtk_hbox_new (FALSE, 0);
8735   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
8736
8737   vpaned2 = gtk_vpaned_new ();
8738   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
8739
8740   frame7 = gtk_frame_new (NULL);
8741   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
8742   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
8743
8744   button12 = gtk_button_new_with_label ("button12");
8745   gtk_container_add (GTK_CONTAINER (frame7), button12);
8746
8747   frame8 = gtk_frame_new (NULL);
8748   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
8749   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
8750
8751   button11 = gtk_button_new_with_label ("button11");
8752   gtk_container_add (GTK_CONTAINER (frame8), button11);
8753
8754   button10 = gtk_button_new_with_label ("button10");
8755   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
8756
8757   return window2;
8758 }
8759
8760 static GtkWidget*
8761 paned_keyboard_window3 (GtkWidget *widget)
8762 {
8763   GtkWidget *window3;
8764   GtkWidget *vbox2;
8765   GtkWidget *label1;
8766   GtkWidget *hpaned3;
8767   GtkWidget *frame9;
8768   GtkWidget *button14;
8769   GtkWidget *hpaned4;
8770   GtkWidget *frame10;
8771   GtkWidget *button15;
8772   GtkWidget *hpaned5;
8773   GtkWidget *frame11;
8774   GtkWidget *button16;
8775   GtkWidget *frame12;
8776   GtkWidget *button17;
8777
8778   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8779   g_object_set_data (G_OBJECT (window3), "window3", window3);
8780   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
8781
8782   gtk_window_set_screen (GTK_WINDOW (window3), 
8783                          gtk_widget_get_screen (widget));
8784   
8785
8786   vbox2 = gtk_vbox_new (FALSE, 0);
8787   gtk_container_add (GTK_CONTAINER (window3), vbox2);
8788
8789   label1 = gtk_label_new ("Three panes nested inside each other");
8790   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
8791
8792   hpaned3 = gtk_hpaned_new ();
8793   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
8794
8795   frame9 = gtk_frame_new (NULL);
8796   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
8797   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
8798
8799   button14 = gtk_button_new_with_label ("button14");
8800   gtk_container_add (GTK_CONTAINER (frame9), button14);
8801
8802   hpaned4 = gtk_hpaned_new ();
8803   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
8804
8805   frame10 = gtk_frame_new (NULL);
8806   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
8807   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
8808
8809   button15 = gtk_button_new_with_label ("button15");
8810   gtk_container_add (GTK_CONTAINER (frame10), button15);
8811
8812   hpaned5 = gtk_hpaned_new ();
8813   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
8814
8815   frame11 = gtk_frame_new (NULL);
8816   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
8817   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
8818
8819   button16 = gtk_button_new_with_label ("button16");
8820   gtk_container_add (GTK_CONTAINER (frame11), button16);
8821
8822   frame12 = gtk_frame_new (NULL);
8823   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
8824   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
8825
8826   button17 = gtk_button_new_with_label ("button17");
8827   gtk_container_add (GTK_CONTAINER (frame12), button17);
8828
8829   return window3;
8830 }
8831
8832 static GtkWidget*
8833 paned_keyboard_window4 (GtkWidget *widget)
8834 {
8835   GtkWidget *window4;
8836   GtkWidget *vbox3;
8837   GtkWidget *label2;
8838   GtkWidget *hpaned6;
8839   GtkWidget *vpaned3;
8840   GtkWidget *button19;
8841   GtkWidget *button18;
8842   GtkWidget *hbox3;
8843   GtkWidget *vpaned4;
8844   GtkWidget *button21;
8845   GtkWidget *button20;
8846   GtkWidget *vpaned5;
8847   GtkWidget *button23;
8848   GtkWidget *button22;
8849   GtkWidget *vpaned6;
8850   GtkWidget *button25;
8851   GtkWidget *button24;
8852
8853   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8854   g_object_set_data (G_OBJECT (window4), "window4", window4);
8855   gtk_window_set_title (GTK_WINDOW (window4), "window4");
8856
8857   gtk_window_set_screen (GTK_WINDOW (window4), 
8858                          gtk_widget_get_screen (widget));
8859
8860   vbox3 = gtk_vbox_new (FALSE, 0);
8861   gtk_container_add (GTK_CONTAINER (window4), vbox3);
8862
8863   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
8864   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
8865   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
8866
8867   hpaned6 = gtk_hpaned_new ();
8868   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
8869
8870   vpaned3 = gtk_vpaned_new ();
8871   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
8872
8873   button19 = gtk_button_new_with_label ("button19");
8874   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
8875
8876   button18 = gtk_button_new_with_label ("button18");
8877   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
8878
8879   hbox3 = gtk_hbox_new (FALSE, 0);
8880   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
8881
8882   vpaned4 = gtk_vpaned_new ();
8883   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
8884
8885   button21 = gtk_button_new_with_label ("button21");
8886   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
8887
8888   button20 = gtk_button_new_with_label ("button20");
8889   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
8890
8891   vpaned5 = gtk_vpaned_new ();
8892   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
8893
8894   button23 = gtk_button_new_with_label ("button23");
8895   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
8896
8897   button22 = gtk_button_new_with_label ("button22");
8898   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
8899
8900   vpaned6 = gtk_vpaned_new ();
8901   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
8902
8903   button25 = gtk_button_new_with_label ("button25");
8904   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
8905
8906   button24 = gtk_button_new_with_label ("button24");
8907   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
8908
8909   return window4;
8910 }
8911
8912 static void
8913 create_paned_keyboard_navigation (GtkWidget *widget)
8914 {
8915   static GtkWidget *window1 = NULL;
8916   static GtkWidget *window2 = NULL;
8917   static GtkWidget *window3 = NULL;
8918   static GtkWidget *window4 = NULL;
8919
8920   if (window1 && 
8921      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
8922     {
8923       gtk_widget_destroy (window1);
8924       gtk_widget_destroy (window2);
8925       gtk_widget_destroy (window3);
8926       gtk_widget_destroy (window4);
8927     }
8928   
8929   if (!window1)
8930     {
8931       window1 = paned_keyboard_window1 (widget);
8932       g_signal_connect (window1, "destroy",
8933                         G_CALLBACK (gtk_widget_destroyed),
8934                         &window1);
8935     }
8936
8937   if (!window2)
8938     {
8939       window2 = paned_keyboard_window2 (widget);
8940       g_signal_connect (window2, "destroy",
8941                         G_CALLBACK (gtk_widget_destroyed),
8942                         &window2);
8943     }
8944
8945   if (!window3)
8946     {
8947       window3 = paned_keyboard_window3 (widget);
8948       g_signal_connect (window3, "destroy",
8949                         G_CALLBACK (gtk_widget_destroyed),
8950                         &window3);
8951     }
8952
8953   if (!window4)
8954     {
8955       window4 = paned_keyboard_window4 (widget);
8956       g_signal_connect (window4, "destroy",
8957                         G_CALLBACK (gtk_widget_destroyed),
8958                         &window4);
8959     }
8960
8961   if (GTK_WIDGET_VISIBLE (window1))
8962     gtk_widget_destroy (GTK_WIDGET (window1));
8963   else
8964     gtk_widget_show_all (GTK_WIDGET (window1));
8965
8966   if (GTK_WIDGET_VISIBLE (window2))
8967     gtk_widget_destroy (GTK_WIDGET (window2));
8968   else
8969     gtk_widget_show_all (GTK_WIDGET (window2));
8970
8971   if (GTK_WIDGET_VISIBLE (window3))
8972     gtk_widget_destroy (GTK_WIDGET (window3));
8973   else
8974     gtk_widget_show_all (GTK_WIDGET (window3));
8975
8976   if (GTK_WIDGET_VISIBLE (window4))
8977     gtk_widget_destroy (GTK_WIDGET (window4));
8978   else
8979     gtk_widget_show_all (GTK_WIDGET (window4));
8980 }
8981
8982
8983 /*
8984  * Shaped Windows
8985  */
8986
8987 typedef struct _cursoroffset {gint x,y;} CursorOffset;
8988
8989 static void
8990 shape_pressed (GtkWidget *widget, GdkEventButton *event)
8991 {
8992   CursorOffset *p;
8993
8994   /* ignore double and triple click */
8995   if (event->type != GDK_BUTTON_PRESS)
8996     return;
8997
8998   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
8999   p->x = (int) event->x;
9000   p->y = (int) event->y;
9001
9002   gtk_grab_add (widget);
9003   gdk_pointer_grab (widget->window, TRUE,
9004                     GDK_BUTTON_RELEASE_MASK |
9005                     GDK_BUTTON_MOTION_MASK |
9006                     GDK_POINTER_MOTION_HINT_MASK,
9007                     NULL, NULL, 0);
9008 }
9009
9010 static void
9011 shape_released (GtkWidget *widget)
9012 {
9013   gtk_grab_remove (widget);
9014   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
9015                               GDK_CURRENT_TIME);
9016 }
9017
9018 static void
9019 shape_motion (GtkWidget      *widget, 
9020               GdkEventMotion *event)
9021 {
9022   gint xp, yp;
9023   CursorOffset * p;
9024   GdkModifierType mask;
9025
9026   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
9027
9028   /*
9029    * Can't use event->x / event->y here 
9030    * because I need absolute coordinates.
9031    */
9032   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
9033   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
9034 }
9035
9036 GtkWidget *
9037 shape_create_icon (GdkScreen *screen,
9038                    char      *xpm_file,
9039                    gint       x,
9040                    gint       y,
9041                    gint       px,
9042                    gint       py,
9043                    gint       window_type)
9044 {
9045   GtkWidget *window;
9046   GtkWidget *pixmap;
9047   GtkWidget *fixed;
9048   CursorOffset* icon_pos;
9049   GdkGC* gc;
9050   GdkBitmap *gdk_pixmap_mask;
9051   GdkPixmap *gdk_pixmap;
9052   GtkStyle *style;
9053
9054   style = gtk_widget_get_default_style ();
9055   gc = style->black_gc; 
9056
9057   /*
9058    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
9059    */
9060   window = gtk_window_new (window_type);
9061   gtk_window_set_screen (GTK_WINDOW (window), screen);
9062   
9063   fixed = gtk_fixed_new ();
9064   gtk_widget_set_size_request (fixed, 100, 100);
9065   gtk_container_add (GTK_CONTAINER (window), fixed);
9066   gtk_widget_show (fixed);
9067   
9068   gtk_widget_set_events (window, 
9069                          gtk_widget_get_events (window) |
9070                          GDK_BUTTON_MOTION_MASK |
9071                          GDK_POINTER_MOTION_HINT_MASK |
9072                          GDK_BUTTON_PRESS_MASK);
9073
9074   gtk_widget_realize (window);
9075   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
9076                                            &style->bg[GTK_STATE_NORMAL],
9077                                            xpm_file);
9078
9079   pixmap = gtk_image_new_from_pixmap (gdk_pixmap, gdk_pixmap_mask);
9080   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
9081   gtk_widget_show (pixmap);
9082   
9083   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px, py);
9084   
9085   g_object_unref (gdk_pixmap_mask);
9086   g_object_unref (gdk_pixmap);
9087
9088   g_signal_connect (window, "button_press_event",
9089                     G_CALLBACK (shape_pressed), NULL);
9090   g_signal_connect (window, "button_release_event",
9091                     G_CALLBACK (shape_released), NULL);
9092   g_signal_connect (window, "motion_notify_event",
9093                     G_CALLBACK (shape_motion), NULL);
9094
9095   icon_pos = g_new (CursorOffset, 1);
9096   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
9097
9098   gtk_widget_set_uposition (window, x, y);
9099   gtk_widget_show (window);
9100   
9101   return window;
9102 }
9103
9104 void 
9105 create_shapes (GtkWidget *widget)
9106 {
9107   /* Variables used by the Drag/Drop and Shape Window demos */
9108   static GtkWidget *modeller = NULL;
9109   static GtkWidget *sheets = NULL;
9110   static GtkWidget *rings = NULL;
9111   static GtkWidget *with_region = NULL;
9112   GdkScreen *screen = gtk_widget_get_screen (widget);
9113   
9114   if (!(file_exists ("Modeller.xpm") &&
9115         file_exists ("FilesQueue.xpm") &&
9116         file_exists ("3DRings.xpm")))
9117     return;
9118   
9119
9120   if (!modeller)
9121     {
9122       modeller = shape_create_icon (screen, "Modeller.xpm",
9123                                     440, 140, 0,0, GTK_WINDOW_POPUP);
9124
9125       g_signal_connect (modeller, "destroy",
9126                         G_CALLBACK (gtk_widget_destroyed),
9127                         &modeller);
9128     }
9129   else
9130     gtk_widget_destroy (modeller);
9131
9132   if (!sheets)
9133     {
9134       sheets = shape_create_icon (screen, "FilesQueue.xpm",
9135                                   580, 170, 0,0, GTK_WINDOW_POPUP);
9136
9137       g_signal_connect (sheets, "destroy",
9138                         G_CALLBACK (gtk_widget_destroyed),
9139                         &sheets);
9140
9141     }
9142   else
9143     gtk_widget_destroy (sheets);
9144
9145   if (!rings)
9146     {
9147       rings = shape_create_icon (screen, "3DRings.xpm",
9148                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9149
9150       g_signal_connect (rings, "destroy",
9151                         G_CALLBACK (gtk_widget_destroyed),
9152                         &rings);
9153     }
9154   else
9155     gtk_widget_destroy (rings);
9156
9157   if (!with_region)
9158     {
9159       GdkRegion *region;
9160       gint x, y;
9161       
9162       with_region = shape_create_icon (screen, "3DRings.xpm",
9163                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9164
9165       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
9166       
9167       g_signal_connect (with_region, "destroy",
9168                         G_CALLBACK (gtk_widget_destroyed),
9169                         &with_region);
9170
9171       /* reset shape from mask to a region */
9172       x = 0;
9173       y = 0;
9174       region = gdk_region_new ();
9175
9176       while (x < 460)
9177         {
9178           while (y < 270)
9179             {
9180               GdkRectangle rect;
9181               rect.x = x;
9182               rect.y = y;
9183               rect.width = 10;
9184               rect.height = 10;
9185
9186               gdk_region_union_with_rect (region, &rect);
9187               
9188               y += 20;
9189             }
9190           y = 0;
9191           x += 20;
9192         }
9193
9194       gdk_window_shape_combine_region (with_region->window,
9195                                        region,
9196                                        0, 0);
9197     }
9198   else
9199     gtk_widget_destroy (with_region);
9200 }
9201
9202 /*
9203  * WM Hints demo
9204  */
9205
9206 void
9207 create_wmhints (GtkWidget *widget)
9208 {
9209   static GtkWidget *window = NULL;
9210   GtkWidget *label;
9211   GtkWidget *separator;
9212   GtkWidget *button;
9213   GtkWidget *box1;
9214   GtkWidget *box2;
9215
9216   GdkBitmap *circles;
9217
9218   if (!window)
9219     {
9220       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9221
9222       gtk_window_set_screen (GTK_WINDOW (window),
9223                              gtk_widget_get_screen (widget));
9224       
9225       g_signal_connect (window, "destroy",
9226                         G_CALLBACK (gtk_widget_destroyed),
9227                         &window);
9228
9229       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
9230       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9231
9232       gtk_widget_realize (window);
9233       
9234       circles = gdk_bitmap_create_from_data (window->window,
9235                                              circles_bits,
9236                                              circles_width,
9237                                              circles_height);
9238       gdk_window_set_icon (window->window, NULL,
9239                            circles, circles);
9240       
9241       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
9242   
9243       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
9244       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
9245       
9246       box1 = gtk_vbox_new (FALSE, 0);
9247       gtk_container_add (GTK_CONTAINER (window), box1);
9248       gtk_widget_show (box1);
9249
9250       label = gtk_label_new ("Try iconizing me!");
9251       gtk_widget_set_size_request (label, 150, 50);
9252       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
9253       gtk_widget_show (label);
9254
9255
9256       separator = gtk_hseparator_new ();
9257       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9258       gtk_widget_show (separator);
9259
9260
9261       box2 = gtk_vbox_new (FALSE, 10);
9262       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9263       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9264       gtk_widget_show (box2);
9265
9266
9267       button = gtk_button_new_with_label ("close");
9268
9269       g_signal_connect_swapped (button, "clicked",
9270                                 G_CALLBACK (gtk_widget_destroy),
9271                                 window);
9272
9273       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9274       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9275       gtk_widget_grab_default (button);
9276       gtk_widget_show (button);
9277     }
9278
9279   if (!GTK_WIDGET_VISIBLE (window))
9280     gtk_widget_show (window);
9281   else
9282     gtk_widget_destroy (window);
9283 }
9284
9285
9286 /*
9287  * Window state tracking
9288  */
9289
9290 static gint
9291 window_state_callback (GtkWidget *widget,
9292                        GdkEventWindowState *event,
9293                        gpointer data)
9294 {
9295   GtkWidget *label = data;
9296   gchar *msg;
9297
9298   msg = g_strconcat (GTK_WINDOW (widget)->title, ": ",
9299                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
9300                      "withdrawn" : "not withdrawn", ", ",
9301                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
9302                      "iconified" : "not iconified", ", ",
9303                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
9304                      "sticky" : "not sticky", ", ",
9305                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
9306                      "maximized" : "not maximized", ", ",
9307                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
9308                      "fullscreen" : "not fullscreen",
9309                      NULL);
9310   
9311   gtk_label_set_text (GTK_LABEL (label), msg);
9312
9313   g_free (msg);
9314
9315   return FALSE;
9316 }
9317
9318 static GtkWidget*
9319 tracking_label (GtkWidget *window)
9320 {
9321   GtkWidget *label;
9322   GtkWidget *hbox;
9323   GtkWidget *button;
9324
9325   hbox = gtk_hbox_new (FALSE, 5);
9326
9327   g_signal_connect_object (hbox,
9328                            "destroy",
9329                            G_CALLBACK (gtk_widget_destroy),
9330                            window,
9331                            G_CONNECT_SWAPPED);
9332   
9333   label = gtk_label_new ("<no window state events received>");
9334   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
9335   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
9336   
9337   g_signal_connect (window,
9338                     "window_state_event",
9339                     G_CALLBACK (window_state_callback),
9340                     label);
9341
9342   button = gtk_button_new_with_label ("Deiconify");
9343   g_signal_connect_object (button,
9344                            "clicked",
9345                            G_CALLBACK (gtk_window_deiconify),
9346                            window,
9347                            G_CONNECT_SWAPPED);
9348   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9349
9350   button = gtk_button_new_with_label ("Iconify");
9351   g_signal_connect_object (button,
9352                            "clicked",
9353                            G_CALLBACK (gtk_window_iconify),
9354                            window,
9355                            G_CONNECT_SWAPPED);
9356   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9357
9358   button = gtk_button_new_with_label ("Fullscreen");
9359   g_signal_connect_object (button,
9360                            "clicked",
9361                            G_CALLBACK (gtk_window_fullscreen),
9362                            window,
9363                            G_CONNECT_SWAPPED);
9364   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9365
9366   button = gtk_button_new_with_label ("Unfullscreen");
9367   g_signal_connect_object (button,
9368                            "clicked",
9369                            G_CALLBACK (gtk_window_unfullscreen),
9370                            window,
9371                            G_CONNECT_SWAPPED);
9372   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9373   
9374   button = gtk_button_new_with_label ("Present");
9375   g_signal_connect_object (button,
9376                            "clicked",
9377                            G_CALLBACK (gtk_window_present),
9378                            window,
9379                            G_CONNECT_SWAPPED);
9380   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9381
9382   button = gtk_button_new_with_label ("Show");
9383   g_signal_connect_object (button,
9384                            "clicked",
9385                            G_CALLBACK (gtk_widget_show),
9386                            window,
9387                            G_CONNECT_SWAPPED);
9388   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9389   
9390   gtk_widget_show_all (hbox);
9391   
9392   return hbox;
9393 }
9394
9395 static GtkWidget*
9396 get_state_controls (GtkWidget *window)
9397 {
9398   GtkWidget *vbox;
9399   GtkWidget *button;
9400
9401   vbox = gtk_vbox_new (FALSE, 0);
9402   
9403   button = gtk_button_new_with_label ("Stick");
9404   g_signal_connect_object (button,
9405                            "clicked",
9406                            G_CALLBACK (gtk_window_stick),
9407                            window,
9408                            G_CONNECT_SWAPPED);
9409   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9410
9411   button = gtk_button_new_with_label ("Unstick");
9412   g_signal_connect_object (button,
9413                            "clicked",
9414                            G_CALLBACK (gtk_window_unstick),
9415                            window,
9416                            G_CONNECT_SWAPPED);
9417   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9418   
9419   button = gtk_button_new_with_label ("Maximize");
9420   g_signal_connect_object (button,
9421                            "clicked",
9422                            G_CALLBACK (gtk_window_maximize),
9423                            window,
9424                            G_CONNECT_SWAPPED);
9425   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9426
9427   button = gtk_button_new_with_label ("Unmaximize");
9428   g_signal_connect_object (button,
9429                            "clicked",
9430                            G_CALLBACK (gtk_window_unmaximize),
9431                            window,
9432                            G_CONNECT_SWAPPED);
9433   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9434
9435   button = gtk_button_new_with_label ("Iconify");
9436   g_signal_connect_object (button,
9437                            "clicked",
9438                            G_CALLBACK (gtk_window_iconify),
9439                            window,
9440                            G_CONNECT_SWAPPED);
9441   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9442
9443   button = gtk_button_new_with_label ("Fullscreen");
9444   g_signal_connect_object (button,
9445                            "clicked",
9446                            G_CALLBACK (gtk_window_fullscreen),
9447                            window,
9448                            G_CONNECT_SWAPPED);
9449   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9450
9451   button = gtk_button_new_with_label ("Unfullscreen");
9452   g_signal_connect_object (button,
9453                            "clicked",
9454                            G_CALLBACK (gtk_window_unfullscreen),
9455                            window,
9456                            G_CONNECT_SWAPPED);
9457   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9458   
9459   button = gtk_button_new_with_label ("Hide (withdraw)");
9460   g_signal_connect_object (button,
9461                            "clicked",
9462                            G_CALLBACK (gtk_widget_hide),
9463                            window,
9464                            G_CONNECT_SWAPPED);
9465   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9466   
9467   gtk_widget_show_all (vbox);
9468
9469   return vbox;
9470 }
9471
9472 void
9473 create_window_states (GtkWidget *widget)
9474 {
9475   static GtkWidget *window = NULL;
9476   GtkWidget *label;
9477   GtkWidget *box1;
9478   GtkWidget *iconified;
9479   GtkWidget *normal;
9480   GtkWidget *controls;
9481
9482   if (!window)
9483     {
9484       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9485       gtk_window_set_screen (GTK_WINDOW (window),
9486                              gtk_widget_get_screen (widget));
9487
9488       g_signal_connect (window, "destroy",
9489                         G_CALLBACK (gtk_widget_destroyed),
9490                         &window);
9491
9492       gtk_window_set_title (GTK_WINDOW (window), "Window states");
9493       
9494       box1 = gtk_vbox_new (FALSE, 0);
9495       gtk_container_add (GTK_CONTAINER (window), box1);
9496
9497       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9498
9499       gtk_window_set_screen (GTK_WINDOW (iconified),
9500                              gtk_widget_get_screen (widget));
9501       
9502       g_signal_connect_object (iconified, "destroy",
9503                                G_CALLBACK (gtk_widget_destroy),
9504                                window,
9505                                G_CONNECT_SWAPPED);
9506       gtk_window_iconify (GTK_WINDOW (iconified));
9507       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
9508       controls = get_state_controls (iconified);
9509       gtk_container_add (GTK_CONTAINER (iconified), controls);
9510       
9511       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9512
9513       gtk_window_set_screen (GTK_WINDOW (normal),
9514                              gtk_widget_get_screen (widget));
9515       
9516       g_signal_connect_object (normal, "destroy",
9517                                G_CALLBACK (gtk_widget_destroy),
9518                                window,
9519                                G_CONNECT_SWAPPED);
9520       
9521       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
9522       controls = get_state_controls (normal);
9523       gtk_container_add (GTK_CONTAINER (normal), controls);
9524       
9525       label = tracking_label (iconified);
9526       gtk_container_add (GTK_CONTAINER (box1), label);
9527
9528       label = tracking_label (normal);
9529       gtk_container_add (GTK_CONTAINER (box1), label);
9530
9531       gtk_widget_show_all (iconified);
9532       gtk_widget_show_all (normal);
9533       gtk_widget_show_all (box1);
9534     }
9535
9536   if (!GTK_WIDGET_VISIBLE (window))
9537     gtk_widget_show (window);
9538   else
9539     gtk_widget_destroy (window);
9540 }
9541
9542 /*
9543  * Window sizing
9544  */
9545
9546 static gint
9547 configure_event_callback (GtkWidget *widget,
9548                           GdkEventConfigure *event,
9549                           gpointer data)
9550 {
9551   GtkWidget *label = data;
9552   gchar *msg;
9553   gint x, y;
9554   
9555   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
9556   
9557   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
9558                          "position: %d, %d",
9559                          event->x, event->y, event->width, event->height,
9560                          x, y);
9561   
9562   gtk_label_set_text (GTK_LABEL (label), msg);
9563
9564   g_free (msg);
9565
9566   return FALSE;
9567 }
9568
9569 static void
9570 get_ints (GtkWidget *window,
9571           gint      *a,
9572           gint      *b)
9573 {
9574   GtkWidget *spin1;
9575   GtkWidget *spin2;
9576
9577   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
9578   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
9579
9580   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
9581   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
9582 }
9583
9584 static void
9585 set_size_callback (GtkWidget *widget,
9586                    gpointer   data)
9587 {
9588   gint w, h;
9589   
9590   get_ints (data, &w, &h);
9591
9592   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
9593 }
9594
9595 static void
9596 unset_default_size_callback (GtkWidget *widget,
9597                              gpointer   data)
9598 {
9599   gtk_window_set_default_size (g_object_get_data (data, "target"),
9600                                -1, -1);
9601 }
9602
9603 static void
9604 set_default_size_callback (GtkWidget *widget,
9605                            gpointer   data)
9606 {
9607   gint w, h;
9608   
9609   get_ints (data, &w, &h);
9610
9611   gtk_window_set_default_size (g_object_get_data (data, "target"),
9612                                w, h);
9613 }
9614
9615 static void
9616 unset_size_request_callback (GtkWidget *widget,
9617                              gpointer   data)
9618 {
9619   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9620                                -1, -1);
9621 }
9622
9623 static void
9624 set_size_request_callback (GtkWidget *widget,
9625                            gpointer   data)
9626 {
9627   gint w, h;
9628   
9629   get_ints (data, &w, &h);
9630
9631   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9632                                w, h);
9633 }
9634
9635 static void
9636 set_location_callback (GtkWidget *widget,
9637                        gpointer   data)
9638 {
9639   gint x, y;
9640   
9641   get_ints (data, &x, &y);
9642
9643   gtk_window_move (g_object_get_data (data, "target"), x, y);
9644 }
9645
9646 static void
9647 move_to_position_callback (GtkWidget *widget,
9648                            gpointer   data)
9649 {
9650   gint x, y;
9651   GtkWindow *window;
9652
9653   window = g_object_get_data (data, "target");
9654   
9655   gtk_window_get_position (window, &x, &y);
9656
9657   gtk_window_move (window, x, y);
9658 }
9659
9660 static void
9661 set_geometry_callback (GtkWidget *entry,
9662                        gpointer   data)
9663 {
9664   gchar *text;
9665   GtkWindow *target;
9666
9667   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
9668   
9669   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
9670
9671   if (!gtk_window_parse_geometry (target, text))
9672     g_print ("Bad geometry string '%s'\n", text);
9673
9674   g_free (text);
9675 }
9676
9677 static void
9678 allow_shrink_callback (GtkWidget *widget,
9679                        gpointer   data)
9680 {
9681   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9682                 "allow_shrink",
9683                 GTK_TOGGLE_BUTTON (widget)->active,
9684                 NULL);
9685 }
9686
9687 static void
9688 allow_grow_callback (GtkWidget *widget,
9689                      gpointer   data)
9690 {
9691   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9692                 "allow_grow",
9693                 GTK_TOGGLE_BUTTON (widget)->active,
9694                 NULL);
9695 }
9696
9697 static void
9698 gravity_selected (GtkWidget *widget,
9699                   gpointer   data)
9700 {
9701   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
9702                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
9703 }
9704
9705 static void
9706 pos_selected (GtkWidget *widget,
9707               gpointer   data)
9708 {
9709   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
9710                            gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
9711 }
9712
9713 static void
9714 move_gravity_window_to_current_position (GtkWidget *widget,
9715                                          gpointer   data)
9716 {
9717   gint x, y;
9718   GtkWindow *window;
9719
9720   window = GTK_WINDOW (data);    
9721   
9722   gtk_window_get_position (window, &x, &y);
9723
9724   gtk_window_move (window, x, y);
9725 }
9726
9727 static void
9728 get_screen_corner (GtkWindow *window,
9729                    gint      *x,
9730                    gint      *y)
9731 {
9732   int w, h;
9733   GdkScreen * screen = gtk_window_get_screen (window);
9734   
9735   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
9736
9737   switch (gtk_window_get_gravity (window))
9738     {
9739     case GDK_GRAVITY_SOUTH_EAST:
9740       *x = gdk_screen_get_width (screen) - w;
9741       *y = gdk_screen_get_height (screen) - h;
9742       break;
9743
9744     case GDK_GRAVITY_NORTH_EAST:
9745       *x = gdk_screen_get_width (screen) - w;
9746       *y = 0;
9747       break;
9748
9749     case GDK_GRAVITY_SOUTH_WEST:
9750       *x = 0;
9751       *y = gdk_screen_get_height (screen) - h;
9752       break;
9753
9754     case GDK_GRAVITY_NORTH_WEST:
9755       *x = 0;
9756       *y = 0;
9757       break;
9758       
9759     case GDK_GRAVITY_SOUTH:
9760       *x = (gdk_screen_get_width (screen) - w) / 2;
9761       *y = gdk_screen_get_height (screen) - h;
9762       break;
9763
9764     case GDK_GRAVITY_NORTH:
9765       *x = (gdk_screen_get_width (screen) - w) / 2;
9766       *y = 0;
9767       break;
9768
9769     case GDK_GRAVITY_WEST:
9770       *x = 0;
9771       *y = (gdk_screen_get_height (screen) - h) / 2;
9772       break;
9773
9774     case GDK_GRAVITY_EAST:
9775       *x = gdk_screen_get_width (screen) - w;
9776       *y = (gdk_screen_get_height (screen) - h) / 2;
9777       break;
9778
9779     case GDK_GRAVITY_CENTER:
9780       *x = (gdk_screen_get_width (screen) - w) / 2;
9781       *y = (gdk_screen_get_height (screen) - h) / 2;
9782       break;
9783
9784     case GDK_GRAVITY_STATIC:
9785       /* pick some random numbers */
9786       *x = 350;
9787       *y = 350;
9788       break;
9789
9790     default:
9791       g_assert_not_reached ();
9792       break;
9793     }
9794 }
9795
9796 static void
9797 move_gravity_window_to_starting_position (GtkWidget *widget,
9798                                           gpointer   data)
9799 {
9800   gint x, y;
9801   GtkWindow *window;
9802
9803   window = GTK_WINDOW (data);    
9804   
9805   get_screen_corner (window,
9806                      &x, &y);
9807   
9808   gtk_window_move (window, x, y);
9809 }
9810
9811 static GtkWidget*
9812 make_gravity_window (GtkWidget   *destroy_with,
9813                      GdkGravity   gravity,
9814                      const gchar *title)
9815 {
9816   GtkWidget *window;
9817   GtkWidget *button;
9818   GtkWidget *vbox;
9819   int x, y;
9820   
9821   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9822
9823   gtk_window_set_screen (GTK_WINDOW (window),
9824                          gtk_widget_get_screen (destroy_with));
9825
9826   vbox = gtk_vbox_new (FALSE, 0);
9827   gtk_widget_show (vbox);
9828   
9829   gtk_container_add (GTK_CONTAINER (window), vbox);
9830   gtk_window_set_title (GTK_WINDOW (window), title);
9831   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
9832
9833   g_signal_connect_object (destroy_with,
9834                            "destroy",
9835                            G_CALLBACK (gtk_widget_destroy),
9836                            window,
9837                            G_CONNECT_SWAPPED);
9838
9839   
9840   button = gtk_button_new_with_mnemonic ("_Move to current position");
9841
9842   g_signal_connect (button, "clicked",
9843                     G_CALLBACK (move_gravity_window_to_current_position),
9844                     window);
9845
9846   gtk_container_add (GTK_CONTAINER (vbox), button);
9847   gtk_widget_show (button);
9848
9849   button = gtk_button_new_with_mnemonic ("Move to _starting position");
9850
9851   g_signal_connect (button, "clicked",
9852                     G_CALLBACK (move_gravity_window_to_starting_position),
9853                     window);
9854
9855   gtk_container_add (GTK_CONTAINER (vbox), button);
9856   gtk_widget_show (button);
9857   
9858   /* Pretend this is the result of --geometry.
9859    * DO NOT COPY THIS CODE unless you are setting --geometry results,
9860    * and in that case you probably should just use gtk_window_parse_geometry().
9861    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
9862    * you are parsing --geometry or equivalent.
9863    */
9864   gtk_window_set_geometry_hints (GTK_WINDOW (window),
9865                                  NULL, NULL,
9866                                  GDK_HINT_USER_POS);
9867
9868   gtk_window_set_default_size (GTK_WINDOW (window),
9869                                200, 200);
9870
9871   get_screen_corner (GTK_WINDOW (window), &x, &y);
9872   
9873   gtk_window_move (GTK_WINDOW (window),
9874                    x, y);
9875   
9876   return window;
9877 }
9878
9879 static void
9880 do_gravity_test (GtkWidget *widget,
9881                  gpointer   data)
9882 {
9883   GtkWidget *destroy_with = data;
9884   GtkWidget *window;
9885   
9886   /* We put a window at each gravity point on the screen. */
9887   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
9888                                 "NorthWest");
9889   gtk_widget_show (window);
9890   
9891   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
9892                                 "SouthEast");
9893   gtk_widget_show (window);
9894
9895   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
9896                                 "NorthEast");
9897   gtk_widget_show (window);
9898
9899   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
9900                                 "SouthWest");
9901   gtk_widget_show (window);
9902
9903   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
9904                                 "South");
9905   gtk_widget_show (window);
9906
9907   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
9908                                 "North");
9909   gtk_widget_show (window);
9910
9911   
9912   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
9913                                 "West");
9914   gtk_widget_show (window);
9915
9916     
9917   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
9918                                 "East");
9919   gtk_widget_show (window);
9920
9921   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
9922                                 "Center");
9923   gtk_widget_show (window);
9924
9925   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
9926                                 "Static");
9927   gtk_widget_show (window);
9928 }
9929
9930 static GtkWidget*
9931 window_controls (GtkWidget *window)
9932 {
9933   GtkWidget *control_window;
9934   GtkWidget *label;
9935   GtkWidget *vbox;
9936   GtkWidget *button;
9937   GtkWidget *spin;
9938   GtkAdjustment *adj;
9939   GtkWidget *entry;
9940   GtkWidget *om;
9941   GtkWidget *menu;
9942   gint i;
9943   
9944   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9945
9946   gtk_window_set_screen (GTK_WINDOW (control_window),
9947                          gtk_widget_get_screen (window));
9948
9949   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
9950   
9951   g_object_set_data (G_OBJECT (control_window),
9952                      "target",
9953                      window);
9954   
9955   g_signal_connect_object (control_window,
9956                            "destroy",
9957                            G_CALLBACK (gtk_widget_destroy),
9958                            window,
9959                            G_CONNECT_SWAPPED);
9960
9961   vbox = gtk_vbox_new (FALSE, 5);
9962   
9963   gtk_container_add (GTK_CONTAINER (control_window), vbox);
9964   
9965   label = gtk_label_new ("<no configure events>");
9966   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9967   
9968   g_signal_connect (window,
9969                     "configure_event",
9970                     G_CALLBACK (configure_event_callback),
9971                     label);
9972
9973   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9974                                               5.0, 0.0);
9975   spin = gtk_spin_button_new (adj, 0, 0);
9976
9977   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9978
9979   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
9980
9981   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9982                                               5.0, 0.0);
9983   spin = gtk_spin_button_new (adj, 0, 0);
9984
9985   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9986
9987   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
9988
9989   entry = gtk_entry_new ();
9990   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9991
9992   g_signal_connect (entry, "changed",
9993                     G_CALLBACK (set_geometry_callback),
9994                     control_window);
9995
9996   button = gtk_button_new_with_label ("Show gravity test windows");
9997   g_signal_connect_swapped (button,
9998                             "clicked",
9999                             G_CALLBACK (do_gravity_test),
10000                             control_window);
10001   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10002
10003   button = gtk_button_new_with_label ("Reshow with initial size");
10004   g_signal_connect_object (button,
10005                            "clicked",
10006                            G_CALLBACK (gtk_window_reshow_with_initial_size),
10007                            window,
10008                            G_CONNECT_SWAPPED);
10009   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10010   
10011   button = gtk_button_new_with_label ("Queue resize");
10012   g_signal_connect_object (button,
10013                            "clicked",
10014                            G_CALLBACK (gtk_widget_queue_resize),
10015                            window,
10016                            G_CONNECT_SWAPPED);
10017   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10018   
10019   button = gtk_button_new_with_label ("Resize");
10020   g_signal_connect (button,
10021                     "clicked",
10022                     G_CALLBACK (set_size_callback),
10023                     control_window);
10024   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10025
10026   button = gtk_button_new_with_label ("Set default size");
10027   g_signal_connect (button,
10028                     "clicked",
10029                     G_CALLBACK (set_default_size_callback),
10030                     control_window);
10031   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10032
10033   button = gtk_button_new_with_label ("Unset default size");
10034   g_signal_connect (button,
10035                     "clicked",
10036                     G_CALLBACK (unset_default_size_callback),
10037                     control_window);
10038   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10039   
10040   button = gtk_button_new_with_label ("Set size request");
10041   g_signal_connect (button,
10042                     "clicked",
10043                     G_CALLBACK (set_size_request_callback),
10044                     control_window);
10045   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10046
10047   button = gtk_button_new_with_label ("Unset size request");
10048   g_signal_connect (button,
10049                     "clicked",
10050                     G_CALLBACK (unset_size_request_callback),
10051                     control_window);
10052   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10053   
10054   button = gtk_button_new_with_label ("Move");
10055   g_signal_connect (button,
10056                     "clicked",
10057                     G_CALLBACK (set_location_callback),
10058                     control_window);
10059   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10060
10061   button = gtk_button_new_with_label ("Move to current position");
10062   g_signal_connect (button,
10063                     "clicked",
10064                     G_CALLBACK (move_to_position_callback),
10065                     control_window);
10066   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10067   
10068   button = gtk_check_button_new_with_label ("Allow shrink");
10069   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
10070   g_signal_connect (button,
10071                     "toggled",
10072                     G_CALLBACK (allow_shrink_callback),
10073                     control_window);
10074   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10075
10076   button = gtk_check_button_new_with_label ("Allow grow");
10077   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
10078   g_signal_connect (button,
10079                     "toggled",
10080                     G_CALLBACK (allow_grow_callback),
10081                     control_window);
10082   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10083   
10084   button = gtk_button_new_with_mnemonic ("_Show");
10085   g_signal_connect_object (button,
10086                            "clicked",
10087                            G_CALLBACK (gtk_widget_show),
10088                            window,
10089                            G_CONNECT_SWAPPED);
10090   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10091
10092   button = gtk_button_new_with_mnemonic ("_Hide");
10093   g_signal_connect_object (button,
10094                            "clicked",
10095                            G_CALLBACK (gtk_widget_hide),
10096                            window,
10097                            G_CONNECT_SWAPPED);
10098   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10099   
10100   menu = gtk_menu_new ();
10101   
10102   i = 0;
10103   while (i < 10)
10104     {
10105       GtkWidget *mi;
10106       static gchar *names[] = {
10107         "GDK_GRAVITY_NORTH_WEST",
10108         "GDK_GRAVITY_NORTH",
10109         "GDK_GRAVITY_NORTH_EAST",
10110         "GDK_GRAVITY_WEST",
10111         "GDK_GRAVITY_CENTER",
10112         "GDK_GRAVITY_EAST",
10113         "GDK_GRAVITY_SOUTH_WEST",
10114         "GDK_GRAVITY_SOUTH",
10115         "GDK_GRAVITY_SOUTH_EAST",
10116         "GDK_GRAVITY_STATIC",
10117         NULL
10118       };
10119
10120       g_assert (names[i]);
10121       
10122       mi = gtk_menu_item_new_with_label (names[i]);
10123
10124       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10125
10126       ++i;
10127     }
10128   
10129   gtk_widget_show_all (menu);
10130   
10131   om = gtk_option_menu_new ();
10132   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10133   
10134
10135   g_signal_connect (om,
10136                     "changed",
10137                     G_CALLBACK (gravity_selected),
10138                     control_window);
10139
10140   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10141
10142
10143   menu = gtk_menu_new ();
10144   
10145   i = 0;
10146   while (i < 5)
10147     {
10148       GtkWidget *mi;
10149       static gchar *names[] = {
10150         "GTK_WIN_POS_NONE",
10151         "GTK_WIN_POS_CENTER",
10152         "GTK_WIN_POS_MOUSE",
10153         "GTK_WIN_POS_CENTER_ALWAYS",
10154         "GTK_WIN_POS_CENTER_ON_PARENT",
10155         NULL
10156       };
10157
10158       g_assert (names[i]);
10159       
10160       mi = gtk_menu_item_new_with_label (names[i]);
10161
10162       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10163
10164       ++i;
10165     }
10166   
10167   gtk_widget_show_all (menu);
10168   
10169   om = gtk_option_menu_new ();
10170   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10171   
10172
10173   g_signal_connect (om,
10174                     "changed",
10175                     G_CALLBACK (pos_selected),
10176                     control_window);
10177
10178   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10179   
10180   gtk_widget_show_all (vbox);
10181   
10182   return control_window;
10183 }
10184
10185 void
10186 create_window_sizing (GtkWidget *widget)
10187 {
10188   static GtkWidget *window = NULL;
10189   static GtkWidget *target_window = NULL;
10190
10191   if (!target_window)
10192     {
10193       GtkWidget *label;
10194       
10195       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10196       gtk_window_set_screen (GTK_WINDOW (target_window),
10197                              gtk_widget_get_screen (widget));
10198       label = gtk_label_new (NULL);
10199       gtk_label_set_markup (GTK_LABEL (label), "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
10200       gtk_container_add (GTK_CONTAINER (target_window), label);
10201       gtk_widget_show (label);
10202       
10203       g_signal_connect (target_window, "destroy",
10204                         G_CALLBACK (gtk_widget_destroyed),
10205                         &target_window);
10206
10207       window = window_controls (target_window);
10208       
10209       g_signal_connect (window, "destroy",
10210                         G_CALLBACK (gtk_widget_destroyed),
10211                         &window);
10212       
10213       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
10214     }
10215
10216   /* don't show target window by default, we want to allow testing
10217    * of behavior on first show.
10218    */
10219   
10220   if (!GTK_WIDGET_VISIBLE (window))
10221     gtk_widget_show (window);
10222   else
10223     gtk_widget_destroy (window);
10224 }
10225
10226 /*
10227  * GtkProgressBar
10228  */
10229
10230 typedef struct _ProgressData {
10231   GtkWidget *window;
10232   GtkWidget *pbar;
10233   GtkWidget *block_spin;
10234   GtkWidget *x_align_spin;
10235   GtkWidget *y_align_spin;
10236   GtkWidget *step_spin;
10237   GtkWidget *act_blocks_spin;
10238   GtkWidget *label;
10239   GtkWidget *omenu1;
10240   GtkWidget *omenu2;
10241   GtkWidget *entry;
10242   int timer;
10243 } ProgressData;
10244
10245 gint
10246 progress_timeout (gpointer data)
10247 {
10248   gdouble new_val;
10249   GtkAdjustment *adj;
10250
10251   adj = GTK_PROGRESS (data)->adjustment;
10252
10253   new_val = adj->value + 1;
10254   if (new_val > adj->upper)
10255     new_val = adj->lower;
10256
10257   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
10258
10259   return TRUE;
10260 }
10261
10262 static void
10263 destroy_progress (GtkWidget     *widget,
10264                   ProgressData **pdata)
10265 {
10266   gtk_timeout_remove ((*pdata)->timer);
10267   (*pdata)->timer = 0;
10268   (*pdata)->window = NULL;
10269   g_free (*pdata);
10270   *pdata = NULL;
10271 }
10272
10273 static void
10274 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
10275 {
10276   ProgressData *pdata;
10277   gint i;
10278
10279   pdata = (ProgressData *) data;
10280
10281   if (!GTK_WIDGET_MAPPED (widget))
10282     return;
10283
10284   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10285
10286   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
10287                                     (GtkProgressBarOrientation) i);
10288 }
10289
10290 static void
10291 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
10292 {
10293   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
10294                               GTK_TOGGLE_BUTTON (widget)->active);
10295   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
10296   gtk_widget_set_sensitive (pdata->x_align_spin,
10297                             GTK_TOGGLE_BUTTON (widget)->active);
10298   gtk_widget_set_sensitive (pdata->y_align_spin,
10299                             GTK_TOGGLE_BUTTON (widget)->active);
10300 }
10301
10302 static void
10303 progressbar_toggle_bar_style (GtkWidget *widget, gpointer data)
10304 {
10305   ProgressData *pdata;
10306   gint i;
10307
10308   pdata = (ProgressData *) data;
10309
10310   if (!GTK_WIDGET_MAPPED (widget))
10311     return;
10312
10313   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10314
10315   if (i == 1)
10316     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
10317   else
10318     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10319   
10320   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
10321                                   (GtkProgressBarStyle) i);
10322 }
10323
10324 static void
10325 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
10326 {
10327   char buf[20];
10328
10329   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
10330     sprintf (buf, "???");
10331   else
10332     sprintf (buf, "%.0f%%", 100 *
10333              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
10334   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
10335 }
10336
10337 static void
10338 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
10339 {
10340   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
10341   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10342      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
10343 }
10344
10345 static void
10346 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
10347 {
10348   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
10349      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
10350 }
10351
10352 static void
10353 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
10354 {
10355   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10356                gtk_spin_button_get_value_as_int 
10357                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
10358 }
10359
10360 static void
10361 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
10362 {
10363   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
10364          gtk_spin_button_get_value (GTK_SPIN_BUTTON (pdata->x_align_spin)),
10365          gtk_spin_button_get_value (GTK_SPIN_BUTTON (pdata->y_align_spin)));
10366 }
10367
10368 static void
10369 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
10370 {
10371   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
10372                                   GTK_TOGGLE_BUTTON (widget)->active);
10373   gtk_widget_set_sensitive (pdata->step_spin, 
10374                             GTK_TOGGLE_BUTTON (widget)->active);
10375   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
10376                             GTK_TOGGLE_BUTTON (widget)->active);
10377 }
10378
10379 static void
10380 entry_changed (GtkWidget *widget, ProgressData *pdata)
10381 {
10382   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10383                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
10384 }
10385
10386 void
10387 create_progress_bar (GtkWidget *widget)
10388 {
10389   GtkWidget *button;
10390   GtkWidget *vbox;
10391   GtkWidget *vbox2;
10392   GtkWidget *hbox;
10393   GtkWidget *check;
10394   GtkWidget *frame;
10395   GtkWidget *tab;
10396   GtkWidget *label;
10397   GtkWidget *align;
10398   GtkAdjustment *adj;
10399   static ProgressData *pdata = NULL;
10400
10401   static gchar *items1[] =
10402   {
10403     "Left-Right",
10404     "Right-Left",
10405     "Bottom-Top",
10406     "Top-Bottom"
10407   };
10408
10409   static gchar *items2[] =
10410   {
10411     "Continuous",
10412     "Discrete"
10413   };
10414   
10415   if (!pdata)
10416     pdata = g_new0 (ProgressData, 1);
10417
10418   if (!pdata->window)
10419     {
10420       pdata->window = gtk_dialog_new ();
10421
10422       gtk_window_set_screen (GTK_WINDOW (pdata->window),
10423                              gtk_widget_get_screen (widget));
10424
10425       gtk_window_set_resizable (GTK_WINDOW (pdata->window), FALSE);
10426
10427       g_signal_connect (pdata->window, "destroy",
10428                         G_CALLBACK (destroy_progress),
10429                         &pdata);
10430
10431       pdata->timer = 0;
10432
10433       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
10434       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
10435
10436       vbox = gtk_vbox_new (FALSE, 5);
10437       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
10438       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
10439                           vbox, FALSE, TRUE, 0);
10440
10441       frame = gtk_frame_new ("Progress");
10442       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10443
10444       vbox2 = gtk_vbox_new (FALSE, 5);
10445       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10446
10447       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10448       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10449
10450       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
10451       g_signal_connect (adj, "value_changed",
10452                         G_CALLBACK (progress_value_changed), pdata);
10453
10454       pdata->pbar = gtk_widget_new (GTK_TYPE_PROGRESS_BAR,
10455                                     "adjustment", adj,
10456                                     NULL);
10457       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10458                                       "%v from [%l,%u] (=%p%%)");
10459       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
10460       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
10461
10462       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10463       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10464
10465       hbox = gtk_hbox_new (FALSE, 5);
10466       gtk_container_add (GTK_CONTAINER (align), hbox);
10467       label = gtk_label_new ("Label updated by user :"); 
10468       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10469       pdata->label = gtk_label_new ("");
10470       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
10471
10472       frame = gtk_frame_new ("Options");
10473       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10474
10475       vbox2 = gtk_vbox_new (FALSE, 5);
10476       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10477
10478       tab = gtk_table_new (7, 2, FALSE);
10479       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
10480
10481       label = gtk_label_new ("Orientation :");
10482       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
10483                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10484                         5, 5);
10485       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10486
10487       pdata->omenu1 = build_option_menu (items1, 4, 0,
10488                                          progressbar_toggle_orientation,
10489                                          pdata);
10490       hbox = gtk_hbox_new (FALSE, 0);
10491       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
10492                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10493                         5, 5);
10494       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
10495       
10496       check = gtk_check_button_new_with_label ("Show text");
10497       g_signal_connect (check, "clicked",
10498                         G_CALLBACK (toggle_show_text),
10499                         pdata);
10500       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
10501                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10502                         5, 5);
10503
10504       hbox = gtk_hbox_new (FALSE, 0);
10505       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
10506                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10507                         5, 5);
10508
10509       label = gtk_label_new ("Format : ");
10510       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10511
10512       pdata->entry = gtk_entry_new ();
10513       g_signal_connect (pdata->entry, "changed",
10514                         G_CALLBACK (entry_changed),
10515                         pdata);
10516       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
10517       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
10518       gtk_widget_set_size_request (pdata->entry, 100, -1);
10519       gtk_widget_set_sensitive (pdata->entry, FALSE);
10520
10521       label = gtk_label_new ("Text align :");
10522       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
10523                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10524                         5, 5);
10525       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10526
10527       hbox = gtk_hbox_new (FALSE, 0);
10528       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
10529                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10530                         5, 5);
10531
10532       label = gtk_label_new ("x :");
10533       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10534       
10535       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10536       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
10537       g_signal_connect (adj, "value_changed",
10538                         G_CALLBACK (adjust_align), pdata);
10539       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
10540       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
10541
10542       label = gtk_label_new ("y :");
10543       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10544
10545       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10546       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
10547       g_signal_connect (adj, "value_changed",
10548                         G_CALLBACK (adjust_align), pdata);
10549       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
10550       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
10551
10552       label = gtk_label_new ("Bar Style :");
10553       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
10554                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10555                         5, 5);
10556       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10557
10558       pdata->omenu2 = build_option_menu (items2, 2, 0,
10559                                          progressbar_toggle_bar_style,
10560                                          pdata);
10561       hbox = gtk_hbox_new (FALSE, 0);
10562       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
10563                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10564                         5, 5);
10565       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
10566
10567       label = gtk_label_new ("Block count :");
10568       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
10569                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10570                         5, 5);
10571       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10572
10573       hbox = gtk_hbox_new (FALSE, 0);
10574       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
10575                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10576                         5, 5);
10577       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
10578       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
10579       g_signal_connect (adj, "value_changed",
10580                         G_CALLBACK (adjust_blocks), pdata);
10581       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
10582       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10583
10584       check = gtk_check_button_new_with_label ("Activity mode");
10585       g_signal_connect (check, "clicked",
10586                         G_CALLBACK (toggle_activity_mode), pdata);
10587       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
10588                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10589                         5, 5);
10590
10591       hbox = gtk_hbox_new (FALSE, 0);
10592       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
10593                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10594                         5, 5);
10595       label = gtk_label_new ("Step size : ");
10596       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10597       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
10598       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
10599       g_signal_connect (adj, "value_changed",
10600                         G_CALLBACK (adjust_step), pdata);
10601       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
10602       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
10603
10604       hbox = gtk_hbox_new (FALSE, 0);
10605       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
10606                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10607                         5, 5);
10608       label = gtk_label_new ("Blocks :     ");
10609       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10610       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
10611       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
10612       g_signal_connect (adj, "value_changed",
10613                         G_CALLBACK (adjust_act_blocks), pdata);
10614       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
10615                           0);
10616       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
10617
10618       button = gtk_button_new_with_label ("close");
10619       g_signal_connect_swapped (button, "clicked",
10620                                 G_CALLBACK (gtk_widget_destroy),
10621                                 pdata->window);
10622       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10623       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
10624                           button, TRUE, TRUE, 0);
10625       gtk_widget_grab_default (button);
10626     }
10627
10628   if (!GTK_WIDGET_VISIBLE (pdata->window))
10629     gtk_widget_show_all (pdata->window);
10630   else
10631     gtk_widget_destroy (pdata->window);
10632 }
10633
10634 /*
10635  * Properties
10636  */
10637
10638 typedef struct {
10639   int x;
10640   int y;
10641   gboolean found;
10642   gboolean first;
10643   GtkWidget *res_widget;
10644 } FindWidgetData;
10645
10646 static void
10647 find_widget (GtkWidget *widget, FindWidgetData *data)
10648 {
10649   GtkAllocation new_allocation;
10650   gint x_offset = 0;
10651   gint y_offset = 0;
10652
10653   new_allocation = widget->allocation;
10654
10655   if (data->found || !GTK_WIDGET_MAPPED (widget))
10656     return;
10657
10658   /* Note that in the following code, we only count the
10659    * position as being inside a WINDOW widget if it is inside
10660    * widget->window; points that are outside of widget->window
10661    * but within the allocation are not counted. This is consistent
10662    * with the way we highlight drag targets.
10663    */
10664   if (!GTK_WIDGET_NO_WINDOW (widget))
10665     {
10666       new_allocation.x = 0;
10667       new_allocation.y = 0;
10668     }
10669   
10670   if (widget->parent && !data->first)
10671     {
10672       GdkWindow *window = widget->window;
10673       while (window != widget->parent->window)
10674         {
10675           gint tx, ty, twidth, theight;
10676           gdk_drawable_get_size (window, &twidth, &theight);
10677
10678           if (new_allocation.x < 0)
10679             {
10680               new_allocation.width += new_allocation.x;
10681               new_allocation.x = 0;
10682             }
10683           if (new_allocation.y < 0)
10684             {
10685               new_allocation.height += new_allocation.y;
10686               new_allocation.y = 0;
10687             }
10688           if (new_allocation.x + new_allocation.width > twidth)
10689             new_allocation.width = twidth - new_allocation.x;
10690           if (new_allocation.y + new_allocation.height > theight)
10691             new_allocation.height = theight - new_allocation.y;
10692
10693           gdk_window_get_position (window, &tx, &ty);
10694           new_allocation.x += tx;
10695           x_offset += tx;
10696           new_allocation.y += ty;
10697           y_offset += ty;
10698           
10699           window = gdk_window_get_parent (window);
10700         }
10701     }
10702
10703   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
10704       (data->x < new_allocation.x + new_allocation.width) && 
10705       (data->y < new_allocation.y + new_allocation.height))
10706     {
10707       /* First, check if the drag is in a valid drop site in
10708        * one of our children 
10709        */
10710       if (GTK_IS_CONTAINER (widget))
10711         {
10712           FindWidgetData new_data = *data;
10713           
10714           new_data.x -= x_offset;
10715           new_data.y -= y_offset;
10716           new_data.found = FALSE;
10717           new_data.first = FALSE;
10718           
10719           gtk_container_forall (GTK_CONTAINER (widget),
10720                                 (GtkCallback)find_widget,
10721                                 &new_data);
10722           
10723           data->found = new_data.found;
10724           if (data->found)
10725             data->res_widget = new_data.res_widget;
10726         }
10727
10728       /* If not, and this widget is registered as a drop site, check to
10729        * emit "drag_motion" to check if we are actually in
10730        * a drop site.
10731        */
10732       if (!data->found)
10733         {
10734           data->found = TRUE;
10735           data->res_widget = widget;
10736         }
10737     }
10738 }
10739
10740 static GtkWidget *
10741 find_widget_at_pointer (GdkDisplay *display)
10742 {
10743   GtkWidget *widget = NULL;
10744   GdkWindow *pointer_window;
10745   gint x, y;
10746   FindWidgetData data;
10747  
10748  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);
10749  
10750  if (pointer_window)
10751    gdk_window_get_user_data (pointer_window, (gpointer*) &widget);
10752
10753  if (widget)
10754    {
10755      gdk_window_get_pointer (widget->window,
10756                              &x, &y, NULL);
10757      
10758      data.x = x;
10759      data.y = y;
10760      data.found = FALSE;
10761      data.first = TRUE;
10762
10763      find_widget (widget, &data);
10764      if (data.found)
10765        return data.res_widget;
10766      return widget;
10767    }
10768  return NULL;
10769 }
10770
10771 struct PropertiesData {
10772   GtkWidget **window;
10773   GdkCursor *cursor;
10774   gboolean in_query;
10775   gint handler;
10776 };
10777
10778 static void
10779 destroy_properties (GtkWidget             *widget,
10780                     struct PropertiesData *data)
10781 {
10782   if (data->window)
10783     {
10784       *data->window = NULL;
10785       data->window = NULL;
10786     }
10787
10788   if (data->cursor)
10789     {
10790       gdk_cursor_unref (data->cursor);
10791       data->cursor = NULL;
10792     }
10793
10794   if (data->handler)
10795     {
10796       g_signal_handler_disconnect (widget, data->handler);
10797       data->handler = 0;
10798     }
10799
10800   g_free (data);
10801 }
10802
10803 static gint
10804 property_query_event (GtkWidget        *widget,
10805                       GdkEvent         *event,
10806                       struct PropertiesData *data)
10807 {
10808   GtkWidget *res_widget = NULL;
10809
10810   if (!data->in_query)
10811     return FALSE;
10812   
10813   if (event->type == GDK_BUTTON_RELEASE)
10814     {
10815       gtk_grab_remove (widget);
10816       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
10817                                   GDK_CURRENT_TIME);
10818       
10819       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
10820       if (res_widget)
10821         {
10822           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
10823                              gtk_widget_get_screen (widget));
10824           create_prop_editor (G_OBJECT (res_widget), 0);
10825         }
10826
10827       data->in_query = FALSE;
10828     }
10829   return FALSE;
10830 }
10831
10832
10833 static void
10834 query_properties (GtkButton *button,
10835                   struct PropertiesData *data)
10836 {
10837   gint failure;
10838
10839   g_signal_connect (button, "event",
10840                     G_CALLBACK (property_query_event), data);
10841
10842
10843   if (!data->cursor)
10844     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (button)),
10845                                                GDK_TARGET);
10846   
10847   failure = gdk_pointer_grab (GTK_WIDGET (button)->window,
10848                               TRUE,
10849                               GDK_BUTTON_RELEASE_MASK,
10850                               NULL,
10851                               data->cursor,
10852                               GDK_CURRENT_TIME);
10853
10854   gtk_grab_add (GTK_WIDGET (button));
10855
10856   data->in_query = TRUE;
10857 }
10858
10859 static void
10860 create_properties (GtkWidget *widget)
10861 {
10862   static GtkWidget *window = NULL;
10863   GtkWidget *button;
10864   GtkWidget *vbox;
10865   GtkWidget *label;
10866   struct PropertiesData *data;
10867
10868   data = g_new (struct PropertiesData, 1);
10869   data->window = &window;
10870   data->in_query = FALSE;
10871   data->cursor = NULL;
10872   data->handler = 0;
10873
10874   if (!window)
10875     {
10876       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10877
10878       gtk_window_set_screen (GTK_WINDOW (window),
10879                              gtk_widget_get_screen (widget));      
10880
10881       data->handler = g_signal_connect (window, "destroy",
10882                                         G_CALLBACK (destroy_properties),
10883                                         data);
10884
10885       gtk_window_set_title (GTK_WINDOW (window), "test properties");
10886       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10887
10888       vbox = gtk_vbox_new (FALSE, 1);
10889       gtk_container_add (GTK_CONTAINER (window), vbox);
10890             
10891       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
10892       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
10893       
10894       button = gtk_button_new_with_label ("Query properties");
10895       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
10896       g_signal_connect (button, "clicked",
10897                         G_CALLBACK (query_properties),
10898                         data);
10899     }
10900
10901   if (!GTK_WIDGET_VISIBLE (window))
10902     gtk_widget_show_all (window);
10903   else
10904     gtk_widget_destroy (window);
10905   
10906 }
10907
10908
10909 /*
10910  * Color Preview
10911  */
10912
10913 static int color_idle = 0;
10914
10915 gint
10916 color_idle_func (GtkWidget *preview)
10917 {
10918   static int count = 1;
10919   guchar buf[768];
10920   int i, j, k;
10921
10922   for (i = 0; i < 256; i++)
10923     {
10924       for (j = 0, k = 0; j < 256; j++)
10925         {
10926           buf[k+0] = i + count;
10927           buf[k+1] = 0;
10928           buf[k+2] = j + count;
10929           k += 3;
10930         }
10931
10932       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10933     }
10934
10935   count += 1;
10936
10937   gtk_widget_queue_draw (preview);
10938   gdk_window_process_updates (preview->window, TRUE);
10939
10940   return TRUE;
10941 }
10942
10943 static void
10944 color_preview_destroy (GtkWidget  *widget,
10945                        GtkWidget **window)
10946 {
10947   gtk_idle_remove (color_idle);
10948   color_idle = 0;
10949
10950   *window = NULL;
10951 }
10952
10953 void
10954 create_color_preview (GtkWidget *widget)
10955 {
10956   static GtkWidget *window = NULL;
10957   GtkWidget *preview;
10958   guchar buf[768];
10959   int i, j, k;
10960
10961   if (!window)
10962     {
10963       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10964       
10965       gtk_window_set_screen (GTK_WINDOW (window),
10966                              gtk_widget_get_screen (widget));
10967
10968       g_signal_connect (window, "destroy",
10969                         G_CALLBACK (color_preview_destroy),
10970                         &window);
10971
10972       gtk_window_set_title (GTK_WINDOW (window), "test");
10973       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10974
10975       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
10976       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10977       gtk_container_add (GTK_CONTAINER (window), preview);
10978
10979       for (i = 0; i < 256; i++)
10980         {
10981           for (j = 0, k = 0; j < 256; j++)
10982             {
10983               buf[k+0] = i;
10984               buf[k+1] = 0;
10985               buf[k+2] = j;
10986               k += 3;
10987             }
10988
10989           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10990         }
10991
10992       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
10993     }
10994
10995   if (!GTK_WIDGET_VISIBLE (window))
10996     gtk_widget_show_all (window);
10997   else
10998     gtk_widget_destroy (window);
10999 }
11000
11001 /*
11002  * Gray Preview
11003  */
11004
11005 static int gray_idle = 0;
11006
11007 gint
11008 gray_idle_func (GtkWidget *preview)
11009 {
11010   static int count = 1;
11011   guchar buf[256];
11012   int i, j;
11013
11014   for (i = 0; i < 256; i++)
11015     {
11016       for (j = 0; j < 256; j++)
11017         buf[j] = i + j + count;
11018
11019       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
11020     }
11021
11022   count += 1;
11023
11024   gtk_widget_draw (preview, NULL);
11025
11026   return TRUE;
11027 }
11028
11029 static void
11030 gray_preview_destroy (GtkWidget  *widget,
11031                       GtkWidget **window)
11032 {
11033   gtk_idle_remove (gray_idle);
11034   gray_idle = 0;
11035
11036   *window = NULL;
11037 }
11038
11039 void
11040 create_gray_preview (GtkWidget *widget)
11041 {
11042   static GtkWidget *window = NULL;
11043   GtkWidget *preview;
11044   guchar buf[256];
11045   int i, j;
11046
11047   if (!window)
11048     {
11049       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11050
11051       gtk_window_set_screen (GTK_WINDOW (window),
11052                              gtk_widget_get_screen (widget));
11053
11054       g_signal_connect (window, "destroy",
11055                         G_CALLBACK (gray_preview_destroy),
11056                         &window);
11057
11058       gtk_window_set_title (GTK_WINDOW (window), "test");
11059       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11060
11061       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
11062       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
11063       gtk_container_add (GTK_CONTAINER (window), preview);
11064
11065       for (i = 0; i < 256; i++)
11066         {
11067           for (j = 0; j < 256; j++)
11068             buf[j] = i + j;
11069
11070           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
11071         }
11072
11073       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
11074     }
11075
11076   if (!GTK_WIDGET_VISIBLE (window))
11077     gtk_widget_show_all (window);
11078   else
11079     gtk_widget_destroy (window);
11080 }
11081
11082
11083 /*
11084  * Selection Test
11085  */
11086
11087 void
11088 selection_test_received (GtkWidget *list, GtkSelectionData *data)
11089 {
11090   GdkAtom *atoms;
11091   GtkWidget *list_item;
11092   GList *item_list;
11093   int i, l;
11094
11095   if (data->length < 0)
11096     {
11097       g_print ("Selection retrieval failed\n");
11098       return;
11099     }
11100   if (data->type != GDK_SELECTION_TYPE_ATOM)
11101     {
11102       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
11103       return;
11104     }
11105
11106   /* Clear out any current list items */
11107
11108   gtk_list_clear_items (GTK_LIST(list), 0, -1);
11109
11110   /* Add new items to list */
11111
11112   atoms = (GdkAtom *)data->data;
11113
11114   item_list = NULL;
11115   l = data->length / sizeof (GdkAtom);
11116   for (i = 0; i < l; i++)
11117     {
11118       char *name;
11119       name = gdk_atom_name (atoms[i]);
11120       if (name != NULL)
11121         {
11122           list_item = gtk_list_item_new_with_label (name);
11123           g_free (name);
11124         }
11125       else
11126         list_item = gtk_list_item_new_with_label ("(bad atom)");
11127
11128       gtk_widget_show (list_item);
11129       item_list = g_list_append (item_list, list_item);
11130     }
11131
11132   gtk_list_append_items (GTK_LIST (list), item_list);
11133
11134   return;
11135 }
11136
11137 void
11138 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
11139 {
11140   static GdkAtom targets_atom = GDK_NONE;
11141
11142   if (targets_atom == GDK_NONE)
11143     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
11144
11145   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
11146                          GDK_CURRENT_TIME);
11147 }
11148
11149 void
11150 create_selection_test (GtkWidget *widget)
11151 {
11152   static GtkWidget *window = NULL;
11153   GtkWidget *button;
11154   GtkWidget *vbox;
11155   GtkWidget *scrolled_win;
11156   GtkWidget *list;
11157   GtkWidget *label;
11158
11159   if (!window)
11160     {
11161       window = gtk_dialog_new ();
11162       
11163       gtk_window_set_screen (GTK_WINDOW (window),
11164                              gtk_widget_get_screen (widget));
11165
11166       g_signal_connect (window, "destroy",
11167                         G_CALLBACK (gtk_widget_destroyed),
11168                         &window);
11169
11170       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
11171       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11172
11173       /* Create the list */
11174
11175       vbox = gtk_vbox_new (FALSE, 5);
11176       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11177       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
11178                           TRUE, TRUE, 0);
11179
11180       label = gtk_label_new ("Gets available targets for current selection");
11181       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11182
11183       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
11184       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
11185                                       GTK_POLICY_AUTOMATIC, 
11186                                       GTK_POLICY_AUTOMATIC);
11187       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
11188       gtk_widget_set_size_request (scrolled_win, 100, 200);
11189
11190       list = gtk_list_new ();
11191       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
11192
11193       g_signal_connect (list, "selection_received",
11194                         G_CALLBACK (selection_test_received), NULL);
11195
11196       /* .. And create some buttons */
11197       button = gtk_button_new_with_label ("Get Targets");
11198       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11199                           button, TRUE, TRUE, 0);
11200
11201       g_signal_connect (button, "clicked",
11202                         G_CALLBACK (selection_test_get_targets), list);
11203
11204       button = gtk_button_new_with_label ("Quit");
11205       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11206                           button, TRUE, TRUE, 0);
11207
11208       g_signal_connect_swapped (button, "clicked",
11209                                 G_CALLBACK (gtk_widget_destroy),
11210                                 window);
11211     }
11212
11213   if (!GTK_WIDGET_VISIBLE (window))
11214     gtk_widget_show_all (window);
11215   else
11216     gtk_widget_destroy (window);
11217 }
11218
11219 /*
11220  * Gamma Curve
11221  */
11222
11223 void
11224 create_gamma_curve (GtkWidget *widget)
11225 {
11226   static GtkWidget *window = NULL, *curve;
11227   static int count = 0;
11228   gfloat vec[256];
11229   gint max;
11230   gint i;
11231   
11232   if (!window)
11233     {
11234       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11235       gtk_window_set_screen (GTK_WINDOW (window),
11236                              gtk_widget_get_screen (widget));
11237
11238       gtk_window_set_title (GTK_WINDOW (window), "test");
11239       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11240
11241       g_signal_connect (window, "destroy",
11242                         G_CALLBACK(gtk_widget_destroyed),
11243                         &window);
11244
11245       curve = gtk_gamma_curve_new ();
11246       gtk_container_add (GTK_CONTAINER (window), curve);
11247       gtk_widget_show (curve);
11248     }
11249
11250   max = 127 + (count % 2)*128;
11251   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11252                        0, max, 0, max);
11253   for (i = 0; i < max; ++i)
11254     vec[i] = (127 / sqrt (max)) * sqrt (i);
11255   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11256                         max, vec);
11257
11258   if (!GTK_WIDGET_VISIBLE (window))
11259     gtk_widget_show (window);
11260   else if (count % 4 == 3)
11261     {
11262       gtk_widget_destroy (window);
11263       window = NULL;
11264     }
11265
11266   ++count;
11267 }
11268
11269 /*
11270  * Test scrolling
11271  */
11272
11273 static int scroll_test_pos = 0.0;
11274
11275 static gint
11276 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
11277                     GtkAdjustment *adj)
11278 {
11279   gint i,j;
11280   gint imin, imax, jmin, jmax;
11281   
11282   imin = (event->area.x) / 10;
11283   imax = (event->area.x + event->area.width + 9) / 10;
11284
11285   jmin = ((int)adj->value + event->area.y) / 10;
11286   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
11287
11288   gdk_window_clear_area (widget->window,
11289                          event->area.x, event->area.y,
11290                          event->area.width, event->area.height);
11291
11292   for (i=imin; i<imax; i++)
11293     for (j=jmin; j<jmax; j++)
11294       if ((i+j) % 2)
11295         gdk_draw_rectangle (widget->window, 
11296                             widget->style->black_gc,
11297                             TRUE,
11298                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
11299
11300   return TRUE;
11301 }
11302
11303 static gint
11304 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
11305                     GtkAdjustment *adj)
11306 {
11307   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
11308                                     -adj->page_increment / 2:
11309                                     adj->page_increment / 2);
11310   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
11311   gtk_adjustment_set_value (adj, new_value);  
11312   
11313   return TRUE;
11314 }
11315
11316 static void
11317 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
11318                        GtkAdjustment *adj)
11319 {
11320   adj->page_increment = 0.9 * widget->allocation.height;
11321   adj->page_size = widget->allocation.height;
11322
11323   g_signal_emit_by_name (adj, "changed");
11324 }
11325
11326 static void
11327 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
11328 {
11329   /* gint source_min = (int)adj->value - scroll_test_pos; */
11330   gint dy;
11331
11332   dy = scroll_test_pos - (int)adj->value;
11333   scroll_test_pos = adj->value;
11334
11335   if (!GTK_WIDGET_DRAWABLE (widget))
11336     return;
11337   gdk_window_scroll (widget->window, 0, dy);
11338   gdk_window_process_updates (widget->window, FALSE);
11339 }
11340
11341
11342 void
11343 create_scroll_test (GtkWidget *widget)
11344 {
11345   static GtkWidget *window = NULL;
11346   GtkWidget *hbox;
11347   GtkWidget *drawing_area;
11348   GtkWidget *scrollbar;
11349   GtkWidget *button;
11350   GtkAdjustment *adj;
11351   GdkGeometry geometry;
11352   GdkWindowHints geometry_mask;
11353
11354   if (!window)
11355     {
11356       window = gtk_dialog_new ();
11357
11358       gtk_window_set_screen (GTK_WINDOW (window),
11359                              gtk_widget_get_screen (widget));
11360
11361       g_signal_connect (window, "destroy",
11362                         G_CALLBACK (gtk_widget_destroyed),
11363                         &window);
11364
11365       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
11366       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11367
11368       hbox = gtk_hbox_new (FALSE, 0);
11369       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
11370                           TRUE, TRUE, 0);
11371       gtk_widget_show (hbox);
11372
11373       drawing_area = gtk_drawing_area_new ();
11374       gtk_widget_set_size_request (drawing_area, 200, 200);
11375       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
11376       gtk_widget_show (drawing_area);
11377
11378       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
11379
11380       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
11381       scroll_test_pos = 0.0;
11382
11383       scrollbar = gtk_vscrollbar_new (adj);
11384       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
11385       gtk_widget_show (scrollbar);
11386
11387       g_signal_connect (drawing_area, "expose_event",
11388                         G_CALLBACK (scroll_test_expose), adj);
11389       g_signal_connect (drawing_area, "configure_event",
11390                         G_CALLBACK (scroll_test_configure), adj);
11391       g_signal_connect (drawing_area, "scroll_event",
11392                         G_CALLBACK (scroll_test_scroll), adj);
11393       
11394       g_signal_connect (adj, "value_changed",
11395                         G_CALLBACK (scroll_test_adjustment_changed),
11396                         drawing_area);
11397       
11398       /* .. And create some buttons */
11399
11400       button = gtk_button_new_with_label ("Quit");
11401       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11402                           button, TRUE, TRUE, 0);
11403
11404       g_signal_connect_swapped (button, "clicked",
11405                                 G_CALLBACK (gtk_widget_destroy),
11406                                 window);
11407       gtk_widget_show (button);
11408
11409       /* Set up gridded geometry */
11410
11411       geometry_mask = GDK_HINT_MIN_SIZE | 
11412                        GDK_HINT_BASE_SIZE | 
11413                        GDK_HINT_RESIZE_INC;
11414
11415       geometry.min_width = 20;
11416       geometry.min_height = 20;
11417       geometry.base_width = 0;
11418       geometry.base_height = 0;
11419       geometry.width_inc = 10;
11420       geometry.height_inc = 10;
11421       
11422       gtk_window_set_geometry_hints (GTK_WINDOW (window),
11423                                drawing_area, &geometry, geometry_mask);
11424     }
11425
11426   if (!GTK_WIDGET_VISIBLE (window))
11427     gtk_widget_show (window);
11428   else
11429     gtk_widget_destroy (window);
11430 }
11431
11432 /*
11433  * Timeout Test
11434  */
11435
11436 static int timer = 0;
11437
11438 gint
11439 timeout_test (GtkWidget *label)
11440 {
11441   static int count = 0;
11442   static char buffer[32];
11443
11444   sprintf (buffer, "count: %d", ++count);
11445   gtk_label_set_text (GTK_LABEL (label), buffer);
11446
11447   return TRUE;
11448 }
11449
11450 void
11451 start_timeout_test (GtkWidget *widget,
11452                     GtkWidget *label)
11453 {
11454   if (!timer)
11455     {
11456       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
11457     }
11458 }
11459
11460 void
11461 stop_timeout_test (GtkWidget *widget,
11462                    gpointer   data)
11463 {
11464   if (timer)
11465     {
11466       gtk_timeout_remove (timer);
11467       timer = 0;
11468     }
11469 }
11470
11471 void
11472 destroy_timeout_test (GtkWidget  *widget,
11473                       GtkWidget **window)
11474 {
11475   stop_timeout_test (NULL, NULL);
11476
11477   *window = NULL;
11478 }
11479
11480 void
11481 create_timeout_test (GtkWidget *widget)
11482 {
11483   static GtkWidget *window = NULL;
11484   GtkWidget *button;
11485   GtkWidget *label;
11486
11487   if (!window)
11488     {
11489       window = gtk_dialog_new ();
11490
11491       gtk_window_set_screen (GTK_WINDOW (window),
11492                              gtk_widget_get_screen (widget));
11493
11494       g_signal_connect (window, "destroy",
11495                         G_CALLBACK (destroy_timeout_test),
11496                         &window);
11497
11498       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
11499       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11500
11501       label = gtk_label_new ("count: 0");
11502       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11503       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11504                           label, TRUE, TRUE, 0);
11505       gtk_widget_show (label);
11506
11507       button = gtk_button_new_with_label ("close");
11508       g_signal_connect_swapped (button, "clicked",
11509                                 G_CALLBACK (gtk_widget_destroy),
11510                                 window);
11511       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11512       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11513                           button, TRUE, TRUE, 0);
11514       gtk_widget_grab_default (button);
11515       gtk_widget_show (button);
11516
11517       button = gtk_button_new_with_label ("start");
11518       g_signal_connect (button, "clicked",
11519                         G_CALLBACK(start_timeout_test),
11520                         label);
11521       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11522       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11523                           button, TRUE, TRUE, 0);
11524       gtk_widget_show (button);
11525
11526       button = gtk_button_new_with_label ("stop");
11527       g_signal_connect (button, "clicked",
11528                         G_CALLBACK (stop_timeout_test),
11529                         NULL);
11530       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11531       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11532                           button, TRUE, TRUE, 0);
11533       gtk_widget_show (button);
11534     }
11535
11536   if (!GTK_WIDGET_VISIBLE (window))
11537     gtk_widget_show (window);
11538   else
11539     gtk_widget_destroy (window);
11540 }
11541
11542 /*
11543  * Idle Test
11544  */
11545
11546 static int idle_id = 0;
11547
11548 static gint
11549 idle_test (GtkWidget *label)
11550 {
11551   static int count = 0;
11552   static char buffer[32];
11553
11554   sprintf (buffer, "count: %d", ++count);
11555   gtk_label_set_text (GTK_LABEL (label), buffer);
11556
11557   return TRUE;
11558 }
11559
11560 static void
11561 start_idle_test (GtkWidget *widget,
11562                  GtkWidget *label)
11563 {
11564   if (!idle_id)
11565     {
11566       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
11567     }
11568 }
11569
11570 static void
11571 stop_idle_test (GtkWidget *widget,
11572                 gpointer   data)
11573 {
11574   if (idle_id)
11575     {
11576       gtk_idle_remove (idle_id);
11577       idle_id = 0;
11578     }
11579 }
11580
11581 static void
11582 destroy_idle_test (GtkWidget  *widget,
11583                    GtkWidget **window)
11584 {
11585   stop_idle_test (NULL, NULL);
11586
11587   *window = NULL;
11588 }
11589
11590 static void
11591 toggle_idle_container (GObject *button,
11592                        GtkContainer *container)
11593 {
11594   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
11595 }
11596
11597 static void
11598 create_idle_test (GtkWidget *widget)
11599 {
11600   static GtkWidget *window = NULL;
11601   GtkWidget *button;
11602   GtkWidget *label;
11603   GtkWidget *container;
11604
11605   if (!window)
11606     {
11607       GtkWidget *button2;
11608       GtkWidget *frame;
11609       GtkWidget *box;
11610
11611       window = gtk_dialog_new ();
11612
11613       gtk_window_set_screen (GTK_WINDOW (window),
11614                              gtk_widget_get_screen (widget));
11615
11616       g_signal_connect (window, "destroy",
11617                         G_CALLBACK (destroy_idle_test),
11618                         &window);
11619
11620       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
11621       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11622
11623       label = gtk_label_new ("count: 0");
11624       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11625       gtk_widget_show (label);
11626       
11627       container =
11628         gtk_widget_new (GTK_TYPE_HBOX,
11629                         "visible", TRUE,
11630                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
11631                          * "GtkWidget::visible", TRUE,
11632                          */
11633                          "child", label,
11634                         /* NULL), */
11635                         NULL);
11636       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11637                           container, TRUE, TRUE, 0);
11638
11639       frame =
11640         gtk_widget_new (GTK_TYPE_FRAME,
11641                         "border_width", 5,
11642                         "label", "Label Container",
11643                         "visible", TRUE,
11644                         "parent", GTK_DIALOG (window)->vbox,
11645                         NULL);
11646       box =
11647         gtk_widget_new (GTK_TYPE_VBOX,
11648                         "visible", TRUE,
11649                         "parent", frame,
11650                         NULL);
11651       button =
11652         g_object_connect (gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11653                                           "label", "Resize-Parent",
11654                                           "user_data", (void*)GTK_RESIZE_PARENT,
11655                                           "visible", TRUE,
11656                                           "parent", box,
11657                                           NULL),
11658                           "signal::clicked", toggle_idle_container, container,
11659                           NULL);
11660       button = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11661                                "label", "Resize-Queue",
11662                                "user_data", (void*)GTK_RESIZE_QUEUE,
11663                                "group", button,
11664                                "visible", TRUE,
11665                                "parent", box,
11666                                NULL);
11667       g_object_connect (button,
11668                         "signal::clicked", toggle_idle_container, container,
11669                         NULL);
11670       button2 = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11671                                 "label", "Resize-Immediate",
11672                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
11673                                 NULL);
11674       g_object_connect (button2,
11675                         "signal::clicked", toggle_idle_container, container,
11676                         NULL);
11677       g_object_set (button2,
11678                     "group", button,
11679                     "visible", TRUE,
11680                     "parent", box,
11681                     NULL);
11682
11683       button = gtk_button_new_with_label ("close");
11684       g_signal_connect_swapped (button, "clicked",
11685                                 G_CALLBACK (gtk_widget_destroy),
11686                                 window);
11687       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11688       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11689                           button, TRUE, TRUE, 0);
11690       gtk_widget_grab_default (button);
11691       gtk_widget_show (button);
11692
11693       button = gtk_button_new_with_label ("start");
11694       g_signal_connect (button, "clicked",
11695                         G_CALLBACK (start_idle_test),
11696                         label);
11697       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11698       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11699                           button, TRUE, TRUE, 0);
11700       gtk_widget_show (button);
11701
11702       button = gtk_button_new_with_label ("stop");
11703       g_signal_connect (button, "clicked",
11704                         G_CALLBACK (stop_idle_test),
11705                         NULL);
11706       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11707       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11708                           button, TRUE, TRUE, 0);
11709       gtk_widget_show (button);
11710     }
11711
11712   if (!GTK_WIDGET_VISIBLE (window))
11713     gtk_widget_show (window);
11714   else
11715     gtk_widget_destroy (window);
11716 }
11717
11718 /*
11719  * rc file test
11720  */
11721
11722 void
11723 reload_all_rc_files (void)
11724 {
11725   static GdkAtom atom_rcfiles = GDK_NONE;
11726
11727   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
11728   int i;
11729   
11730   if (!atom_rcfiles)
11731     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
11732
11733   for(i = 0; i < 5; i++)
11734     send_event->client.data.l[i] = 0;
11735   send_event->client.data_format = 32;
11736   send_event->client.message_type = atom_rcfiles;
11737   gdk_event_send_clientmessage_toall (send_event);
11738
11739   gdk_event_free (send_event);
11740 }
11741
11742 void
11743 create_rc_file (GtkWidget *widget)
11744 {
11745   static GtkWidget *window = NULL;
11746   GtkWidget *button;
11747   GtkWidget *frame;
11748   GtkWidget *vbox;
11749   GtkWidget *label;
11750
11751   if (!window)
11752     {
11753       window = gtk_dialog_new ();
11754
11755       gtk_window_set_screen (GTK_WINDOW (window),
11756                              gtk_widget_get_screen (widget));
11757
11758       g_signal_connect (window, "destroy",
11759                         G_CALLBACK (gtk_widget_destroyed),
11760                         &window);
11761
11762       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
11763       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), frame, FALSE, FALSE, 0);
11764
11765       vbox = gtk_vbox_new (FALSE, 0);
11766       gtk_container_add (GTK_CONTAINER (frame), vbox);
11767       
11768       label = gtk_label_new ("This label should be red");
11769       gtk_widget_set_name (label, "testgtk-red-label");
11770       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11771
11772       label = gtk_label_new ("This label should be green");
11773       gtk_widget_set_name (label, "testgtk-green-label");
11774       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11775
11776       label = gtk_label_new ("This label should be blue");
11777       gtk_widget_set_name (label, "testgtk-blue-label");
11778       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11779
11780       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
11781       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11782
11783       button = gtk_button_new_with_label ("Reload");
11784       g_signal_connect (button, "clicked",
11785                         G_CALLBACK (gtk_rc_reparse_all), NULL);
11786       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11787       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11788                           button, TRUE, TRUE, 0);
11789       gtk_widget_grab_default (button);
11790
11791       button = gtk_button_new_with_label ("Reload All");
11792       g_signal_connect (button, "clicked",
11793                         G_CALLBACK (reload_all_rc_files), NULL);
11794       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11795       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11796                           button, TRUE, TRUE, 0);
11797
11798       button = gtk_button_new_with_label ("Close");
11799       g_signal_connect_swapped (button, "clicked",
11800                                 G_CALLBACK (gtk_widget_destroy),
11801                                 window);
11802       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11803       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11804                           button, TRUE, TRUE, 0);
11805     }
11806
11807   if (!GTK_WIDGET_VISIBLE (window))
11808     gtk_widget_show_all (window);
11809   else
11810     gtk_widget_destroy (window);
11811 }
11812
11813 /*
11814  * Test of recursive mainloop
11815  */
11816
11817 void
11818 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
11819 {
11820   *window = NULL;
11821   gtk_main_quit ();
11822 }
11823
11824 void
11825 create_mainloop (GtkWidget *widget)
11826 {
11827   static GtkWidget *window = NULL;
11828   GtkWidget *label;
11829   GtkWidget *button;
11830
11831   if (!window)
11832     {
11833       window = gtk_dialog_new ();
11834
11835       gtk_window_set_screen (GTK_WINDOW (window),
11836                              gtk_widget_get_screen (widget));
11837
11838       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
11839
11840       g_signal_connect (window, "destroy",
11841                         G_CALLBACK (mainloop_destroyed),
11842                         &window);
11843
11844       label = gtk_label_new ("In recursive main loop...");
11845       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
11846
11847       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
11848                           TRUE, TRUE, 0);
11849       gtk_widget_show (label);
11850
11851       button = gtk_button_new_with_label ("Leave");
11852       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
11853                           FALSE, TRUE, 0);
11854
11855       g_signal_connect_swapped (button, "clicked",
11856                                 G_CALLBACK (gtk_widget_destroy),
11857                                 window);
11858
11859       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11860       gtk_widget_grab_default (button);
11861
11862       gtk_widget_show (button);
11863     }
11864
11865   if (!GTK_WIDGET_VISIBLE (window))
11866     {
11867       gtk_widget_show (window);
11868
11869       g_print ("create_mainloop: start\n");
11870       gtk_main ();
11871       g_print ("create_mainloop: done\n");
11872     }
11873   else
11874     gtk_widget_destroy (window);
11875 }
11876
11877 gboolean
11878 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
11879 {
11880   GtkLayout *layout;
11881
11882   gint i,j;
11883   gint imin, imax, jmin, jmax;
11884
11885   layout = GTK_LAYOUT (widget);
11886
11887   if (event->window != layout->bin_window)
11888     return FALSE;
11889   
11890   imin = (event->area.x) / 10;
11891   imax = (event->area.x + event->area.width + 9) / 10;
11892
11893   jmin = (event->area.y) / 10;
11894   jmax = (event->area.y + event->area.height + 9) / 10;
11895
11896   for (i=imin; i<imax; i++)
11897     for (j=jmin; j<jmax; j++)
11898       if ((i+j) % 2)
11899         gdk_draw_rectangle (layout->bin_window,
11900                             widget->style->black_gc,
11901                             TRUE,
11902                             10*i, 10*j, 
11903                             1+i%10, 1+j%10);
11904   
11905   return FALSE;
11906 }
11907
11908 void create_layout (GtkWidget *widget)
11909 {
11910   static GtkWidget *window = NULL;
11911   GtkWidget *layout;
11912   GtkWidget *scrolledwindow;
11913   GtkWidget *button;
11914
11915   if (!window)
11916     {
11917       gchar buf[16];
11918
11919       gint i, j;
11920       
11921       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11922       gtk_window_set_screen (GTK_WINDOW (window),
11923                              gtk_widget_get_screen (widget));
11924
11925       g_signal_connect (window, "destroy",
11926                         G_CALLBACK (gtk_widget_destroyed),
11927                         &window);
11928
11929       gtk_window_set_title (GTK_WINDOW (window), "Layout");
11930       gtk_widget_set_size_request (window, 200, 200);
11931
11932       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
11933       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
11934                                            GTK_SHADOW_IN);
11935       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
11936                                          GTK_CORNER_TOP_RIGHT);
11937
11938       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
11939       
11940       layout = gtk_layout_new (NULL, NULL);
11941       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
11942
11943       /* We set step sizes here since GtkLayout does not set
11944        * them itself.
11945        */
11946       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
11947       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
11948       
11949       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
11950       g_signal_connect (layout, "expose_event",
11951                         G_CALLBACK (layout_expose_handler), NULL);
11952       
11953       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
11954       
11955       for (i=0 ; i < 16 ; i++)
11956         for (j=0 ; j < 16 ; j++)
11957           {
11958             sprintf(buf, "Button %d, %d", i, j);
11959             if ((i + j) % 2)
11960               button = gtk_button_new_with_label (buf);
11961             else
11962               button = gtk_label_new (buf);
11963
11964             gtk_layout_put (GTK_LAYOUT (layout), button,
11965                             j*100, i*100);
11966           }
11967
11968       for (i=16; i < 1280; i++)
11969         {
11970           sprintf(buf, "Button %d, %d", i, 0);
11971           if (i % 2)
11972             button = gtk_button_new_with_label (buf);
11973           else
11974             button = gtk_label_new (buf);
11975
11976           gtk_layout_put (GTK_LAYOUT (layout), button,
11977                           0, i*100);
11978         }
11979     }
11980
11981   if (!GTK_WIDGET_VISIBLE (window))
11982     gtk_widget_show_all (window);
11983   else
11984     gtk_widget_destroy (window);
11985 }
11986
11987 void
11988 create_styles (GtkWidget *widget)
11989 {
11990   static GtkWidget *window = NULL;
11991   GtkWidget *label;
11992   GtkWidget *button;
11993   GtkWidget *entry;
11994   GtkWidget *vbox;
11995   static GdkColor red =    { 0, 0xffff, 0,      0      };
11996   static GdkColor green =  { 0, 0,      0xffff, 0      };
11997   static GdkColor blue =   { 0, 0,      0,      0xffff };
11998   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
11999   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
12000   PangoFontDescription *font_desc;
12001
12002   GtkRcStyle *rc_style;
12003
12004   if (!window)
12005     {
12006       window = gtk_dialog_new ();
12007       gtk_window_set_screen (GTK_WINDOW (window),
12008                              gtk_widget_get_screen (widget));
12009      
12010       g_signal_connect (window, "destroy",
12011                         G_CALLBACK (gtk_widget_destroyed),
12012                         &window);
12013
12014       
12015       button = gtk_button_new_with_label ("Close");
12016       g_signal_connect_swapped (button, "clicked",
12017                                 G_CALLBACK (gtk_widget_destroy),
12018                                 window);
12019       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12020       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12021                           button, TRUE, TRUE, 0);
12022       gtk_widget_show (button);
12023
12024       vbox = gtk_vbox_new (FALSE, 5);
12025       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
12026       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, FALSE, FALSE, 0);
12027       
12028       label = gtk_label_new ("Font:");
12029       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12030       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12031
12032       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
12033
12034       button = gtk_button_new_with_label ("Some Text");
12035       gtk_widget_modify_font (GTK_BIN (button)->child, font_desc);
12036       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12037
12038       label = gtk_label_new ("Foreground:");
12039       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12040       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12041
12042       button = gtk_button_new_with_label ("Some Text");
12043       gtk_widget_modify_fg (GTK_BIN (button)->child, GTK_STATE_NORMAL, &red);
12044       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12045
12046       label = gtk_label_new ("Background:");
12047       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12048       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12049
12050       button = gtk_button_new_with_label ("Some Text");
12051       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
12052       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12053
12054       label = gtk_label_new ("Text:");
12055       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12056       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12057
12058       entry = gtk_entry_new ();
12059       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
12060       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
12061       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
12062
12063       label = gtk_label_new ("Base:");
12064       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12065       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12066
12067       entry = gtk_entry_new ();
12068       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
12069       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
12070       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
12071
12072       label = gtk_label_new ("Multiple:");
12073       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12074       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12075
12076       button = gtk_button_new_with_label ("Some Text");
12077
12078       rc_style = gtk_rc_style_new ();
12079
12080       rc_style->font_desc = pango_font_description_copy (font_desc);
12081       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
12082       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
12083       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
12084       rc_style->fg[GTK_STATE_NORMAL] = yellow;
12085       rc_style->bg[GTK_STATE_NORMAL] = blue;
12086       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
12087       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
12088       rc_style->fg[GTK_STATE_ACTIVE] = red;
12089       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
12090       rc_style->xthickness = 5;
12091       rc_style->ythickness = 5;
12092
12093       gtk_widget_modify_style (button, rc_style);
12094       gtk_widget_modify_style (GTK_BIN (button)->child, rc_style);
12095
12096       g_object_unref (rc_style);
12097       
12098       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12099     }
12100   
12101   if (!GTK_WIDGET_VISIBLE (window))
12102     gtk_widget_show_all (window);
12103   else
12104     gtk_widget_destroy (window);
12105 }
12106
12107 /*
12108  * Main Window and Exit
12109  */
12110
12111 void
12112 do_exit (GtkWidget *widget, GtkWidget *window)
12113 {
12114   gtk_widget_destroy (window);
12115   gtk_main_quit ();
12116 }
12117
12118 struct {
12119   char *label;
12120   void (*func) ();
12121   gboolean do_not_benchmark;
12122 } buttons[] =
12123 {
12124   { "big windows", create_big_windows },
12125   { "button box", create_button_box },
12126   { "buttons", create_buttons },
12127   { "check buttons", create_check_buttons },
12128   { "clist", create_clist},
12129   { "color selection", create_color_selection },
12130   { "ctree", create_ctree },
12131   { "cursors", create_cursors },
12132   { "dialog", create_dialog },
12133   { "display & screen", create_display_screen },
12134   { "entry", create_entry },
12135   { "event watcher", create_event_watcher },
12136   { "file selection", create_file_selection },
12137   { "flipping", create_flipping },
12138   { "focus", create_focus },
12139   { "font selection", create_font_selection },
12140   { "gamma curve", create_gamma_curve, TRUE },
12141   { "gridded geometry", create_gridded_geometry, TRUE },
12142   { "handle box", create_handle_box },
12143   { "image from drawable", create_get_image },
12144   { "image", create_image },
12145   { "item factory", create_item_factory },
12146   { "key lookup", create_key_lookup },
12147   { "labels", create_labels },
12148   { "layout", create_layout },
12149   { "list", create_list },
12150   { "menus", create_menus },
12151   { "message dialog", create_message_dialog },
12152   { "modal window", create_modal_window, TRUE },
12153   { "notebook", create_notebook },
12154   { "panes", create_panes },
12155   { "paned keyboard", create_paned_keyboard_navigation },
12156   { "pixmap", create_pixmap },
12157   { "preview color", create_color_preview, TRUE },
12158   { "preview gray", create_gray_preview, TRUE },
12159   { "progress bar", create_progress_bar },
12160   { "properties", create_properties },
12161   { "radio buttons", create_radio_buttons },
12162   { "range controls", create_range_controls },
12163   { "rc file", create_rc_file },
12164   { "reparent", create_reparent },
12165   { "rulers", create_rulers },
12166   { "saved position", create_saved_position },
12167   { "scrolled windows", create_scrolled_windows },
12168   { "shapes", create_shapes },
12169   { "size groups", create_size_groups },
12170   { "spinbutton", create_spins },
12171   { "statusbar", create_statusbar },
12172   { "styles", create_styles },
12173   { "test idle", create_idle_test },
12174   { "test mainloop", create_mainloop, TRUE },
12175   { "test scrolling", create_scroll_test },
12176   { "test selection", create_selection_test },
12177   { "test timeout", create_timeout_test },
12178   { "text", create_text },
12179   { "toggle buttons", create_toggle_buttons },
12180   { "toolbar", create_toolbar },
12181   { "tooltips", create_tooltips },
12182   { "tree", create_tree_mode_window},
12183   { "WM hints", create_wmhints },
12184   { "window sizing", create_window_sizing },
12185   { "window states", create_window_states }
12186 };
12187 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
12188
12189 void
12190 create_main_window (void)
12191 {
12192   GtkWidget *window;
12193   GtkWidget *box1;
12194   GtkWidget *box2;
12195   GtkWidget *scrolled_window;
12196   GtkWidget *button;
12197   GtkWidget *label;
12198   gchar buffer[64];
12199   GtkWidget *separator;
12200   GdkGeometry geometry;
12201   int i;
12202
12203   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12204   gtk_widget_set_name (window, "main window");
12205   gtk_widget_set_uposition (window, 20, 20);
12206   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
12207
12208   geometry.min_width = -1;
12209   geometry.min_height = -1;
12210   geometry.max_width = -1;
12211   geometry.max_height = G_MAXSHORT;
12212   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
12213                                  &geometry,
12214                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
12215
12216   g_signal_connect (window, "destroy",
12217                     G_CALLBACK (gtk_main_quit),
12218                     NULL);
12219   g_signal_connect (window, "delete-event",
12220                     G_CALLBACK (gtk_false),
12221                     NULL);
12222
12223   box1 = gtk_vbox_new (FALSE, 0);
12224   gtk_container_add (GTK_CONTAINER (window), box1);
12225
12226   if (gtk_micro_version > 0)
12227     sprintf (buffer,
12228              "Gtk+ v%d.%d.%d",
12229              gtk_major_version,
12230              gtk_minor_version,
12231              gtk_micro_version);
12232   else
12233     sprintf (buffer,
12234              "Gtk+ v%d.%d",
12235              gtk_major_version,
12236              gtk_minor_version);
12237
12238   label = gtk_label_new (buffer);
12239   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
12240   gtk_widget_set_name (label, "testgtk-version-label");
12241
12242   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
12243   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
12244   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
12245                                   GTK_POLICY_NEVER, 
12246                                   GTK_POLICY_AUTOMATIC);
12247   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
12248
12249   box2 = gtk_vbox_new (FALSE, 0);
12250   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12251   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
12252   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
12253                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
12254   gtk_widget_show (box2);
12255
12256   for (i = 0; i < nbuttons; i++)
12257     {
12258       button = gtk_button_new_with_label (buttons[i].label);
12259       if (buttons[i].func)
12260         g_signal_connect (button, 
12261                           "clicked", 
12262                           G_CALLBACK(buttons[i].func),
12263                           NULL);
12264       else
12265         gtk_widget_set_sensitive (button, FALSE);
12266       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12267     }
12268
12269   separator = gtk_hseparator_new ();
12270   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
12271
12272   box2 = gtk_vbox_new (FALSE, 10);
12273   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12274   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
12275
12276   button = gtk_button_new_with_mnemonic ("_Close");
12277   g_signal_connect (button, "clicked",
12278                     G_CALLBACK (do_exit),
12279                     window);
12280   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12281   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12282   gtk_widget_grab_default (button);
12283
12284   gtk_widget_show_all (window);
12285 }
12286
12287 static void
12288 test_init ()
12289 {
12290   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
12291                    G_FILE_TEST_EXISTS))
12292     {
12293       putenv ("GDK_PIXBUF_MODULE_FILE=../gdk-pixbuf/gdk-pixbuf.loaders");
12294       putenv ("GTK_IM_MODULE_FILE=../modules/input/gtk.immodules");
12295     }
12296 }
12297
12298 static char *
12299 pad (const char *str, int to)
12300 {
12301   static char buf[256];
12302   int len = strlen (str);
12303   int i;
12304
12305   for (i = 0; i < to; i++)
12306     buf[i] = ' ';
12307
12308   buf[to] = '\0';
12309
12310   memcpy (buf, str, len);
12311
12312   return buf;
12313 }
12314
12315 static void
12316 bench_iteration (void (* fn) ())
12317 {
12318   fn (); /* on */
12319   while (g_main_context_iteration (NULL, FALSE));
12320   fn (); /* off */
12321   while (g_main_context_iteration (NULL, FALSE));
12322 }
12323
12324 void
12325 do_real_bench (void (* fn) (), char *name, int num)
12326 {
12327   GTimeVal tv0, tv1;
12328   double dt_first;
12329   double dt;
12330   int n;
12331   static gboolean printed_headers = FALSE;
12332
12333   if (!printed_headers) {
12334     g_print ("Test                 Iters      First      Other\n");
12335     g_print ("-------------------- ----- ---------- ----------\n");
12336     printed_headers = TRUE;
12337   }
12338
12339   g_get_current_time (&tv0);
12340   bench_iteration (fn); 
12341   g_get_current_time (&tv1);
12342
12343   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12344         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12345
12346   g_get_current_time (&tv0);
12347   for (n = 0; n < num - 1; n++)
12348     bench_iteration (fn); 
12349   g_get_current_time (&tv1);
12350   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12351         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12352
12353   g_print ("%s %5d ", pad (name, 20), num);
12354   if (num > 1)
12355     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
12356   else
12357     g_print ("%10.1f\n", dt_first);
12358 }
12359
12360 void
12361 do_bench (char* what, int num)
12362 {
12363   int i;
12364   void (* fn) ();
12365   fn = NULL;
12366
12367   if (g_ascii_strcasecmp (what, "ALL") == 0)
12368     {
12369       for (i = 0; i < nbuttons; i++)
12370         {
12371           if (!buttons[i].do_not_benchmark)
12372             do_real_bench (buttons[i].func, buttons[i].label, num);
12373         }
12374
12375       return;
12376     }
12377   else
12378     {
12379       for (i = 0; i < nbuttons; i++)
12380         {
12381           if (strcmp (buttons[i].label, what) == 0)
12382             {
12383               fn = buttons[i].func;
12384               break;
12385             }
12386         }
12387       
12388       if (!fn)
12389         g_print ("Can't bench: \"%s\" not found.\n", what);
12390       else
12391         do_real_bench (fn, buttons[i].label, num);
12392     }
12393 }
12394
12395 void 
12396 usage (void)
12397 {
12398   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
12399   exit (1);
12400 }
12401
12402 int
12403 main (int argc, char *argv[])
12404 {
12405   GtkBindingSet *binding_set;
12406   int i;
12407   gboolean done_benchmarks = FALSE;
12408
12409   srand (time (NULL));
12410
12411   test_init ();
12412
12413   /* Check to see if we are being run from the correct
12414    * directory.
12415    */
12416   if (file_exists ("testgtkrc"))
12417     gtk_rc_add_default_file ("testgtkrc");
12418
12419   gtk_init (&argc, &argv);
12420
12421   /*  benchmarking
12422    */
12423   for (i = 1; i < argc; i++)
12424     {
12425       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
12426         {
12427           int num = 1;
12428           char *nextarg;
12429           char *what;
12430           char *count;
12431           
12432           nextarg = strchr (argv[i], '=');
12433           if (nextarg)
12434             nextarg++;
12435           else
12436             {
12437               i++;
12438               if (i == argc)
12439                 usage ();
12440               nextarg = argv[i];
12441             }
12442
12443           count = strchr (nextarg, ':');
12444           if (count)
12445             {
12446               what = g_strndup (nextarg, count - nextarg);
12447               count++;
12448               num = atoi (count);
12449               if (num <= 0)
12450                 usage ();
12451             }
12452           else
12453             what = g_strdup (nextarg);
12454
12455           do_bench (what, num ? num : 1);
12456           done_benchmarks = TRUE;
12457         }
12458       else
12459         usage ();
12460     }
12461   if (done_benchmarks)
12462     return 0;
12463
12464   /* bindings test
12465    */
12466   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
12467   gtk_binding_entry_add_signal (binding_set,
12468                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
12469                                 "debug_msg",
12470                                 1,
12471                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
12472   
12473   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
12474    * changes
12475    */
12476
12477   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
12478                        "   fg[NORMAL] = \"#ff0000\"\n"
12479                        "   font = \"Sans 18\"\n"
12480                        "}\n"
12481                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
12482   
12483   create_main_window ();
12484
12485   gtk_main ();
12486
12487   if (1)
12488     {
12489       while (g_main_context_pending (NULL))
12490         g_main_context_iteration (NULL, FALSE);
12491 #if 0
12492       sleep (1);
12493       while (g_main_context_pending (NULL))
12494         g_main_context_iteration (NULL, FALSE);
12495 #endif
12496     }
12497   return 0;
12498 }