]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
Use g_get_application_name() instead of g_get_prgname() as the default
[~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  * Resize Grips
2795  */
2796 static gboolean
2797 grippy_button_press (GtkWidget *area, GdkEventButton *event, GdkWindowEdge edge)
2798 {
2799   if (event->button == 1)
2800     gtk_window_begin_resize_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)), edge,
2801                                   event->button, event->x_root, event->y_root,
2802                                   event->time);
2803   return TRUE;
2804 }
2805
2806 static gboolean
2807 grippy_expose (GtkWidget *area, GdkEventExpose *event, GdkWindowEdge edge)
2808 {
2809   gtk_paint_resize_grip (area->style,
2810                          area->window,
2811                          GTK_WIDGET_STATE (area),
2812                          &event->area,
2813                          area,
2814                          "statusbar",
2815                          edge,
2816                          0, 0,
2817                          area->allocation.width,
2818                          area->allocation.height);
2819
2820   return TRUE;
2821 }
2822
2823 static void
2824 create_resize_grips (GtkWidget *widget)
2825 {
2826   static GtkWidget *window = NULL;
2827   GtkWidget *area;
2828   GtkWidget *hbox, *vbox;
2829   if (!window)
2830     {
2831       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2832
2833       gtk_window_set_screen (GTK_WINDOW (window),
2834                              gtk_widget_get_screen (widget));
2835
2836       gtk_window_set_title (GTK_WINDOW (window), "resize grips");
2837       
2838       g_signal_connect (window, "destroy",
2839                         G_CALLBACK (gtk_widget_destroyed),
2840                         &window);
2841
2842       vbox = gtk_vbox_new (FALSE, 0);
2843       gtk_container_add (GTK_CONTAINER (window), vbox);
2844       
2845       hbox = gtk_hbox_new (FALSE, 0);
2846       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2847
2848       /* South west */
2849       area = gtk_drawing_area_new ();
2850       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2851       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2852       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
2853                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
2854       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2855                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
2856       /* South */
2857       area = gtk_drawing_area_new ();
2858       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2859       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2860       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
2861                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
2862       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2863                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
2864       
2865       /* South east */
2866       area = gtk_drawing_area_new ();
2867       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2868       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2869       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
2870                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
2871       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2872                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
2873     }
2874
2875   if (!GTK_WIDGET_VISIBLE (window))
2876     gtk_widget_show_all (window);
2877   else
2878     gtk_widget_destroy (window);
2879 }
2880
2881 /*
2882  * Saved Position
2883  */
2884 gint upositionx = 0;
2885 gint upositiony = 0;
2886
2887 static gint
2888 uposition_configure (GtkWidget *window)
2889 {
2890   GtkLabel *lx;
2891   GtkLabel *ly;
2892   gchar buffer[64];
2893
2894   lx = g_object_get_data (G_OBJECT (window), "x");
2895   ly = g_object_get_data (G_OBJECT (window), "y");
2896
2897   gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
2898   sprintf (buffer, "%d", upositionx);
2899   gtk_label_set_text (lx, buffer);
2900   sprintf (buffer, "%d", upositiony);
2901   gtk_label_set_text (ly, buffer);
2902
2903   return FALSE;
2904 }
2905
2906 static void
2907 uposition_stop_configure (GtkToggleButton *toggle,
2908                           GtkObject       *window)
2909 {
2910   if (toggle->active)
2911     g_signal_handlers_block_by_func (window, G_CALLBACK (uposition_configure), NULL);
2912   else
2913     g_signal_handlers_unblock_by_func (window, G_CALLBACK (uposition_configure), NULL);
2914 }
2915
2916 static void
2917 create_saved_position (GtkWidget *widget)
2918 {
2919   static GtkWidget *window = NULL;
2920
2921   if (!window)
2922     {
2923       GtkWidget *hbox;
2924       GtkWidget *main_vbox;
2925       GtkWidget *vbox;
2926       GtkWidget *x_label;
2927       GtkWidget *y_label;
2928       GtkWidget *button;
2929       GtkWidget *label;
2930       GtkWidget *any;
2931
2932       window = g_object_connect (gtk_widget_new (GTK_TYPE_WINDOW,
2933                                                  "type", GTK_WINDOW_TOPLEVEL,
2934                                                  "x", upositionx,
2935                                                  "y", upositiony,
2936                                                  "title", "Saved Position",
2937                                                  NULL),
2938                                  "signal::configure_event", uposition_configure, NULL,
2939                                  NULL);
2940
2941       gtk_window_set_screen (GTK_WINDOW (window),
2942                              gtk_widget_get_screen (widget));
2943       
2944
2945       g_signal_connect (window, "destroy",
2946                         G_CALLBACK (gtk_widget_destroyed),
2947                         &window);
2948
2949       main_vbox = gtk_vbox_new (FALSE, 5);
2950       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
2951       gtk_container_add (GTK_CONTAINER (window), main_vbox);
2952
2953       vbox =
2954         gtk_widget_new (gtk_vbox_get_type (),
2955                         "GtkBox::homogeneous", FALSE,
2956                         "GtkBox::spacing", 5,
2957                         "GtkContainer::border_width", 10,
2958                         "GtkWidget::parent", main_vbox,
2959                         "GtkWidget::visible", TRUE,
2960                         "child", g_object_connect (gtk_widget_new (GTK_TYPE_TOGGLE_BUTTON,
2961                                                                    "label", "Stop Events",
2962                                                                    "active", FALSE,
2963                                                                    "visible", TRUE,
2964                                                                    NULL),
2965                                                    "signal::clicked", uposition_stop_configure, window,
2966                                                    NULL),
2967                         NULL);
2968
2969       hbox = gtk_hbox_new (FALSE, 0);
2970       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2971       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2972
2973       label = gtk_label_new ("X Origin : ");
2974       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2975       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2976
2977       x_label = gtk_label_new ("");
2978       gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
2979       g_object_set_data (G_OBJECT (window), "x", x_label);
2980
2981       hbox = gtk_hbox_new (FALSE, 0);
2982       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2983       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2984
2985       label = gtk_label_new ("Y Origin : ");
2986       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2987       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2988
2989       y_label = gtk_label_new ("");
2990       gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
2991       g_object_set_data (G_OBJECT (window), "y", y_label);
2992
2993       any =
2994         gtk_widget_new (gtk_hseparator_get_type (),
2995                         "GtkWidget::visible", TRUE,
2996                         NULL);
2997       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
2998
2999       hbox = gtk_hbox_new (FALSE, 0);
3000       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
3001       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
3002
3003       button = gtk_button_new_with_label ("Close");
3004       g_signal_connect_swapped (button, "clicked",
3005                                 G_CALLBACK (gtk_widget_destroy),
3006                                 window);
3007       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3008       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3009       gtk_widget_grab_default (button);
3010       
3011       gtk_widget_show_all (window);
3012     }
3013   else
3014     gtk_widget_destroy (window);
3015 }
3016
3017 /*
3018  * GtkPixmap
3019  */
3020
3021 static void
3022 create_pixmap (GtkWidget *widget)
3023 {
3024   static GtkWidget *window = NULL;
3025   GtkWidget *box1;
3026   GtkWidget *box2;
3027   GtkWidget *box3;
3028   GtkWidget *button;
3029   GtkWidget *label;
3030   GtkWidget *separator;
3031   GtkWidget *pixmapwid;
3032
3033   if (!window)
3034     {
3035       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3036
3037       gtk_window_set_screen (GTK_WINDOW (window),
3038                              gtk_widget_get_screen (widget));
3039
3040       g_signal_connect (window, "destroy",
3041                         G_CALLBACK (gtk_widget_destroyed),
3042                         &window);
3043
3044       gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
3045       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3046       gtk_widget_realize(window);
3047
3048       box1 = gtk_vbox_new (FALSE, 0);
3049       gtk_container_add (GTK_CONTAINER (window), box1);
3050
3051       box2 = gtk_vbox_new (FALSE, 10);
3052       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3053       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3054
3055       button = gtk_button_new ();
3056       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
3057
3058       pixmapwid = new_pixmap ("test.xpm", window->window, NULL);
3059
3060       label = gtk_label_new ("Pixmap\ntest");
3061       box3 = gtk_hbox_new (FALSE, 0);
3062       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
3063       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
3064       gtk_container_add (GTK_CONTAINER (box3), label);
3065       gtk_container_add (GTK_CONTAINER (button), box3);
3066
3067       button = gtk_button_new ();
3068       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
3069       
3070       pixmapwid = new_pixmap ("test.xpm", window->window, NULL);
3071
3072       label = gtk_label_new ("Pixmap\ntest");
3073       box3 = gtk_hbox_new (FALSE, 0);
3074       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
3075       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
3076       gtk_container_add (GTK_CONTAINER (box3), label);
3077       gtk_container_add (GTK_CONTAINER (button), box3);
3078
3079       gtk_widget_set_sensitive (button, FALSE);
3080       
3081       separator = gtk_hseparator_new ();
3082       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3083
3084       box2 = gtk_vbox_new (FALSE, 10);
3085       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3086       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3087
3088       button = gtk_button_new_with_label ("close");
3089       g_signal_connect_swapped (button, "clicked",
3090                                 G_CALLBACK (gtk_widget_destroy),
3091                                 window);
3092       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3093       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3094       gtk_widget_grab_default (button);
3095     }
3096
3097   if (!GTK_WIDGET_VISIBLE (window))
3098     gtk_widget_show_all (window);
3099   else
3100     gtk_widget_destroy (window);
3101 }
3102
3103 static void
3104 tips_query_widget_entered (GtkTipsQuery   *tips_query,
3105                            GtkWidget      *widget,
3106                            const gchar    *tip_text,
3107                            const gchar    *tip_private,
3108                            GtkWidget      *toggle)
3109 {
3110   if (GTK_TOGGLE_BUTTON (toggle)->active)
3111     {
3112       gtk_label_set_text (GTK_LABEL (tips_query), tip_text ? "There is a Tip!" : "There is no Tip!");
3113       /* don't let GtkTipsQuery reset its label */
3114       g_signal_stop_emission_by_name (tips_query, "widget_entered");
3115     }
3116 }
3117
3118 static gint
3119 tips_query_widget_selected (GtkWidget      *tips_query,
3120                             GtkWidget      *widget,
3121                             const gchar    *tip_text,
3122                             const gchar    *tip_private,
3123                             GdkEventButton *event,
3124                             gpointer        func_data)
3125 {
3126   if (widget)
3127     g_print ("Help \"%s\" requested for <%s>\n",
3128              tip_private ? tip_private : "None",
3129              g_type_name (G_OBJECT_TYPE (widget)));
3130   return TRUE;
3131 }
3132
3133 static void
3134 create_tooltips (GtkWidget *widget)
3135 {
3136   static GtkWidget *window = NULL;
3137   GtkWidget *box1;
3138   GtkWidget *box2;
3139   GtkWidget *box3;
3140   GtkWidget *button;
3141   GtkWidget *toggle;
3142   GtkWidget *frame;
3143   GtkWidget *tips_query;
3144   GtkWidget *separator;
3145   GtkTooltips *tooltips;
3146
3147   if (!window)
3148     {
3149       window =
3150         gtk_widget_new (gtk_window_get_type (),
3151                         "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
3152                         "GtkContainer::border_width", 0,
3153                         "GtkWindow::title", "Tooltips",
3154                         "GtkWindow::allow_shrink", TRUE,
3155                         "GtkWindow::allow_grow", FALSE,
3156                         NULL);
3157
3158       gtk_window_set_screen (GTK_WINDOW (window),
3159                              gtk_widget_get_screen (widget));
3160
3161       g_signal_connect (window, "destroy",
3162                         G_CALLBACK (destroy_tooltips),
3163                         &window);
3164
3165       tooltips=gtk_tooltips_new();
3166       g_object_ref (tooltips);
3167       gtk_object_sink (GTK_OBJECT (tooltips));
3168       g_object_set_data (G_OBJECT (window), "tooltips", tooltips);
3169       
3170       box1 = gtk_vbox_new (FALSE, 0);
3171       gtk_container_add (GTK_CONTAINER (window), box1);
3172
3173       box2 = gtk_vbox_new (FALSE, 10);
3174       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3175       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3176
3177       button = gtk_toggle_button_new_with_label ("button1");
3178       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3179
3180       gtk_tooltips_set_tip (tooltips,
3181                             button,
3182                             "This is button 1",
3183                             "ContextHelp/buttons/1");
3184
3185       button = gtk_toggle_button_new_with_label ("button2");
3186       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3187
3188       gtk_tooltips_set_tip (tooltips,
3189                             button,
3190                             "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.",
3191                             "ContextHelp/buttons/2_long");
3192
3193       toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
3194       gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
3195
3196       gtk_tooltips_set_tip (tooltips,
3197                             toggle,
3198                             "Toggle TipsQuery view.",
3199                             "Hi msw! ;)");
3200
3201       box3 =
3202         gtk_widget_new (gtk_vbox_get_type (),
3203                         "homogeneous", FALSE,
3204                         "spacing", 5,
3205                         "border_width", 5,
3206                         "visible", TRUE,
3207                         NULL);
3208
3209       tips_query = gtk_tips_query_new ();
3210
3211       button =
3212         gtk_widget_new (gtk_button_get_type (),
3213                         "label", "[?]",
3214                         "visible", TRUE,
3215                         "parent", box3,
3216                         NULL);
3217       g_object_connect (button,
3218                         "swapped_signal::clicked", gtk_tips_query_start_query, tips_query,
3219                         NULL);
3220       gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
3221       gtk_tooltips_set_tip (tooltips,
3222                             button,
3223                             "Start the Tooltips Inspector",
3224                             "ContextHelp/buttons/?");
3225       
3226       
3227       g_object_set (g_object_connect (tips_query,
3228                                       "signal::widget_entered", tips_query_widget_entered, toggle,
3229                                       "signal::widget_selected", tips_query_widget_selected, NULL,
3230                                       NULL),
3231                     "visible", TRUE,
3232                     "parent", box3,
3233                     "caller", button,
3234                     NULL);
3235       
3236       frame = gtk_widget_new (gtk_frame_get_type (),
3237                               "label", "ToolTips Inspector",
3238                               "label_xalign", (double) 0.5,
3239                               "border_width", 0,
3240                               "visible", TRUE,
3241                               "parent", box2,
3242                               "child", box3,
3243                               NULL);
3244       gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
3245
3246       separator = gtk_hseparator_new ();
3247       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3248
3249       box2 = gtk_vbox_new (FALSE, 10);
3250       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3251       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3252
3253       button = gtk_button_new_with_label ("close");
3254       g_signal_connect_swapped (button, "clicked",
3255                                 G_CALLBACK (gtk_widget_destroy),
3256                                 window);
3257       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3258       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3259       gtk_widget_grab_default (button);
3260
3261       gtk_tooltips_set_tip (tooltips, button, "Push this button to close window", "ContextHelp/buttons/Close");
3262     }
3263
3264   if (!GTK_WIDGET_VISIBLE (window))
3265     gtk_widget_show_all (window);
3266   else
3267     gtk_widget_destroy (window);
3268 }
3269
3270 /*
3271  * GtkImage
3272  */
3273
3274 static void
3275 pack_image (GtkWidget *box,
3276             const gchar *text,
3277             GtkWidget *image)
3278 {
3279   gtk_box_pack_start (GTK_BOX (box),
3280                       gtk_label_new (text),
3281                       FALSE, FALSE, 0);
3282
3283   gtk_box_pack_start (GTK_BOX (box),
3284                       image,
3285                       TRUE, TRUE, 0);  
3286 }
3287
3288 static void
3289 create_image (GtkWidget *widget)
3290 {
3291   static GtkWidget *window = NULL;
3292
3293   if (window == NULL)
3294     {
3295       GtkWidget *vbox;
3296       GdkPixmap *pixmap;
3297       GdkBitmap *mask;
3298         
3299       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3300       
3301       gtk_window_set_screen (GTK_WINDOW (window),
3302                              gtk_widget_get_screen (widget));
3303
3304       /* this is bogus for testing drawing when allocation < request,
3305        * don't copy into real code
3306        */
3307       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
3308       
3309       g_signal_connect (window, "destroy",
3310                         G_CALLBACK (gtk_widget_destroyed),
3311                         &window);
3312
3313       vbox = gtk_vbox_new (FALSE, 5);
3314
3315       gtk_container_add (GTK_CONTAINER (window), vbox);
3316
3317       pack_image (vbox, "Stock Warning Dialog",
3318                   gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
3319                                             GTK_ICON_SIZE_DIALOG));
3320
3321       pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
3322                                                       gtk_widget_get_colormap (window),
3323                                                       &mask,
3324                                                       NULL,
3325                                                       openfile);
3326       
3327       pack_image (vbox, "Pixmap",
3328                   gtk_image_new_from_pixmap (pixmap, mask));
3329     }
3330
3331   if (!GTK_WIDGET_VISIBLE (window))
3332     gtk_widget_show_all (window);
3333   else
3334     gtk_widget_destroy (window);
3335 }
3336      
3337 /*
3338  * Menu demo
3339  */
3340
3341 static GtkWidget*
3342 create_menu (GdkScreen *screen, gint depth, gint length, gboolean tearoff)
3343 {
3344   GtkWidget *menu;
3345   GtkWidget *menuitem;
3346   GtkWidget *image;
3347   GSList *group;
3348   char buf[32];
3349   int i, j;
3350
3351   if (depth < 1)
3352     return NULL;
3353
3354   menu = gtk_menu_new ();
3355   gtk_menu_set_screen (GTK_MENU (menu), screen);
3356
3357   group = NULL;
3358
3359   if (tearoff)
3360     {
3361       menuitem = gtk_tearoff_menu_item_new ();
3362       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3363       gtk_widget_show (menuitem);
3364     }
3365
3366   image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
3367                                     GTK_ICON_SIZE_MENU);
3368   gtk_widget_show (image);
3369   menuitem = gtk_image_menu_item_new_with_label ("Image item");
3370   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3371   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3372   gtk_widget_show (menuitem);
3373   
3374   for (i = 0, j = 1; i < length; i++, j++)
3375     {
3376       sprintf (buf, "item %2d - %d", depth, j);
3377
3378       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
3379       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
3380
3381 #if 0
3382       if (depth % 2)
3383         gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
3384 #endif
3385
3386       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3387       gtk_widget_show (menuitem);
3388       if (i == 3)
3389         gtk_widget_set_sensitive (menuitem, FALSE);
3390
3391       if (i == 5)
3392         gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (menuitem),
3393                                               TRUE);
3394
3395       if (i < 5)
3396         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), 
3397                                    create_menu (screen, depth - 1, 5,  TRUE));
3398     }
3399
3400   return menu;
3401 }
3402
3403 static void
3404 create_menus (GtkWidget *widget)
3405 {
3406   static GtkWidget *window = NULL;
3407   GtkWidget *box1;
3408   GtkWidget *box2;
3409   GtkWidget *button;
3410   GtkWidget *optionmenu;
3411   GtkWidget *separator;
3412   
3413   if (!window)
3414     {
3415       GtkWidget *menubar;
3416       GtkWidget *menu;
3417       GtkWidget *menuitem;
3418       GtkAccelGroup *accel_group;
3419       GtkWidget *image;
3420       GdkScreen *screen = gtk_widget_get_screen (widget);
3421       
3422       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3423
3424       gtk_window_set_screen (GTK_WINDOW (window), screen);
3425       
3426       g_signal_connect (window, "destroy",
3427                         G_CALLBACK (gtk_widget_destroyed),
3428                         &window);
3429       g_signal_connect (window, "delete-event",
3430                         G_CALLBACK (gtk_true),
3431                         NULL);
3432       
3433       accel_group = gtk_accel_group_new ();
3434       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3435
3436       gtk_window_set_title (GTK_WINDOW (window), "menus");
3437       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3438       
3439       
3440       box1 = gtk_vbox_new (FALSE, 0);
3441       gtk_container_add (GTK_CONTAINER (window), box1);
3442       gtk_widget_show (box1);
3443       
3444       menubar = gtk_menu_bar_new ();
3445       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3446       gtk_widget_show (menubar);
3447       
3448       menu = create_menu (screen, 2, 50, TRUE);
3449       
3450       menuitem = gtk_menu_item_new_with_label ("test\nline2");
3451       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3452       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3453       gtk_widget_show (menuitem);
3454       
3455       menuitem = gtk_menu_item_new_with_label ("foo");
3456       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE));
3457       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3458       gtk_widget_show (menuitem);
3459
3460       image = gtk_image_new_from_stock (GTK_STOCK_HELP,
3461                                         GTK_ICON_SIZE_MENU);
3462       gtk_widget_show (image);
3463       menuitem = gtk_image_menu_item_new_with_label ("Help");
3464       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3465       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 4, 5, TRUE));
3466       gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
3467       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3468       gtk_widget_show (menuitem);
3469       
3470       menubar = gtk_menu_bar_new ();
3471       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3472       gtk_widget_show (menubar);
3473       
3474       menu = create_menu (screen, 2, 10, TRUE);
3475       
3476       menuitem = gtk_menu_item_new_with_label ("Second menu bar");
3477       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3478       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3479       gtk_widget_show (menuitem);
3480       
3481       box2 = gtk_vbox_new (FALSE, 10);
3482       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3483       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3484       gtk_widget_show (box2);
3485       
3486       menu = create_menu (screen, 1, 5, FALSE);
3487       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
3488
3489       menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
3490       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3491       gtk_widget_show (menuitem);
3492       
3493       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
3494       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3495       gtk_widget_show (menuitem);
3496       gtk_widget_add_accelerator (menuitem,
3497                                   "activate",
3498                                   accel_group,
3499                                   GDK_F1,
3500                                   0,
3501                                   GTK_ACCEL_VISIBLE);
3502       menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
3503       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3504       gtk_widget_show (menuitem);
3505       gtk_widget_add_accelerator (menuitem,
3506                                   "activate",
3507                                   accel_group,
3508                                   GDK_F2,
3509                                   0,
3510                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3511       menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
3512       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3513       gtk_widget_show (menuitem);
3514       gtk_widget_add_accelerator (menuitem,
3515                                   "activate",
3516                                   accel_group,
3517                                   GDK_F2,
3518                                   0,
3519                                   GTK_ACCEL_VISIBLE);
3520       gtk_widget_add_accelerator (menuitem,
3521                                   "activate",
3522                                   accel_group,
3523                                   GDK_F3,
3524                                   0,
3525                                   GTK_ACCEL_VISIBLE);
3526       
3527       optionmenu = gtk_option_menu_new ();
3528       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
3529       gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 3);
3530       gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
3531       gtk_widget_show (optionmenu);
3532
3533       separator = gtk_hseparator_new ();
3534       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3535       gtk_widget_show (separator);
3536
3537       box2 = gtk_vbox_new (FALSE, 10);
3538       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3539       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3540       gtk_widget_show (box2);
3541
3542       button = gtk_button_new_with_label ("close");
3543       g_signal_connect_swapped (button, "clicked",
3544                                 G_CALLBACK (gtk_widget_destroy),
3545                                 window);
3546       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3547       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3548       gtk_widget_grab_default (button);
3549       gtk_widget_show (button);
3550     }
3551
3552   if (!GTK_WIDGET_VISIBLE (window))
3553     gtk_widget_show (window);
3554   else
3555     gtk_widget_destroy (window);
3556 }
3557
3558 static void
3559 gtk_ifactory_cb (gpointer             callback_data,
3560                  guint                callback_action,
3561                  GtkWidget           *widget)
3562 {
3563   g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
3564 }
3565
3566 /* GdkPixbuf RGBA C-Source image dump */
3567
3568 static const guint8 apple[] = 
3569 { ""
3570   /* Pixbuf magic (0x47646b50) */
3571   "GdkP"
3572   /* length: header (24) + pixel_data (2304) */
3573   "\0\0\11\30"
3574   /* pixdata_type (0x1010002) */
3575   "\1\1\0\2"
3576   /* rowstride (96) */
3577   "\0\0\0`"
3578   /* width (24) */
3579   "\0\0\0\30"
3580   /* height (24) */
3581   "\0\0\0\30"
3582   /* pixel_data: */
3583   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3584   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3585   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3586   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3587   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3588   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3589   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\26\24"
3590   "\17\11\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3591   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`m"
3592   "[pn{a\344hv_\345_k[`\0\0\0\0\0\0\0\0\0\0\0\0D>/\305\0\0\0_\0\0\0\0\0"
3593   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3594   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`l[Blza\373s\202d\354w\206g\372p~c"
3595   "\374`l[y\0\0\0\0[S\77/\27\25\17\335\0\0\0\20\0\0\0\0\0\0\0\0\0\0\0\0"
3596   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3597   "\0\0\0\0\0\0`l\\\20iw_\356y\211h\373x\207g\364~\216i\364u\204e\366gt"
3598   "_\374^jX\241A;-_\0\0\0~\0\0\0\0SM4)SM21B9&\22\320\270\204\1\320\270\204"
3599   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0eq"
3600   "]\212r\200c\366v\205f\371jx_\323_kY\232_kZH^jY\26]iW\211@G9\272:6%j\220"
3601   "\211]\320\221\211`\377\212\203Z\377~xP\377mkE\331]^;|/0\37\21\0\0\0\0"
3602   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ly`\40p~b\360lz`\353^kY\246["
3603   "eT<\216\200Z\203\227\211_\354\234\217c\377\232\217b\362\232\220c\337"
3604   "\243\233k\377\252\241p\377\250\236p\377\241\225h\377\231\214_\377\210"
3605   "\202U\377srI\377[]:\355KO0U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0i"
3606   "v^\200`lY\211^jY\"\0\0\0\0\221\204\\\273\250\233r\377\302\267\224\377"
3607   "\311\300\237\377\272\256\204\377\271\256\177\377\271\257\200\377\267"
3608   "\260\177\377\260\251x\377\250\236l\377\242\225e\377\226\213]\377~zP\377"
3609   "ff@\377QT5\377LR2d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0]iW(\0\0\0\0\0\0\0"
3610   "\0\213\203[v\253\240t\377\334\326\301\377\344\340\317\377\321\312\253"
3611   "\377\303\271\217\377\300\270\213\377\277\267\210\377\272\264\203\377"
3612   "\261\255z\377\250\242n\377\243\232h\377\232\220`\377\210\202V\377nnE"
3613   "\377SW6\377RX6\364Za<\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0b]@\20"
3614   "\234\222e\362\304\274\232\377\337\333\306\377\332\325\273\377\311\302"
3615   "\232\377\312\303\236\377\301\273\216\377\300\271\212\377\270\264\200"
3616   "\377\256\253v\377\246\243n\377\236\232h\377\230\220`\377\213\203V\377"
3617   "wvL\377X]:\377KR0\377NU5v\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\212"
3618   "\203Zl\242\234l\377\321\315\260\377\331\324\271\377\320\313\251\377\307"
3619   "\301\232\377\303\276\224\377\300\272\214\377\274\267\206\377\264\260"
3620   "|\377\253\251s\377\244\243n\377\232\230e\377\223\216^\377\207\200U\377"
3621   "ttJ\377[_<\377HO/\377GN0\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3622   "\210\204Y\240\245\237o\377\316\310\253\377\310\303\237\377\304\300\230"
3623   "\377\303\277\225\377\277\272\216\377\274\270\210\377\266\263\200\377"
3624   "\256\254v\377\247\246p\377\237\236j\377\227\226d\377\215\212[\377\203"
3625   "\177T\377qsH\377X]8\377FN.\377DK-\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3626   "\0\0\0\0\207\204X\257\244\240o\377\300\275\231\377\301\275\226\377\274"
3627   "\270\213\377\274\270\214\377\267\264\205\377\264\262\200\377\260\256"
3628   "z\377\251\251s\377\243\244n\377\231\232g\377\220\222`\377\210\211Y\377"
3629   "|}Q\377hlC\377PU3\377CK,\377DL/Y\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3630   "\0\0\205\204X\220\232\230h\377\261\260\204\377\266\264\212\377\261\260"
3631   "\201\377\263\260\200\377\260\257}\377\256\256x\377\253\254t\377\244\246"
3632   "o\377\233\236i\377\221\224b\377\211\214\\\377\202\204V\377txM\377]b>"
3633   "\377HP0\377@H+\373CJ-\25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0xxO>"
3634   "\215\215_\377\237\237r\377\247\247x\377\247\247t\377\252\252w\377\252"
3635   "\252u\377\252\253t\377\243\246o\377\235\240j\377\223\230c\377\213\217"
3636   "]\377\201\206V\377x}P\377gkD\377RY5\377BI,\377AI,\262\0\0\0\0\0\0\0\0"
3637   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\202\205W\312\216\220`\377\230"
3638   "\232g\377\234\236i\377\236\241l\377\241\244n\377\240\244m\377\232\237"
3639   "i\377\223\230c\377\212\221]\377\200\210W\377v|P\377jnG\377Za>\377HP2"
3640   "\377=D)\377HQ1:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3641   "\0wzQ6\177\201U\371\206\211Z\377\216\222`\377\220\225a\377\220\225b\377"
3642   "\220\226a\377\213\221_\377\204\213Z\377{\203R\377ryN\377iqH\377^fA\377"
3643   "R[;\377BJ-\3778@'\317\0\0\0>\0\0\0\36\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0"
3644   "\0\0\0\0\0\0\0\0\0\0\0\0ptJTw|Q\371z\177R\377}\202T\377|\203T\377z\200"
3645   "R\377v|O\377pwL\377jpF\377dlB\377`hB\377Yb@\377LT6\377<C*\377\11\12\6"
3646   "\376\0\0\0\347\0\0\0\262\0\0\0Y\0\0\0\32\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3647   "\0\0\0\0\0\0\0\0\0\0\\`=UgnE\370hnG\377gmE\377djB\377]d>\377[c<\377Y"
3648   "b<\377Zc>\377V_>\377OW8\377BK/\377\16\20\12\377\0\0\0\377\0\0\0\377\0"
3649   "\0\0\374\0\0\0\320\0\0\0I\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3650   "\0\1\0\0\0\40\22\24\15\260@D+\377W`;\377OV5\377.3\36\377.3\37\377IP0"
3651   "\377RZ7\377PZ8\3776=&\377\14\15\10\377\0\0\0\377\0\0\0\377\0\0\0\377"
3652   "\0\0\0\347\0\0\0\217\0\0\0""4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3653   "\0\0\0\0\0\0\0\20\0\0\0P\0\0\0\252\7\10\5\346\7\7\5\375\0\0\0\377\0\0"
3654   "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\374\0"
3655   "\0\0\336\0\0\0\254\0\0\0i\0\0\0""2\0\0\0\10\0\0\0\0\0\0\0\0\0\0\0\0\0"
3656   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\11\0\0\0\40\0\0\0D\0\0\0m\0\0\0"
3657   "\226\0\0\0\234\0\0\0\234\0\0\0\244\0\0\0\246\0\0\0\232\0\0\0\202\0\0"
3658   "\0i\0\0\0T\0\0\0,\0\0\0\15\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3659   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\0\0\0\6\0\0\0"
3660   "\16\0\0\0\22\0\0\0\24\0\0\0\23\0\0\0\17\0\0\0\14\0\0\0\13\0\0\0\10\0"
3661   "\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"};
3662
3663
3664 static void
3665 dump_accels (gpointer             callback_data,
3666              guint                callback_action,
3667              GtkWidget           *widget)
3668 {
3669   gtk_accel_map_save_fd (1 /* stdout */);
3670 }
3671     
3672 static GtkItemFactoryEntry menu_items[] =
3673 {
3674   { "/_File",                  NULL,         0,                     0, "<Branch>" },
3675   { "/File/tearoff1",          NULL,         gtk_ifactory_cb,       0, "<Tearoff>" },
3676   { "/File/_New",              NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_NEW },
3677   { "/File/_Open",             NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_OPEN },
3678   { "/File/_Save",             NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
3679   { "/File/Save _As...",       "<control>A", gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
3680   { "/File/_Dump \"_Accels\"",  NULL,        dump_accels,           0 },
3681   { "/File/\\/Test__Escaping/And\\/\n\tWei\\\\rdly",
3682                                 NULL,        gtk_ifactory_cb,       0 },
3683   { "/File/sep1",        NULL,               gtk_ifactory_cb,       0, "<Separator>" },
3684   { "/File/_Quit",       NULL,               gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_QUIT },
3685
3686   { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
3687   { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
3688   { "/_Preferences/Color/_Red",         NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
3689   { "/_Preferences/Color/_Green",       NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
3690   { "/_Preferences/Color/_Blue",        NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
3691   { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
3692   { "/_Preferences/Shape/_Square",      NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
3693   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
3694   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
3695   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
3696   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
3697   { "/_Preferences/Shape/_Image",       NULL, gtk_ifactory_cb, 0, "<ImageItem>", apple },
3698
3699   /* For testing deletion of menus */
3700   { "/_Preferences/Should_NotAppear",          NULL, 0,               0, "<Branch>" },
3701   { "/Preferences/ShouldNotAppear/SubItem1",   NULL, gtk_ifactory_cb, 0 },
3702   { "/Preferences/ShouldNotAppear/SubItem2",   NULL, gtk_ifactory_cb, 0 },
3703
3704   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
3705   { "/Help/_Help",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_HELP},
3706   { "/Help/_About",      NULL,         gtk_ifactory_cb,       0 },
3707 };
3708
3709
3710 static int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
3711
3712 static void
3713 create_item_factory (GtkWidget *widget)
3714 {
3715   static GtkWidget *window = NULL;
3716   
3717   if (!window)
3718     {
3719       GtkWidget *box1;
3720       GtkWidget *box2;
3721       GtkWidget *separator;
3722       GtkWidget *label;
3723       GtkWidget *button;
3724       GtkAccelGroup *accel_group;
3725       GtkItemFactory *item_factory;
3726       GtkTooltips *tooltips;
3727       
3728       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3729       
3730       gtk_window_set_screen (GTK_WINDOW (window),
3731                              gtk_widget_get_screen (widget));
3732       
3733       g_signal_connect (window, "destroy",
3734                         G_CALLBACK(gtk_widget_destroyed),
3735                         &window);
3736       g_signal_connect (window, "delete-event",
3737                         G_CALLBACK (gtk_true),
3738                         NULL);
3739       
3740       accel_group = gtk_accel_group_new ();
3741       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
3742       g_object_set_data_full (G_OBJECT (window),
3743                               "<main>",
3744                               item_factory,
3745                               g_object_unref);
3746       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3747       gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
3748       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3749       gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
3750
3751       /* preselect /Preferences/Shape/Oval over the other radios
3752        */
3753       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory,
3754                                                                                       "/Preferences/Shape/Oval")),
3755                                       TRUE);
3756
3757       /* Test how tooltips (ugh) work on menu items
3758        */
3759       tooltips = gtk_tooltips_new ();
3760       g_object_ref (tooltips);
3761       gtk_object_sink (GTK_OBJECT (tooltips));
3762       g_object_set_data_full (G_OBJECT (window), "testgtk-tooltips",
3763                               tooltips, (GDestroyNotify)g_object_unref);
3764       
3765       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/New"),
3766                             "Create a new file", NULL);
3767       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/Open"),
3768                             "Open a file", NULL);
3769       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/Save"),
3770                             "Safe file", NULL);
3771       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/Preferences/Color"),
3772                             "Modify color", NULL);
3773
3774       box1 = gtk_vbox_new (FALSE, 0);
3775       gtk_container_add (GTK_CONTAINER (window), box1);
3776       
3777       gtk_box_pack_start (GTK_BOX (box1),
3778                           gtk_item_factory_get_widget (item_factory, "<main>"),
3779                           FALSE, FALSE, 0);
3780
3781       label = gtk_label_new ("Type\n<alt>\nto start");
3782       gtk_widget_set_size_request (label, 200, 200);
3783       gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
3784       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
3785
3786
3787       separator = gtk_hseparator_new ();
3788       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3789
3790
3791       box2 = gtk_vbox_new (FALSE, 10);
3792       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3793       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3794
3795       button = gtk_button_new_with_label ("close");
3796       g_signal_connect_swapped (button, "clicked",
3797                                 G_CALLBACK (gtk_widget_destroy),
3798                                 window);
3799       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3800       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3801       gtk_widget_grab_default (button);
3802
3803       gtk_item_factory_delete_item (item_factory, "/Preferences/ShouldNotAppear");
3804       
3805       gtk_widget_show_all (window);
3806     }
3807   else
3808     gtk_widget_destroy (window);
3809 }
3810
3811 static GtkWidget *
3812 accel_button_new (GtkAccelGroup *accel_group,
3813                   const gchar   *text,
3814                   const gchar   *accel)
3815 {
3816   guint keyval;
3817   GdkModifierType modifiers;
3818   GtkWidget *button;
3819   GtkWidget *label;
3820
3821   gtk_accelerator_parse (accel, &keyval, &modifiers);
3822   g_assert (keyval);
3823
3824   button = gtk_button_new ();
3825   gtk_widget_add_accelerator (button, "activate", accel_group,
3826                               keyval, modifiers, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3827
3828   label = gtk_accel_label_new (text);
3829   gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), button);
3830   gtk_widget_show (label);
3831   
3832   gtk_container_add (GTK_CONTAINER (button), label);
3833
3834   return button;
3835 }
3836
3837 static void
3838 create_key_lookup (GtkWidget *widget)
3839 {
3840   static GtkWidget *window = NULL;
3841
3842   if (!window)
3843     {
3844       GtkAccelGroup *accel_group = gtk_accel_group_new ();
3845       GtkWidget *button;
3846       
3847       window = gtk_dialog_new_with_buttons ("Key Lookup", NULL, 0,
3848                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
3849                                             NULL);
3850
3851       gtk_window_set_screen (GTK_WINDOW (window),
3852                              gtk_widget_get_screen (widget));
3853
3854       /* We have to expand it so the accel labels will draw their labels
3855        */
3856       gtk_window_set_default_size (GTK_WINDOW (window), 300, -1);
3857       
3858       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3859       
3860       button = gtk_button_new_with_mnemonic ("Button 1 (_a)");
3861       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3862       button = gtk_button_new_with_mnemonic ("Button 2 (_A)");
3863       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3864       button = gtk_button_new_with_mnemonic ("Button 3 (_ф)");
3865       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3866       button = gtk_button_new_with_mnemonic ("Button 4 (_Ф)");
3867       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3868       button = gtk_button_new_with_mnemonic ("Button 6 (_b)");
3869       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3870       button = accel_button_new (accel_group, "Button 7", "<Alt><Shift>b");
3871       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3872       button = accel_button_new (accel_group, "Button 8", "<Alt>d");
3873       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3874       button = accel_button_new (accel_group, "Button 9", "<Alt>Cyrillic_ve");
3875       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3876       button = gtk_button_new_with_mnemonic ("Button 10 (_1)");
3877       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3878       button = gtk_button_new_with_mnemonic ("Button 11 (_!)");
3879       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
3880       
3881       g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
3882       g_signal_connect (window, "response", G_CALLBACK (gtk_object_destroy), NULL);
3883
3884       gtk_widget_show_all (window);
3885     }
3886   else
3887     gtk_widget_destroy (window);
3888 }
3889
3890
3891 /*
3892  create_modal_window
3893  */
3894
3895 static gboolean
3896 cmw_destroy_cb(GtkWidget *widget)
3897 {
3898   /* This is needed to get out of gtk_main */
3899   gtk_main_quit ();
3900
3901   return FALSE;
3902 }
3903
3904 static void
3905 cmw_color (GtkWidget *widget, GtkWidget *parent)
3906 {
3907     GtkWidget *csd;
3908
3909     csd = gtk_color_selection_dialog_new ("This is a modal color selection dialog");
3910
3911     gtk_window_set_screen (GTK_WINDOW (csd), gtk_widget_get_screen (parent));
3912
3913     gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (csd)->colorsel),
3914                                          TRUE);
3915     
3916     /* Set as modal */
3917     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
3918
3919     /* And mark it as a transient dialog */
3920     gtk_window_set_transient_for (GTK_WINDOW (csd), GTK_WINDOW (parent));
3921     
3922     g_signal_connect (csd, "destroy",
3923                       G_CALLBACK (cmw_destroy_cb), NULL);
3924
3925     g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (csd)->ok_button,
3926                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
3927     g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (csd)->cancel_button,
3928                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
3929     
3930     /* wait until destroy calls gtk_main_quit */
3931     gtk_widget_show (csd);    
3932     gtk_main ();
3933 }
3934
3935 static void
3936 cmw_file (GtkWidget *widget, GtkWidget *parent)
3937 {
3938     GtkWidget *fs;
3939
3940     fs = gtk_file_selection_new("This is a modal file selection dialog");
3941
3942     gtk_window_set_screen (GTK_WINDOW (fs), gtk_widget_get_screen (parent));
3943
3944     /* Set as modal */
3945     gtk_window_set_modal (GTK_WINDOW(fs),TRUE);
3946
3947     /* And mark it as a transient dialog */
3948     gtk_window_set_transient_for (GTK_WINDOW (fs), GTK_WINDOW (parent));
3949
3950     g_signal_connect (fs, "destroy",
3951                       G_CALLBACK (cmw_destroy_cb), NULL);
3952
3953     g_signal_connect_swapped (GTK_FILE_SELECTION (fs)->ok_button,
3954                               "clicked", G_CALLBACK (gtk_widget_destroy), fs);
3955     g_signal_connect_swapped (GTK_FILE_SELECTION (fs)->cancel_button,
3956                               "clicked", G_CALLBACK (gtk_widget_destroy), fs);
3957     
3958     /* wait until destroy calls gtk_main_quit */
3959     gtk_widget_show (fs);
3960     
3961     gtk_main();
3962 }
3963
3964
3965 static void
3966 create_modal_window (GtkWidget *widget)
3967 {
3968   GtkWidget *window = NULL;
3969   GtkWidget *box1,*box2;
3970   GtkWidget *frame1;
3971   GtkWidget *btnColor,*btnFile,*btnClose;
3972
3973   /* Create modal window (Here you can use any window descendent )*/
3974   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3975   gtk_window_set_screen (GTK_WINDOW (window),
3976                          gtk_widget_get_screen (widget));
3977
3978   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
3979
3980   /* Set window as modal */
3981   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
3982
3983   /* Create widgets */
3984   box1 = gtk_vbox_new (FALSE,5);
3985   frame1 = gtk_frame_new ("Standard dialogs in modal form");
3986   box2 = gtk_vbox_new (TRUE,5);
3987   btnColor = gtk_button_new_with_label ("Color");
3988   btnFile = gtk_button_new_with_label ("File Selection");
3989   btnClose = gtk_button_new_with_label ("Close");
3990
3991   /* Init widgets */
3992   gtk_container_set_border_width (GTK_CONTAINER (box1), 3);
3993   gtk_container_set_border_width (GTK_CONTAINER (box2), 3);
3994     
3995   /* Pack widgets */
3996   gtk_container_add (GTK_CONTAINER (window), box1);
3997   gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
3998   gtk_container_add (GTK_CONTAINER (frame1), box2);
3999   gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
4000   gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
4001   gtk_box_pack_start (GTK_BOX (box1), gtk_hseparator_new (), FALSE, FALSE, 4);
4002   gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
4003    
4004   /* connect signals */
4005   g_signal_connect_swapped (btnClose, "clicked",
4006                             G_CALLBACK (gtk_widget_destroy), window);
4007
4008   g_signal_connect (window, "destroy",
4009                     G_CALLBACK (cmw_destroy_cb), NULL);
4010   
4011   g_signal_connect (btnColor, "clicked",
4012                     G_CALLBACK (cmw_color), window);
4013   g_signal_connect (btnFile, "clicked",
4014                     G_CALLBACK (cmw_file), window);
4015
4016   /* Show widgets */
4017   gtk_widget_show_all (window);
4018
4019   /* wait until dialog get destroyed */
4020   gtk_main();
4021 }
4022
4023 /*
4024  * GtkMessageDialog
4025  */
4026
4027 static void
4028 make_message_dialog (GdkScreen *screen,
4029                      GtkWidget **dialog,
4030                      GtkMessageType  type,
4031                      GtkButtonsType  buttons,
4032                      guint           default_response)
4033 {
4034   if (*dialog)
4035     {
4036       gtk_widget_destroy (*dialog);
4037
4038       return;
4039     }
4040
4041   *dialog = gtk_message_dialog_new (NULL, 0, type, buttons,
4042                                     "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.)");
4043
4044   gtk_window_set_screen (GTK_WINDOW (*dialog), screen);
4045
4046   g_signal_connect_swapped (*dialog,
4047                             "response",
4048                             G_CALLBACK (gtk_widget_destroy),
4049                             *dialog);
4050   
4051   g_signal_connect (*dialog,
4052                     "destroy",
4053                     G_CALLBACK (gtk_widget_destroyed),
4054                     dialog);
4055
4056   gtk_dialog_set_default_response (GTK_DIALOG (*dialog), default_response);
4057
4058   gtk_widget_show (*dialog);
4059 }
4060
4061 static void
4062 create_message_dialog (GtkWidget *widget)
4063 {
4064   static GtkWidget *info = NULL;
4065   static GtkWidget *warning = NULL;
4066   static GtkWidget *error = NULL;
4067   static GtkWidget *question = NULL;
4068   GdkScreen *screen = gtk_widget_get_screen (widget);
4069
4070   make_message_dialog (screen, &info, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, GTK_RESPONSE_OK);
4071   make_message_dialog (screen, &warning, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_OK);
4072   make_message_dialog (screen, &error, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK);
4073   make_message_dialog (screen, &question, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, GTK_RESPONSE_YES);
4074 }
4075
4076 /*
4077  * GtkScrolledWindow
4078  */
4079
4080 static GtkWidget *sw_parent = NULL;
4081 static GtkWidget *sw_float_parent;
4082 static guint sw_destroyed_handler = 0;
4083
4084 static gboolean
4085 scrolled_windows_delete_cb (GtkWidget *widget, GdkEventAny *event, GtkWidget *scrollwin)
4086 {
4087   gtk_widget_reparent (scrollwin, sw_parent);
4088   
4089   g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
4090   sw_float_parent = NULL;
4091   sw_parent = NULL;
4092   sw_destroyed_handler = 0;
4093
4094   return FALSE;
4095 }
4096
4097 static void
4098 scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
4099 {
4100   gtk_widget_destroy (sw_float_parent);
4101
4102   sw_float_parent = NULL;
4103   sw_parent = NULL;
4104   sw_destroyed_handler = 0;
4105 }
4106
4107 static void
4108 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
4109 {
4110   if (sw_parent)
4111     {
4112       gtk_widget_reparent (scrollwin, sw_parent);
4113       gtk_widget_destroy (sw_float_parent);
4114
4115       g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
4116       sw_float_parent = NULL;
4117       sw_parent = NULL;
4118       sw_destroyed_handler = 0;
4119     }
4120   else
4121     {
4122       sw_parent = scrollwin->parent;
4123       sw_float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4124       gtk_window_set_screen (GTK_WINDOW (sw_float_parent),
4125                              gtk_widget_get_screen (widget));
4126       
4127       gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), 200, 200);
4128       
4129       gtk_widget_reparent (scrollwin, sw_float_parent);
4130       gtk_widget_show (sw_float_parent);
4131
4132       sw_destroyed_handler =
4133         g_signal_connect (sw_parent, "destroy",
4134                           G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
4135       g_signal_connect (sw_float_parent, "delete_event",
4136                         G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
4137     }
4138 }
4139
4140 static void
4141 create_scrolled_windows (GtkWidget *widget)
4142 {
4143   static GtkWidget *window;
4144   GtkWidget *scrolled_window;
4145   GtkWidget *table;
4146   GtkWidget *button;
4147   char buffer[32];
4148   int i, j;
4149
4150   if (!window)
4151     {
4152       window = gtk_dialog_new ();
4153
4154       gtk_window_set_screen (GTK_WINDOW (window),
4155                              gtk_widget_get_screen (widget));
4156
4157       g_signal_connect (window, "destroy",
4158                         G_CALLBACK (gtk_widget_destroyed),
4159                         &window);
4160
4161       gtk_window_set_title (GTK_WINDOW (window), "dialog");
4162       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4163
4164
4165       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
4166       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
4167       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
4168                                       GTK_POLICY_AUTOMATIC,
4169                                       GTK_POLICY_AUTOMATIC);
4170       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
4171                           scrolled_window, TRUE, TRUE, 0);
4172       gtk_widget_show (scrolled_window);
4173
4174       table = gtk_table_new (20, 20, FALSE);
4175       gtk_table_set_row_spacings (GTK_TABLE (table), 10);
4176       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
4177       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
4178       gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
4179                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
4180       gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
4181                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
4182       gtk_widget_show (table);
4183
4184       for (i = 0; i < 20; i++)
4185         for (j = 0; j < 20; j++)
4186           {
4187             sprintf (buffer, "button (%d,%d)\n", i, j);
4188             button = gtk_toggle_button_new_with_label (buffer);
4189             gtk_table_attach_defaults (GTK_TABLE (table), button,
4190                                        i, i+1, j, j+1);
4191             gtk_widget_show (button);
4192           }
4193
4194
4195       button = gtk_button_new_with_label ("Close");
4196       g_signal_connect_swapped (button, "clicked",
4197                                 G_CALLBACK (gtk_widget_destroy),
4198                                 window);
4199       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4200       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
4201                           button, TRUE, TRUE, 0);
4202       gtk_widget_grab_default (button);
4203       gtk_widget_show (button);
4204
4205       button = gtk_button_new_with_label ("Reparent Out");
4206       g_signal_connect (button, "clicked",
4207                         G_CALLBACK (scrolled_windows_remove),
4208                         scrolled_window);
4209       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4210       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
4211                           button, TRUE, TRUE, 0);
4212       gtk_widget_grab_default (button);
4213       gtk_widget_show (button);
4214
4215       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
4216     }
4217
4218   if (!GTK_WIDGET_VISIBLE (window))
4219     gtk_widget_show (window);
4220   else
4221     gtk_widget_destroy (window);
4222 }
4223
4224 /*
4225  * GtkEntry
4226  */
4227
4228 static void
4229 entry_toggle_frame (GtkWidget *checkbutton,
4230                     GtkWidget *entry)
4231 {
4232    gtk_entry_set_has_frame (GTK_ENTRY(entry),
4233                             GTK_TOGGLE_BUTTON(checkbutton)->active);
4234 }
4235
4236 static void
4237 entry_toggle_sensitive (GtkWidget *checkbutton,
4238                         GtkWidget *entry)
4239 {
4240    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
4241 }
4242
4243 static void
4244 entry_props_clicked (GtkWidget *button,
4245                      GObject   *entry)
4246 {
4247   GtkWidget *window = create_prop_editor (entry, 0);
4248
4249   gtk_window_set_title (GTK_WINDOW (window), "Entry Properties");
4250 }
4251
4252 static void
4253 create_entry (GtkWidget *widget)
4254 {
4255   static GtkWidget *window = NULL;
4256   GtkWidget *box1;
4257   GtkWidget *box2;
4258   GtkWidget *hbox;
4259   GtkWidget *has_frame_check;
4260   GtkWidget *sensitive_check;
4261   GtkWidget *entry, *cb;
4262   GtkWidget *button;
4263   GtkWidget *separator;
4264   GList *cbitems = NULL;
4265
4266   if (!window)
4267     {
4268       cbitems = g_list_append(cbitems, "item0");
4269       cbitems = g_list_append(cbitems, "item1 item1");
4270       cbitems = g_list_append(cbitems, "item2 item2 item2");
4271       cbitems = g_list_append(cbitems, "item3 item3 item3 item3");
4272       cbitems = g_list_append(cbitems, "item4 item4 item4 item4 item4");
4273       cbitems = g_list_append(cbitems, "item5 item5 item5 item5 item5 item5");
4274       cbitems = g_list_append(cbitems, "item6 item6 item6 item6 item6");
4275       cbitems = g_list_append(cbitems, "item7 item7 item7 item7");
4276       cbitems = g_list_append(cbitems, "item8 item8 item8");
4277       cbitems = g_list_append(cbitems, "item9 item9");
4278
4279       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4280       gtk_window_set_screen (GTK_WINDOW (window),
4281                              gtk_widget_get_screen (widget));
4282
4283       g_signal_connect (window, "destroy",
4284                         G_CALLBACK (gtk_widget_destroyed),
4285                         &window);
4286
4287       gtk_window_set_title (GTK_WINDOW (window), "entry");
4288       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4289
4290
4291       box1 = gtk_vbox_new (FALSE, 0);
4292       gtk_container_add (GTK_CONTAINER (window), box1);
4293
4294
4295       box2 = gtk_vbox_new (FALSE, 10);
4296       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4297       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4298
4299       hbox = gtk_hbox_new (FALSE, 5);
4300       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
4301       
4302       entry = gtk_entry_new ();
4303       gtk_entry_set_text (GTK_ENTRY (entry), "hello world السلام عليكم");
4304       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
4305       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
4306
4307       button = gtk_button_new_with_mnemonic ("_Props");
4308       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4309       g_signal_connect (button, "clicked",
4310                         G_CALLBACK (entry_props_clicked),
4311                         entry);
4312
4313       cb = gtk_combo_new ();
4314       gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
4315       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO(cb)->entry), "hello world \n\n\n foo");
4316       gtk_editable_select_region (GTK_EDITABLE (GTK_COMBO(cb)->entry),
4317                                   0, -1);
4318       gtk_box_pack_start (GTK_BOX (box2), cb, TRUE, TRUE, 0);
4319
4320       sensitive_check = gtk_check_button_new_with_label("Sensitive");
4321       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
4322       g_signal_connect (sensitive_check, "toggled",
4323                         G_CALLBACK (entry_toggle_sensitive), entry);
4324       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
4325
4326       has_frame_check = gtk_check_button_new_with_label("Has Frame");
4327       gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
4328       g_signal_connect (has_frame_check, "toggled",
4329                         G_CALLBACK (entry_toggle_frame), entry);
4330       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
4331       
4332       separator = gtk_hseparator_new ();
4333       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4334
4335       box2 = gtk_vbox_new (FALSE, 10);
4336       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4337       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4338
4339       button = gtk_button_new_with_label ("close");
4340       g_signal_connect_swapped (button, "clicked",
4341                                 G_CALLBACK (gtk_widget_destroy),
4342                                 window);
4343       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4344       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4345       gtk_widget_grab_default (button);
4346     }
4347
4348   if (!GTK_WIDGET_VISIBLE (window))
4349     gtk_widget_show_all (window);
4350   else
4351     gtk_widget_destroy (window);
4352 }
4353
4354 /*
4355  * GtkSizeGroup
4356  */
4357
4358 #define SIZE_GROUP_INITIAL_SIZE 50
4359
4360 static void
4361 size_group_hsize_changed (GtkSpinButton *spin_button,
4362                           GtkWidget     *button)
4363 {
4364   gtk_widget_set_size_request (GTK_BIN (button)->child,
4365                                gtk_spin_button_get_value_as_int (spin_button),
4366                                -1);
4367 }
4368
4369 static void
4370 size_group_vsize_changed (GtkSpinButton *spin_button,
4371                           GtkWidget     *button)
4372 {
4373   gtk_widget_set_size_request (GTK_BIN (button)->child,
4374                                -1,
4375                                gtk_spin_button_get_value_as_int (spin_button));
4376 }
4377
4378 static GtkWidget *
4379 create_size_group_window (GdkScreen    *screen,
4380                           GtkSizeGroup *master_size_group)
4381 {
4382   GtkWidget *window;
4383   GtkWidget *table;
4384   GtkWidget *main_button;
4385   GtkWidget *button;
4386   GtkWidget *spin_button;
4387   GtkWidget *hbox;
4388   GtkSizeGroup *hgroup1;
4389   GtkSizeGroup *hgroup2;
4390   GtkSizeGroup *vgroup1;
4391   GtkSizeGroup *vgroup2;
4392
4393   window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
4394                                         NULL, 0,
4395                                         GTK_STOCK_CLOSE,
4396                                         GTK_RESPONSE_NONE,
4397                                         NULL);
4398
4399   gtk_window_set_screen (GTK_WINDOW (window), screen);
4400
4401   gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
4402
4403   g_signal_connect (window, "response",
4404                     G_CALLBACK (gtk_widget_destroy),
4405                     NULL);
4406
4407   table = gtk_table_new (2, 2, FALSE);
4408   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), table, TRUE, TRUE, 0);
4409
4410   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
4411   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
4412   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
4413   gtk_widget_set_size_request (table, 250, 250);
4414
4415   hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4416   hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4417   vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4418   vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4419
4420   main_button = gtk_button_new_with_label ("X");
4421   
4422   gtk_table_attach (GTK_TABLE (table), main_button,
4423                     0, 1,       0, 1,
4424                     GTK_EXPAND, GTK_EXPAND,
4425                     0,          0);
4426   gtk_size_group_add_widget (master_size_group, main_button);
4427   gtk_size_group_add_widget (hgroup1, main_button);
4428   gtk_size_group_add_widget (vgroup1, main_button);
4429   gtk_widget_set_size_request (GTK_BIN (main_button)->child,
4430                                SIZE_GROUP_INITIAL_SIZE,
4431                                SIZE_GROUP_INITIAL_SIZE);
4432
4433   button = gtk_button_new ();
4434   gtk_table_attach (GTK_TABLE (table), button,
4435                     1, 2,       0, 1,
4436                     GTK_EXPAND, GTK_EXPAND,
4437                     0,          0);
4438   gtk_size_group_add_widget (vgroup1, button);
4439   gtk_size_group_add_widget (vgroup2, button);
4440
4441   button = gtk_button_new ();
4442   gtk_table_attach (GTK_TABLE (table), button,
4443                     0, 1,       1, 2,
4444                     GTK_EXPAND, GTK_EXPAND,
4445                     0,          0);
4446   gtk_size_group_add_widget (hgroup1, button);
4447   gtk_size_group_add_widget (hgroup2, button);
4448
4449   button = gtk_button_new ();
4450   gtk_table_attach (GTK_TABLE (table), button,
4451                     1, 2,       1, 2,
4452                     GTK_EXPAND, GTK_EXPAND,
4453                     0,          0);
4454   gtk_size_group_add_widget (hgroup2, button);
4455   gtk_size_group_add_widget (vgroup2, button);
4456
4457   g_object_unref (hgroup1);
4458   g_object_unref (hgroup2);
4459   g_object_unref (vgroup1);
4460   g_object_unref (vgroup2);
4461   
4462   hbox = gtk_hbox_new (FALSE, 5);
4463   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox, FALSE, FALSE, 0);
4464   
4465   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4466   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4467   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4468   g_signal_connect (spin_button, "value_changed",
4469                     G_CALLBACK (size_group_hsize_changed), main_button);
4470
4471   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4472   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4473   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4474   g_signal_connect (spin_button, "value_changed",
4475                     G_CALLBACK (size_group_vsize_changed), main_button);
4476
4477   return window;
4478 }
4479
4480 static void
4481 create_size_groups (GtkWidget *widget)
4482 {
4483   static GtkWidget *window1 = NULL;
4484   static GtkWidget *window2 = NULL;
4485   static GtkSizeGroup *master_size_group;
4486
4487   if (!master_size_group)
4488     master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
4489
4490   if (!window1)
4491     {
4492       window1 = create_size_group_window (gtk_widget_get_screen (widget),
4493                                           master_size_group);
4494
4495       g_signal_connect (window1, "destroy",
4496                         G_CALLBACK (gtk_widget_destroyed),
4497                         &window1);
4498     }
4499
4500   if (!window2)
4501     {
4502       window2 = create_size_group_window (gtk_widget_get_screen (widget),
4503                                           master_size_group);
4504
4505       g_signal_connect (window2, "destroy",
4506                         G_CALLBACK (gtk_widget_destroyed),
4507                         &window2);
4508     }
4509
4510   if (GTK_WIDGET_VISIBLE (window1) && GTK_WIDGET_VISIBLE (window2))
4511     {
4512       gtk_widget_destroy (window1);
4513       gtk_widget_destroy (window2);
4514     }
4515   else
4516     {
4517       if (!GTK_WIDGET_VISIBLE (window1))
4518         gtk_widget_show_all (window1);
4519       if (!GTK_WIDGET_VISIBLE (window2))
4520         gtk_widget_show_all (window2);
4521     }
4522 }
4523
4524 /*
4525  * GtkSpinButton
4526  */
4527
4528 static GtkWidget *spinner1;
4529
4530 static void
4531 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
4532 {
4533   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
4534 }
4535
4536 static void
4537 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
4538 {
4539   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
4540 }
4541
4542 static void
4543 change_digits (GtkWidget *widget, GtkSpinButton *spin)
4544 {
4545   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
4546                               gtk_spin_button_get_value_as_int (spin));
4547 }
4548
4549 static void
4550 get_value (GtkWidget *widget, gpointer data)
4551 {
4552   gchar buf[32];
4553   GtkLabel *label;
4554   GtkSpinButton *spin;
4555
4556   spin = GTK_SPIN_BUTTON (spinner1);
4557   label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
4558   if (GPOINTER_TO_INT (data) == 1)
4559     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
4560   else
4561     sprintf (buf, "%0.*f", spin->digits, gtk_spin_button_get_value (spin));
4562   gtk_label_set_text (label, buf);
4563 }
4564
4565 static void
4566 get_spin_value (GtkWidget *widget, gpointer data)
4567 {
4568   gchar *buffer;
4569   GtkLabel *label;
4570   GtkSpinButton *spin;
4571
4572   spin = GTK_SPIN_BUTTON (widget);
4573   label = GTK_LABEL (data);
4574
4575   buffer = g_strdup_printf ("%0.*f", spin->digits,
4576                             gtk_spin_button_get_value (spin));
4577   gtk_label_set_text (label, buffer);
4578
4579   g_free (buffer);
4580 }
4581
4582 static gint
4583 spin_button_time_output_func (GtkSpinButton *spin_button)
4584 {
4585   static gchar buf[6];
4586   gdouble hours;
4587   gdouble minutes;
4588
4589   hours = spin_button->adjustment->value / 60.0;
4590   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
4591   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
4592   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4593     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4594   return TRUE;
4595 }
4596
4597 static gint
4598 spin_button_month_input_func (GtkSpinButton *spin_button,
4599                               gdouble       *new_val)
4600 {
4601   gint i;
4602   static gchar *month[12] = { "January", "February", "March", "April",
4603                               "May", "June", "July", "August",
4604                               "September", "October", "November", "December" };
4605   gchar *tmp1, *tmp2;
4606   gboolean found = FALSE;
4607
4608   for (i = 1; i <= 12; i++)
4609     {
4610       tmp1 = g_ascii_strup (month[i - 1], -1);
4611       tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
4612       if (strstr (tmp1, tmp2) == tmp1)
4613         found = TRUE;
4614       g_free (tmp1);
4615       g_free (tmp2);
4616       if (found)
4617         break;
4618     }
4619   if (!found)
4620     {
4621       *new_val = 0.0;
4622       return GTK_INPUT_ERROR;
4623     }
4624   *new_val = (gdouble) i;
4625   return TRUE;
4626 }
4627
4628 static gint
4629 spin_button_month_output_func (GtkSpinButton *spin_button)
4630 {
4631   gint i;
4632   static gchar *month[12] = { "January", "February", "March", "April",
4633                               "May", "June", "July", "August", "September",
4634                               "October", "November", "December" };
4635
4636   for (i = 1; i <= 12; i++)
4637     if (fabs (spin_button->adjustment->value - (double)i) < 1e-5)
4638       {
4639         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
4640           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
4641       }
4642   return TRUE;
4643 }
4644
4645 static gint
4646 spin_button_hex_input_func (GtkSpinButton *spin_button,
4647                             gdouble       *new_val)
4648 {
4649   const gchar *buf;
4650   gchar *err;
4651   gdouble res;
4652
4653   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
4654   res = strtol(buf, &err, 16);
4655   *new_val = res;
4656   if (*err)
4657     return GTK_INPUT_ERROR;
4658   else
4659     return TRUE;
4660 }
4661
4662 static gint
4663 spin_button_hex_output_func (GtkSpinButton *spin_button)
4664 {
4665   static gchar buf[7];
4666   gint val;
4667
4668   val = (gint) spin_button->adjustment->value;
4669   if (fabs (val) < 1e-5)
4670     sprintf (buf, "0x00");
4671   else
4672     sprintf (buf, "0x%.2X", val);
4673   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4674     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4675   return TRUE;
4676 }
4677
4678 static void
4679 create_spins (GtkWidget *widget)
4680 {
4681   static GtkWidget *window = NULL;
4682   GtkWidget *frame;
4683   GtkWidget *hbox;
4684   GtkWidget *main_vbox;
4685   GtkWidget *vbox;
4686   GtkWidget *vbox2;
4687   GtkWidget *spinner2;
4688   GtkWidget *spinner;
4689   GtkWidget *button;
4690   GtkWidget *label;
4691   GtkWidget *val_label;
4692   GtkAdjustment *adj;
4693
4694   if (!window)
4695     {
4696       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4697       gtk_window_set_screen (GTK_WINDOW (window),
4698                              gtk_widget_get_screen (widget));
4699       
4700       g_signal_connect (window, "destroy",
4701                         G_CALLBACK (gtk_widget_destroyed),
4702                         &window);
4703       
4704       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
4705       
4706       main_vbox = gtk_vbox_new (FALSE, 5);
4707       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
4708       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4709       
4710       frame = gtk_frame_new ("Not accelerated");
4711       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4712       
4713       vbox = gtk_vbox_new (FALSE, 0);
4714       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4715       gtk_container_add (GTK_CONTAINER (frame), vbox);
4716       
4717       /* Time, month, hex spinners */
4718       
4719       hbox = gtk_hbox_new (FALSE, 0);
4720       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
4721       
4722       vbox2 = gtk_vbox_new (FALSE, 0);
4723       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4724       
4725       label = gtk_label_new ("Time :");
4726       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4727       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4728       
4729       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
4730       spinner = gtk_spin_button_new (adj, 0, 0);
4731       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
4732       g_signal_connect (spinner,
4733                         "output",
4734                         G_CALLBACK (spin_button_time_output_func),
4735                         NULL);
4736       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4737       gtk_widget_set_size_request (spinner, 55, -1);
4738       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4739
4740       vbox2 = gtk_vbox_new (FALSE, 0);
4741       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4742       
4743       label = gtk_label_new ("Month :");
4744       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4745       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4746       
4747       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
4748                                                   5.0, 0.0);
4749       spinner = gtk_spin_button_new (adj, 0, 0);
4750       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
4751                                          GTK_UPDATE_IF_VALID);
4752       g_signal_connect (spinner,
4753                         "input",
4754                         G_CALLBACK (spin_button_month_input_func),
4755                         NULL);
4756       g_signal_connect (spinner,
4757                         "output",
4758                         G_CALLBACK (spin_button_month_output_func),
4759                         NULL);
4760       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4761       gtk_widget_set_size_request (spinner, 85, -1);
4762       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4763       
4764       vbox2 = gtk_vbox_new (FALSE, 0);
4765       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4766
4767       label = gtk_label_new ("Hex :");
4768       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4769       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4770
4771       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 255, 1, 16, 0);
4772       spinner = gtk_spin_button_new (adj, 0, 0);
4773       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
4774       g_signal_connect (spinner,
4775                         "input",
4776                         G_CALLBACK (spin_button_hex_input_func),
4777                         NULL);
4778       g_signal_connect (spinner,
4779                         "output",
4780                         G_CALLBACK (spin_button_hex_output_func),
4781                         NULL);
4782       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4783       gtk_widget_set_size_request (spinner, 55, -1);
4784       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4785
4786       frame = gtk_frame_new ("Accelerated");
4787       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4788   
4789       vbox = gtk_vbox_new (FALSE, 0);
4790       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4791       gtk_container_add (GTK_CONTAINER (frame), vbox);
4792       
4793       hbox = gtk_hbox_new (FALSE, 0);
4794       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4795       
4796       vbox2 = gtk_vbox_new (FALSE, 0);
4797       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4798       
4799       label = gtk_label_new ("Value :");
4800       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4801       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4802
4803       adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,
4804                                                   0.5, 100.0, 0.0);
4805       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
4806       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
4807       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
4808
4809       vbox2 = gtk_vbox_new (FALSE, 0);
4810       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4811
4812       label = gtk_label_new ("Digits :");
4813       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4814       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4815
4816       adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 15, 1, 1, 0);
4817       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
4818       g_signal_connect (adj, "value_changed",
4819                         G_CALLBACK (change_digits),
4820                         spinner2);
4821       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
4822
4823       hbox = gtk_hbox_new (FALSE, 0);
4824       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4825
4826       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
4827       g_signal_connect (button, "clicked",
4828                         G_CALLBACK (toggle_snap),
4829                         spinner1);
4830       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4831       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4832
4833       button = gtk_check_button_new_with_label ("Numeric only input mode");
4834       g_signal_connect (button, "clicked",
4835                         G_CALLBACK (toggle_numeric),
4836                         spinner1);
4837       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4838       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4839
4840       val_label = gtk_label_new ("");
4841
4842       hbox = gtk_hbox_new (FALSE, 0);
4843       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4844
4845       button = gtk_button_new_with_label ("Value as Int");
4846       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4847       g_signal_connect (button, "clicked",
4848                         G_CALLBACK (get_value),
4849                         GINT_TO_POINTER (1));
4850       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4851
4852       button = gtk_button_new_with_label ("Value as Float");
4853       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4854       g_signal_connect (button, "clicked",
4855                         G_CALLBACK (get_value),
4856                         GINT_TO_POINTER (2));
4857       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4858
4859       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
4860       gtk_label_set_text (GTK_LABEL (val_label), "0");
4861
4862       frame = gtk_frame_new ("Using Convenience Constructor");
4863       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4864   
4865       hbox = gtk_hbox_new (FALSE, 0);
4866       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4867       gtk_container_add (GTK_CONTAINER (frame), hbox);
4868       
4869       val_label = gtk_label_new ("0.0");
4870
4871       spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
4872       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
4873       g_signal_connect (spinner, "value_changed",
4874                         G_CALLBACK (get_spin_value), val_label);
4875       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
4876       gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
4877
4878       hbox = gtk_hbox_new (FALSE, 0);
4879       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4880   
4881       button = gtk_button_new_with_label ("Close");
4882       g_signal_connect_swapped (button, "clicked",
4883                                 G_CALLBACK (gtk_widget_destroy),
4884                                 window);
4885       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4886     }
4887
4888   if (!GTK_WIDGET_VISIBLE (window))
4889     gtk_widget_show_all (window);
4890   else
4891     gtk_widget_destroy (window);
4892 }
4893
4894
4895 /*
4896  * Cursors
4897  */
4898
4899 static gint
4900 cursor_expose_event (GtkWidget *widget,
4901                      GdkEvent  *event,
4902                      gpointer   user_data)
4903 {
4904   GtkDrawingArea *darea;
4905   GdkDrawable *drawable;
4906   GdkGC *black_gc;
4907   GdkGC *gray_gc;
4908   GdkGC *white_gc;
4909   guint max_width;
4910   guint max_height;
4911
4912   g_return_val_if_fail (widget != NULL, TRUE);
4913   g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE);
4914
4915   darea = GTK_DRAWING_AREA (widget);
4916   drawable = widget->window;
4917   white_gc = widget->style->white_gc;
4918   gray_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
4919   black_gc = widget->style->black_gc;
4920   max_width = widget->allocation.width;
4921   max_height = widget->allocation.height;
4922
4923   gdk_draw_rectangle (drawable, white_gc,
4924                       TRUE,
4925                       0,
4926                       0,
4927                       max_width,
4928                       max_height / 2);
4929
4930   gdk_draw_rectangle (drawable, black_gc,
4931                       TRUE,
4932                       0,
4933                       max_height / 2,
4934                       max_width,
4935                       max_height / 2);
4936
4937   gdk_draw_rectangle (drawable, gray_gc,
4938                       TRUE,
4939                       max_width / 3,
4940                       max_height / 3,
4941                       max_width / 3,
4942                       max_height / 3);
4943
4944   return TRUE;
4945 }
4946
4947 static void
4948 set_cursor (GtkWidget *spinner,
4949             GtkWidget *widget)
4950 {
4951   guint c;
4952   GdkCursor *cursor;
4953   GtkWidget *label;
4954   GEnumClass *class;
4955   GEnumValue *vals;
4956
4957   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
4958   c &= 0xfe;
4959
4960   label = g_object_get_data (G_OBJECT (spinner), "user_data");
4961   
4962   class = gtk_type_class (GDK_TYPE_CURSOR_TYPE);
4963   vals = class->values;
4964
4965   while (vals && vals->value != c)
4966     vals++;
4967   if (vals)
4968     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
4969   else
4970     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
4971
4972   cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), c);
4973   gdk_window_set_cursor (widget->window, cursor);
4974   gdk_cursor_unref (cursor);
4975 }
4976
4977 static gint
4978 cursor_event (GtkWidget          *widget,
4979               GdkEvent           *event,
4980               GtkSpinButton      *spinner)
4981 {
4982   if ((event->type == GDK_BUTTON_PRESS) &&
4983       ((event->button.button == 1) ||
4984        (event->button.button == 3)))
4985     {
4986       gtk_spin_button_spin (spinner, event->button.button == 1 ?
4987                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
4988       return TRUE;
4989     }
4990
4991   return FALSE;
4992 }
4993
4994 static void
4995 create_cursors (GtkWidget *widget)
4996 {
4997   static GtkWidget *window = NULL;
4998   GtkWidget *frame;
4999   GtkWidget *hbox;
5000   GtkWidget *main_vbox;
5001   GtkWidget *vbox;
5002   GtkWidget *darea;
5003   GtkWidget *spinner;
5004   GtkWidget *button;
5005   GtkWidget *label;
5006   GtkWidget *any;
5007   GtkAdjustment *adj;
5008
5009   if (!window)
5010     {
5011       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5012       gtk_window_set_screen (GTK_WINDOW (window), 
5013                              gtk_widget_get_screen (widget));
5014       
5015       g_signal_connect (window, "destroy",
5016                         G_CALLBACK (gtk_widget_destroyed),
5017                         &window);
5018       
5019       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
5020       
5021       main_vbox = gtk_vbox_new (FALSE, 5);
5022       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
5023       gtk_container_add (GTK_CONTAINER (window), main_vbox);
5024
5025       vbox =
5026         gtk_widget_new (gtk_vbox_get_type (),
5027                         "GtkBox::homogeneous", FALSE,
5028                         "GtkBox::spacing", 5,
5029                         "GtkContainer::border_width", 10,
5030                         "GtkWidget::parent", main_vbox,
5031                         "GtkWidget::visible", TRUE,
5032                         NULL);
5033
5034       hbox = gtk_hbox_new (FALSE, 0);
5035       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5036       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5037       
5038       label = gtk_label_new ("Cursor Value : ");
5039       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5040       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5041       
5042       adj = (GtkAdjustment *) gtk_adjustment_new (0,
5043                                                   0, 152,
5044                                                   2,
5045                                                   10, 0);
5046       spinner = gtk_spin_button_new (adj, 0, 0);
5047       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
5048
5049       frame =
5050         gtk_widget_new (gtk_frame_get_type (),
5051                         "GtkFrame::shadow", GTK_SHADOW_ETCHED_IN,
5052                         "GtkFrame::label_xalign", 0.5,
5053                         "GtkFrame::label", "Cursor Area",
5054                         "GtkContainer::border_width", 10,
5055                         "GtkWidget::parent", vbox,
5056                         "GtkWidget::visible", TRUE,
5057                         NULL);
5058
5059       darea = gtk_drawing_area_new ();
5060       gtk_widget_set_size_request (darea, 80, 80);
5061       gtk_container_add (GTK_CONTAINER (frame), darea);
5062       g_signal_connect (darea,
5063                         "expose_event",
5064                         G_CALLBACK (cursor_expose_event),
5065                         NULL);
5066       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
5067       g_signal_connect (darea,
5068                         "button_press_event",
5069                         G_CALLBACK (cursor_event),
5070                         spinner);
5071       gtk_widget_show (darea);
5072
5073       g_signal_connect (spinner, "changed",
5074                         G_CALLBACK (set_cursor),
5075                         darea);
5076
5077       label = gtk_widget_new (GTK_TYPE_LABEL,
5078                               "visible", TRUE,
5079                               "label", "XXX",
5080                               "parent", vbox,
5081                               NULL);
5082       gtk_container_child_set (GTK_CONTAINER (vbox), label,
5083                                "expand", FALSE,
5084                                NULL);
5085       g_object_set_data (G_OBJECT (spinner), "user_data", label);
5086
5087       any =
5088         gtk_widget_new (gtk_hseparator_get_type (),
5089                         "GtkWidget::visible", TRUE,
5090                         NULL);
5091       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
5092   
5093       hbox = gtk_hbox_new (FALSE, 0);
5094       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
5095       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
5096
5097       button = gtk_button_new_with_label ("Close");
5098       g_signal_connect_swapped (button, "clicked",
5099                                 G_CALLBACK (gtk_widget_destroy),
5100                                 window);
5101       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5102
5103       gtk_widget_show_all (window);
5104
5105       set_cursor (spinner, darea);
5106     }
5107   else
5108     gtk_widget_destroy (window);
5109 }
5110
5111 /*
5112  * GtkList
5113  */
5114
5115 static void
5116 list_add (GtkWidget *widget,
5117           GtkWidget *list)
5118 {
5119   static int i = 1;
5120   gchar buffer[64];
5121   GtkWidget *list_item;
5122   GtkContainer *container;
5123
5124   container = GTK_CONTAINER (list);
5125
5126   sprintf (buffer, "added item %d", i++);
5127   list_item = gtk_list_item_new_with_label (buffer);
5128   gtk_widget_show (list_item);
5129
5130   gtk_container_add (container, list_item);
5131 }
5132
5133 static void
5134 list_remove (GtkWidget *widget,
5135              GtkList   *list)
5136 {
5137   GList *clear_list = NULL;
5138   GList *sel_row = NULL;
5139   GList *work = NULL;
5140
5141   if (list->selection_mode == GTK_SELECTION_EXTENDED)
5142     {
5143       GtkWidget *item;
5144
5145       item = GTK_CONTAINER (list)->focus_child;
5146       if (!item && list->selection)
5147         item = list->selection->data;
5148
5149       if (item)
5150         {
5151           work = g_list_find (list->children, item);
5152           for (sel_row = work; sel_row; sel_row = sel_row->next)
5153             if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
5154               break;
5155
5156           if (!sel_row)
5157             {
5158               for (sel_row = work; sel_row; sel_row = sel_row->prev)
5159                 if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
5160                   break;
5161             }
5162         }
5163     }
5164
5165   for (work = list->selection; work; work = work->next)
5166     clear_list = g_list_prepend (clear_list, work->data);
5167
5168   clear_list = g_list_reverse (clear_list);
5169   gtk_list_remove_items (GTK_LIST (list), clear_list);
5170   g_list_free (clear_list);
5171
5172   if (list->selection_mode == GTK_SELECTION_EXTENDED && sel_row)
5173     gtk_list_select_child (list, GTK_WIDGET(sel_row->data));
5174 }
5175
5176 static void
5177 list_clear (GtkWidget *widget,
5178             GtkWidget *list)
5179 {
5180   gtk_list_clear_items (GTK_LIST (list), 0, -1);
5181 }
5182
5183 static gchar *selection_mode_items[] =
5184 {
5185   "Single",
5186   "Browse",
5187   "Multiple"
5188 };
5189
5190 static const GtkSelectionMode selection_modes[] = {
5191   GTK_SELECTION_SINGLE,
5192   GTK_SELECTION_BROWSE,
5193   GTK_SELECTION_MULTIPLE
5194 };
5195
5196 static GtkWidget *list_omenu;
5197
5198 static void 
5199 list_toggle_sel_mode (GtkWidget *widget, gpointer data)
5200 {
5201   GtkList *list;
5202   gint i;
5203
5204   list = GTK_LIST (data);
5205
5206   if (!GTK_WIDGET_MAPPED (widget))
5207     return;
5208
5209   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
5210
5211   gtk_list_set_selection_mode (list, selection_modes[i]);
5212 }
5213
5214 static void
5215 create_list (GtkWidget *widget)
5216 {
5217   static GtkWidget *window = NULL;
5218
5219   if (!window)
5220     {
5221       GtkWidget *cbox;
5222       GtkWidget *vbox;
5223       GtkWidget *hbox;
5224       GtkWidget *label;
5225       GtkWidget *scrolled_win;
5226       GtkWidget *list;
5227       GtkWidget *button;
5228       GtkWidget *separator;
5229       FILE *infile;
5230
5231       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5232
5233       gtk_window_set_screen (GTK_WINDOW (window),
5234                              gtk_widget_get_screen (widget));
5235
5236       g_signal_connect (window, "destroy",
5237                         G_CALLBACK (gtk_widget_destroyed),
5238                         &window);
5239
5240       gtk_window_set_title (GTK_WINDOW (window), "list");
5241       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5242
5243       vbox = gtk_vbox_new (FALSE, 0);
5244       gtk_container_add (GTK_CONTAINER (window), vbox);
5245
5246       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
5247       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
5248       gtk_widget_set_size_request (scrolled_win, -1, 300);
5249       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
5250       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
5251                                       GTK_POLICY_AUTOMATIC,
5252                                       GTK_POLICY_AUTOMATIC);
5253
5254       list = gtk_list_new ();
5255       gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
5256       gtk_scrolled_window_add_with_viewport
5257         (GTK_SCROLLED_WINDOW (scrolled_win), list);
5258       gtk_container_set_focus_vadjustment
5259         (GTK_CONTAINER (list),
5260          gtk_scrolled_window_get_vadjustment
5261          (GTK_SCROLLED_WINDOW (scrolled_win)));
5262       gtk_container_set_focus_hadjustment
5263         (GTK_CONTAINER (list),
5264          gtk_scrolled_window_get_hadjustment
5265          (GTK_SCROLLED_WINDOW (scrolled_win)));
5266
5267       if ((infile = fopen("../gtk/gtkenums.h", "r")))
5268         {
5269           char buffer[256];
5270           char *pos;
5271           GtkWidget *item;
5272
5273           while (fgets (buffer, 256, infile))
5274             {
5275               if ((pos = strchr (buffer, '\n')))
5276                 *pos = 0;
5277               item = gtk_list_item_new_with_label (buffer);
5278               gtk_container_add (GTK_CONTAINER (list), item);
5279             }
5280           
5281           fclose (infile);
5282         }
5283
5284
5285       hbox = gtk_hbox_new (TRUE, 5);
5286       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5287       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5288
5289       button = gtk_button_new_with_label ("Insert Row");
5290       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5291       g_signal_connect (button, "clicked",
5292                         G_CALLBACK (list_add),
5293                         list);
5294
5295       button = gtk_button_new_with_label ("Clear List");
5296       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5297       g_signal_connect (button, "clicked",
5298                         G_CALLBACK (list_clear),
5299                         list);
5300
5301       button = gtk_button_new_with_label ("Remove Selection");
5302       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5303       g_signal_connect (button, "clicked",
5304                         G_CALLBACK (list_remove),
5305                         list);
5306
5307       cbox = gtk_hbox_new (FALSE, 0);
5308       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
5309
5310       hbox = gtk_hbox_new (FALSE, 5);
5311       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5312       gtk_box_pack_start (GTK_BOX (cbox), hbox, TRUE, FALSE, 0);
5313
5314       label = gtk_label_new ("Selection Mode :");
5315       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5316
5317       list_omenu = build_option_menu (selection_mode_items, 3, 3, 
5318                                       list_toggle_sel_mode,
5319                                       list);
5320       gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
5321
5322       separator = gtk_hseparator_new ();
5323       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
5324
5325       cbox = gtk_hbox_new (FALSE, 0);
5326       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
5327
5328       button = gtk_button_new_with_label ("close");
5329       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5330       gtk_box_pack_start (GTK_BOX (cbox), button, TRUE, TRUE, 0);
5331       g_signal_connect_swapped (button, "clicked",
5332                                 G_CALLBACK (gtk_widget_destroy),
5333                                 window);
5334
5335       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5336       gtk_widget_grab_default (button);
5337     }
5338
5339   if (!GTK_WIDGET_VISIBLE (window))
5340     gtk_widget_show_all (window);
5341   else
5342     gtk_widget_destroy (window);
5343 }
5344
5345 /*
5346  * GtkCList
5347  */
5348
5349 static char * book_open_xpm[] = {
5350 "16 16 4 1",
5351 "       c None s None",
5352 ".      c black",
5353 "X      c #808080",
5354 "o      c white",
5355 "                ",
5356 "  ..            ",
5357 " .Xo.    ...    ",
5358 " .Xoo. ..oo.    ",
5359 " .Xooo.Xooo...  ",
5360 " .Xooo.oooo.X.  ",
5361 " .Xooo.Xooo.X.  ",
5362 " .Xooo.oooo.X.  ",
5363 " .Xooo.Xooo.X.  ",
5364 " .Xooo.oooo.X.  ",
5365 "  .Xoo.Xoo..X.  ",
5366 "   .Xo.o..ooX.  ",
5367 "    .X..XXXXX.  ",
5368 "    ..X.......  ",
5369 "     ..         ",
5370 "                "};
5371
5372 static char * book_closed_xpm[] = {
5373 "16 16 6 1",
5374 "       c None s None",
5375 ".      c black",
5376 "X      c red",
5377 "o      c yellow",
5378 "O      c #808080",
5379 "#      c white",
5380 "                ",
5381 "       ..       ",
5382 "     ..XX.      ",
5383 "   ..XXXXX.     ",
5384 " ..XXXXXXXX.    ",
5385 ".ooXXXXXXXXX.   ",
5386 "..ooXXXXXXXXX.  ",
5387 ".X.ooXXXXXXXXX. ",
5388 ".XX.ooXXXXXX..  ",
5389 " .XX.ooXXX..#O  ",
5390 "  .XX.oo..##OO. ",
5391 "   .XX..##OO..  ",
5392 "    .X.#OO..    ",
5393 "     ..O..      ",
5394 "      ..        ",
5395 "                "};
5396
5397 static char * mini_page_xpm[] = {
5398 "16 16 4 1",
5399 "       c None s None",
5400 ".      c black",
5401 "X      c white",
5402 "o      c #808080",
5403 "                ",
5404 "   .......      ",
5405 "   .XXXXX..     ",
5406 "   .XoooX.X.    ",
5407 "   .XXXXX....   ",
5408 "   .XooooXoo.o  ",
5409 "   .XXXXXXXX.o  ",
5410 "   .XooooooX.o  ",
5411 "   .XXXXXXXX.o  ",
5412 "   .XooooooX.o  ",
5413 "   .XXXXXXXX.o  ",
5414 "   .XooooooX.o  ",
5415 "   .XXXXXXXX.o  ",
5416 "   ..........o  ",
5417 "    oooooooooo  ",
5418 "                "};
5419
5420 static char * gtk_mini_xpm[] = {
5421 "15 20 17 1",
5422 "       c None",
5423 ".      c #14121F",
5424 "+      c #278828",
5425 "@      c #9B3334",
5426 "#      c #284C72",
5427 "$      c #24692A",
5428 "%      c #69282E",
5429 "&      c #37C539",
5430 "*      c #1D2F4D",
5431 "=      c #6D7076",
5432 "-      c #7D8482",
5433 ";      c #E24A49",
5434 ">      c #515357",
5435 ",      c #9B9C9B",
5436 "'      c #2FA232",
5437 ")      c #3CE23D",
5438 "!      c #3B6CCB",
5439 "               ",
5440 "      ***>     ",
5441 "    >.*!!!*    ",
5442 "   ***....#*=  ",
5443 "  *!*.!!!**!!# ",
5444 " .!!#*!#*!!!!# ",
5445 " @%#!.##.*!!$& ",
5446 " @;%*!*.#!#')) ",
5447 " @;;@%!!*$&)'' ",
5448 " @%.%@%$'&)$+' ",
5449 " @;...@$'*'*)+ ",
5450 " @;%..@$+*.')$ ",
5451 " @;%%;;$+..$)# ",
5452 " @;%%;@$$$'.$# ",
5453 " %;@@;;$$+))&* ",
5454 "  %;;;@+$&)&*  ",
5455 "   %;;@'))+>   ",
5456 "    %;@'&#     ",
5457 "     >%$$      ",
5458 "      >=       "};
5459
5460 #define TESTGTK_CLIST_COLUMNS 12
5461 static gint clist_rows = 0;
5462 static GtkWidget *clist_omenu;
5463
5464 static void
5465 add1000_clist (GtkWidget *widget, gpointer data)
5466 {
5467   gint i, row;
5468   char text[TESTGTK_CLIST_COLUMNS][50];
5469   char *texts[TESTGTK_CLIST_COLUMNS];
5470   GdkBitmap *mask;
5471   GdkPixmap *pixmap;
5472   GtkCList  *clist;
5473
5474   clist = GTK_CLIST (data);
5475
5476   pixmap = gdk_pixmap_create_from_xpm_d (clist->clist_window,
5477                                          &mask, 
5478                                          &GTK_WIDGET (data)->style->white,
5479                                          gtk_mini_xpm);
5480
5481   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5482     {
5483       texts[i] = text[i];
5484       sprintf (text[i], "Column %d", i);
5485     }
5486   
5487   texts[3] = NULL;
5488   sprintf (text[1], "Right");
5489   sprintf (text[2], "Center");
5490   
5491   gtk_clist_freeze (GTK_CLIST (data));
5492   for (i = 0; i < 1000; i++)
5493     {
5494       sprintf (text[0], "CListRow %d", rand() % 10000);
5495       row = gtk_clist_append (clist, texts);
5496       gtk_clist_set_pixtext (clist, row, 3, "gtk+", 5, pixmap, mask);
5497     }
5498
5499   gtk_clist_thaw (GTK_CLIST (data));
5500
5501   g_object_unref (pixmap);
5502   g_object_unref (mask);
5503 }
5504
5505 static void
5506 add10000_clist (GtkWidget *widget, gpointer data)
5507 {
5508   gint i;
5509   char text[TESTGTK_CLIST_COLUMNS][50];
5510   char *texts[TESTGTK_CLIST_COLUMNS];
5511
5512   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5513     {
5514       texts[i] = text[i];
5515       sprintf (text[i], "Column %d", i);
5516     }
5517   
5518   sprintf (text[1], "Right");
5519   sprintf (text[2], "Center");
5520   
5521   gtk_clist_freeze (GTK_CLIST (data));
5522   for (i = 0; i < 10000; i++)
5523     {
5524       sprintf (text[0], "CListRow %d", rand() % 10000);
5525       gtk_clist_append (GTK_CLIST (data), texts);
5526     }
5527   gtk_clist_thaw (GTK_CLIST (data));
5528 }
5529
5530 void
5531 clear_clist (GtkWidget *widget, gpointer data)
5532 {
5533   gtk_clist_clear (GTK_CLIST (data));
5534   clist_rows = 0;
5535 }
5536
5537 void clist_remove_selection (GtkWidget *widget, GtkCList *clist)
5538 {
5539   gtk_clist_freeze (clist);
5540
5541   while (clist->selection)
5542     {
5543       gint row;
5544
5545       clist_rows--;
5546       row = GPOINTER_TO_INT (clist->selection->data);
5547
5548       gtk_clist_remove (clist, row);
5549
5550       if (clist->selection_mode == GTK_SELECTION_BROWSE)
5551         break;
5552     }
5553
5554   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
5555       clist->focus_row >= 0)
5556     gtk_clist_select_row (clist, clist->focus_row, -1);
5557
5558   gtk_clist_thaw (clist);
5559 }
5560
5561 void toggle_title_buttons (GtkWidget *widget, GtkCList *clist)
5562 {
5563   if (GTK_TOGGLE_BUTTON (widget)->active)
5564     gtk_clist_column_titles_show (clist);
5565   else
5566     gtk_clist_column_titles_hide (clist);
5567 }
5568
5569 void toggle_reorderable (GtkWidget *widget, GtkCList *clist)
5570 {
5571   gtk_clist_set_reorderable (clist, GTK_TOGGLE_BUTTON (widget)->active);
5572 }
5573
5574 static void
5575 insert_row_clist (GtkWidget *widget, gpointer data)
5576 {
5577   static char *text[] =
5578   {
5579     "This", "is an", "inserted", "row.",
5580     "This", "is an", "inserted", "row.",
5581     "This", "is an", "inserted", "row."
5582   };
5583
5584   static GtkStyle *style1 = NULL;
5585   static GtkStyle *style2 = NULL;
5586   static GtkStyle *style3 = NULL;
5587   gint row;
5588   
5589   if (GTK_CLIST (data)->focus_row >= 0)
5590     row = gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row,
5591                             text);
5592   else
5593     row = gtk_clist_prepend (GTK_CLIST (data), text);
5594
5595   if (!style1)
5596     {
5597       GdkColor col1;
5598       GdkColor col2;
5599
5600       col1.red   = 0;
5601       col1.green = 56000;
5602       col1.blue  = 0;
5603       col2.red   = 32000;
5604       col2.green = 0;
5605       col2.blue  = 56000;
5606
5607       style1 = gtk_style_copy (GTK_WIDGET (data)->style);
5608       style1->base[GTK_STATE_NORMAL] = col1;
5609       style1->base[GTK_STATE_SELECTED] = col2;
5610
5611       style2 = gtk_style_copy (GTK_WIDGET (data)->style);
5612       style2->fg[GTK_STATE_NORMAL] = col1;
5613       style2->fg[GTK_STATE_SELECTED] = col2;
5614
5615       style3 = gtk_style_copy (GTK_WIDGET (data)->style);
5616       style3->fg[GTK_STATE_NORMAL] = col1;
5617       style3->base[GTK_STATE_NORMAL] = col2;
5618       pango_font_description_free (style3->font_desc);
5619       style3->font_desc = pango_font_description_from_string ("courier 12");
5620     }
5621
5622   gtk_clist_set_cell_style (GTK_CLIST (data), row, 3, style1);
5623   gtk_clist_set_cell_style (GTK_CLIST (data), row, 4, style2);
5624   gtk_clist_set_cell_style (GTK_CLIST (data), row, 0, style3);
5625
5626   clist_rows++;
5627 }
5628
5629 static void
5630 clist_warning_test (GtkWidget *button,
5631                     GtkWidget *clist)
5632 {
5633   GtkWidget *child;
5634   static gboolean add_remove = FALSE;
5635
5636   add_remove = !add_remove;
5637
5638   child = gtk_label_new ("Test");
5639   g_object_ref (child);
5640   gtk_object_sink (GTK_OBJECT (child));
5641
5642   if (add_remove)
5643     gtk_container_add (GTK_CONTAINER (clist), child);
5644   else
5645     {
5646       child->parent = clist;
5647       gtk_container_remove (GTK_CONTAINER (clist), child);
5648       child->parent = NULL;
5649     }
5650
5651   gtk_widget_destroy (child);
5652   gtk_widget_unref (child);
5653 }
5654
5655 static void
5656 undo_selection (GtkWidget *button, GtkCList *clist)
5657 {
5658   gtk_clist_undo_selection (clist);
5659 }
5660
5661 static void 
5662 clist_toggle_sel_mode (GtkWidget *widget, gpointer data)
5663 {
5664   GtkCList *clist;
5665   gint i;
5666
5667   clist = GTK_CLIST (data);
5668
5669   if (!GTK_WIDGET_MAPPED (widget))
5670     return;
5671
5672   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
5673
5674   gtk_clist_set_selection_mode (clist, selection_modes[i]);
5675 }
5676
5677 static void 
5678 clist_click_column (GtkCList *clist, gint column, gpointer data)
5679 {
5680   if (column == 4)
5681     gtk_clist_set_column_visibility (clist, column, FALSE);
5682   else if (column == clist->sort_column)
5683     {
5684       if (clist->sort_type == GTK_SORT_ASCENDING)
5685         clist->sort_type = GTK_SORT_DESCENDING;
5686       else
5687         clist->sort_type = GTK_SORT_ASCENDING;
5688     }
5689   else
5690     gtk_clist_set_sort_column (clist, column);
5691
5692   gtk_clist_sort (clist);
5693 }
5694
5695 static void
5696 create_clist (GtkWidget *widget)
5697 {
5698   gint i;
5699   static GtkWidget *window = NULL;
5700
5701   static char *titles[] =
5702   {
5703     "auto resize", "not resizeable", "max width 100", "min width 50",
5704     "hide column", "Title 5", "Title 6", "Title 7",
5705     "Title 8",  "Title 9",  "Title 10", "Title 11"
5706   };
5707
5708   char text[TESTGTK_CLIST_COLUMNS][50];
5709   char *texts[TESTGTK_CLIST_COLUMNS];
5710
5711   GtkWidget *vbox;
5712   GtkWidget *hbox;
5713   GtkWidget *clist;
5714   GtkWidget *button;
5715   GtkWidget *separator;
5716   GtkWidget *scrolled_win;
5717   GtkWidget *check;
5718
5719   GtkWidget *undo_button;
5720   GtkWidget *label;
5721
5722   GtkStyle *style;
5723   GdkColor col1;
5724   GdkColor col2;
5725
5726   if (!window)
5727     {
5728       clist_rows = 0;
5729       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5730       gtk_window_set_screen (GTK_WINDOW (window), 
5731                              gtk_widget_get_screen (widget));
5732
5733       g_signal_connect (window, "destroy",
5734                         G_CALLBACK (gtk_widget_destroyed), &window);
5735
5736       gtk_window_set_title (GTK_WINDOW (window), "clist");
5737       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5738
5739       vbox = gtk_vbox_new (FALSE, 0);
5740       gtk_container_add (GTK_CONTAINER (window), vbox);
5741
5742       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
5743       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
5744       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
5745                                       GTK_POLICY_AUTOMATIC, 
5746                                       GTK_POLICY_AUTOMATIC);
5747
5748       /* create GtkCList here so we have a pointer to throw at the 
5749        * button callbacks -- more is done with it later */
5750       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
5751       gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
5752       g_signal_connect (clist, "click_column",
5753                         G_CALLBACK (clist_click_column), NULL);
5754
5755       /* control buttons */
5756       hbox = gtk_hbox_new (FALSE, 5);
5757       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5758       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5759
5760       button = gtk_button_new_with_label ("Insert Row");
5761       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5762       g_signal_connect (button, "clicked",
5763                         G_CALLBACK (insert_row_clist), clist);
5764
5765       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
5766       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5767       g_signal_connect (button, "clicked",
5768                         G_CALLBACK (add1000_clist), clist);
5769
5770       button = gtk_button_new_with_label ("Add 10,000 Rows");
5771       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5772       g_signal_connect (button, "clicked",
5773                         G_CALLBACK (add10000_clist), clist);
5774
5775       /* second layer of buttons */
5776       hbox = gtk_hbox_new (FALSE, 5);
5777       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5778       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5779
5780       button = gtk_button_new_with_label ("Clear List");
5781       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5782       g_signal_connect (button, "clicked",
5783                         G_CALLBACK (clear_clist), clist);
5784
5785       button = gtk_button_new_with_label ("Remove Selection");
5786       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5787       g_signal_connect (button, "clicked",
5788                         G_CALLBACK (clist_remove_selection), clist);
5789
5790       undo_button = gtk_button_new_with_label ("Undo Selection");
5791       gtk_box_pack_start (GTK_BOX (hbox), undo_button, TRUE, TRUE, 0);
5792       g_signal_connect (undo_button, "clicked",
5793                         G_CALLBACK (undo_selection), clist);
5794
5795       button = gtk_button_new_with_label ("Warning Test");
5796       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5797       g_signal_connect (button, "clicked",
5798                         G_CALLBACK (clist_warning_test), clist);
5799
5800       /* third layer of buttons */
5801       hbox = gtk_hbox_new (FALSE, 5);
5802       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5803       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5804
5805       check = gtk_check_button_new_with_label ("Show Title Buttons");
5806       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5807       g_signal_connect (check, "clicked",
5808                         G_CALLBACK (toggle_title_buttons), clist);
5809       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5810
5811       check = gtk_check_button_new_with_label ("Reorderable");
5812       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5813       g_signal_connect (check, "clicked",
5814                         G_CALLBACK (toggle_reorderable), clist);
5815       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5816
5817       label = gtk_label_new ("Selection Mode :");
5818       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5819
5820       clist_omenu = build_option_menu (selection_mode_items, 3, 3, 
5821                                        clist_toggle_sel_mode,
5822                                        clist);
5823       gtk_box_pack_start (GTK_BOX (hbox), clist_omenu, FALSE, TRUE, 0);
5824
5825       /* 
5826        * the rest of the clist configuration
5827        */
5828
5829       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
5830       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
5831       gtk_widget_set_size_request (clist, -1, 300);
5832
5833       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
5834         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
5835
5836       gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
5837       gtk_clist_set_column_resizeable (GTK_CLIST (clist), 1, FALSE);
5838       gtk_clist_set_column_max_width (GTK_CLIST (clist), 2, 100);
5839       gtk_clist_set_column_min_width (GTK_CLIST (clist), 3, 50);
5840       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
5841       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
5842                                           GTK_JUSTIFY_RIGHT);
5843       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
5844                                           GTK_JUSTIFY_CENTER);
5845       
5846       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5847         {
5848           texts[i] = text[i];
5849           sprintf (text[i], "Column %d", i);
5850         }
5851
5852       sprintf (text[1], "Right");
5853       sprintf (text[2], "Center");
5854
5855       col1.red   = 56000;
5856       col1.green = 0;
5857       col1.blue  = 0;
5858       col2.red   = 0;
5859       col2.green = 56000;
5860       col2.blue  = 32000;
5861
5862       style = gtk_style_new ();
5863       style->fg[GTK_STATE_NORMAL] = col1;
5864       style->base[GTK_STATE_NORMAL] = col2;
5865
5866       pango_font_description_set_size (style->font_desc, 14 * PANGO_SCALE);
5867       pango_font_description_set_weight (style->font_desc, PANGO_WEIGHT_BOLD);
5868
5869       for (i = 0; i < 10; i++)
5870         {
5871           sprintf (text[0], "CListRow %d", clist_rows++);
5872           gtk_clist_append (GTK_CLIST (clist), texts);
5873
5874           switch (i % 4)
5875             {
5876             case 2:
5877               gtk_clist_set_row_style (GTK_CLIST (clist), i, style);
5878               break;
5879             default:
5880               gtk_clist_set_cell_style (GTK_CLIST (clist), i, i % 4, style);
5881               break;
5882             }
5883         }
5884
5885       gtk_style_unref (style);
5886       
5887       separator = gtk_hseparator_new ();
5888       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
5889
5890       hbox = gtk_hbox_new (FALSE, 0);
5891       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5892
5893       button = gtk_button_new_with_label ("close");
5894       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5895       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5896       g_signal_connect_swapped (button, "clicked",
5897                                 G_CALLBACK (gtk_widget_destroy),
5898                                 window);
5899
5900       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5901       gtk_widget_grab_default (button);
5902     }
5903
5904   if (!GTK_WIDGET_VISIBLE (window))
5905     gtk_widget_show_all (window);
5906   else
5907     {
5908       clist_rows = 0;
5909       gtk_widget_destroy (window);
5910     }
5911 }
5912
5913 /*
5914  * GtkCTree
5915  */
5916
5917 typedef struct 
5918 {
5919   GdkPixmap *pixmap1;
5920   GdkPixmap *pixmap2;
5921   GdkPixmap *pixmap3;
5922   GdkBitmap *mask1;
5923   GdkBitmap *mask2;
5924   GdkBitmap *mask3;
5925 } CTreePixmaps;
5926
5927 static gint books = 0;
5928 static gint pages = 0;
5929
5930 static GtkWidget *book_label;
5931 static GtkWidget *page_label;
5932 static GtkWidget *sel_label;
5933 static GtkWidget *vis_label;
5934 static GtkWidget *omenu1;
5935 static GtkWidget *omenu2;
5936 static GtkWidget *omenu3;
5937 static GtkWidget *omenu4;
5938 static GtkWidget *spin1;
5939 static GtkWidget *spin2;
5940 static GtkWidget *spin3;
5941 static gint line_style;
5942
5943
5944 static CTreePixmaps *
5945 get_ctree_pixmaps (GtkCTree *ctree)
5946 {
5947   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (ctree));
5948   CTreePixmaps *pixmaps = g_object_get_data (G_OBJECT (screen), "ctree-pixmaps");
5949
5950   if (!pixmaps)
5951     {
5952       GdkColormap *colormap = gdk_screen_get_rgb_colormap (screen);
5953       pixmaps = g_new (CTreePixmaps, 1);
5954       
5955       pixmaps->pixmap1 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5956                                                                 &pixmaps->mask1, 
5957                                                                 NULL, book_closed_xpm);
5958       pixmaps->pixmap2 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5959                                                                 &pixmaps->mask2, 
5960                                                                 NULL, book_open_xpm);
5961       pixmaps->pixmap3 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5962                                                                 &pixmaps->mask3,
5963                                                                 NULL, mini_page_xpm);
5964       
5965       g_object_set_data (G_OBJECT (screen), "ctree-pixmaps", pixmaps);
5966     }
5967
5968   return pixmaps;
5969 }
5970
5971 void after_press (GtkCTree *ctree, gpointer data)
5972 {
5973   char buf[80];
5974
5975   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
5976   gtk_label_set_text (GTK_LABEL (sel_label), buf);
5977
5978   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
5979   gtk_label_set_text (GTK_LABEL (vis_label), buf);
5980
5981   sprintf (buf, "%d", books);
5982   gtk_label_set_text (GTK_LABEL (book_label), buf);
5983
5984   sprintf (buf, "%d", pages);
5985   gtk_label_set_text (GTK_LABEL (page_label), buf);
5986 }
5987
5988 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
5989                  GtkCTreeNode *sibling, gpointer data)
5990 {
5991   char *source;
5992   char *target1;
5993   char *target2;
5994
5995   gtk_ctree_get_node_info (ctree, child, &source, 
5996                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5997   if (parent)
5998     gtk_ctree_get_node_info (ctree, parent, &target1, 
5999                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
6000   if (sibling)
6001     gtk_ctree_get_node_info (ctree, sibling, &target2, 
6002                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
6003
6004   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
6005            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
6006 }
6007
6008 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
6009 {
6010   if (GTK_CTREE_ROW (list)->is_leaf)
6011     pages--;
6012   else
6013     books--;
6014 }
6015
6016 void expand_all (GtkWidget *widget, GtkCTree *ctree)
6017 {
6018   gtk_ctree_expand_recursive (ctree, NULL);
6019   after_press (ctree, NULL);
6020 }
6021
6022 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
6023 {
6024   gtk_ctree_collapse_recursive (ctree, NULL);
6025   after_press (ctree, NULL);
6026 }
6027
6028 void select_all (GtkWidget *widget, GtkCTree *ctree)
6029 {
6030   gtk_ctree_select_recursive (ctree, NULL);
6031   after_press (ctree, NULL);
6032 }
6033
6034 void change_style (GtkWidget *widget, GtkCTree *ctree)
6035 {
6036   static GtkStyle *style1 = NULL;
6037   static GtkStyle *style2 = NULL;
6038
6039   GtkCTreeNode *node;
6040   GdkColor col1;
6041   GdkColor col2;
6042
6043   if (GTK_CLIST (ctree)->focus_row >= 0)
6044     node = GTK_CTREE_NODE
6045       (g_list_nth (GTK_CLIST (ctree)->row_list,GTK_CLIST (ctree)->focus_row));
6046   else
6047     node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
6048
6049   if (!node)
6050     return;
6051
6052   if (!style1)
6053     {
6054       col1.red   = 0;
6055       col1.green = 56000;
6056       col1.blue  = 0;
6057       col2.red   = 32000;
6058       col2.green = 0;
6059       col2.blue  = 56000;
6060
6061       style1 = gtk_style_new ();
6062       style1->base[GTK_STATE_NORMAL] = col1;
6063       style1->fg[GTK_STATE_SELECTED] = col2;
6064
6065       style2 = gtk_style_new ();
6066       style2->base[GTK_STATE_SELECTED] = col2;
6067       style2->fg[GTK_STATE_NORMAL] = col1;
6068       style2->base[GTK_STATE_NORMAL] = col2;
6069       pango_font_description_free (style2->font_desc);
6070       style2->font_desc = pango_font_description_from_string ("courier 30");
6071     }
6072
6073   gtk_ctree_node_set_cell_style (ctree, node, 1, style1);
6074   gtk_ctree_node_set_cell_style (ctree, node, 0, style2);
6075
6076   if (GTK_CTREE_ROW (node)->children)
6077     gtk_ctree_node_set_row_style (ctree, GTK_CTREE_ROW (node)->children,
6078                                   style2);
6079 }
6080
6081 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
6082 {
6083   gtk_ctree_unselect_recursive (ctree, NULL);
6084   after_press (ctree, NULL);
6085 }
6086
6087 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
6088 {
6089   GtkCList *clist;
6090   GtkCTreeNode *node;
6091
6092   clist = GTK_CLIST (ctree);
6093
6094   gtk_clist_freeze (clist);
6095
6096   while (clist->selection)
6097     {
6098       node = clist->selection->data;
6099
6100       if (GTK_CTREE_ROW (node)->is_leaf)
6101         pages--;
6102       else
6103         gtk_ctree_post_recursive (ctree, node,
6104                                   (GtkCTreeFunc) count_items, NULL);
6105
6106       gtk_ctree_remove_node (ctree, node);
6107
6108       if (clist->selection_mode == GTK_SELECTION_BROWSE)
6109         break;
6110     }
6111
6112   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
6113       clist->focus_row >= 0)
6114     {
6115       node = gtk_ctree_node_nth (ctree, clist->focus_row);
6116
6117       if (node)
6118         gtk_ctree_select (ctree, node);
6119     }
6120     
6121   gtk_clist_thaw (clist);
6122   after_press (ctree, NULL);
6123 }
6124
6125 struct _ExportStruct {
6126   gchar *tree;
6127   gchar *info;
6128   gboolean is_leaf;
6129 };
6130
6131 typedef struct _ExportStruct ExportStruct;
6132
6133 gboolean
6134 gnode2ctree (GtkCTree   *ctree,
6135              guint       depth,
6136              GNode        *gnode,
6137              GtkCTreeNode *cnode,
6138              gpointer    data)
6139 {
6140   ExportStruct *es;
6141   GdkPixmap *pixmap_closed;
6142   GdkBitmap *mask_closed;
6143   GdkPixmap *pixmap_opened;
6144   GdkBitmap *mask_opened;
6145   CTreePixmaps *pixmaps;
6146
6147   if (!cnode || !gnode || (!(es = gnode->data)))
6148     return FALSE;
6149
6150   pixmaps = get_ctree_pixmaps (ctree);
6151
6152   if (es->is_leaf)
6153     {
6154       pixmap_closed = pixmaps->pixmap3;
6155       mask_closed = pixmaps->mask3;
6156       pixmap_opened = NULL;
6157       mask_opened = NULL;
6158     }
6159   else
6160     {
6161       pixmap_closed = pixmaps->pixmap1;
6162       mask_closed = pixmaps->mask1;
6163       pixmap_opened = pixmaps->pixmap2;
6164       mask_opened = pixmaps->mask2;
6165     }
6166
6167   gtk_ctree_set_node_info (ctree, cnode, es->tree, 2, pixmap_closed,
6168                            mask_closed, pixmap_opened, mask_opened,
6169                            es->is_leaf, (depth < 3));
6170   gtk_ctree_node_set_text (ctree, cnode, 1, es->info);
6171   g_free (es);
6172   gnode->data = NULL;
6173
6174   return TRUE;
6175 }
6176
6177 gboolean
6178 ctree2gnode (GtkCTree   *ctree,
6179              guint       depth,
6180              GNode        *gnode,
6181              GtkCTreeNode *cnode,
6182              gpointer    data)
6183 {
6184   ExportStruct *es;
6185
6186   if (!cnode || !gnode)
6187     return FALSE;
6188   
6189   es = g_new (ExportStruct, 1);
6190   gnode->data = es;
6191   es->is_leaf = GTK_CTREE_ROW (cnode)->is_leaf;
6192   es->tree = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[0])->text;
6193   es->info = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[1])->text;
6194   return TRUE;
6195 }
6196
6197 void export_ctree (GtkWidget *widget, GtkCTree *ctree)
6198 {
6199   char *title[] = { "Tree" , "Info" };
6200   static GtkWidget *export_window = NULL;
6201   static GtkCTree *export_ctree;
6202   GtkWidget *vbox;
6203   GtkWidget *scrolled_win;
6204   GtkWidget *button;
6205   GtkWidget *sep;
6206   GNode *gnode;
6207   GtkCTreeNode *node;
6208
6209   if (!export_window)
6210     {
6211       export_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6212
6213       gtk_window_set_screen (GTK_WINDOW (export_window),
6214                              gtk_widget_get_screen (widget));
6215   
6216       g_signal_connect (export_window, "destroy",
6217                         G_CALLBACK (gtk_widget_destroyed),
6218                         &export_window);
6219
6220       gtk_window_set_title (GTK_WINDOW (export_window), "exported ctree");
6221       gtk_container_set_border_width (GTK_CONTAINER (export_window), 5);
6222
6223       vbox = gtk_vbox_new (FALSE, 0);
6224       gtk_container_add (GTK_CONTAINER (export_window), vbox);
6225       
6226       button = gtk_button_new_with_label ("Close");
6227       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, TRUE, 0);
6228
6229       g_signal_connect_swapped (button, "clicked",
6230                                 G_CALLBACK (gtk_widget_destroy),
6231                                 export_window);
6232
6233       sep = gtk_hseparator_new ();
6234       gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, TRUE, 10);
6235
6236       export_ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
6237       gtk_ctree_set_line_style (export_ctree, GTK_CTREE_LINES_DOTTED);
6238
6239       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6240       gtk_container_add (GTK_CONTAINER (scrolled_win),
6241                          GTK_WIDGET (export_ctree));
6242       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6243                                       GTK_POLICY_AUTOMATIC,
6244                                       GTK_POLICY_AUTOMATIC);
6245       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6246       gtk_clist_set_selection_mode (GTK_CLIST (export_ctree),
6247                                     GTK_SELECTION_EXTENDED);
6248       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 0, 200);
6249       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 1, 200);
6250       gtk_widget_set_size_request (GTK_WIDGET (export_ctree), 300, 200);
6251     }
6252
6253   if (!GTK_WIDGET_VISIBLE (export_window))
6254     gtk_widget_show_all (export_window);
6255       
6256   gtk_clist_clear (GTK_CLIST (export_ctree));
6257
6258   node = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list,
6259                                      GTK_CLIST (ctree)->focus_row));
6260   if (!node)
6261     return;
6262
6263   gnode = gtk_ctree_export_to_gnode (ctree, NULL, NULL, node,
6264                                      ctree2gnode, NULL);
6265   if (gnode)
6266     {
6267       gtk_ctree_insert_gnode (export_ctree, NULL, NULL, gnode,
6268                               gnode2ctree, NULL);
6269       g_node_destroy (gnode);
6270     }
6271 }
6272
6273 void change_indent (GtkWidget *widget, GtkCTree *ctree)
6274 {
6275   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
6276 }
6277
6278 void change_spacing (GtkWidget *widget, GtkCTree *ctree)
6279 {
6280   gtk_ctree_set_spacing (ctree, GTK_ADJUSTMENT (widget)->value);
6281 }
6282
6283 void change_row_height (GtkWidget *widget, GtkCList *clist)
6284 {
6285   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
6286 }
6287
6288 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
6289 {
6290   GtkStyle *style = NULL;
6291   
6292   if (!node)
6293     return;
6294   
6295   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
6296     {
6297       if (!GTK_CTREE_ROW (node)->is_leaf)
6298         style = GTK_CTREE_ROW (node)->row.data;
6299       else if (GTK_CTREE_ROW (node)->parent)
6300         style = GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data;
6301     }
6302
6303   gtk_ctree_node_set_row_style (ctree, node, style);
6304 }
6305
6306 void 
6307 ctree_toggle_line_style (GtkWidget *widget, gpointer data)
6308 {
6309   GtkCTree *ctree;
6310   gint i;
6311
6312   ctree = GTK_CTREE (data);
6313
6314   if (!GTK_WIDGET_MAPPED (widget))
6315     return;
6316
6317   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6318
6319   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
6320        ((GtkCTreeLineStyle) i) != GTK_CTREE_LINES_TABBED) ||
6321       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
6322        ((GtkCTreeLineStyle) i) == GTK_CTREE_LINES_TABBED))
6323     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
6324   gtk_ctree_set_line_style (ctree, i);
6325   line_style = i;
6326 }
6327
6328 void 
6329 ctree_toggle_expander_style (GtkWidget *widget, gpointer data)
6330 {
6331   GtkCTree *ctree;
6332   gint i;
6333
6334   ctree = GTK_CTREE (data);
6335
6336   if (!GTK_WIDGET_MAPPED (widget))
6337     return;
6338   
6339   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6340   
6341   gtk_ctree_set_expander_style (ctree, (GtkCTreeExpanderStyle) i);
6342 }
6343
6344 void 
6345 ctree_toggle_justify (GtkWidget *widget, gpointer data)
6346 {
6347   GtkCTree *ctree;
6348   gint i;
6349
6350   ctree = GTK_CTREE (data);
6351
6352   if (!GTK_WIDGET_MAPPED (widget))
6353     return;
6354
6355   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6356
6357   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
6358                                       (GtkJustification) i);
6359 }
6360
6361 void 
6362 ctree_toggle_sel_mode (GtkWidget *widget, gpointer data)
6363 {
6364   GtkCTree *ctree;
6365   gint i;
6366
6367   ctree = GTK_CTREE (data);
6368
6369   if (!GTK_WIDGET_MAPPED (widget))
6370     return;
6371
6372   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6373
6374   gtk_clist_set_selection_mode (GTK_CLIST (ctree), selection_modes[i]);
6375   after_press (ctree, NULL);
6376 }
6377     
6378 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
6379                       gint num_books, gint num_pages, GtkCTreeNode *parent)
6380 {
6381   gchar *text[2];
6382   gchar buf1[60];
6383   gchar buf2[60];
6384   GtkCTreeNode *sibling;
6385   CTreePixmaps *pixmaps;
6386   gint i;
6387
6388   text[0] = buf1;
6389   text[1] = buf2;
6390   sibling = NULL;
6391
6392   pixmaps = get_ctree_pixmaps (ctree);
6393
6394   for (i = num_pages + num_books; i > num_books; i--)
6395     {
6396       pages++;
6397       sprintf (buf1, "Page %02d", (gint) rand() % 100);
6398       sprintf (buf2, "Item %d-%d", cur_depth, i);
6399       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
6400                                        pixmaps->pixmap3, pixmaps->mask3, NULL, NULL,
6401                                        TRUE, FALSE);
6402
6403       if (parent && ctree->line_style == GTK_CTREE_LINES_TABBED)
6404         gtk_ctree_node_set_row_style (ctree, sibling,
6405                                       GTK_CTREE_ROW (parent)->row.style);
6406     }
6407
6408   if (cur_depth == depth)
6409     return;
6410
6411   for (i = num_books; i > 0; i--)
6412     {
6413       GtkStyle *style;
6414
6415       books++;
6416       sprintf (buf1, "Book %02d", (gint) rand() % 100);
6417       sprintf (buf2, "Item %d-%d", cur_depth, i);
6418       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
6419                                        pixmaps->pixmap1, pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2,
6420                                        FALSE, FALSE);
6421
6422       style = gtk_style_new ();
6423       switch (cur_depth % 3)
6424         {
6425         case 0:
6426           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
6427           style->base[GTK_STATE_NORMAL].green = 0;
6428           style->base[GTK_STATE_NORMAL].blue  = 65535 - ((i * 10000) % 65535);
6429           break;
6430         case 1:
6431           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
6432           style->base[GTK_STATE_NORMAL].green = 65535 - ((i * 10000) % 65535);
6433           style->base[GTK_STATE_NORMAL].blue  = 0;
6434           break;
6435         default:
6436           style->base[GTK_STATE_NORMAL].red   = 65535 - ((i * 10000) % 65535);
6437           style->base[GTK_STATE_NORMAL].green = 0;
6438           style->base[GTK_STATE_NORMAL].blue  = 10000 * (cur_depth % 6);
6439           break;
6440         }
6441       gtk_ctree_node_set_row_data_full (ctree, sibling, style,
6442                                         (GtkDestroyNotify) gtk_style_unref);
6443
6444       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
6445         gtk_ctree_node_set_row_style (ctree, sibling, style);
6446
6447       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
6448                        sibling);
6449     }
6450 }
6451
6452 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
6453 {
6454   gchar *text [2];
6455   gchar label1[] = "Root";
6456   gchar label2[] = "";
6457   GtkCTreeNode *parent;
6458   GtkStyle *style;
6459   guint b, d, p, n;
6460   CTreePixmaps *pixmaps;
6461
6462   pixmaps = get_ctree_pixmaps (ctree);
6463
6464   text[0] = label1;
6465   text[1] = label2;
6466   
6467   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
6468   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
6469   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
6470
6471   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
6472
6473   if (n > 100000)
6474     {
6475       g_print ("%d total items? Try less\n",n);
6476       return;
6477     }
6478
6479   gtk_clist_freeze (GTK_CLIST (ctree));
6480   gtk_clist_clear (GTK_CLIST (ctree));
6481
6482   books = 1;
6483   pages = 0;
6484
6485   parent = gtk_ctree_insert_node (ctree, NULL, NULL, text, 5, pixmaps->pixmap1,
6486                                   pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2, FALSE, TRUE);
6487
6488   style = gtk_style_new ();
6489   style->base[GTK_STATE_NORMAL].red   = 0;
6490   style->base[GTK_STATE_NORMAL].green = 45000;
6491   style->base[GTK_STATE_NORMAL].blue  = 55000;
6492   gtk_ctree_node_set_row_data_full (ctree, parent, style,
6493                                     (GtkDestroyNotify) gtk_style_unref);
6494
6495   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
6496     gtk_ctree_node_set_row_style (ctree, parent, style);
6497
6498   build_recursive (ctree, 1, d, b, p, parent);
6499   gtk_clist_thaw (GTK_CLIST (ctree));
6500   after_press (ctree, NULL);
6501 }
6502
6503 static void 
6504 ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
6505 {
6506   GtkCList *clist;
6507
6508   clist = GTK_CLIST (ctree);
6509
6510   if (column == clist->sort_column)
6511     {
6512       if (clist->sort_type == GTK_SORT_ASCENDING)
6513         clist->sort_type = GTK_SORT_DESCENDING;
6514       else
6515         clist->sort_type = GTK_SORT_ASCENDING;
6516     }
6517   else
6518     gtk_clist_set_sort_column (clist, column);
6519
6520   gtk_ctree_sort_recursive (ctree, NULL);
6521 }
6522
6523 void create_ctree (GtkWidget *widget)
6524 {
6525   static GtkWidget *window = NULL;
6526   GtkTooltips *tooltips;
6527   GtkCTree *ctree;
6528   GtkWidget *scrolled_win;
6529   GtkWidget *vbox;
6530   GtkWidget *bbox;
6531   GtkWidget *mbox;
6532   GtkWidget *hbox;
6533   GtkWidget *hbox2;
6534   GtkWidget *frame;
6535   GtkWidget *label;
6536   GtkWidget *button;
6537   GtkWidget *check;
6538   GtkAdjustment *adj;
6539   GtkWidget *spinner;
6540
6541   char *title[] = { "Tree" , "Info" };
6542   char buf[80];
6543
6544   static gchar *items1[] =
6545   {
6546     "No lines",
6547     "Solid",
6548     "Dotted",
6549     "Tabbed"
6550   };
6551
6552   static gchar *items2[] =
6553   {
6554     "None",
6555     "Square",
6556     "Triangle",
6557     "Circular"
6558   };
6559
6560   static gchar *items3[] =
6561   {
6562     "Left",
6563     "Right"
6564   };
6565   
6566   if (!window)
6567     {
6568       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6569       gtk_window_set_screen (GTK_WINDOW (window), 
6570                              gtk_widget_get_screen (widget));
6571
6572       g_signal_connect (window, "destroy",
6573                         G_CALLBACK (gtk_widget_destroyed),
6574                         &window);
6575
6576       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
6577       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6578
6579       tooltips = gtk_tooltips_new ();
6580       g_object_ref (tooltips);
6581       gtk_object_sink (GTK_OBJECT (tooltips));
6582
6583       g_object_set_data_full (G_OBJECT (window), "tooltips", tooltips,
6584                               g_object_unref);
6585
6586       vbox = gtk_vbox_new (FALSE, 0);
6587       gtk_container_add (GTK_CONTAINER (window), vbox);
6588
6589       hbox = gtk_hbox_new (FALSE, 5);
6590       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6591       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
6592       
6593       label = gtk_label_new ("Depth :");
6594       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6595       
6596       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
6597       spin1 = gtk_spin_button_new (adj, 0, 0);
6598       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
6599   
6600       label = gtk_label_new ("Books :");
6601       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6602       
6603       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
6604       spin2 = gtk_spin_button_new (adj, 0, 0);
6605       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
6606
6607       label = gtk_label_new ("Pages :");
6608       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6609       
6610       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
6611       spin3 = gtk_spin_button_new (adj, 0, 0);
6612       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
6613
6614       button = gtk_button_new_with_label ("Close");
6615       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6616
6617       g_signal_connect_swapped (button, "clicked",
6618                                 G_CALLBACK (gtk_widget_destroy),
6619                                 window);
6620
6621       button = gtk_button_new_with_label ("Rebuild Tree");
6622       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6623
6624       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6625       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
6626       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6627                                       GTK_POLICY_AUTOMATIC,
6628                                       GTK_POLICY_ALWAYS);
6629       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6630
6631       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
6632       gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
6633
6634       gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
6635       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
6636       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
6637       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
6638       line_style = GTK_CTREE_LINES_DOTTED;
6639
6640       g_signal_connect (button, "clicked",
6641                         G_CALLBACK (rebuild_tree), ctree);
6642       g_signal_connect (ctree, "click_column",
6643                         G_CALLBACK (ctree_click_column), NULL);
6644
6645       g_signal_connect_after (ctree, "button_press_event",
6646                               G_CALLBACK (after_press), NULL);
6647       g_signal_connect_after (ctree, "button_release_event",
6648                               G_CALLBACK (after_press), NULL);
6649       g_signal_connect_after (ctree, "tree_move",
6650                               G_CALLBACK (after_move), NULL);
6651       g_signal_connect_after (ctree, "end_selection",
6652                               G_CALLBACK (after_press), NULL);
6653       g_signal_connect_after (ctree, "toggle_focus_row",
6654                               G_CALLBACK (after_press), NULL);
6655       g_signal_connect_after (ctree, "select_all",
6656                               G_CALLBACK (after_press), NULL);
6657       g_signal_connect_after (ctree, "unselect_all",
6658                               G_CALLBACK (after_press), NULL);
6659       g_signal_connect_after (ctree, "scroll_vertical",
6660                               G_CALLBACK (after_press), NULL);
6661
6662       bbox = gtk_hbox_new (FALSE, 5);
6663       gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
6664       gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, TRUE, 0);
6665
6666       mbox = gtk_vbox_new (TRUE, 5);
6667       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6668
6669       label = gtk_label_new ("Row Height :");
6670       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6671
6672       label = gtk_label_new ("Indent :");
6673       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6674
6675       label = gtk_label_new ("Spacing :");
6676       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6677
6678       mbox = gtk_vbox_new (TRUE, 5);
6679       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6680
6681       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
6682       spinner = gtk_spin_button_new (adj, 0, 0);
6683       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6684       gtk_tooltips_set_tip (tooltips, spinner,
6685                             "Row height of list items", NULL);
6686       g_signal_connect (adj, "value_changed",
6687                         G_CALLBACK (change_row_height), ctree);
6688       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
6689
6690       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
6691       spinner = gtk_spin_button_new (adj, 0, 0);
6692       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6693       gtk_tooltips_set_tip (tooltips, spinner, "Tree Indentation.", NULL);
6694       g_signal_connect (adj, "value_changed",
6695                         G_CALLBACK (change_indent), ctree);
6696
6697       adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 60, 1, 10, 0);
6698       spinner = gtk_spin_button_new (adj, 0, 0);
6699       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6700       gtk_tooltips_set_tip (tooltips, spinner, "Tree Spacing.", NULL);
6701       g_signal_connect (adj, "value_changed",
6702                         G_CALLBACK (change_spacing), ctree);
6703
6704       mbox = gtk_vbox_new (TRUE, 5);
6705       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6706
6707       hbox = gtk_hbox_new (FALSE, 5);
6708       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6709
6710       button = gtk_button_new_with_label ("Expand All");
6711       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6712       g_signal_connect (button, "clicked",
6713                         G_CALLBACK (expand_all), ctree);
6714
6715       button = gtk_button_new_with_label ("Collapse All");
6716       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6717       g_signal_connect (button, "clicked",
6718                         G_CALLBACK (collapse_all), ctree);
6719
6720       button = gtk_button_new_with_label ("Change Style");
6721       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6722       g_signal_connect (button, "clicked",
6723                         G_CALLBACK (change_style), ctree);
6724
6725       button = gtk_button_new_with_label ("Export Tree");
6726       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6727       g_signal_connect (button, "clicked",
6728                         G_CALLBACK (export_ctree), ctree);
6729
6730       hbox = gtk_hbox_new (FALSE, 5);
6731       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6732
6733       button = gtk_button_new_with_label ("Select All");
6734       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6735       g_signal_connect (button, "clicked",
6736                         G_CALLBACK (select_all), ctree);
6737
6738       button = gtk_button_new_with_label ("Unselect All");
6739       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6740       g_signal_connect (button, "clicked",
6741                         G_CALLBACK (unselect_all), ctree);
6742
6743       button = gtk_button_new_with_label ("Remove Selection");
6744       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6745       g_signal_connect (button, "clicked",
6746                         G_CALLBACK (remove_selection), ctree);
6747
6748       check = gtk_check_button_new_with_label ("Reorderable");
6749       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
6750       gtk_tooltips_set_tip (tooltips, check,
6751                             "Tree items can be reordered by dragging.", NULL);
6752       g_signal_connect (check, "clicked",
6753                         G_CALLBACK (toggle_reorderable), ctree);
6754       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
6755
6756       hbox = gtk_hbox_new (TRUE, 5);
6757       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6758
6759       omenu1 = build_option_menu (items1, 4, 2, 
6760                                   ctree_toggle_line_style,
6761                                   ctree);
6762       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
6763       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
6764
6765       omenu2 = build_option_menu (items2, 4, 1, 
6766                                   ctree_toggle_expander_style,
6767                                   ctree);
6768       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
6769       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's expander style.",
6770                             NULL);
6771
6772       omenu3 = build_option_menu (items3, 2, 0, 
6773                                   ctree_toggle_justify, ctree);
6774       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
6775       gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.",
6776                             NULL);
6777
6778       omenu4 = build_option_menu (selection_mode_items, 3, 3, 
6779                                   ctree_toggle_sel_mode, ctree);
6780       gtk_box_pack_start (GTK_BOX (hbox), omenu4, FALSE, TRUE, 0);
6781       gtk_tooltips_set_tip (tooltips, omenu4, "The list's selection mode.",
6782                             NULL);
6783
6784       gtk_widget_realize (window);
6785       
6786       gtk_widget_set_size_request (GTK_WIDGET (ctree), -1, 300);
6787
6788       frame = gtk_frame_new (NULL);
6789       gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
6790       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
6791       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
6792
6793       hbox = gtk_hbox_new (TRUE, 2);
6794       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
6795       gtk_container_add (GTK_CONTAINER (frame), hbox);
6796
6797       frame = gtk_frame_new (NULL);
6798       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6799       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6800
6801       hbox2 = gtk_hbox_new (FALSE, 0);
6802       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6803       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6804
6805       label = gtk_label_new ("Books :");
6806       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6807
6808       sprintf (buf, "%d", books);
6809       book_label = gtk_label_new (buf);
6810       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
6811
6812       frame = gtk_frame_new (NULL);
6813       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6814       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6815
6816       hbox2 = gtk_hbox_new (FALSE, 0);
6817       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6818       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6819
6820       label = gtk_label_new ("Pages :");
6821       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6822
6823       sprintf (buf, "%d", pages);
6824       page_label = gtk_label_new (buf);
6825       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
6826
6827       frame = gtk_frame_new (NULL);
6828       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6829       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6830
6831       hbox2 = gtk_hbox_new (FALSE, 0);
6832       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6833       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6834
6835       label = gtk_label_new ("Selected :");
6836       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6837
6838       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
6839       sel_label = gtk_label_new (buf);
6840       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
6841
6842       frame = gtk_frame_new (NULL);
6843       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6844       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6845
6846       hbox2 = gtk_hbox_new (FALSE, 0);
6847       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6848       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6849
6850       label = gtk_label_new ("Visible :");
6851       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6852
6853       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
6854       vis_label = gtk_label_new (buf);
6855       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
6856
6857       rebuild_tree (NULL, ctree);
6858     }
6859
6860   if (!GTK_WIDGET_VISIBLE (window))
6861     gtk_widget_show_all (window);
6862   else
6863     gtk_widget_destroy (window);
6864 }
6865
6866 /*
6867  * GtkColorSelection
6868  */
6869
6870 void
6871 color_selection_ok (GtkWidget               *w,
6872                     GtkColorSelectionDialog *cs)
6873 {
6874   GtkColorSelection *colorsel;
6875   gdouble color[4];
6876
6877   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
6878
6879   gtk_color_selection_get_color(colorsel,color);
6880   gtk_color_selection_set_color(colorsel,color);
6881 }
6882
6883 void
6884 color_selection_changed (GtkWidget *w,
6885                          GtkColorSelectionDialog *cs)
6886 {
6887   GtkColorSelection *colorsel;
6888   gdouble color[4];
6889
6890   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
6891   gtk_color_selection_get_color(colorsel,color);
6892 }
6893
6894 static void
6895 opacity_toggled_cb (GtkWidget *w,
6896                     GtkColorSelectionDialog *cs)
6897 {
6898   GtkColorSelection *colorsel;
6899
6900   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
6901   gtk_color_selection_set_has_opacity_control (colorsel,
6902                                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
6903 }
6904
6905 static void
6906 palette_toggled_cb (GtkWidget *w,
6907                     GtkColorSelectionDialog *cs)
6908 {
6909   GtkColorSelection *colorsel;
6910
6911   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
6912   gtk_color_selection_set_has_palette (colorsel,
6913                                        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
6914 }
6915
6916 void
6917 create_color_selection (GtkWidget *widget)
6918 {
6919   static GtkWidget *window = NULL;
6920
6921   if (!window)
6922     {
6923       GtkWidget *options_hbox;
6924       GtkWidget *check_button;
6925       
6926       window = gtk_color_selection_dialog_new ("color selection dialog");
6927       gtk_window_set_screen (GTK_WINDOW (window), 
6928                              gtk_widget_get_screen (widget));
6929                              
6930       gtk_widget_show (GTK_COLOR_SELECTION_DIALOG (window)->help_button);
6931
6932       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
6933
6934       g_signal_connect (window, "destroy",
6935                         G_CALLBACK(gtk_widget_destroyed),
6936                         &window);
6937
6938       options_hbox = gtk_hbox_new (FALSE, 0);
6939       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), options_hbox, FALSE, FALSE, 0);
6940       gtk_container_set_border_width (GTK_CONTAINER (options_hbox), 10);
6941       
6942       check_button = gtk_check_button_new_with_label ("Show Opacity");
6943       gtk_box_pack_start (GTK_BOX (options_hbox), check_button, FALSE, FALSE, 0);
6944       g_signal_connect (check_button, "toggled",
6945                         G_CALLBACK (opacity_toggled_cb), window);
6946
6947       check_button = gtk_check_button_new_with_label ("Show Palette");
6948       gtk_box_pack_end (GTK_BOX (options_hbox), check_button, FALSE, FALSE, 0);
6949       g_signal_connect (check_button, "toggled",
6950                         G_CALLBACK (palette_toggled_cb), window);
6951
6952       g_signal_connect (GTK_COLOR_SELECTION_DIALOG (window)->colorsel,
6953                         "color_changed",
6954                         G_CALLBACK (color_selection_changed),
6955                         window);
6956
6957       g_signal_connect (GTK_COLOR_SELECTION_DIALOG (window)->ok_button,
6958                         "clicked",
6959                         G_CALLBACK (color_selection_ok),
6960                         window);
6961
6962       g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button,
6963                                 "clicked",
6964                                 G_CALLBACK (gtk_widget_destroy),
6965                                 window);
6966     }
6967
6968   if (!GTK_WIDGET_VISIBLE (window))
6969     gtk_widget_show_all (window);
6970   else
6971     gtk_widget_destroy (window);
6972 }
6973
6974 /*
6975  * GtkFileSelection
6976  */
6977
6978 void
6979 show_fileops (GtkWidget        *widget,
6980               GtkFileSelection *fs)
6981 {
6982   gboolean show_ops;
6983
6984   show_ops = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6985
6986   if (show_ops)
6987     gtk_file_selection_show_fileop_buttons (fs);
6988   else
6989     gtk_file_selection_hide_fileop_buttons (fs);
6990 }
6991
6992 void
6993 select_multiple (GtkWidget        *widget,
6994                  GtkFileSelection *fs)
6995 {
6996   gboolean select_multiple;
6997
6998   select_multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6999   gtk_file_selection_set_select_multiple (fs, select_multiple);
7000 }
7001
7002 void
7003 file_selection_ok (GtkFileSelection *fs)
7004 {
7005   int i;
7006   gchar **selections;
7007
7008   selections = gtk_file_selection_get_selections (fs);
7009
7010   for (i = 0; selections[i] != NULL; i++)
7011     g_print ("%s\n", selections[i]);
7012
7013   g_strfreev (selections);
7014
7015   gtk_widget_destroy (GTK_WIDGET (fs));
7016 }
7017
7018 void
7019 create_file_selection (GtkWidget *widget)
7020 {
7021   static GtkWidget *window = NULL;
7022   GtkWidget *button;
7023
7024   if (!window)
7025     {
7026       window = gtk_file_selection_new ("file selection dialog");
7027       gtk_window_set_screen (GTK_WINDOW (window),
7028                              gtk_widget_get_screen (widget));
7029
7030       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
7031
7032       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
7033
7034       g_signal_connect (window, "destroy",
7035                         G_CALLBACK (gtk_widget_destroyed),
7036                         &window);
7037
7038       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->ok_button,
7039                                 "clicked",
7040                                 G_CALLBACK (file_selection_ok),
7041                                 window);
7042       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->cancel_button,
7043                                 "clicked",
7044                                 G_CALLBACK (gtk_widget_destroy),
7045                                 window);
7046       
7047       button = gtk_check_button_new_with_label ("Show Fileops");
7048       g_signal_connect (button, "toggled",
7049                         G_CALLBACK (show_fileops),
7050                         window);
7051       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
7052                           button, FALSE, FALSE, 0);
7053       gtk_widget_show (button);
7054
7055       button = gtk_check_button_new_with_label ("Select Multiple");
7056       g_signal_connect (button, "clicked",
7057                         G_CALLBACK (select_multiple),
7058                         window);
7059       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
7060                           button, FALSE, FALSE, 0);
7061       gtk_widget_show (button);
7062     }
7063   
7064   if (!GTK_WIDGET_VISIBLE (window))
7065     gtk_widget_show (window);
7066   else
7067     gtk_widget_destroy (window);
7068 }
7069
7070 void
7071 flipping_toggled_cb (GtkWidget *widget, gpointer data)
7072 {
7073   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
7074   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
7075
7076   gtk_widget_set_default_direction (new_direction);
7077 }
7078
7079 static void
7080 set_direction_recurse (GtkWidget *widget,
7081                        gpointer   data)
7082 {
7083   GtkTextDirection *dir = data;
7084   
7085   gtk_widget_set_direction (widget, *dir);
7086   if (GTK_IS_CONTAINER (widget))
7087     gtk_container_foreach (GTK_CONTAINER (widget),
7088                            set_direction_recurse,
7089                            data);
7090 }
7091
7092 static GtkWidget *
7093 create_forward_back (const char       *title,
7094                      GtkTextDirection  text_dir)
7095 {
7096   GtkWidget *frame = gtk_frame_new (title);
7097   GtkWidget *bbox = gtk_hbutton_box_new ();
7098   GtkWidget *back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
7099   GtkWidget *forward_button = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
7100
7101   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
7102   
7103   gtk_container_add (GTK_CONTAINER (frame), bbox);
7104   gtk_container_add (GTK_CONTAINER (bbox), back_button);
7105   gtk_container_add (GTK_CONTAINER (bbox), forward_button);
7106
7107   set_direction_recurse (frame, &text_dir);
7108
7109   return frame;
7110 }
7111
7112 void
7113 create_flipping (GtkWidget *widget)
7114 {
7115   static GtkWidget *window = NULL;
7116   GtkWidget *check_button, *button;
7117
7118   if (!window)
7119     {
7120       window = gtk_dialog_new ();
7121
7122       gtk_window_set_screen (GTK_WINDOW (window),
7123                              gtk_widget_get_screen (widget));
7124
7125       g_signal_connect (window, "destroy",
7126                         G_CALLBACK (gtk_widget_destroyed),
7127                         &window);
7128
7129       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
7130
7131       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
7132       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7133                           check_button, TRUE, TRUE, 0);
7134
7135       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7136                           create_forward_back ("Default", GTK_TEXT_DIR_NONE),
7137                           TRUE, TRUE, 0);
7138
7139       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7140                           create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
7141                           TRUE, TRUE, 0);
7142
7143       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7144                           create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
7145                           TRUE, TRUE, 0);
7146
7147       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
7148         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
7149
7150       g_signal_connect (check_button, "toggled",
7151                         G_CALLBACK (flipping_toggled_cb), FALSE);
7152
7153       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
7154       
7155       button = gtk_button_new_with_label ("Close");
7156       g_signal_connect_swapped (button, "clicked",
7157                                 G_CALLBACK (gtk_widget_destroy), window);
7158       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7159                           button, TRUE, TRUE, 0);
7160     }
7161   
7162   if (!GTK_WIDGET_VISIBLE (window))
7163     gtk_widget_show_all (window);
7164   else
7165     gtk_widget_destroy (window);
7166 }
7167
7168 /*
7169  * Focus test
7170  */
7171
7172 static GtkWidget*
7173 make_focus_table (GList **list)
7174 {
7175   GtkWidget *table;
7176   gint i, j;
7177   
7178   table = gtk_table_new (5, 5, FALSE);
7179
7180   i = 0;
7181   j = 0;
7182
7183   while (i < 5)
7184     {
7185       j = 0;
7186       while (j < 5)
7187         {
7188           GtkWidget *widget;
7189           
7190           if ((i + j) % 2)
7191             widget = gtk_entry_new ();
7192           else
7193             widget = gtk_button_new_with_label ("Foo");
7194
7195           *list = g_list_prepend (*list, widget);
7196           
7197           gtk_table_attach (GTK_TABLE (table),
7198                             widget,
7199                             i, i + 1,
7200                             j, j + 1,
7201                             GTK_EXPAND | GTK_FILL,
7202                             GTK_EXPAND | GTK_FILL,
7203                             5, 5);
7204           
7205           ++j;
7206         }
7207
7208       ++i;
7209     }
7210
7211   *list = g_list_reverse (*list);
7212   
7213   return table;
7214 }
7215
7216 static void
7217 create_focus (GtkWidget *widget)
7218 {
7219   static GtkWidget *window = NULL;
7220   
7221   if (!window)
7222     {
7223       GtkWidget *table;
7224       GtkWidget *frame;
7225       GList *list = NULL;
7226       
7227       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
7228                                             NULL, 0,
7229                                             GTK_STOCK_CLOSE,
7230                                             GTK_RESPONSE_NONE,
7231                                             NULL);
7232
7233       gtk_window_set_screen (GTK_WINDOW (window),
7234                              gtk_widget_get_screen (widget));
7235
7236       g_signal_connect (window, "destroy",
7237                         G_CALLBACK (gtk_widget_destroyed),
7238                         &window);
7239
7240       g_signal_connect (window, "response",
7241                         G_CALLBACK (gtk_widget_destroy),
7242                         NULL);
7243       
7244       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
7245
7246       frame = gtk_frame_new ("Weird tab focus chain");
7247
7248       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7249                           frame, TRUE, TRUE, 0);
7250       
7251       table = make_focus_table (&list);
7252
7253       gtk_container_add (GTK_CONTAINER (frame), table);
7254
7255       gtk_container_set_focus_chain (GTK_CONTAINER (table),
7256                                      list);
7257
7258       g_list_free (list);
7259       
7260       frame = gtk_frame_new ("Default tab focus chain");
7261
7262       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7263                           frame, TRUE, TRUE, 0);
7264
7265       list = NULL;
7266       table = make_focus_table (&list);
7267
7268       g_list_free (list);
7269       
7270       gtk_container_add (GTK_CONTAINER (frame), table);      
7271     }
7272   
7273   if (!GTK_WIDGET_VISIBLE (window))
7274     gtk_widget_show_all (window);
7275   else
7276     gtk_widget_destroy (window);
7277 }
7278
7279 /*
7280  * GtkFontSelection
7281  */
7282
7283 void
7284 font_selection_ok (GtkWidget              *w,
7285                    GtkFontSelectionDialog *fs)
7286 {
7287   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
7288
7289   g_print ("%s\n", s);
7290   g_free (s);
7291   gtk_widget_destroy (GTK_WIDGET (fs));
7292 }
7293
7294 void
7295 create_font_selection (GtkWidget *widget)
7296 {
7297   static GtkWidget *window = NULL;
7298
7299   if (!window)
7300     {
7301       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
7302       
7303       gtk_window_set_screen (GTK_WINDOW (window),
7304                              gtk_widget_get_screen (widget));
7305
7306       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
7307
7308       g_signal_connect (window, "destroy",
7309                         G_CALLBACK (gtk_widget_destroyed),
7310                         &window);
7311
7312       g_signal_connect (GTK_FONT_SELECTION_DIALOG (window)->ok_button,
7313                         "clicked", G_CALLBACK (font_selection_ok),
7314                         GTK_FONT_SELECTION_DIALOG (window));
7315       g_signal_connect_swapped (GTK_FONT_SELECTION_DIALOG (window)->cancel_button,
7316                                 "clicked", G_CALLBACK (gtk_widget_destroy),
7317                                 window);
7318     }
7319   
7320   if (!GTK_WIDGET_VISIBLE (window))
7321     gtk_widget_show (window);
7322   else
7323     gtk_widget_destroy (window);
7324 }
7325
7326 /*
7327  * GtkDialog
7328  */
7329
7330 static GtkWidget *dialog_window = NULL;
7331
7332 static void
7333 label_toggle (GtkWidget  *widget,
7334               GtkWidget **label)
7335 {
7336   if (!(*label))
7337     {
7338       *label = gtk_label_new ("Dialog Test");
7339       g_signal_connect (*label,
7340                         "destroy",
7341                         G_CALLBACK (gtk_widget_destroyed),
7342                         label);
7343       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
7344       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7345                           *label, TRUE, TRUE, 0);
7346       gtk_widget_show (*label);
7347     }
7348   else
7349     gtk_widget_destroy (*label);
7350 }
7351
7352 #define RESPONSE_TOGGLE_SEPARATOR 1
7353
7354 static void
7355 print_response (GtkWidget *dialog,
7356                 gint       response_id,
7357                 gpointer   data)
7358 {
7359   g_print ("response signal received (%d)\n", response_id);
7360
7361   if (response_id == RESPONSE_TOGGLE_SEPARATOR)
7362     {
7363       gtk_dialog_set_has_separator (GTK_DIALOG (dialog),
7364                                     !gtk_dialog_get_has_separator (GTK_DIALOG (dialog)));
7365     }
7366 }
7367
7368 static void
7369 create_dialog (GtkWidget *widget)
7370 {
7371   static GtkWidget *label;
7372   GtkWidget *button;
7373
7374   if (!dialog_window)
7375     {
7376       /* This is a terrible example; it's much simpler to create
7377        * dialogs than this. Don't use testgtk for example code,
7378        * use gtk-demo ;-)
7379        */
7380       
7381       dialog_window = gtk_dialog_new ();
7382       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7383                              gtk_widget_get_screen (widget));
7384
7385       g_signal_connect (dialog_window,
7386                         "response",
7387                         G_CALLBACK (print_response),
7388                         NULL);
7389       
7390       g_signal_connect (dialog_window, "destroy",
7391                         G_CALLBACK (gtk_widget_destroyed),
7392                         &dialog_window);
7393
7394       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
7395       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7396
7397       button = gtk_button_new_with_label ("OK");
7398       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7399       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
7400                           button, TRUE, TRUE, 0);
7401       gtk_widget_grab_default (button);
7402       gtk_widget_show (button);
7403
7404       button = gtk_button_new_with_label ("Toggle");
7405       g_signal_connect (button, "clicked",
7406                         G_CALLBACK (label_toggle),
7407                         &label);
7408       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7409       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7410                           button, TRUE, TRUE, 0);
7411       gtk_widget_show (button);
7412
7413       label = NULL;
7414       
7415       button = gtk_button_new_with_label ("Separator");
7416
7417       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7418
7419       gtk_dialog_add_action_widget (GTK_DIALOG (dialog_window),
7420                                     button,
7421                                     RESPONSE_TOGGLE_SEPARATOR);
7422       gtk_widget_show (button);
7423     }
7424
7425   if (!GTK_WIDGET_VISIBLE (dialog_window))
7426     gtk_widget_show (dialog_window);
7427   else
7428     gtk_widget_destroy (dialog_window);
7429 }
7430
7431 /* Display & Screen test 
7432  */
7433
7434 typedef struct 
7435
7436   GtkEntry *entry;
7437   GtkWidget *radio_dpy;
7438   GtkWidget *toplevel; 
7439   GtkWidget *dialog_window;
7440   GList *valid_display_list;
7441 } ScreenDisplaySelection;
7442
7443 static gint
7444 display_name_cmp (gconstpointer a,
7445                   gconstpointer b)
7446 {
7447   return g_ascii_strcasecmp (a,b);
7448 }
7449
7450 static void
7451 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
7452 {
7453   char *display_name;
7454   GdkDisplay *display = gtk_widget_get_display (widget);
7455   GtkWidget *dialog;
7456   GdkScreen *new_screen = NULL;
7457   GdkScreen *current_screen = gtk_widget_get_screen (widget);
7458   
7459   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
7460     {
7461       display_name = g_strdup (gtk_entry_get_text (data->entry));
7462       display = gdk_display_open (display_name);
7463       
7464       if (!display)
7465         {
7466           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
7467                                            GTK_DIALOG_DESTROY_WITH_PARENT,
7468                                            GTK_MESSAGE_ERROR,
7469                                            GTK_BUTTONS_OK,
7470                                            "The display :\n%s\ncannot be opened",
7471                                            display_name);
7472           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
7473           gtk_widget_show (dialog);
7474           g_signal_connect (dialog, "response",
7475                             G_CALLBACK (gtk_widget_destroy),
7476                             NULL);
7477         }
7478       else
7479         {
7480           if (!g_list_find_custom (data->valid_display_list, 
7481                                    display_name,
7482                                    display_name_cmp))
7483             data->valid_display_list = g_list_append (data->valid_display_list,
7484                                                       display_name);
7485           
7486           new_screen = gdk_display_get_default_screen (display);
7487         }
7488     }
7489   else
7490     {
7491       gint number_of_screens = gdk_display_get_n_screens (display);
7492       gint screen_num = gdk_screen_get_number (current_screen);
7493       if ((screen_num +1) < number_of_screens)
7494         new_screen = gdk_display_get_screen (display, screen_num + 1);
7495       else
7496         new_screen = gdk_display_get_screen (display, 0);
7497     }
7498   
7499   if (new_screen) 
7500     {
7501       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
7502       gtk_widget_destroy (data->dialog_window);
7503     }
7504 }
7505
7506 void
7507 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
7508 {
7509   gtk_widget_destroy (data);
7510 }
7511
7512 void
7513 create_display_screen (GtkWidget *widget)
7514 {
7515   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
7516   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
7517   GtkWidget *bbox;
7518   ScreenDisplaySelection *scr_dpy_data;
7519   GdkScreen *screen = gtk_widget_get_screen (widget);
7520   static GList *valid_display_list = NULL;
7521   
7522   GdkDisplay *display = gdk_screen_get_display (screen);
7523
7524   window = gtk_widget_new (gtk_window_get_type (),
7525                            "screen", screen,
7526                            "user_data", NULL,
7527                            "type", GTK_WINDOW_TOPLEVEL,
7528                            "title",
7529                            "Screen or Display selection",
7530                            "border_width", 10, NULL);
7531   g_signal_connect (window, "destroy", 
7532                     G_CALLBACK (gtk_widget_destroy), NULL);
7533
7534   vbox = gtk_vbox_new (FALSE, 3);
7535   gtk_container_add (GTK_CONTAINER (window), vbox);
7536   
7537   frame = gtk_frame_new ("Select screen or display");
7538   gtk_container_add (GTK_CONTAINER (vbox), frame);
7539   
7540   table = gtk_table_new (2, 2, TRUE);
7541   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
7542   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
7543
7544   gtk_container_add (GTK_CONTAINER (frame), table);
7545
7546   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
7547   if (gdk_display_get_n_screens(display) > 1)
7548     radio_scr = gtk_radio_button_new_with_label 
7549     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
7550   else
7551     {    
7552       radio_scr = gtk_radio_button_new_with_label 
7553         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
7554          "only one screen on the current display");
7555       gtk_widget_set_sensitive (radio_scr, FALSE);
7556     }
7557   combo_dpy = gtk_combo_new ();
7558   if (!valid_display_list)
7559     valid_display_list = g_list_append (valid_display_list, "diabolo:0.0");
7560     
7561   gtk_combo_set_popdown_strings (GTK_COMBO (combo_dpy), valid_display_list);
7562     
7563   gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo_dpy)->entry), 
7564                       "<hostname>:<X Server Num>.<Screen Num>");
7565
7566   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
7567   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
7568   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
7569
7570   bbox = gtk_hbutton_box_new ();
7571   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
7572   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
7573   
7574   gtk_container_add (GTK_CONTAINER (vbox), bbox);
7575
7576   gtk_container_add (GTK_CONTAINER (bbox), applyb);
7577   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
7578
7579   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
7580
7581   scr_dpy_data->entry = GTK_ENTRY (GTK_COMBO (combo_dpy)->entry);
7582   scr_dpy_data->radio_dpy = radio_dpy;
7583   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
7584   scr_dpy_data->dialog_window = window;
7585   scr_dpy_data->valid_display_list = valid_display_list;
7586
7587   g_signal_connect (cancelb, "clicked", 
7588                     G_CALLBACK (screen_display_destroy_diag), window);
7589   g_signal_connect (applyb, "clicked", 
7590                     G_CALLBACK (screen_display_check), scr_dpy_data);
7591   gtk_widget_show_all (window);
7592 }
7593
7594 /* Event Watcher
7595  */
7596 static gboolean event_watcher_enter_id = 0;
7597 static gboolean event_watcher_leave_id = 0;
7598
7599 static gboolean
7600 event_watcher (GSignalInvocationHint *ihint,
7601                guint                  n_param_values,
7602                const GValue          *param_values,
7603                gpointer               data)
7604 {
7605   g_print ("Watch: \"%s\" emitted for %s\n",
7606            g_signal_name (ihint->signal_id),
7607            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
7608
7609   return TRUE;
7610 }
7611
7612 static void
7613 event_watcher_down (void)
7614 {
7615   if (event_watcher_enter_id)
7616     {
7617       guint signal_id;
7618
7619       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7620       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
7621       event_watcher_enter_id = 0;
7622       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7623       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
7624       event_watcher_leave_id = 0;
7625     }
7626 }
7627
7628 static void
7629 event_watcher_toggle (void)
7630 {
7631   if (event_watcher_enter_id)
7632     event_watcher_down ();
7633   else
7634     {
7635       guint signal_id;
7636
7637       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7638       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7639       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7640       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7641     }
7642 }
7643
7644 static void
7645 create_event_watcher (GtkWidget *widget)
7646 {
7647   GtkWidget *button;
7648
7649   if (!dialog_window)
7650     {
7651       dialog_window = gtk_dialog_new ();
7652       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7653                              gtk_widget_get_screen (widget));
7654
7655       g_signal_connect (dialog_window, "destroy",
7656                         G_CALLBACK (gtk_widget_destroyed),
7657                         &dialog_window);
7658       g_signal_connect (dialog_window, "destroy",
7659                         G_CALLBACK (event_watcher_down),
7660                         NULL);
7661
7662       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
7663       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7664       gtk_widget_set_size_request (dialog_window, 200, 110);
7665
7666       button = gtk_toggle_button_new_with_label ("Activate Watch");
7667       g_signal_connect (button, "clicked",
7668                         G_CALLBACK (event_watcher_toggle),
7669                         NULL);
7670       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
7671       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7672                           button, TRUE, TRUE, 0);
7673       gtk_widget_show (button);
7674
7675       button = gtk_button_new_with_label ("Close");
7676       g_signal_connect_swapped (button, "clicked",
7677                                 G_CALLBACK (gtk_widget_destroy),
7678                                 dialog_window);
7679       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7680       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7681                           button, TRUE, TRUE, 0);
7682       gtk_widget_grab_default (button);
7683       gtk_widget_show (button);
7684     }
7685
7686   if (!GTK_WIDGET_VISIBLE (dialog_window))
7687     gtk_widget_show (dialog_window);
7688   else
7689     gtk_widget_destroy (dialog_window);
7690 }
7691
7692 /*
7693  * GtkRange
7694  */
7695
7696 static gchar*
7697 reformat_value (GtkScale *scale,
7698                 gdouble   value)
7699 {
7700   return g_strdup_printf ("-->%0.*g<--",
7701                           gtk_scale_get_digits (scale), value);
7702 }
7703
7704 static void
7705 create_range_controls (GtkWidget *widget)
7706 {
7707   static GtkWidget *window = NULL;
7708   GtkWidget *box1;
7709   GtkWidget *box2;
7710   GtkWidget *button;
7711   GtkWidget *scrollbar;
7712   GtkWidget *scale;
7713   GtkWidget *separator;
7714   GtkObject *adjustment;
7715   GtkWidget *hbox;
7716
7717   if (!window)
7718     {
7719       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7720
7721       gtk_window_set_screen (GTK_WINDOW (window),
7722                              gtk_widget_get_screen (widget));
7723
7724       g_signal_connect (window, "destroy",
7725                         G_CALLBACK (gtk_widget_destroyed),
7726                         &window);
7727
7728       gtk_window_set_title (GTK_WINDOW (window), "range controls");
7729       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7730
7731
7732       box1 = gtk_vbox_new (FALSE, 0);
7733       gtk_container_add (GTK_CONTAINER (window), box1);
7734       gtk_widget_show (box1);
7735
7736
7737       box2 = gtk_vbox_new (FALSE, 10);
7738       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7739       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7740       gtk_widget_show (box2);
7741
7742
7743       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
7744
7745       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7746       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
7747       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
7748       gtk_scale_set_digits (GTK_SCALE (scale), 1);
7749       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7750       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7751       gtk_widget_show (scale);
7752
7753       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
7754       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
7755                                    GTK_UPDATE_CONTINUOUS);
7756       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
7757       gtk_widget_show (scrollbar);
7758
7759       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7760       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7761       g_signal_connect (scale,
7762                         "format_value",
7763                         G_CALLBACK (reformat_value),
7764                         NULL);
7765       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7766       gtk_widget_show (scale);
7767       
7768       hbox = gtk_hbox_new (FALSE, 0);
7769
7770       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7771       gtk_widget_set_size_request (scale, -1, 200);
7772       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7773       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7774       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7775       gtk_widget_show (scale);
7776
7777       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7778       gtk_widget_set_size_request (scale, -1, 200);
7779       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7780       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7781       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
7782       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7783       gtk_widget_show (scale);
7784
7785       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7786       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7787       g_signal_connect (scale,
7788                         "format_value",
7789                         G_CALLBACK (reformat_value),
7790                         NULL);
7791       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7792       gtk_widget_show (scale);
7793
7794       
7795       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
7796       gtk_widget_show (hbox);
7797       
7798       separator = gtk_hseparator_new ();
7799       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7800       gtk_widget_show (separator);
7801
7802
7803       box2 = gtk_vbox_new (FALSE, 10);
7804       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7805       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7806       gtk_widget_show (box2);
7807
7808
7809       button = gtk_button_new_with_label ("close");
7810       g_signal_connect_swapped (button, "clicked",
7811                                 G_CALLBACK (gtk_widget_destroy),
7812                                 window);
7813       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7814       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7815       gtk_widget_grab_default (button);
7816       gtk_widget_show (button);
7817     }
7818
7819   if (!GTK_WIDGET_VISIBLE (window))
7820     gtk_widget_show (window);
7821   else
7822     gtk_widget_destroy (window);
7823 }
7824
7825 /*
7826  * GtkRulers
7827  */
7828
7829 void
7830 create_rulers (GtkWidget *widget)
7831 {
7832   static GtkWidget *window = NULL;
7833   GtkWidget *table;
7834   GtkWidget *ruler;
7835
7836   if (!window)
7837     {
7838       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7839
7840       gtk_window_set_screen (GTK_WINDOW (window),
7841                              gtk_widget_get_screen (widget));
7842
7843       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
7844
7845       g_signal_connect (window, "destroy",
7846                         G_CALLBACK (gtk_widget_destroyed),
7847                         &window);
7848
7849       gtk_window_set_title (GTK_WINDOW (window), "rulers");
7850       gtk_widget_set_size_request (window, 300, 300);
7851       gtk_widget_set_events (window, 
7852                              GDK_POINTER_MOTION_MASK 
7853                              | GDK_POINTER_MOTION_HINT_MASK);
7854       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7855
7856       table = gtk_table_new (2, 2, FALSE);
7857       gtk_container_add (GTK_CONTAINER (window), table);
7858       gtk_widget_show (table);
7859
7860       ruler = gtk_hruler_new ();
7861       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
7862       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
7863
7864       g_signal_connect_swapped (window, 
7865                                 "motion_notify_event",
7866                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7867                                 ruler);
7868       
7869       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
7870                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
7871       gtk_widget_show (ruler);
7872
7873
7874       ruler = gtk_vruler_new ();
7875       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
7876
7877       g_signal_connect_swapped (window, 
7878                                 "motion_notify_event",
7879                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7880                                 ruler);
7881       
7882       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
7883                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
7884       gtk_widget_show (ruler);
7885     }
7886
7887   if (!GTK_WIDGET_VISIBLE (window))
7888     gtk_widget_show (window);
7889   else
7890     gtk_widget_destroy (window);
7891 }
7892
7893 static void
7894 text_toggle_editable (GtkWidget *checkbutton,
7895                        GtkWidget *text)
7896 {
7897    gtk_text_set_editable(GTK_TEXT(text),
7898                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7899 }
7900
7901 static void
7902 text_toggle_word_wrap (GtkWidget *checkbutton,
7903                        GtkWidget *text)
7904 {
7905    gtk_text_set_word_wrap(GTK_TEXT(text),
7906                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7907 }
7908
7909 struct {
7910   GdkColor color;
7911   gchar *name;
7912 } text_colors[] = {
7913  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
7914  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
7915  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
7916  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
7917  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
7918  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
7919  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
7920  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
7921 };
7922
7923 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
7924
7925 /*
7926  * GtkText
7927  */
7928 void
7929 text_insert_random (GtkWidget *w, GtkText *text)
7930 {
7931   int i;
7932   char c;
7933    for (i=0; i<10; i++)
7934     {
7935       c = 'A' + rand() % ('Z' - 'A');
7936       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
7937       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
7938     }
7939 }
7940
7941 void
7942 create_text (GtkWidget *widget)
7943 {
7944   int i, j;
7945
7946   static GtkWidget *window = NULL;
7947   GtkWidget *box1;
7948   GtkWidget *box2;
7949   GtkWidget *hbox;
7950   GtkWidget *button;
7951   GtkWidget *check;
7952   GtkWidget *separator;
7953   GtkWidget *scrolled_window;
7954   GtkWidget *text;
7955
7956   FILE *infile;
7957
7958   if (!window)
7959     {
7960       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7961       gtk_window_set_screen (GTK_WINDOW (window),
7962                              gtk_widget_get_screen (widget));
7963
7964       gtk_widget_set_name (window, "text window");
7965       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
7966       gtk_widget_set_size_request (window, 500, 500);
7967
7968       g_signal_connect (window, "destroy",
7969                         G_CALLBACK (gtk_widget_destroyed),
7970                         &window);
7971
7972       gtk_window_set_title (GTK_WINDOW (window), "test");
7973       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7974
7975
7976       box1 = gtk_vbox_new (FALSE, 0);
7977       gtk_container_add (GTK_CONTAINER (window), box1);
7978       gtk_widget_show (box1);
7979
7980
7981       box2 = gtk_vbox_new (FALSE, 10);
7982       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7983       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7984       gtk_widget_show (box2);
7985
7986
7987       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
7988       gtk_box_pack_start (GTK_BOX (box2), scrolled_window, TRUE, TRUE, 0);
7989       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
7990                                       GTK_POLICY_NEVER,
7991                                       GTK_POLICY_ALWAYS);
7992       gtk_widget_show (scrolled_window);
7993
7994       text = gtk_text_new (NULL, NULL);
7995       gtk_text_set_editable (GTK_TEXT (text), TRUE);
7996       gtk_container_add (GTK_CONTAINER (scrolled_window), text);
7997       gtk_widget_grab_focus (text);
7998       gtk_widget_show (text);
7999
8000
8001       gtk_text_freeze (GTK_TEXT (text));
8002
8003       for (i=0; i<ntext_colors; i++)
8004         {
8005           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, 
8006                            text_colors[i].name, -1);
8007           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\t", -1);
8008
8009           for (j=0; j<ntext_colors; j++)
8010             {
8011               gtk_text_insert (GTK_TEXT (text), NULL,
8012                                &text_colors[j].color, &text_colors[i].color,
8013                                "XYZ", -1);
8014             }
8015           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
8016         }
8017
8018       infile = fopen("testgtk.c", "r");
8019       
8020       if (infile)
8021         {
8022           char *buffer;
8023           int nbytes_read, nbytes_alloc;
8024           
8025           nbytes_read = 0;
8026           nbytes_alloc = 1024;
8027           buffer = g_new (char, nbytes_alloc);
8028           while (1)
8029             {
8030               int len;
8031               if (nbytes_alloc < nbytes_read + 1024)
8032                 {
8033                   nbytes_alloc *= 2;
8034                   buffer = g_realloc (buffer, nbytes_alloc);
8035                 }
8036               len = fread (buffer + nbytes_read, 1, 1024, infile);
8037               nbytes_read += len;
8038               if (len < 1024)
8039                 break;
8040             }
8041           
8042           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
8043                            NULL, buffer, nbytes_read);
8044           g_free(buffer);
8045           fclose (infile);
8046         }
8047       
8048       gtk_text_thaw (GTK_TEXT (text));
8049
8050       hbox = gtk_hbutton_box_new ();
8051       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
8052       gtk_widget_show (hbox);
8053
8054       check = gtk_check_button_new_with_label("Editable");
8055       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
8056       g_signal_connect (check, "toggled",
8057                         G_CALLBACK (text_toggle_editable), text);
8058       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
8059       gtk_widget_show (check);
8060
8061       check = gtk_check_button_new_with_label("Wrap Words");
8062       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
8063       g_signal_connect (check, "toggled",
8064                         G_CALLBACK (text_toggle_word_wrap), text);
8065       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
8066       gtk_widget_show (check);
8067
8068       separator = gtk_hseparator_new ();
8069       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
8070       gtk_widget_show (separator);
8071
8072
8073       box2 = gtk_vbox_new (FALSE, 10);
8074       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8075       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8076       gtk_widget_show (box2);
8077
8078
8079       button = gtk_button_new_with_label ("insert random");
8080       g_signal_connect (button, "clicked",
8081                         G_CALLBACK (text_insert_random),
8082                         text);
8083       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8084       gtk_widget_show (button);
8085
8086       button = gtk_button_new_with_label ("close");
8087       g_signal_connect_swapped (button, "clicked",
8088                                 G_CALLBACK (gtk_widget_destroy),
8089                                 window);
8090       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8091       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8092       gtk_widget_grab_default (button);
8093       gtk_widget_show (button);
8094     }
8095
8096   if (!GTK_WIDGET_VISIBLE (window))
8097     gtk_widget_show (window);
8098   else
8099     gtk_widget_destroy (window);
8100 }
8101
8102 /*
8103  * GtkNotebook
8104  */
8105
8106 GdkPixbuf *book_open;
8107 GdkPixbuf *book_closed;
8108 GtkWidget *sample_notebook;
8109
8110 static void
8111 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
8112 {
8113   GtkWidget *page_widget;
8114   GtkWidget *pixwid;
8115
8116   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
8117
8118   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
8119   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
8120   
8121   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
8122   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
8123 }
8124
8125 static void
8126 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
8127 {
8128   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
8129   gint old_page_num = gtk_notebook_get_current_page (notebook);
8130  
8131   if (page_num == old_page_num)
8132     return;
8133
8134   set_page_image (notebook, page_num, book_open);
8135
8136   if (old_page_num != -1)
8137     set_page_image (notebook, old_page_num, book_closed);
8138 }
8139
8140 static void
8141 tab_fill (GtkToggleButton *button, GtkWidget *child)
8142 {
8143   gboolean expand;
8144   GtkPackType pack_type;
8145
8146   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8147                                         &expand, NULL, &pack_type);
8148   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8149                                       expand, button->active, pack_type);
8150 }
8151
8152 static void
8153 tab_expand (GtkToggleButton *button, GtkWidget *child)
8154 {
8155   gboolean fill;
8156   GtkPackType pack_type;
8157
8158   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8159                                         NULL, &fill, &pack_type);
8160   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8161                                       button->active, fill, pack_type);
8162 }
8163
8164 static void
8165 tab_pack (GtkToggleButton *button, GtkWidget *child)
8166           
8167
8168   gboolean expand;
8169   gboolean fill;
8170
8171   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8172                                         &expand, &fill, NULL);
8173   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8174                                       expand, fill, button->active);
8175 }
8176
8177 static void
8178 create_pages (GtkNotebook *notebook, gint start, gint end)
8179 {
8180   GtkWidget *child = NULL;
8181   GtkWidget *button;
8182   GtkWidget *label;
8183   GtkWidget *hbox;
8184   GtkWidget *vbox;
8185   GtkWidget *label_box;
8186   GtkWidget *menu_box;
8187   GtkWidget *pixwid;
8188   gint i;
8189   char buffer[32];
8190   char accel_buffer[32];
8191
8192   for (i = start; i <= end; i++)
8193     {
8194       sprintf (buffer, "Page %d", i);
8195       sprintf (accel_buffer, "Page _%d", i);
8196
8197       child = gtk_frame_new (buffer);
8198       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
8199
8200       vbox = gtk_vbox_new (TRUE,0);
8201       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8202       gtk_container_add (GTK_CONTAINER (child), vbox);
8203
8204       hbox = gtk_hbox_new (TRUE,0);
8205       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
8206
8207       button = gtk_check_button_new_with_label ("Fill Tab");
8208       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8209       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8210       g_signal_connect (button, "toggled",
8211                         G_CALLBACK (tab_fill), child);
8212
8213       button = gtk_check_button_new_with_label ("Expand Tab");
8214       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8215       g_signal_connect (button, "toggled",
8216                         G_CALLBACK (tab_expand), child);
8217
8218       button = gtk_check_button_new_with_label ("Pack end");
8219       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8220       g_signal_connect (button, "toggled",
8221                         G_CALLBACK (tab_pack), child);
8222
8223       button = gtk_button_new_with_label ("Hide Page");
8224       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
8225       g_signal_connect_swapped (button, "clicked",
8226                                 G_CALLBACK (gtk_widget_hide),
8227                                 child);
8228
8229       gtk_widget_show_all (child);
8230
8231       label_box = gtk_hbox_new (FALSE, 0);
8232       pixwid = gtk_image_new_from_pixbuf (book_closed);
8233       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
8234                            
8235       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
8236       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8237       label = gtk_label_new_with_mnemonic (accel_buffer);
8238       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
8239       gtk_widget_show_all (label_box);
8240       
8241                                        
8242       menu_box = gtk_hbox_new (FALSE, 0);
8243       pixwid = gtk_image_new_from_pixbuf (book_closed);
8244       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
8245       
8246       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
8247       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8248       label = gtk_label_new (buffer);
8249       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
8250       gtk_widget_show_all (menu_box);
8251
8252       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
8253     }
8254 }
8255
8256 static void
8257 rotate_notebook (GtkButton   *button,
8258                  GtkNotebook *notebook)
8259 {
8260   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
8261 }
8262
8263 static void
8264 show_all_pages (GtkButton   *button,
8265                 GtkNotebook *notebook)
8266 {  
8267   gtk_container_foreach (GTK_CONTAINER (notebook),
8268                          (GtkCallback) gtk_widget_show, NULL);
8269 }
8270
8271 static void
8272 notebook_type_changed (GtkWidget *optionmenu,
8273                        gpointer   data)
8274 {
8275   GtkNotebook *notebook;
8276   gint i, c;
8277
8278   enum {
8279     STANDARD,
8280     NOTABS,
8281     BORDERLESS,
8282     SCROLLABLE
8283   };
8284
8285   notebook = GTK_NOTEBOOK (data);
8286
8287   c = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu));
8288
8289   switch (c)
8290     {
8291     case STANDARD:
8292       /* standard notebook */
8293       gtk_notebook_set_show_tabs (notebook, TRUE);
8294       gtk_notebook_set_show_border (notebook, TRUE);
8295       gtk_notebook_set_scrollable (notebook, FALSE);
8296       break;
8297
8298     case NOTABS:
8299       /* notabs notebook */
8300       gtk_notebook_set_show_tabs (notebook, FALSE);
8301       gtk_notebook_set_show_border (notebook, TRUE);
8302       break;
8303
8304     case BORDERLESS:
8305       /* borderless */
8306       gtk_notebook_set_show_tabs (notebook, FALSE);
8307       gtk_notebook_set_show_border (notebook, FALSE);
8308       break;
8309
8310     case SCROLLABLE:  
8311       /* scrollable */
8312       gtk_notebook_set_show_tabs (notebook, TRUE);
8313       gtk_notebook_set_show_border (notebook, TRUE);
8314       gtk_notebook_set_scrollable (notebook, TRUE);
8315       if (g_list_length (notebook->children) == 5)
8316         create_pages (notebook, 6, 15);
8317       
8318       return;
8319       break;
8320     }
8321   
8322   if (g_list_length (notebook->children) == 15)
8323     for (i = 0; i < 10; i++)
8324       gtk_notebook_remove_page (notebook, 5);
8325 }
8326
8327 static void
8328 notebook_popup (GtkToggleButton *button,
8329                 GtkNotebook     *notebook)
8330 {
8331   if (button->active)
8332     gtk_notebook_popup_enable (notebook);
8333   else
8334     gtk_notebook_popup_disable (notebook);
8335 }
8336
8337 static void
8338 notebook_homogeneous (GtkToggleButton *button,
8339                       GtkNotebook     *notebook)
8340 {
8341   g_object_set (G_OBJECT (notebook), "homogeneous", button->active, NULL);
8342 }
8343
8344 static void
8345 create_notebook (GtkWidget *widget)
8346 {
8347   static GtkWidget *window = NULL;
8348   GtkWidget *box1;
8349   GtkWidget *box2;
8350   GtkWidget *button;
8351   GtkWidget *separator;
8352   GtkWidget *omenu;
8353   GtkWidget *label;
8354
8355   static gchar *items[] =
8356   {
8357     "Standard",
8358     "No tabs",
8359     "Borderless",
8360     "Scrollable"
8361   };
8362   
8363   if (!window)
8364     {
8365       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8366       gtk_window_set_screen (GTK_WINDOW (window),
8367                              gtk_widget_get_screen (widget));
8368
8369       g_signal_connect (window, "destroy",
8370                         G_CALLBACK (gtk_widget_destroyed),
8371                         &window);
8372
8373       gtk_window_set_title (GTK_WINDOW (window), "notebook");
8374       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8375
8376       box1 = gtk_vbox_new (FALSE, 0);
8377       gtk_container_add (GTK_CONTAINER (window), box1);
8378
8379       sample_notebook = gtk_notebook_new ();
8380       g_signal_connect (sample_notebook, "switch_page",
8381                         G_CALLBACK (page_switch), NULL);
8382       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
8383       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
8384       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
8385
8386       gtk_widget_realize (sample_notebook);
8387
8388       if (!book_open)
8389         book_open = gdk_pixbuf_new_from_xpm_data ((const char **)book_open_xpm);
8390                                                   
8391       if (!book_closed)
8392         book_closed = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
8393
8394       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
8395
8396       separator = gtk_hseparator_new ();
8397       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
8398       
8399       box2 = gtk_hbox_new (FALSE, 5);
8400       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8401       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8402
8403       button = gtk_check_button_new_with_label ("popup menu");
8404       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8405       g_signal_connect (button, "clicked",
8406                         G_CALLBACK (notebook_popup),
8407                         sample_notebook);
8408
8409       button = gtk_check_button_new_with_label ("homogeneous tabs");
8410       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8411       g_signal_connect (button, "clicked",
8412                         G_CALLBACK (notebook_homogeneous),
8413                         sample_notebook);
8414
8415       box2 = gtk_hbox_new (FALSE, 5);
8416       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8417       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8418
8419       label = gtk_label_new ("Notebook Style :");
8420       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
8421
8422       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
8423                                  notebook_type_changed,
8424                                  sample_notebook);
8425       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
8426
8427       button = gtk_button_new_with_label ("Show all Pages");
8428       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
8429       g_signal_connect (button, "clicked",
8430                         G_CALLBACK (show_all_pages), sample_notebook);
8431
8432       box2 = gtk_hbox_new (TRUE, 10);
8433       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8434       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8435
8436       button = gtk_button_new_with_label ("prev");
8437       g_signal_connect_swapped (button, "clicked",
8438                                 G_CALLBACK (gtk_notebook_prev_page),
8439                                 sample_notebook);
8440       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8441
8442       button = gtk_button_new_with_label ("next");
8443       g_signal_connect_swapped (button, "clicked",
8444                                 G_CALLBACK (gtk_notebook_next_page),
8445                                 sample_notebook);
8446       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8447
8448       button = gtk_button_new_with_label ("rotate");
8449       g_signal_connect (button, "clicked",
8450                         G_CALLBACK (rotate_notebook), sample_notebook);
8451       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8452
8453       separator = gtk_hseparator_new ();
8454       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
8455
8456       button = gtk_button_new_with_label ("close");
8457       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
8458       g_signal_connect_swapped (button, "clicked",
8459                                 G_CALLBACK (gtk_widget_destroy),
8460                                 window);
8461       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
8462       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8463       gtk_widget_grab_default (button);
8464     }
8465
8466   if (!GTK_WIDGET_VISIBLE (window))
8467     gtk_widget_show_all (window);
8468   else
8469     gtk_widget_destroy (window);
8470 }
8471
8472 /*
8473  * GtkPanes
8474  */
8475
8476 void
8477 toggle_resize (GtkWidget *widget, GtkWidget *child)
8478 {
8479   GtkPaned *paned = GTK_PANED (child->parent);
8480   gboolean is_child1 = (child == paned->child1);
8481   gboolean resize, shrink;
8482
8483   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8484   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8485
8486   gtk_widget_ref (child);
8487   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8488   if (is_child1)
8489     gtk_paned_pack1 (paned, child, !resize, shrink);
8490   else
8491     gtk_paned_pack2 (paned, child, !resize, shrink);
8492   gtk_widget_unref (child);
8493 }
8494
8495 void
8496 toggle_shrink (GtkWidget *widget, GtkWidget *child)
8497 {
8498   GtkPaned *paned = GTK_PANED (child->parent);
8499   gboolean is_child1 = (child == paned->child1);
8500   gboolean resize, shrink;
8501
8502   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8503   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8504
8505   gtk_widget_ref (child);
8506   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8507   if (is_child1)
8508     gtk_paned_pack1 (paned, child, resize, !shrink);
8509   else
8510     gtk_paned_pack2 (paned, child, resize, !shrink);
8511   gtk_widget_unref (child);
8512 }
8513
8514 static void
8515 paned_props_clicked (GtkWidget *button,
8516                      GObject   *paned)
8517 {
8518   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
8519   
8520   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
8521 }
8522
8523 GtkWidget *
8524 create_pane_options (GtkPaned    *paned,
8525                      const gchar *frame_label,
8526                      const gchar *label1,
8527                      const gchar *label2)
8528 {
8529   GtkWidget *frame;
8530   GtkWidget *table;
8531   GtkWidget *label;
8532   GtkWidget *button;
8533   GtkWidget *check_button;
8534   
8535   frame = gtk_frame_new (frame_label);
8536   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
8537   
8538   table = gtk_table_new (4, 2, 4);
8539   gtk_container_add (GTK_CONTAINER (frame), table);
8540   
8541   label = gtk_label_new (label1);
8542   gtk_table_attach_defaults (GTK_TABLE (table), label,
8543                              0, 1, 0, 1);
8544   
8545   check_button = gtk_check_button_new_with_label ("Resize");
8546   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8547                              0, 1, 1, 2);
8548   g_signal_connect (check_button, "toggled",
8549                     G_CALLBACK (toggle_resize),
8550                     paned->child1);
8551   
8552   check_button = gtk_check_button_new_with_label ("Shrink");
8553   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8554                              0, 1, 2, 3);
8555   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8556                                TRUE);
8557   g_signal_connect (check_button, "toggled",
8558                     G_CALLBACK (toggle_shrink),
8559                     paned->child1);
8560   
8561   label = gtk_label_new (label2);
8562   gtk_table_attach_defaults (GTK_TABLE (table), label,
8563                              1, 2, 0, 1);
8564   
8565   check_button = gtk_check_button_new_with_label ("Resize");
8566   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8567                              1, 2, 1, 2);
8568   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8569                                TRUE);
8570   g_signal_connect (check_button, "toggled",
8571                     G_CALLBACK (toggle_resize),
8572                     paned->child2);
8573   
8574   check_button = gtk_check_button_new_with_label ("Shrink");
8575   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8576                              1, 2, 2, 3);
8577   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8578                                TRUE);
8579   g_signal_connect (check_button, "toggled",
8580                     G_CALLBACK (toggle_shrink),
8581                     paned->child2);
8582
8583   button = gtk_button_new_with_mnemonic ("_Properties");
8584   gtk_table_attach_defaults (GTK_TABLE (table), button,
8585                              0, 2, 3, 4);
8586   g_signal_connect (button, "clicked",
8587                     G_CALLBACK (paned_props_clicked),
8588                     paned);
8589
8590   return frame;
8591 }
8592
8593 void
8594 create_panes (GtkWidget *widget)
8595 {
8596   static GtkWidget *window = NULL;
8597   GtkWidget *frame;
8598   GtkWidget *hpaned;
8599   GtkWidget *vpaned;
8600   GtkWidget *button;
8601   GtkWidget *vbox;
8602
8603   if (!window)
8604     {
8605       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8606
8607       gtk_window_set_screen (GTK_WINDOW (window),
8608                              gtk_widget_get_screen (widget));
8609       
8610       g_signal_connect (window, "destroy",
8611                         G_CALLBACK (gtk_widget_destroyed),
8612                         &window);
8613
8614       gtk_window_set_title (GTK_WINDOW (window), "Panes");
8615       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8616
8617       vbox = gtk_vbox_new (FALSE, 0);
8618       gtk_container_add (GTK_CONTAINER (window), vbox);
8619       
8620       vpaned = gtk_vpaned_new ();
8621       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
8622       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
8623
8624       hpaned = gtk_hpaned_new ();
8625       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
8626
8627       frame = gtk_frame_new (NULL);
8628       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8629       gtk_widget_set_size_request (frame, 60, 60);
8630       gtk_paned_add1 (GTK_PANED (hpaned), frame);
8631       
8632       button = gtk_button_new_with_label ("Hi there");
8633       gtk_container_add (GTK_CONTAINER(frame), button);
8634
8635       frame = gtk_frame_new (NULL);
8636       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8637       gtk_widget_set_size_request (frame, 80, 60);
8638       gtk_paned_add2 (GTK_PANED (hpaned), frame);
8639
8640       frame = gtk_frame_new (NULL);
8641       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8642       gtk_widget_set_size_request (frame, 60, 80);
8643       gtk_paned_add2 (GTK_PANED (vpaned), frame);
8644
8645       /* Now create toggle buttons to control sizing */
8646
8647       gtk_box_pack_start (GTK_BOX (vbox),
8648                           create_pane_options (GTK_PANED (hpaned),
8649                                                "Horizontal",
8650                                                "Left",
8651                                                "Right"),
8652                           FALSE, FALSE, 0);
8653
8654       gtk_box_pack_start (GTK_BOX (vbox),
8655                           create_pane_options (GTK_PANED (vpaned),
8656                                                "Vertical",
8657                                                "Top",
8658                                                "Bottom"),
8659                           FALSE, FALSE, 0);
8660
8661       gtk_widget_show_all (vbox);
8662     }
8663
8664   if (!GTK_WIDGET_VISIBLE (window))
8665     gtk_widget_show (window);
8666   else
8667     gtk_widget_destroy (window);
8668 }
8669
8670 /*
8671  * Paned keyboard navigation
8672  */
8673
8674 static GtkWidget*
8675 paned_keyboard_window1 (GtkWidget *widget)
8676 {
8677   GtkWidget *window1;
8678   GtkWidget *hpaned1;
8679   GtkWidget *frame1;
8680   GtkWidget *vbox1;
8681   GtkWidget *button7;
8682   GtkWidget *button8;
8683   GtkWidget *button9;
8684   GtkWidget *vpaned1;
8685   GtkWidget *frame2;
8686   GtkWidget *frame5;
8687   GtkWidget *hbox1;
8688   GtkWidget *button5;
8689   GtkWidget *button6;
8690   GtkWidget *frame3;
8691   GtkWidget *frame4;
8692   GtkWidget *table1;
8693   GtkWidget *button1;
8694   GtkWidget *button2;
8695   GtkWidget *button3;
8696   GtkWidget *button4;
8697
8698   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8699   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
8700   gtk_window_set_screen (GTK_WINDOW (window1), 
8701                          gtk_widget_get_screen (widget));
8702
8703   hpaned1 = gtk_hpaned_new ();
8704   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
8705
8706   frame1 = gtk_frame_new (NULL);
8707   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
8708   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
8709
8710   vbox1 = gtk_vbox_new (FALSE, 0);
8711   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
8712
8713   button7 = gtk_button_new_with_label ("button7");
8714   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
8715
8716   button8 = gtk_button_new_with_label ("button8");
8717   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
8718
8719   button9 = gtk_button_new_with_label ("button9");
8720   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
8721
8722   vpaned1 = gtk_vpaned_new ();
8723   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
8724
8725   frame2 = gtk_frame_new (NULL);
8726   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
8727   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
8728
8729   frame5 = gtk_frame_new (NULL);
8730   gtk_container_add (GTK_CONTAINER (frame2), frame5);
8731
8732   hbox1 = gtk_hbox_new (FALSE, 0);
8733   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
8734
8735   button5 = gtk_button_new_with_label ("button5");
8736   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
8737
8738   button6 = gtk_button_new_with_label ("button6");
8739   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
8740
8741   frame3 = gtk_frame_new (NULL);
8742   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
8743   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
8744
8745   frame4 = gtk_frame_new ("Buttons");
8746   gtk_container_add (GTK_CONTAINER (frame3), frame4);
8747   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
8748
8749   table1 = gtk_table_new (2, 2, FALSE);
8750   gtk_container_add (GTK_CONTAINER (frame4), table1);
8751   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
8752
8753   button1 = gtk_button_new_with_label ("button1");
8754   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
8755                     (GtkAttachOptions) (GTK_FILL),
8756                     (GtkAttachOptions) (0), 0, 0);
8757
8758   button2 = gtk_button_new_with_label ("button2");
8759   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
8760                     (GtkAttachOptions) (GTK_FILL),
8761                     (GtkAttachOptions) (0), 0, 0);
8762
8763   button3 = gtk_button_new_with_label ("button3");
8764   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
8765                     (GtkAttachOptions) (GTK_FILL),
8766                     (GtkAttachOptions) (0), 0, 0);
8767
8768   button4 = gtk_button_new_with_label ("button4");
8769   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
8770                     (GtkAttachOptions) (GTK_FILL),
8771                     (GtkAttachOptions) (0), 0, 0);
8772
8773   return window1;
8774 }
8775
8776 static GtkWidget*
8777 paned_keyboard_window2 (GtkWidget *widget)
8778 {
8779   GtkWidget *window2;
8780   GtkWidget *hpaned2;
8781   GtkWidget *frame6;
8782   GtkWidget *button13;
8783   GtkWidget *hbox2;
8784   GtkWidget *vpaned2;
8785   GtkWidget *frame7;
8786   GtkWidget *button12;
8787   GtkWidget *frame8;
8788   GtkWidget *button11;
8789   GtkWidget *button10;
8790
8791   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8792   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
8793
8794   gtk_window_set_screen (GTK_WINDOW (window2), 
8795                          gtk_widget_get_screen (widget));
8796
8797   hpaned2 = gtk_hpaned_new ();
8798   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
8799
8800   frame6 = gtk_frame_new (NULL);
8801   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
8802   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
8803
8804   button13 = gtk_button_new_with_label ("button13");
8805   gtk_container_add (GTK_CONTAINER (frame6), button13);
8806
8807   hbox2 = gtk_hbox_new (FALSE, 0);
8808   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
8809
8810   vpaned2 = gtk_vpaned_new ();
8811   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
8812
8813   frame7 = gtk_frame_new (NULL);
8814   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
8815   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
8816
8817   button12 = gtk_button_new_with_label ("button12");
8818   gtk_container_add (GTK_CONTAINER (frame7), button12);
8819
8820   frame8 = gtk_frame_new (NULL);
8821   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
8822   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
8823
8824   button11 = gtk_button_new_with_label ("button11");
8825   gtk_container_add (GTK_CONTAINER (frame8), button11);
8826
8827   button10 = gtk_button_new_with_label ("button10");
8828   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
8829
8830   return window2;
8831 }
8832
8833 static GtkWidget*
8834 paned_keyboard_window3 (GtkWidget *widget)
8835 {
8836   GtkWidget *window3;
8837   GtkWidget *vbox2;
8838   GtkWidget *label1;
8839   GtkWidget *hpaned3;
8840   GtkWidget *frame9;
8841   GtkWidget *button14;
8842   GtkWidget *hpaned4;
8843   GtkWidget *frame10;
8844   GtkWidget *button15;
8845   GtkWidget *hpaned5;
8846   GtkWidget *frame11;
8847   GtkWidget *button16;
8848   GtkWidget *frame12;
8849   GtkWidget *button17;
8850
8851   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8852   g_object_set_data (G_OBJECT (window3), "window3", window3);
8853   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
8854
8855   gtk_window_set_screen (GTK_WINDOW (window3), 
8856                          gtk_widget_get_screen (widget));
8857   
8858
8859   vbox2 = gtk_vbox_new (FALSE, 0);
8860   gtk_container_add (GTK_CONTAINER (window3), vbox2);
8861
8862   label1 = gtk_label_new ("Three panes nested inside each other");
8863   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
8864
8865   hpaned3 = gtk_hpaned_new ();
8866   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
8867
8868   frame9 = gtk_frame_new (NULL);
8869   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
8870   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
8871
8872   button14 = gtk_button_new_with_label ("button14");
8873   gtk_container_add (GTK_CONTAINER (frame9), button14);
8874
8875   hpaned4 = gtk_hpaned_new ();
8876   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
8877
8878   frame10 = gtk_frame_new (NULL);
8879   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
8880   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
8881
8882   button15 = gtk_button_new_with_label ("button15");
8883   gtk_container_add (GTK_CONTAINER (frame10), button15);
8884
8885   hpaned5 = gtk_hpaned_new ();
8886   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
8887
8888   frame11 = gtk_frame_new (NULL);
8889   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
8890   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
8891
8892   button16 = gtk_button_new_with_label ("button16");
8893   gtk_container_add (GTK_CONTAINER (frame11), button16);
8894
8895   frame12 = gtk_frame_new (NULL);
8896   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
8897   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
8898
8899   button17 = gtk_button_new_with_label ("button17");
8900   gtk_container_add (GTK_CONTAINER (frame12), button17);
8901
8902   return window3;
8903 }
8904
8905 static GtkWidget*
8906 paned_keyboard_window4 (GtkWidget *widget)
8907 {
8908   GtkWidget *window4;
8909   GtkWidget *vbox3;
8910   GtkWidget *label2;
8911   GtkWidget *hpaned6;
8912   GtkWidget *vpaned3;
8913   GtkWidget *button19;
8914   GtkWidget *button18;
8915   GtkWidget *hbox3;
8916   GtkWidget *vpaned4;
8917   GtkWidget *button21;
8918   GtkWidget *button20;
8919   GtkWidget *vpaned5;
8920   GtkWidget *button23;
8921   GtkWidget *button22;
8922   GtkWidget *vpaned6;
8923   GtkWidget *button25;
8924   GtkWidget *button24;
8925
8926   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8927   g_object_set_data (G_OBJECT (window4), "window4", window4);
8928   gtk_window_set_title (GTK_WINDOW (window4), "window4");
8929
8930   gtk_window_set_screen (GTK_WINDOW (window4), 
8931                          gtk_widget_get_screen (widget));
8932
8933   vbox3 = gtk_vbox_new (FALSE, 0);
8934   gtk_container_add (GTK_CONTAINER (window4), vbox3);
8935
8936   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
8937   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
8938   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
8939
8940   hpaned6 = gtk_hpaned_new ();
8941   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
8942
8943   vpaned3 = gtk_vpaned_new ();
8944   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
8945
8946   button19 = gtk_button_new_with_label ("button19");
8947   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
8948
8949   button18 = gtk_button_new_with_label ("button18");
8950   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
8951
8952   hbox3 = gtk_hbox_new (FALSE, 0);
8953   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
8954
8955   vpaned4 = gtk_vpaned_new ();
8956   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
8957
8958   button21 = gtk_button_new_with_label ("button21");
8959   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
8960
8961   button20 = gtk_button_new_with_label ("button20");
8962   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
8963
8964   vpaned5 = gtk_vpaned_new ();
8965   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
8966
8967   button23 = gtk_button_new_with_label ("button23");
8968   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
8969
8970   button22 = gtk_button_new_with_label ("button22");
8971   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
8972
8973   vpaned6 = gtk_vpaned_new ();
8974   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
8975
8976   button25 = gtk_button_new_with_label ("button25");
8977   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
8978
8979   button24 = gtk_button_new_with_label ("button24");
8980   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
8981
8982   return window4;
8983 }
8984
8985 static void
8986 create_paned_keyboard_navigation (GtkWidget *widget)
8987 {
8988   static GtkWidget *window1 = NULL;
8989   static GtkWidget *window2 = NULL;
8990   static GtkWidget *window3 = NULL;
8991   static GtkWidget *window4 = NULL;
8992
8993   if (window1 && 
8994      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
8995     {
8996       gtk_widget_destroy (window1);
8997       gtk_widget_destroy (window2);
8998       gtk_widget_destroy (window3);
8999       gtk_widget_destroy (window4);
9000     }
9001   
9002   if (!window1)
9003     {
9004       window1 = paned_keyboard_window1 (widget);
9005       g_signal_connect (window1, "destroy",
9006                         G_CALLBACK (gtk_widget_destroyed),
9007                         &window1);
9008     }
9009
9010   if (!window2)
9011     {
9012       window2 = paned_keyboard_window2 (widget);
9013       g_signal_connect (window2, "destroy",
9014                         G_CALLBACK (gtk_widget_destroyed),
9015                         &window2);
9016     }
9017
9018   if (!window3)
9019     {
9020       window3 = paned_keyboard_window3 (widget);
9021       g_signal_connect (window3, "destroy",
9022                         G_CALLBACK (gtk_widget_destroyed),
9023                         &window3);
9024     }
9025
9026   if (!window4)
9027     {
9028       window4 = paned_keyboard_window4 (widget);
9029       g_signal_connect (window4, "destroy",
9030                         G_CALLBACK (gtk_widget_destroyed),
9031                         &window4);
9032     }
9033
9034   if (GTK_WIDGET_VISIBLE (window1))
9035     gtk_widget_destroy (GTK_WIDGET (window1));
9036   else
9037     gtk_widget_show_all (GTK_WIDGET (window1));
9038
9039   if (GTK_WIDGET_VISIBLE (window2))
9040     gtk_widget_destroy (GTK_WIDGET (window2));
9041   else
9042     gtk_widget_show_all (GTK_WIDGET (window2));
9043
9044   if (GTK_WIDGET_VISIBLE (window3))
9045     gtk_widget_destroy (GTK_WIDGET (window3));
9046   else
9047     gtk_widget_show_all (GTK_WIDGET (window3));
9048
9049   if (GTK_WIDGET_VISIBLE (window4))
9050     gtk_widget_destroy (GTK_WIDGET (window4));
9051   else
9052     gtk_widget_show_all (GTK_WIDGET (window4));
9053 }
9054
9055
9056 /*
9057  * Shaped Windows
9058  */
9059
9060 typedef struct _cursoroffset {gint x,y;} CursorOffset;
9061
9062 static void
9063 shape_pressed (GtkWidget *widget, GdkEventButton *event)
9064 {
9065   CursorOffset *p;
9066
9067   /* ignore double and triple click */
9068   if (event->type != GDK_BUTTON_PRESS)
9069     return;
9070
9071   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
9072   p->x = (int) event->x;
9073   p->y = (int) event->y;
9074
9075   gtk_grab_add (widget);
9076   gdk_pointer_grab (widget->window, TRUE,
9077                     GDK_BUTTON_RELEASE_MASK |
9078                     GDK_BUTTON_MOTION_MASK |
9079                     GDK_POINTER_MOTION_HINT_MASK,
9080                     NULL, NULL, 0);
9081 }
9082
9083 static void
9084 shape_released (GtkWidget *widget)
9085 {
9086   gtk_grab_remove (widget);
9087   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
9088                               GDK_CURRENT_TIME);
9089 }
9090
9091 static void
9092 shape_motion (GtkWidget      *widget, 
9093               GdkEventMotion *event)
9094 {
9095   gint xp, yp;
9096   CursorOffset * p;
9097   GdkModifierType mask;
9098
9099   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
9100
9101   /*
9102    * Can't use event->x / event->y here 
9103    * because I need absolute coordinates.
9104    */
9105   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
9106   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
9107 }
9108
9109 GtkWidget *
9110 shape_create_icon (GdkScreen *screen,
9111                    char      *xpm_file,
9112                    gint       x,
9113                    gint       y,
9114                    gint       px,
9115                    gint       py,
9116                    gint       window_type)
9117 {
9118   GtkWidget *window;
9119   GtkWidget *pixmap;
9120   GtkWidget *fixed;
9121   CursorOffset* icon_pos;
9122   GdkGC* gc;
9123   GdkBitmap *gdk_pixmap_mask;
9124   GdkPixmap *gdk_pixmap;
9125   GtkStyle *style;
9126
9127   style = gtk_widget_get_default_style ();
9128   gc = style->black_gc; 
9129
9130   /*
9131    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
9132    */
9133   window = gtk_window_new (window_type);
9134   gtk_window_set_screen (GTK_WINDOW (window), screen);
9135   
9136   fixed = gtk_fixed_new ();
9137   gtk_widget_set_size_request (fixed, 100, 100);
9138   gtk_container_add (GTK_CONTAINER (window), fixed);
9139   gtk_widget_show (fixed);
9140   
9141   gtk_widget_set_events (window, 
9142                          gtk_widget_get_events (window) |
9143                          GDK_BUTTON_MOTION_MASK |
9144                          GDK_POINTER_MOTION_HINT_MASK |
9145                          GDK_BUTTON_PRESS_MASK);
9146
9147   gtk_widget_realize (window);
9148   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
9149                                            &style->bg[GTK_STATE_NORMAL],
9150                                            xpm_file);
9151
9152   pixmap = gtk_image_new_from_pixmap (gdk_pixmap, gdk_pixmap_mask);
9153   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
9154   gtk_widget_show (pixmap);
9155   
9156   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px, py);
9157   
9158   g_object_unref (gdk_pixmap_mask);
9159   g_object_unref (gdk_pixmap);
9160
9161   g_signal_connect (window, "button_press_event",
9162                     G_CALLBACK (shape_pressed), NULL);
9163   g_signal_connect (window, "button_release_event",
9164                     G_CALLBACK (shape_released), NULL);
9165   g_signal_connect (window, "motion_notify_event",
9166                     G_CALLBACK (shape_motion), NULL);
9167
9168   icon_pos = g_new (CursorOffset, 1);
9169   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
9170
9171   gtk_widget_set_uposition (window, x, y);
9172   gtk_widget_show (window);
9173   
9174   return window;
9175 }
9176
9177 void 
9178 create_shapes (GtkWidget *widget)
9179 {
9180   /* Variables used by the Drag/Drop and Shape Window demos */
9181   static GtkWidget *modeller = NULL;
9182   static GtkWidget *sheets = NULL;
9183   static GtkWidget *rings = NULL;
9184   static GtkWidget *with_region = NULL;
9185   GdkScreen *screen = gtk_widget_get_screen (widget);
9186   
9187   if (!(file_exists ("Modeller.xpm") &&
9188         file_exists ("FilesQueue.xpm") &&
9189         file_exists ("3DRings.xpm")))
9190     return;
9191   
9192
9193   if (!modeller)
9194     {
9195       modeller = shape_create_icon (screen, "Modeller.xpm",
9196                                     440, 140, 0,0, GTK_WINDOW_POPUP);
9197
9198       g_signal_connect (modeller, "destroy",
9199                         G_CALLBACK (gtk_widget_destroyed),
9200                         &modeller);
9201     }
9202   else
9203     gtk_widget_destroy (modeller);
9204
9205   if (!sheets)
9206     {
9207       sheets = shape_create_icon (screen, "FilesQueue.xpm",
9208                                   580, 170, 0,0, GTK_WINDOW_POPUP);
9209
9210       g_signal_connect (sheets, "destroy",
9211                         G_CALLBACK (gtk_widget_destroyed),
9212                         &sheets);
9213
9214     }
9215   else
9216     gtk_widget_destroy (sheets);
9217
9218   if (!rings)
9219     {
9220       rings = shape_create_icon (screen, "3DRings.xpm",
9221                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9222
9223       g_signal_connect (rings, "destroy",
9224                         G_CALLBACK (gtk_widget_destroyed),
9225                         &rings);
9226     }
9227   else
9228     gtk_widget_destroy (rings);
9229
9230   if (!with_region)
9231     {
9232       GdkRegion *region;
9233       gint x, y;
9234       
9235       with_region = shape_create_icon (screen, "3DRings.xpm",
9236                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9237
9238       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
9239       
9240       g_signal_connect (with_region, "destroy",
9241                         G_CALLBACK (gtk_widget_destroyed),
9242                         &with_region);
9243
9244       /* reset shape from mask to a region */
9245       x = 0;
9246       y = 0;
9247       region = gdk_region_new ();
9248
9249       while (x < 460)
9250         {
9251           while (y < 270)
9252             {
9253               GdkRectangle rect;
9254               rect.x = x;
9255               rect.y = y;
9256               rect.width = 10;
9257               rect.height = 10;
9258
9259               gdk_region_union_with_rect (region, &rect);
9260               
9261               y += 20;
9262             }
9263           y = 0;
9264           x += 20;
9265         }
9266
9267       gdk_window_shape_combine_region (with_region->window,
9268                                        region,
9269                                        0, 0);
9270     }
9271   else
9272     gtk_widget_destroy (with_region);
9273 }
9274
9275 /*
9276  * WM Hints demo
9277  */
9278
9279 void
9280 create_wmhints (GtkWidget *widget)
9281 {
9282   static GtkWidget *window = NULL;
9283   GtkWidget *label;
9284   GtkWidget *separator;
9285   GtkWidget *button;
9286   GtkWidget *box1;
9287   GtkWidget *box2;
9288
9289   GdkBitmap *circles;
9290
9291   if (!window)
9292     {
9293       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9294
9295       gtk_window_set_screen (GTK_WINDOW (window),
9296                              gtk_widget_get_screen (widget));
9297       
9298       g_signal_connect (window, "destroy",
9299                         G_CALLBACK (gtk_widget_destroyed),
9300                         &window);
9301
9302       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
9303       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9304
9305       gtk_widget_realize (window);
9306       
9307       circles = gdk_bitmap_create_from_data (window->window,
9308                                              circles_bits,
9309                                              circles_width,
9310                                              circles_height);
9311       gdk_window_set_icon (window->window, NULL,
9312                            circles, circles);
9313       
9314       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
9315   
9316       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
9317       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
9318       
9319       box1 = gtk_vbox_new (FALSE, 0);
9320       gtk_container_add (GTK_CONTAINER (window), box1);
9321       gtk_widget_show (box1);
9322
9323       label = gtk_label_new ("Try iconizing me!");
9324       gtk_widget_set_size_request (label, 150, 50);
9325       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
9326       gtk_widget_show (label);
9327
9328
9329       separator = gtk_hseparator_new ();
9330       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9331       gtk_widget_show (separator);
9332
9333
9334       box2 = gtk_vbox_new (FALSE, 10);
9335       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9336       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9337       gtk_widget_show (box2);
9338
9339
9340       button = gtk_button_new_with_label ("close");
9341
9342       g_signal_connect_swapped (button, "clicked",
9343                                 G_CALLBACK (gtk_widget_destroy),
9344                                 window);
9345
9346       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9347       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9348       gtk_widget_grab_default (button);
9349       gtk_widget_show (button);
9350     }
9351
9352   if (!GTK_WIDGET_VISIBLE (window))
9353     gtk_widget_show (window);
9354   else
9355     gtk_widget_destroy (window);
9356 }
9357
9358
9359 /*
9360  * Window state tracking
9361  */
9362
9363 static gint
9364 window_state_callback (GtkWidget *widget,
9365                        GdkEventWindowState *event,
9366                        gpointer data)
9367 {
9368   GtkWidget *label = data;
9369   gchar *msg;
9370
9371   msg = g_strconcat (GTK_WINDOW (widget)->title, ": ",
9372                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
9373                      "withdrawn" : "not withdrawn", ", ",
9374                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
9375                      "iconified" : "not iconified", ", ",
9376                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
9377                      "sticky" : "not sticky", ", ",
9378                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
9379                      "maximized" : "not maximized", ", ",
9380                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
9381                      "fullscreen" : "not fullscreen",
9382                      NULL);
9383   
9384   gtk_label_set_text (GTK_LABEL (label), msg);
9385
9386   g_free (msg);
9387
9388   return FALSE;
9389 }
9390
9391 static GtkWidget*
9392 tracking_label (GtkWidget *window)
9393 {
9394   GtkWidget *label;
9395   GtkWidget *hbox;
9396   GtkWidget *button;
9397
9398   hbox = gtk_hbox_new (FALSE, 5);
9399
9400   g_signal_connect_object (hbox,
9401                            "destroy",
9402                            G_CALLBACK (gtk_widget_destroy),
9403                            window,
9404                            G_CONNECT_SWAPPED);
9405   
9406   label = gtk_label_new ("<no window state events received>");
9407   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
9408   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
9409   
9410   g_signal_connect (window,
9411                     "window_state_event",
9412                     G_CALLBACK (window_state_callback),
9413                     label);
9414
9415   button = gtk_button_new_with_label ("Deiconify");
9416   g_signal_connect_object (button,
9417                            "clicked",
9418                            G_CALLBACK (gtk_window_deiconify),
9419                            window,
9420                            G_CONNECT_SWAPPED);
9421   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9422
9423   button = gtk_button_new_with_label ("Iconify");
9424   g_signal_connect_object (button,
9425                            "clicked",
9426                            G_CALLBACK (gtk_window_iconify),
9427                            window,
9428                            G_CONNECT_SWAPPED);
9429   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9430
9431   button = gtk_button_new_with_label ("Fullscreen");
9432   g_signal_connect_object (button,
9433                            "clicked",
9434                            G_CALLBACK (gtk_window_fullscreen),
9435                            window,
9436                            G_CONNECT_SWAPPED);
9437   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9438
9439   button = gtk_button_new_with_label ("Unfullscreen");
9440   g_signal_connect_object (button,
9441                            "clicked",
9442                            G_CALLBACK (gtk_window_unfullscreen),
9443                            window,
9444                            G_CONNECT_SWAPPED);
9445   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9446   
9447   button = gtk_button_new_with_label ("Present");
9448   g_signal_connect_object (button,
9449                            "clicked",
9450                            G_CALLBACK (gtk_window_present),
9451                            window,
9452                            G_CONNECT_SWAPPED);
9453   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9454
9455   button = gtk_button_new_with_label ("Show");
9456   g_signal_connect_object (button,
9457                            "clicked",
9458                            G_CALLBACK (gtk_widget_show),
9459                            window,
9460                            G_CONNECT_SWAPPED);
9461   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9462   
9463   gtk_widget_show_all (hbox);
9464   
9465   return hbox;
9466 }
9467
9468 static GtkWidget*
9469 get_state_controls (GtkWidget *window)
9470 {
9471   GtkWidget *vbox;
9472   GtkWidget *button;
9473
9474   vbox = gtk_vbox_new (FALSE, 0);
9475   
9476   button = gtk_button_new_with_label ("Stick");
9477   g_signal_connect_object (button,
9478                            "clicked",
9479                            G_CALLBACK (gtk_window_stick),
9480                            window,
9481                            G_CONNECT_SWAPPED);
9482   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9483
9484   button = gtk_button_new_with_label ("Unstick");
9485   g_signal_connect_object (button,
9486                            "clicked",
9487                            G_CALLBACK (gtk_window_unstick),
9488                            window,
9489                            G_CONNECT_SWAPPED);
9490   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9491   
9492   button = gtk_button_new_with_label ("Maximize");
9493   g_signal_connect_object (button,
9494                            "clicked",
9495                            G_CALLBACK (gtk_window_maximize),
9496                            window,
9497                            G_CONNECT_SWAPPED);
9498   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9499
9500   button = gtk_button_new_with_label ("Unmaximize");
9501   g_signal_connect_object (button,
9502                            "clicked",
9503                            G_CALLBACK (gtk_window_unmaximize),
9504                            window,
9505                            G_CONNECT_SWAPPED);
9506   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9507
9508   button = gtk_button_new_with_label ("Iconify");
9509   g_signal_connect_object (button,
9510                            "clicked",
9511                            G_CALLBACK (gtk_window_iconify),
9512                            window,
9513                            G_CONNECT_SWAPPED);
9514   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9515
9516   button = gtk_button_new_with_label ("Fullscreen");
9517   g_signal_connect_object (button,
9518                            "clicked",
9519                            G_CALLBACK (gtk_window_fullscreen),
9520                            window,
9521                            G_CONNECT_SWAPPED);
9522   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9523
9524   button = gtk_button_new_with_label ("Unfullscreen");
9525   g_signal_connect_object (button,
9526                            "clicked",
9527                            G_CALLBACK (gtk_window_unfullscreen),
9528                            window,
9529                            G_CONNECT_SWAPPED);
9530   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9531   
9532   button = gtk_button_new_with_label ("Hide (withdraw)");
9533   g_signal_connect_object (button,
9534                            "clicked",
9535                            G_CALLBACK (gtk_widget_hide),
9536                            window,
9537                            G_CONNECT_SWAPPED);
9538   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9539   
9540   gtk_widget_show_all (vbox);
9541
9542   return vbox;
9543 }
9544
9545 void
9546 create_window_states (GtkWidget *widget)
9547 {
9548   static GtkWidget *window = NULL;
9549   GtkWidget *label;
9550   GtkWidget *box1;
9551   GtkWidget *iconified;
9552   GtkWidget *normal;
9553   GtkWidget *controls;
9554
9555   if (!window)
9556     {
9557       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9558       gtk_window_set_screen (GTK_WINDOW (window),
9559                              gtk_widget_get_screen (widget));
9560
9561       g_signal_connect (window, "destroy",
9562                         G_CALLBACK (gtk_widget_destroyed),
9563                         &window);
9564
9565       gtk_window_set_title (GTK_WINDOW (window), "Window states");
9566       
9567       box1 = gtk_vbox_new (FALSE, 0);
9568       gtk_container_add (GTK_CONTAINER (window), box1);
9569
9570       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9571
9572       gtk_window_set_screen (GTK_WINDOW (iconified),
9573                              gtk_widget_get_screen (widget));
9574       
9575       g_signal_connect_object (iconified, "destroy",
9576                                G_CALLBACK (gtk_widget_destroy),
9577                                window,
9578                                G_CONNECT_SWAPPED);
9579       gtk_window_iconify (GTK_WINDOW (iconified));
9580       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
9581       controls = get_state_controls (iconified);
9582       gtk_container_add (GTK_CONTAINER (iconified), controls);
9583       
9584       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9585
9586       gtk_window_set_screen (GTK_WINDOW (normal),
9587                              gtk_widget_get_screen (widget));
9588       
9589       g_signal_connect_object (normal, "destroy",
9590                                G_CALLBACK (gtk_widget_destroy),
9591                                window,
9592                                G_CONNECT_SWAPPED);
9593       
9594       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
9595       controls = get_state_controls (normal);
9596       gtk_container_add (GTK_CONTAINER (normal), controls);
9597       
9598       label = tracking_label (iconified);
9599       gtk_container_add (GTK_CONTAINER (box1), label);
9600
9601       label = tracking_label (normal);
9602       gtk_container_add (GTK_CONTAINER (box1), label);
9603
9604       gtk_widget_show_all (iconified);
9605       gtk_widget_show_all (normal);
9606       gtk_widget_show_all (box1);
9607     }
9608
9609   if (!GTK_WIDGET_VISIBLE (window))
9610     gtk_widget_show (window);
9611   else
9612     gtk_widget_destroy (window);
9613 }
9614
9615 /*
9616  * Window sizing
9617  */
9618
9619 static gint
9620 configure_event_callback (GtkWidget *widget,
9621                           GdkEventConfigure *event,
9622                           gpointer data)
9623 {
9624   GtkWidget *label = data;
9625   gchar *msg;
9626   gint x, y;
9627   
9628   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
9629   
9630   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
9631                          "position: %d, %d",
9632                          event->x, event->y, event->width, event->height,
9633                          x, y);
9634   
9635   gtk_label_set_text (GTK_LABEL (label), msg);
9636
9637   g_free (msg);
9638
9639   return FALSE;
9640 }
9641
9642 static void
9643 get_ints (GtkWidget *window,
9644           gint      *a,
9645           gint      *b)
9646 {
9647   GtkWidget *spin1;
9648   GtkWidget *spin2;
9649
9650   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
9651   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
9652
9653   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
9654   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
9655 }
9656
9657 static void
9658 set_size_callback (GtkWidget *widget,
9659                    gpointer   data)
9660 {
9661   gint w, h;
9662   
9663   get_ints (data, &w, &h);
9664
9665   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
9666 }
9667
9668 static void
9669 unset_default_size_callback (GtkWidget *widget,
9670                              gpointer   data)
9671 {
9672   gtk_window_set_default_size (g_object_get_data (data, "target"),
9673                                -1, -1);
9674 }
9675
9676 static void
9677 set_default_size_callback (GtkWidget *widget,
9678                            gpointer   data)
9679 {
9680   gint w, h;
9681   
9682   get_ints (data, &w, &h);
9683
9684   gtk_window_set_default_size (g_object_get_data (data, "target"),
9685                                w, h);
9686 }
9687
9688 static void
9689 unset_size_request_callback (GtkWidget *widget,
9690                              gpointer   data)
9691 {
9692   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9693                                -1, -1);
9694 }
9695
9696 static void
9697 set_size_request_callback (GtkWidget *widget,
9698                            gpointer   data)
9699 {
9700   gint w, h;
9701   
9702   get_ints (data, &w, &h);
9703
9704   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9705                                w, h);
9706 }
9707
9708 static void
9709 set_location_callback (GtkWidget *widget,
9710                        gpointer   data)
9711 {
9712   gint x, y;
9713   
9714   get_ints (data, &x, &y);
9715
9716   gtk_window_move (g_object_get_data (data, "target"), x, y);
9717 }
9718
9719 static void
9720 move_to_position_callback (GtkWidget *widget,
9721                            gpointer   data)
9722 {
9723   gint x, y;
9724   GtkWindow *window;
9725
9726   window = g_object_get_data (data, "target");
9727   
9728   gtk_window_get_position (window, &x, &y);
9729
9730   gtk_window_move (window, x, y);
9731 }
9732
9733 static void
9734 set_geometry_callback (GtkWidget *entry,
9735                        gpointer   data)
9736 {
9737   gchar *text;
9738   GtkWindow *target;
9739
9740   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
9741   
9742   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
9743
9744   if (!gtk_window_parse_geometry (target, text))
9745     g_print ("Bad geometry string '%s'\n", text);
9746
9747   g_free (text);
9748 }
9749
9750 static void
9751 allow_shrink_callback (GtkWidget *widget,
9752                        gpointer   data)
9753 {
9754   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9755                 "allow_shrink",
9756                 GTK_TOGGLE_BUTTON (widget)->active,
9757                 NULL);
9758 }
9759
9760 static void
9761 allow_grow_callback (GtkWidget *widget,
9762                      gpointer   data)
9763 {
9764   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9765                 "allow_grow",
9766                 GTK_TOGGLE_BUTTON (widget)->active,
9767                 NULL);
9768 }
9769
9770 static void
9771 gravity_selected (GtkWidget *widget,
9772                   gpointer   data)
9773 {
9774   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
9775                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
9776 }
9777
9778 static void
9779 pos_selected (GtkWidget *widget,
9780               gpointer   data)
9781 {
9782   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
9783                            gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
9784 }
9785
9786 static void
9787 move_gravity_window_to_current_position (GtkWidget *widget,
9788                                          gpointer   data)
9789 {
9790   gint x, y;
9791   GtkWindow *window;
9792
9793   window = GTK_WINDOW (data);    
9794   
9795   gtk_window_get_position (window, &x, &y);
9796
9797   gtk_window_move (window, x, y);
9798 }
9799
9800 static void
9801 get_screen_corner (GtkWindow *window,
9802                    gint      *x,
9803                    gint      *y)
9804 {
9805   int w, h;
9806   GdkScreen * screen = gtk_window_get_screen (window);
9807   
9808   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
9809
9810   switch (gtk_window_get_gravity (window))
9811     {
9812     case GDK_GRAVITY_SOUTH_EAST:
9813       *x = gdk_screen_get_width (screen) - w;
9814       *y = gdk_screen_get_height (screen) - h;
9815       break;
9816
9817     case GDK_GRAVITY_NORTH_EAST:
9818       *x = gdk_screen_get_width (screen) - w;
9819       *y = 0;
9820       break;
9821
9822     case GDK_GRAVITY_SOUTH_WEST:
9823       *x = 0;
9824       *y = gdk_screen_get_height (screen) - h;
9825       break;
9826
9827     case GDK_GRAVITY_NORTH_WEST:
9828       *x = 0;
9829       *y = 0;
9830       break;
9831       
9832     case GDK_GRAVITY_SOUTH:
9833       *x = (gdk_screen_get_width (screen) - w) / 2;
9834       *y = gdk_screen_get_height (screen) - h;
9835       break;
9836
9837     case GDK_GRAVITY_NORTH:
9838       *x = (gdk_screen_get_width (screen) - w) / 2;
9839       *y = 0;
9840       break;
9841
9842     case GDK_GRAVITY_WEST:
9843       *x = 0;
9844       *y = (gdk_screen_get_height (screen) - h) / 2;
9845       break;
9846
9847     case GDK_GRAVITY_EAST:
9848       *x = gdk_screen_get_width (screen) - w;
9849       *y = (gdk_screen_get_height (screen) - h) / 2;
9850       break;
9851
9852     case GDK_GRAVITY_CENTER:
9853       *x = (gdk_screen_get_width (screen) - w) / 2;
9854       *y = (gdk_screen_get_height (screen) - h) / 2;
9855       break;
9856
9857     case GDK_GRAVITY_STATIC:
9858       /* pick some random numbers */
9859       *x = 350;
9860       *y = 350;
9861       break;
9862
9863     default:
9864       g_assert_not_reached ();
9865       break;
9866     }
9867 }
9868
9869 static void
9870 move_gravity_window_to_starting_position (GtkWidget *widget,
9871                                           gpointer   data)
9872 {
9873   gint x, y;
9874   GtkWindow *window;
9875
9876   window = GTK_WINDOW (data);    
9877   
9878   get_screen_corner (window,
9879                      &x, &y);
9880   
9881   gtk_window_move (window, x, y);
9882 }
9883
9884 static GtkWidget*
9885 make_gravity_window (GtkWidget   *destroy_with,
9886                      GdkGravity   gravity,
9887                      const gchar *title)
9888 {
9889   GtkWidget *window;
9890   GtkWidget *button;
9891   GtkWidget *vbox;
9892   int x, y;
9893   
9894   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9895
9896   gtk_window_set_screen (GTK_WINDOW (window),
9897                          gtk_widget_get_screen (destroy_with));
9898
9899   vbox = gtk_vbox_new (FALSE, 0);
9900   gtk_widget_show (vbox);
9901   
9902   gtk_container_add (GTK_CONTAINER (window), vbox);
9903   gtk_window_set_title (GTK_WINDOW (window), title);
9904   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
9905
9906   g_signal_connect_object (destroy_with,
9907                            "destroy",
9908                            G_CALLBACK (gtk_widget_destroy),
9909                            window,
9910                            G_CONNECT_SWAPPED);
9911
9912   
9913   button = gtk_button_new_with_mnemonic ("_Move to current position");
9914
9915   g_signal_connect (button, "clicked",
9916                     G_CALLBACK (move_gravity_window_to_current_position),
9917                     window);
9918
9919   gtk_container_add (GTK_CONTAINER (vbox), button);
9920   gtk_widget_show (button);
9921
9922   button = gtk_button_new_with_mnemonic ("Move to _starting position");
9923
9924   g_signal_connect (button, "clicked",
9925                     G_CALLBACK (move_gravity_window_to_starting_position),
9926                     window);
9927
9928   gtk_container_add (GTK_CONTAINER (vbox), button);
9929   gtk_widget_show (button);
9930   
9931   /* Pretend this is the result of --geometry.
9932    * DO NOT COPY THIS CODE unless you are setting --geometry results,
9933    * and in that case you probably should just use gtk_window_parse_geometry().
9934    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
9935    * you are parsing --geometry or equivalent.
9936    */
9937   gtk_window_set_geometry_hints (GTK_WINDOW (window),
9938                                  NULL, NULL,
9939                                  GDK_HINT_USER_POS);
9940
9941   gtk_window_set_default_size (GTK_WINDOW (window),
9942                                200, 200);
9943
9944   get_screen_corner (GTK_WINDOW (window), &x, &y);
9945   
9946   gtk_window_move (GTK_WINDOW (window),
9947                    x, y);
9948   
9949   return window;
9950 }
9951
9952 static void
9953 do_gravity_test (GtkWidget *widget,
9954                  gpointer   data)
9955 {
9956   GtkWidget *destroy_with = data;
9957   GtkWidget *window;
9958   
9959   /* We put a window at each gravity point on the screen. */
9960   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
9961                                 "NorthWest");
9962   gtk_widget_show (window);
9963   
9964   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
9965                                 "SouthEast");
9966   gtk_widget_show (window);
9967
9968   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
9969                                 "NorthEast");
9970   gtk_widget_show (window);
9971
9972   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
9973                                 "SouthWest");
9974   gtk_widget_show (window);
9975
9976   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
9977                                 "South");
9978   gtk_widget_show (window);
9979
9980   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
9981                                 "North");
9982   gtk_widget_show (window);
9983
9984   
9985   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
9986                                 "West");
9987   gtk_widget_show (window);
9988
9989     
9990   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
9991                                 "East");
9992   gtk_widget_show (window);
9993
9994   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
9995                                 "Center");
9996   gtk_widget_show (window);
9997
9998   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
9999                                 "Static");
10000   gtk_widget_show (window);
10001 }
10002
10003 static GtkWidget*
10004 window_controls (GtkWidget *window)
10005 {
10006   GtkWidget *control_window;
10007   GtkWidget *label;
10008   GtkWidget *vbox;
10009   GtkWidget *button;
10010   GtkWidget *spin;
10011   GtkAdjustment *adj;
10012   GtkWidget *entry;
10013   GtkWidget *om;
10014   GtkWidget *menu;
10015   gint i;
10016   
10017   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10018
10019   gtk_window_set_screen (GTK_WINDOW (control_window),
10020                          gtk_widget_get_screen (window));
10021
10022   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
10023   
10024   g_object_set_data (G_OBJECT (control_window),
10025                      "target",
10026                      window);
10027   
10028   g_signal_connect_object (control_window,
10029                            "destroy",
10030                            G_CALLBACK (gtk_widget_destroy),
10031                            window,
10032                            G_CONNECT_SWAPPED);
10033
10034   vbox = gtk_vbox_new (FALSE, 5);
10035   
10036   gtk_container_add (GTK_CONTAINER (control_window), vbox);
10037   
10038   label = gtk_label_new ("<no configure events>");
10039   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
10040   
10041   g_signal_connect (window,
10042                     "configure_event",
10043                     G_CALLBACK (configure_event_callback),
10044                     label);
10045
10046   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
10047                                               5.0, 0.0);
10048   spin = gtk_spin_button_new (adj, 0, 0);
10049
10050   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
10051
10052   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
10053
10054   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
10055                                               5.0, 0.0);
10056   spin = gtk_spin_button_new (adj, 0, 0);
10057
10058   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
10059
10060   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
10061
10062   entry = gtk_entry_new ();
10063   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
10064
10065   g_signal_connect (entry, "changed",
10066                     G_CALLBACK (set_geometry_callback),
10067                     control_window);
10068
10069   button = gtk_button_new_with_label ("Show gravity test windows");
10070   g_signal_connect_swapped (button,
10071                             "clicked",
10072                             G_CALLBACK (do_gravity_test),
10073                             control_window);
10074   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10075
10076   button = gtk_button_new_with_label ("Reshow with initial size");
10077   g_signal_connect_object (button,
10078                            "clicked",
10079                            G_CALLBACK (gtk_window_reshow_with_initial_size),
10080                            window,
10081                            G_CONNECT_SWAPPED);
10082   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10083   
10084   button = gtk_button_new_with_label ("Queue resize");
10085   g_signal_connect_object (button,
10086                            "clicked",
10087                            G_CALLBACK (gtk_widget_queue_resize),
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_label ("Resize");
10093   g_signal_connect (button,
10094                     "clicked",
10095                     G_CALLBACK (set_size_callback),
10096                     control_window);
10097   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10098
10099   button = gtk_button_new_with_label ("Set default size");
10100   g_signal_connect (button,
10101                     "clicked",
10102                     G_CALLBACK (set_default_size_callback),
10103                     control_window);
10104   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10105
10106   button = gtk_button_new_with_label ("Unset default size");
10107   g_signal_connect (button,
10108                     "clicked",
10109                     G_CALLBACK (unset_default_size_callback),
10110                     control_window);
10111   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10112   
10113   button = gtk_button_new_with_label ("Set size request");
10114   g_signal_connect (button,
10115                     "clicked",
10116                     G_CALLBACK (set_size_request_callback),
10117                     control_window);
10118   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10119
10120   button = gtk_button_new_with_label ("Unset size request");
10121   g_signal_connect (button,
10122                     "clicked",
10123                     G_CALLBACK (unset_size_request_callback),
10124                     control_window);
10125   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10126   
10127   button = gtk_button_new_with_label ("Move");
10128   g_signal_connect (button,
10129                     "clicked",
10130                     G_CALLBACK (set_location_callback),
10131                     control_window);
10132   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10133
10134   button = gtk_button_new_with_label ("Move to current position");
10135   g_signal_connect (button,
10136                     "clicked",
10137                     G_CALLBACK (move_to_position_callback),
10138                     control_window);
10139   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10140   
10141   button = gtk_check_button_new_with_label ("Allow shrink");
10142   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
10143   g_signal_connect (button,
10144                     "toggled",
10145                     G_CALLBACK (allow_shrink_callback),
10146                     control_window);
10147   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10148
10149   button = gtk_check_button_new_with_label ("Allow grow");
10150   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
10151   g_signal_connect (button,
10152                     "toggled",
10153                     G_CALLBACK (allow_grow_callback),
10154                     control_window);
10155   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10156   
10157   button = gtk_button_new_with_mnemonic ("_Show");
10158   g_signal_connect_object (button,
10159                            "clicked",
10160                            G_CALLBACK (gtk_widget_show),
10161                            window,
10162                            G_CONNECT_SWAPPED);
10163   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10164
10165   button = gtk_button_new_with_mnemonic ("_Hide");
10166   g_signal_connect_object (button,
10167                            "clicked",
10168                            G_CALLBACK (gtk_widget_hide),
10169                            window,
10170                            G_CONNECT_SWAPPED);
10171   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10172   
10173   menu = gtk_menu_new ();
10174   
10175   i = 0;
10176   while (i < 10)
10177     {
10178       GtkWidget *mi;
10179       static gchar *names[] = {
10180         "GDK_GRAVITY_NORTH_WEST",
10181         "GDK_GRAVITY_NORTH",
10182         "GDK_GRAVITY_NORTH_EAST",
10183         "GDK_GRAVITY_WEST",
10184         "GDK_GRAVITY_CENTER",
10185         "GDK_GRAVITY_EAST",
10186         "GDK_GRAVITY_SOUTH_WEST",
10187         "GDK_GRAVITY_SOUTH",
10188         "GDK_GRAVITY_SOUTH_EAST",
10189         "GDK_GRAVITY_STATIC",
10190         NULL
10191       };
10192
10193       g_assert (names[i]);
10194       
10195       mi = gtk_menu_item_new_with_label (names[i]);
10196
10197       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10198
10199       ++i;
10200     }
10201   
10202   gtk_widget_show_all (menu);
10203   
10204   om = gtk_option_menu_new ();
10205   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10206   
10207
10208   g_signal_connect (om,
10209                     "changed",
10210                     G_CALLBACK (gravity_selected),
10211                     control_window);
10212
10213   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10214
10215
10216   menu = gtk_menu_new ();
10217   
10218   i = 0;
10219   while (i < 5)
10220     {
10221       GtkWidget *mi;
10222       static gchar *names[] = {
10223         "GTK_WIN_POS_NONE",
10224         "GTK_WIN_POS_CENTER",
10225         "GTK_WIN_POS_MOUSE",
10226         "GTK_WIN_POS_CENTER_ALWAYS",
10227         "GTK_WIN_POS_CENTER_ON_PARENT",
10228         NULL
10229       };
10230
10231       g_assert (names[i]);
10232       
10233       mi = gtk_menu_item_new_with_label (names[i]);
10234
10235       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10236
10237       ++i;
10238     }
10239   
10240   gtk_widget_show_all (menu);
10241   
10242   om = gtk_option_menu_new ();
10243   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10244   
10245
10246   g_signal_connect (om,
10247                     "changed",
10248                     G_CALLBACK (pos_selected),
10249                     control_window);
10250
10251   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10252   
10253   gtk_widget_show_all (vbox);
10254   
10255   return control_window;
10256 }
10257
10258 void
10259 create_window_sizing (GtkWidget *widget)
10260 {
10261   static GtkWidget *window = NULL;
10262   static GtkWidget *target_window = NULL;
10263
10264   if (!target_window)
10265     {
10266       GtkWidget *label;
10267       
10268       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10269       gtk_window_set_screen (GTK_WINDOW (target_window),
10270                              gtk_widget_get_screen (widget));
10271       label = gtk_label_new (NULL);
10272       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");
10273       gtk_container_add (GTK_CONTAINER (target_window), label);
10274       gtk_widget_show (label);
10275       
10276       g_signal_connect (target_window, "destroy",
10277                         G_CALLBACK (gtk_widget_destroyed),
10278                         &target_window);
10279
10280       window = window_controls (target_window);
10281       
10282       g_signal_connect (window, "destroy",
10283                         G_CALLBACK (gtk_widget_destroyed),
10284                         &window);
10285       
10286       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
10287     }
10288
10289   /* don't show target window by default, we want to allow testing
10290    * of behavior on first show.
10291    */
10292   
10293   if (!GTK_WIDGET_VISIBLE (window))
10294     gtk_widget_show (window);
10295   else
10296     gtk_widget_destroy (window);
10297 }
10298
10299 /*
10300  * GtkProgressBar
10301  */
10302
10303 typedef struct _ProgressData {
10304   GtkWidget *window;
10305   GtkWidget *pbar;
10306   GtkWidget *block_spin;
10307   GtkWidget *x_align_spin;
10308   GtkWidget *y_align_spin;
10309   GtkWidget *step_spin;
10310   GtkWidget *act_blocks_spin;
10311   GtkWidget *label;
10312   GtkWidget *omenu1;
10313   GtkWidget *omenu2;
10314   GtkWidget *entry;
10315   int timer;
10316 } ProgressData;
10317
10318 gint
10319 progress_timeout (gpointer data)
10320 {
10321   gdouble new_val;
10322   GtkAdjustment *adj;
10323
10324   adj = GTK_PROGRESS (data)->adjustment;
10325
10326   new_val = adj->value + 1;
10327   if (new_val > adj->upper)
10328     new_val = adj->lower;
10329
10330   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
10331
10332   return TRUE;
10333 }
10334
10335 static void
10336 destroy_progress (GtkWidget     *widget,
10337                   ProgressData **pdata)
10338 {
10339   gtk_timeout_remove ((*pdata)->timer);
10340   (*pdata)->timer = 0;
10341   (*pdata)->window = NULL;
10342   g_free (*pdata);
10343   *pdata = NULL;
10344 }
10345
10346 static void
10347 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
10348 {
10349   ProgressData *pdata;
10350   gint i;
10351
10352   pdata = (ProgressData *) data;
10353
10354   if (!GTK_WIDGET_MAPPED (widget))
10355     return;
10356
10357   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10358
10359   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
10360                                     (GtkProgressBarOrientation) i);
10361 }
10362
10363 static void
10364 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
10365 {
10366   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
10367                               GTK_TOGGLE_BUTTON (widget)->active);
10368   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
10369   gtk_widget_set_sensitive (pdata->x_align_spin,
10370                             GTK_TOGGLE_BUTTON (widget)->active);
10371   gtk_widget_set_sensitive (pdata->y_align_spin,
10372                             GTK_TOGGLE_BUTTON (widget)->active);
10373 }
10374
10375 static void
10376 progressbar_toggle_bar_style (GtkWidget *widget, gpointer data)
10377 {
10378   ProgressData *pdata;
10379   gint i;
10380
10381   pdata = (ProgressData *) data;
10382
10383   if (!GTK_WIDGET_MAPPED (widget))
10384     return;
10385
10386   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10387
10388   if (i == 1)
10389     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
10390   else
10391     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10392   
10393   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
10394                                   (GtkProgressBarStyle) i);
10395 }
10396
10397 static void
10398 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
10399 {
10400   char buf[20];
10401
10402   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
10403     sprintf (buf, "???");
10404   else
10405     sprintf (buf, "%.0f%%", 100 *
10406              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
10407   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
10408 }
10409
10410 static void
10411 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
10412 {
10413   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
10414   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10415      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
10416 }
10417
10418 static void
10419 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
10420 {
10421   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
10422      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
10423 }
10424
10425 static void
10426 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
10427 {
10428   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10429                gtk_spin_button_get_value_as_int 
10430                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
10431 }
10432
10433 static void
10434 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
10435 {
10436   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
10437          gtk_spin_button_get_value (GTK_SPIN_BUTTON (pdata->x_align_spin)),
10438          gtk_spin_button_get_value (GTK_SPIN_BUTTON (pdata->y_align_spin)));
10439 }
10440
10441 static void
10442 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
10443 {
10444   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
10445                                   GTK_TOGGLE_BUTTON (widget)->active);
10446   gtk_widget_set_sensitive (pdata->step_spin, 
10447                             GTK_TOGGLE_BUTTON (widget)->active);
10448   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
10449                             GTK_TOGGLE_BUTTON (widget)->active);
10450 }
10451
10452 static void
10453 entry_changed (GtkWidget *widget, ProgressData *pdata)
10454 {
10455   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10456                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
10457 }
10458
10459 void
10460 create_progress_bar (GtkWidget *widget)
10461 {
10462   GtkWidget *button;
10463   GtkWidget *vbox;
10464   GtkWidget *vbox2;
10465   GtkWidget *hbox;
10466   GtkWidget *check;
10467   GtkWidget *frame;
10468   GtkWidget *tab;
10469   GtkWidget *label;
10470   GtkWidget *align;
10471   GtkAdjustment *adj;
10472   static ProgressData *pdata = NULL;
10473
10474   static gchar *items1[] =
10475   {
10476     "Left-Right",
10477     "Right-Left",
10478     "Bottom-Top",
10479     "Top-Bottom"
10480   };
10481
10482   static gchar *items2[] =
10483   {
10484     "Continuous",
10485     "Discrete"
10486   };
10487   
10488   if (!pdata)
10489     pdata = g_new0 (ProgressData, 1);
10490
10491   if (!pdata->window)
10492     {
10493       pdata->window = gtk_dialog_new ();
10494
10495       gtk_window_set_screen (GTK_WINDOW (pdata->window),
10496                              gtk_widget_get_screen (widget));
10497
10498       gtk_window_set_resizable (GTK_WINDOW (pdata->window), FALSE);
10499
10500       g_signal_connect (pdata->window, "destroy",
10501                         G_CALLBACK (destroy_progress),
10502                         &pdata);
10503
10504       pdata->timer = 0;
10505
10506       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
10507       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
10508
10509       vbox = gtk_vbox_new (FALSE, 5);
10510       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
10511       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
10512                           vbox, FALSE, TRUE, 0);
10513
10514       frame = gtk_frame_new ("Progress");
10515       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10516
10517       vbox2 = gtk_vbox_new (FALSE, 5);
10518       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10519
10520       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10521       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10522
10523       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
10524       g_signal_connect (adj, "value_changed",
10525                         G_CALLBACK (progress_value_changed), pdata);
10526
10527       pdata->pbar = gtk_widget_new (GTK_TYPE_PROGRESS_BAR,
10528                                     "adjustment", adj,
10529                                     NULL);
10530       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10531                                       "%v from [%l,%u] (=%p%%)");
10532       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
10533       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
10534
10535       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10536       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10537
10538       hbox = gtk_hbox_new (FALSE, 5);
10539       gtk_container_add (GTK_CONTAINER (align), hbox);
10540       label = gtk_label_new ("Label updated by user :"); 
10541       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10542       pdata->label = gtk_label_new ("");
10543       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
10544
10545       frame = gtk_frame_new ("Options");
10546       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10547
10548       vbox2 = gtk_vbox_new (FALSE, 5);
10549       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10550
10551       tab = gtk_table_new (7, 2, FALSE);
10552       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
10553
10554       label = gtk_label_new ("Orientation :");
10555       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
10556                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10557                         5, 5);
10558       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10559
10560       pdata->omenu1 = build_option_menu (items1, 4, 0,
10561                                          progressbar_toggle_orientation,
10562                                          pdata);
10563       hbox = gtk_hbox_new (FALSE, 0);
10564       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
10565                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10566                         5, 5);
10567       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
10568       
10569       check = gtk_check_button_new_with_label ("Show text");
10570       g_signal_connect (check, "clicked",
10571                         G_CALLBACK (toggle_show_text),
10572                         pdata);
10573       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
10574                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10575                         5, 5);
10576
10577       hbox = gtk_hbox_new (FALSE, 0);
10578       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
10579                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10580                         5, 5);
10581
10582       label = gtk_label_new ("Format : ");
10583       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10584
10585       pdata->entry = gtk_entry_new ();
10586       g_signal_connect (pdata->entry, "changed",
10587                         G_CALLBACK (entry_changed),
10588                         pdata);
10589       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
10590       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
10591       gtk_widget_set_size_request (pdata->entry, 100, -1);
10592       gtk_widget_set_sensitive (pdata->entry, FALSE);
10593
10594       label = gtk_label_new ("Text align :");
10595       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
10596                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10597                         5, 5);
10598       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10599
10600       hbox = gtk_hbox_new (FALSE, 0);
10601       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
10602                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10603                         5, 5);
10604
10605       label = gtk_label_new ("x :");
10606       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10607       
10608       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10609       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
10610       g_signal_connect (adj, "value_changed",
10611                         G_CALLBACK (adjust_align), pdata);
10612       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
10613       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
10614
10615       label = gtk_label_new ("y :");
10616       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10617
10618       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10619       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
10620       g_signal_connect (adj, "value_changed",
10621                         G_CALLBACK (adjust_align), pdata);
10622       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
10623       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
10624
10625       label = gtk_label_new ("Bar Style :");
10626       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
10627                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10628                         5, 5);
10629       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10630
10631       pdata->omenu2 = build_option_menu (items2, 2, 0,
10632                                          progressbar_toggle_bar_style,
10633                                          pdata);
10634       hbox = gtk_hbox_new (FALSE, 0);
10635       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
10636                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10637                         5, 5);
10638       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
10639
10640       label = gtk_label_new ("Block count :");
10641       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
10642                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10643                         5, 5);
10644       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10645
10646       hbox = gtk_hbox_new (FALSE, 0);
10647       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
10648                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10649                         5, 5);
10650       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
10651       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
10652       g_signal_connect (adj, "value_changed",
10653                         G_CALLBACK (adjust_blocks), pdata);
10654       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
10655       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10656
10657       check = gtk_check_button_new_with_label ("Activity mode");
10658       g_signal_connect (check, "clicked",
10659                         G_CALLBACK (toggle_activity_mode), pdata);
10660       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
10661                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10662                         5, 5);
10663
10664       hbox = gtk_hbox_new (FALSE, 0);
10665       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
10666                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10667                         5, 5);
10668       label = gtk_label_new ("Step size : ");
10669       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10670       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
10671       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
10672       g_signal_connect (adj, "value_changed",
10673                         G_CALLBACK (adjust_step), pdata);
10674       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
10675       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
10676
10677       hbox = gtk_hbox_new (FALSE, 0);
10678       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
10679                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10680                         5, 5);
10681       label = gtk_label_new ("Blocks :     ");
10682       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10683       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
10684       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
10685       g_signal_connect (adj, "value_changed",
10686                         G_CALLBACK (adjust_act_blocks), pdata);
10687       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
10688                           0);
10689       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
10690
10691       button = gtk_button_new_with_label ("close");
10692       g_signal_connect_swapped (button, "clicked",
10693                                 G_CALLBACK (gtk_widget_destroy),
10694                                 pdata->window);
10695       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10696       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
10697                           button, TRUE, TRUE, 0);
10698       gtk_widget_grab_default (button);
10699     }
10700
10701   if (!GTK_WIDGET_VISIBLE (pdata->window))
10702     gtk_widget_show_all (pdata->window);
10703   else
10704     gtk_widget_destroy (pdata->window);
10705 }
10706
10707 /*
10708  * Properties
10709  */
10710
10711 typedef struct {
10712   int x;
10713   int y;
10714   gboolean found;
10715   gboolean first;
10716   GtkWidget *res_widget;
10717 } FindWidgetData;
10718
10719 static void
10720 find_widget (GtkWidget *widget, FindWidgetData *data)
10721 {
10722   GtkAllocation new_allocation;
10723   gint x_offset = 0;
10724   gint y_offset = 0;
10725
10726   new_allocation = widget->allocation;
10727
10728   if (data->found || !GTK_WIDGET_MAPPED (widget))
10729     return;
10730
10731   /* Note that in the following code, we only count the
10732    * position as being inside a WINDOW widget if it is inside
10733    * widget->window; points that are outside of widget->window
10734    * but within the allocation are not counted. This is consistent
10735    * with the way we highlight drag targets.
10736    */
10737   if (!GTK_WIDGET_NO_WINDOW (widget))
10738     {
10739       new_allocation.x = 0;
10740       new_allocation.y = 0;
10741     }
10742   
10743   if (widget->parent && !data->first)
10744     {
10745       GdkWindow *window = widget->window;
10746       while (window != widget->parent->window)
10747         {
10748           gint tx, ty, twidth, theight;
10749           gdk_drawable_get_size (window, &twidth, &theight);
10750
10751           if (new_allocation.x < 0)
10752             {
10753               new_allocation.width += new_allocation.x;
10754               new_allocation.x = 0;
10755             }
10756           if (new_allocation.y < 0)
10757             {
10758               new_allocation.height += new_allocation.y;
10759               new_allocation.y = 0;
10760             }
10761           if (new_allocation.x + new_allocation.width > twidth)
10762             new_allocation.width = twidth - new_allocation.x;
10763           if (new_allocation.y + new_allocation.height > theight)
10764             new_allocation.height = theight - new_allocation.y;
10765
10766           gdk_window_get_position (window, &tx, &ty);
10767           new_allocation.x += tx;
10768           x_offset += tx;
10769           new_allocation.y += ty;
10770           y_offset += ty;
10771           
10772           window = gdk_window_get_parent (window);
10773         }
10774     }
10775
10776   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
10777       (data->x < new_allocation.x + new_allocation.width) && 
10778       (data->y < new_allocation.y + new_allocation.height))
10779     {
10780       /* First, check if the drag is in a valid drop site in
10781        * one of our children 
10782        */
10783       if (GTK_IS_CONTAINER (widget))
10784         {
10785           FindWidgetData new_data = *data;
10786           
10787           new_data.x -= x_offset;
10788           new_data.y -= y_offset;
10789           new_data.found = FALSE;
10790           new_data.first = FALSE;
10791           
10792           gtk_container_forall (GTK_CONTAINER (widget),
10793                                 (GtkCallback)find_widget,
10794                                 &new_data);
10795           
10796           data->found = new_data.found;
10797           if (data->found)
10798             data->res_widget = new_data.res_widget;
10799         }
10800
10801       /* If not, and this widget is registered as a drop site, check to
10802        * emit "drag_motion" to check if we are actually in
10803        * a drop site.
10804        */
10805       if (!data->found)
10806         {
10807           data->found = TRUE;
10808           data->res_widget = widget;
10809         }
10810     }
10811 }
10812
10813 static GtkWidget *
10814 find_widget_at_pointer (GdkDisplay *display)
10815 {
10816   GtkWidget *widget = NULL;
10817   GdkWindow *pointer_window;
10818   gint x, y;
10819   FindWidgetData data;
10820  
10821  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);
10822  
10823  if (pointer_window)
10824    gdk_window_get_user_data (pointer_window, (gpointer*) &widget);
10825
10826  if (widget)
10827    {
10828      gdk_window_get_pointer (widget->window,
10829                              &x, &y, NULL);
10830      
10831      data.x = x;
10832      data.y = y;
10833      data.found = FALSE;
10834      data.first = TRUE;
10835
10836      find_widget (widget, &data);
10837      if (data.found)
10838        return data.res_widget;
10839      return widget;
10840    }
10841  return NULL;
10842 }
10843
10844 struct PropertiesData {
10845   GtkWidget **window;
10846   GdkCursor *cursor;
10847   gboolean in_query;
10848   gint handler;
10849 };
10850
10851 static void
10852 destroy_properties (GtkWidget             *widget,
10853                     struct PropertiesData *data)
10854 {
10855   if (data->window)
10856     {
10857       *data->window = NULL;
10858       data->window = NULL;
10859     }
10860
10861   if (data->cursor)
10862     {
10863       gdk_cursor_unref (data->cursor);
10864       data->cursor = NULL;
10865     }
10866
10867   if (data->handler)
10868     {
10869       g_signal_handler_disconnect (widget, data->handler);
10870       data->handler = 0;
10871     }
10872
10873   g_free (data);
10874 }
10875
10876 static gint
10877 property_query_event (GtkWidget        *widget,
10878                       GdkEvent         *event,
10879                       struct PropertiesData *data)
10880 {
10881   GtkWidget *res_widget = NULL;
10882
10883   if (!data->in_query)
10884     return FALSE;
10885   
10886   if (event->type == GDK_BUTTON_RELEASE)
10887     {
10888       gtk_grab_remove (widget);
10889       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
10890                                   GDK_CURRENT_TIME);
10891       
10892       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
10893       if (res_widget)
10894         {
10895           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
10896                              gtk_widget_get_screen (widget));
10897           create_prop_editor (G_OBJECT (res_widget), 0);
10898         }
10899
10900       data->in_query = FALSE;
10901     }
10902   return FALSE;
10903 }
10904
10905
10906 static void
10907 query_properties (GtkButton *button,
10908                   struct PropertiesData *data)
10909 {
10910   gint failure;
10911
10912   g_signal_connect (button, "event",
10913                     G_CALLBACK (property_query_event), data);
10914
10915
10916   if (!data->cursor)
10917     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (button)),
10918                                                GDK_TARGET);
10919   
10920   failure = gdk_pointer_grab (GTK_WIDGET (button)->window,
10921                               TRUE,
10922                               GDK_BUTTON_RELEASE_MASK,
10923                               NULL,
10924                               data->cursor,
10925                               GDK_CURRENT_TIME);
10926
10927   gtk_grab_add (GTK_WIDGET (button));
10928
10929   data->in_query = TRUE;
10930 }
10931
10932 static void
10933 create_properties (GtkWidget *widget)
10934 {
10935   static GtkWidget *window = NULL;
10936   GtkWidget *button;
10937   GtkWidget *vbox;
10938   GtkWidget *label;
10939   struct PropertiesData *data;
10940
10941   data = g_new (struct PropertiesData, 1);
10942   data->window = &window;
10943   data->in_query = FALSE;
10944   data->cursor = NULL;
10945   data->handler = 0;
10946
10947   if (!window)
10948     {
10949       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10950
10951       gtk_window_set_screen (GTK_WINDOW (window),
10952                              gtk_widget_get_screen (widget));      
10953
10954       data->handler = g_signal_connect (window, "destroy",
10955                                         G_CALLBACK (destroy_properties),
10956                                         data);
10957
10958       gtk_window_set_title (GTK_WINDOW (window), "test properties");
10959       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10960
10961       vbox = gtk_vbox_new (FALSE, 1);
10962       gtk_container_add (GTK_CONTAINER (window), vbox);
10963             
10964       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
10965       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
10966       
10967       button = gtk_button_new_with_label ("Query properties");
10968       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
10969       g_signal_connect (button, "clicked",
10970                         G_CALLBACK (query_properties),
10971                         data);
10972     }
10973
10974   if (!GTK_WIDGET_VISIBLE (window))
10975     gtk_widget_show_all (window);
10976   else
10977     gtk_widget_destroy (window);
10978   
10979 }
10980
10981
10982 /*
10983  * Color Preview
10984  */
10985
10986 static int color_idle = 0;
10987
10988 gint
10989 color_idle_func (GtkWidget *preview)
10990 {
10991   static int count = 1;
10992   guchar buf[768];
10993   int i, j, k;
10994
10995   for (i = 0; i < 256; i++)
10996     {
10997       for (j = 0, k = 0; j < 256; j++)
10998         {
10999           buf[k+0] = i + count;
11000           buf[k+1] = 0;
11001           buf[k+2] = j + count;
11002           k += 3;
11003         }
11004
11005       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
11006     }
11007
11008   count += 1;
11009
11010   gtk_widget_queue_draw (preview);
11011   gdk_window_process_updates (preview->window, TRUE);
11012
11013   return TRUE;
11014 }
11015
11016 static void
11017 color_preview_destroy (GtkWidget  *widget,
11018                        GtkWidget **window)
11019 {
11020   gtk_idle_remove (color_idle);
11021   color_idle = 0;
11022
11023   *window = NULL;
11024 }
11025
11026 void
11027 create_color_preview (GtkWidget *widget)
11028 {
11029   static GtkWidget *window = NULL;
11030   GtkWidget *preview;
11031   guchar buf[768];
11032   int i, j, k;
11033
11034   if (!window)
11035     {
11036       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11037       
11038       gtk_window_set_screen (GTK_WINDOW (window),
11039                              gtk_widget_get_screen (widget));
11040
11041       g_signal_connect (window, "destroy",
11042                         G_CALLBACK (color_preview_destroy),
11043                         &window);
11044
11045       gtk_window_set_title (GTK_WINDOW (window), "test");
11046       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11047
11048       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
11049       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
11050       gtk_container_add (GTK_CONTAINER (window), preview);
11051
11052       for (i = 0; i < 256; i++)
11053         {
11054           for (j = 0, k = 0; j < 256; j++)
11055             {
11056               buf[k+0] = i;
11057               buf[k+1] = 0;
11058               buf[k+2] = j;
11059               k += 3;
11060             }
11061
11062           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
11063         }
11064
11065       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
11066     }
11067
11068   if (!GTK_WIDGET_VISIBLE (window))
11069     gtk_widget_show_all (window);
11070   else
11071     gtk_widget_destroy (window);
11072 }
11073
11074 /*
11075  * Gray Preview
11076  */
11077
11078 static int gray_idle = 0;
11079
11080 gint
11081 gray_idle_func (GtkWidget *preview)
11082 {
11083   static int count = 1;
11084   guchar buf[256];
11085   int i, j;
11086
11087   for (i = 0; i < 256; i++)
11088     {
11089       for (j = 0; j < 256; j++)
11090         buf[j] = i + j + count;
11091
11092       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
11093     }
11094
11095   count += 1;
11096
11097   gtk_widget_draw (preview, NULL);
11098
11099   return TRUE;
11100 }
11101
11102 static void
11103 gray_preview_destroy (GtkWidget  *widget,
11104                       GtkWidget **window)
11105 {
11106   gtk_idle_remove (gray_idle);
11107   gray_idle = 0;
11108
11109   *window = NULL;
11110 }
11111
11112 void
11113 create_gray_preview (GtkWidget *widget)
11114 {
11115   static GtkWidget *window = NULL;
11116   GtkWidget *preview;
11117   guchar buf[256];
11118   int i, j;
11119
11120   if (!window)
11121     {
11122       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11123
11124       gtk_window_set_screen (GTK_WINDOW (window),
11125                              gtk_widget_get_screen (widget));
11126
11127       g_signal_connect (window, "destroy",
11128                         G_CALLBACK (gray_preview_destroy),
11129                         &window);
11130
11131       gtk_window_set_title (GTK_WINDOW (window), "test");
11132       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11133
11134       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
11135       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
11136       gtk_container_add (GTK_CONTAINER (window), preview);
11137
11138       for (i = 0; i < 256; i++)
11139         {
11140           for (j = 0; j < 256; j++)
11141             buf[j] = i + j;
11142
11143           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
11144         }
11145
11146       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
11147     }
11148
11149   if (!GTK_WIDGET_VISIBLE (window))
11150     gtk_widget_show_all (window);
11151   else
11152     gtk_widget_destroy (window);
11153 }
11154
11155
11156 /*
11157  * Selection Test
11158  */
11159
11160 void
11161 selection_test_received (GtkWidget *list, GtkSelectionData *data)
11162 {
11163   GdkAtom *atoms;
11164   GtkWidget *list_item;
11165   GList *item_list;
11166   int i, l;
11167
11168   if (data->length < 0)
11169     {
11170       g_print ("Selection retrieval failed\n");
11171       return;
11172     }
11173   if (data->type != GDK_SELECTION_TYPE_ATOM)
11174     {
11175       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
11176       return;
11177     }
11178
11179   /* Clear out any current list items */
11180
11181   gtk_list_clear_items (GTK_LIST(list), 0, -1);
11182
11183   /* Add new items to list */
11184
11185   atoms = (GdkAtom *)data->data;
11186
11187   item_list = NULL;
11188   l = data->length / sizeof (GdkAtom);
11189   for (i = 0; i < l; i++)
11190     {
11191       char *name;
11192       name = gdk_atom_name (atoms[i]);
11193       if (name != NULL)
11194         {
11195           list_item = gtk_list_item_new_with_label (name);
11196           g_free (name);
11197         }
11198       else
11199         list_item = gtk_list_item_new_with_label ("(bad atom)");
11200
11201       gtk_widget_show (list_item);
11202       item_list = g_list_append (item_list, list_item);
11203     }
11204
11205   gtk_list_append_items (GTK_LIST (list), item_list);
11206
11207   return;
11208 }
11209
11210 void
11211 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
11212 {
11213   static GdkAtom targets_atom = GDK_NONE;
11214
11215   if (targets_atom == GDK_NONE)
11216     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
11217
11218   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
11219                          GDK_CURRENT_TIME);
11220 }
11221
11222 void
11223 create_selection_test (GtkWidget *widget)
11224 {
11225   static GtkWidget *window = NULL;
11226   GtkWidget *button;
11227   GtkWidget *vbox;
11228   GtkWidget *scrolled_win;
11229   GtkWidget *list;
11230   GtkWidget *label;
11231
11232   if (!window)
11233     {
11234       window = gtk_dialog_new ();
11235       
11236       gtk_window_set_screen (GTK_WINDOW (window),
11237                              gtk_widget_get_screen (widget));
11238
11239       g_signal_connect (window, "destroy",
11240                         G_CALLBACK (gtk_widget_destroyed),
11241                         &window);
11242
11243       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
11244       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11245
11246       /* Create the list */
11247
11248       vbox = gtk_vbox_new (FALSE, 5);
11249       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11250       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
11251                           TRUE, TRUE, 0);
11252
11253       label = gtk_label_new ("Gets available targets for current selection");
11254       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11255
11256       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
11257       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
11258                                       GTK_POLICY_AUTOMATIC, 
11259                                       GTK_POLICY_AUTOMATIC);
11260       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
11261       gtk_widget_set_size_request (scrolled_win, 100, 200);
11262
11263       list = gtk_list_new ();
11264       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
11265
11266       g_signal_connect (list, "selection_received",
11267                         G_CALLBACK (selection_test_received), NULL);
11268
11269       /* .. And create some buttons */
11270       button = gtk_button_new_with_label ("Get Targets");
11271       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11272                           button, TRUE, TRUE, 0);
11273
11274       g_signal_connect (button, "clicked",
11275                         G_CALLBACK (selection_test_get_targets), list);
11276
11277       button = gtk_button_new_with_label ("Quit");
11278       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11279                           button, TRUE, TRUE, 0);
11280
11281       g_signal_connect_swapped (button, "clicked",
11282                                 G_CALLBACK (gtk_widget_destroy),
11283                                 window);
11284     }
11285
11286   if (!GTK_WIDGET_VISIBLE (window))
11287     gtk_widget_show_all (window);
11288   else
11289     gtk_widget_destroy (window);
11290 }
11291
11292 /*
11293  * Gamma Curve
11294  */
11295
11296 void
11297 create_gamma_curve (GtkWidget *widget)
11298 {
11299   static GtkWidget *window = NULL, *curve;
11300   static int count = 0;
11301   gfloat vec[256];
11302   gint max;
11303   gint i;
11304   
11305   if (!window)
11306     {
11307       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11308       gtk_window_set_screen (GTK_WINDOW (window),
11309                              gtk_widget_get_screen (widget));
11310
11311       gtk_window_set_title (GTK_WINDOW (window), "test");
11312       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11313
11314       g_signal_connect (window, "destroy",
11315                         G_CALLBACK(gtk_widget_destroyed),
11316                         &window);
11317
11318       curve = gtk_gamma_curve_new ();
11319       gtk_container_add (GTK_CONTAINER (window), curve);
11320       gtk_widget_show (curve);
11321     }
11322
11323   max = 127 + (count % 2)*128;
11324   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11325                        0, max, 0, max);
11326   for (i = 0; i < max; ++i)
11327     vec[i] = (127 / sqrt (max)) * sqrt (i);
11328   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11329                         max, vec);
11330
11331   if (!GTK_WIDGET_VISIBLE (window))
11332     gtk_widget_show (window);
11333   else if (count % 4 == 3)
11334     {
11335       gtk_widget_destroy (window);
11336       window = NULL;
11337     }
11338
11339   ++count;
11340 }
11341
11342 /*
11343  * Test scrolling
11344  */
11345
11346 static int scroll_test_pos = 0.0;
11347
11348 static gint
11349 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
11350                     GtkAdjustment *adj)
11351 {
11352   gint i,j;
11353   gint imin, imax, jmin, jmax;
11354   
11355   imin = (event->area.x) / 10;
11356   imax = (event->area.x + event->area.width + 9) / 10;
11357
11358   jmin = ((int)adj->value + event->area.y) / 10;
11359   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
11360
11361   gdk_window_clear_area (widget->window,
11362                          event->area.x, event->area.y,
11363                          event->area.width, event->area.height);
11364
11365   for (i=imin; i<imax; i++)
11366     for (j=jmin; j<jmax; j++)
11367       if ((i+j) % 2)
11368         gdk_draw_rectangle (widget->window, 
11369                             widget->style->black_gc,
11370                             TRUE,
11371                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
11372
11373   return TRUE;
11374 }
11375
11376 static gint
11377 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
11378                     GtkAdjustment *adj)
11379 {
11380   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
11381                                     -adj->page_increment / 2:
11382                                     adj->page_increment / 2);
11383   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
11384   gtk_adjustment_set_value (adj, new_value);  
11385   
11386   return TRUE;
11387 }
11388
11389 static void
11390 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
11391                        GtkAdjustment *adj)
11392 {
11393   adj->page_increment = 0.9 * widget->allocation.height;
11394   adj->page_size = widget->allocation.height;
11395
11396   g_signal_emit_by_name (adj, "changed");
11397 }
11398
11399 static void
11400 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
11401 {
11402   /* gint source_min = (int)adj->value - scroll_test_pos; */
11403   gint dy;
11404
11405   dy = scroll_test_pos - (int)adj->value;
11406   scroll_test_pos = adj->value;
11407
11408   if (!GTK_WIDGET_DRAWABLE (widget))
11409     return;
11410   gdk_window_scroll (widget->window, 0, dy);
11411   gdk_window_process_updates (widget->window, FALSE);
11412 }
11413
11414
11415 void
11416 create_scroll_test (GtkWidget *widget)
11417 {
11418   static GtkWidget *window = NULL;
11419   GtkWidget *hbox;
11420   GtkWidget *drawing_area;
11421   GtkWidget *scrollbar;
11422   GtkWidget *button;
11423   GtkAdjustment *adj;
11424   GdkGeometry geometry;
11425   GdkWindowHints geometry_mask;
11426
11427   if (!window)
11428     {
11429       window = gtk_dialog_new ();
11430
11431       gtk_window_set_screen (GTK_WINDOW (window),
11432                              gtk_widget_get_screen (widget));
11433
11434       g_signal_connect (window, "destroy",
11435                         G_CALLBACK (gtk_widget_destroyed),
11436                         &window);
11437
11438       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
11439       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11440
11441       hbox = gtk_hbox_new (FALSE, 0);
11442       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
11443                           TRUE, TRUE, 0);
11444       gtk_widget_show (hbox);
11445
11446       drawing_area = gtk_drawing_area_new ();
11447       gtk_widget_set_size_request (drawing_area, 200, 200);
11448       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
11449       gtk_widget_show (drawing_area);
11450
11451       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
11452
11453       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
11454       scroll_test_pos = 0.0;
11455
11456       scrollbar = gtk_vscrollbar_new (adj);
11457       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
11458       gtk_widget_show (scrollbar);
11459
11460       g_signal_connect (drawing_area, "expose_event",
11461                         G_CALLBACK (scroll_test_expose), adj);
11462       g_signal_connect (drawing_area, "configure_event",
11463                         G_CALLBACK (scroll_test_configure), adj);
11464       g_signal_connect (drawing_area, "scroll_event",
11465                         G_CALLBACK (scroll_test_scroll), adj);
11466       
11467       g_signal_connect (adj, "value_changed",
11468                         G_CALLBACK (scroll_test_adjustment_changed),
11469                         drawing_area);
11470       
11471       /* .. And create some buttons */
11472
11473       button = gtk_button_new_with_label ("Quit");
11474       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11475                           button, TRUE, TRUE, 0);
11476
11477       g_signal_connect_swapped (button, "clicked",
11478                                 G_CALLBACK (gtk_widget_destroy),
11479                                 window);
11480       gtk_widget_show (button);
11481
11482       /* Set up gridded geometry */
11483
11484       geometry_mask = GDK_HINT_MIN_SIZE | 
11485                        GDK_HINT_BASE_SIZE | 
11486                        GDK_HINT_RESIZE_INC;
11487
11488       geometry.min_width = 20;
11489       geometry.min_height = 20;
11490       geometry.base_width = 0;
11491       geometry.base_height = 0;
11492       geometry.width_inc = 10;
11493       geometry.height_inc = 10;
11494       
11495       gtk_window_set_geometry_hints (GTK_WINDOW (window),
11496                                drawing_area, &geometry, geometry_mask);
11497     }
11498
11499   if (!GTK_WIDGET_VISIBLE (window))
11500     gtk_widget_show (window);
11501   else
11502     gtk_widget_destroy (window);
11503 }
11504
11505 /*
11506  * Timeout Test
11507  */
11508
11509 static int timer = 0;
11510
11511 gint
11512 timeout_test (GtkWidget *label)
11513 {
11514   static int count = 0;
11515   static char buffer[32];
11516
11517   sprintf (buffer, "count: %d", ++count);
11518   gtk_label_set_text (GTK_LABEL (label), buffer);
11519
11520   return TRUE;
11521 }
11522
11523 void
11524 start_timeout_test (GtkWidget *widget,
11525                     GtkWidget *label)
11526 {
11527   if (!timer)
11528     {
11529       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
11530     }
11531 }
11532
11533 void
11534 stop_timeout_test (GtkWidget *widget,
11535                    gpointer   data)
11536 {
11537   if (timer)
11538     {
11539       gtk_timeout_remove (timer);
11540       timer = 0;
11541     }
11542 }
11543
11544 void
11545 destroy_timeout_test (GtkWidget  *widget,
11546                       GtkWidget **window)
11547 {
11548   stop_timeout_test (NULL, NULL);
11549
11550   *window = NULL;
11551 }
11552
11553 void
11554 create_timeout_test (GtkWidget *widget)
11555 {
11556   static GtkWidget *window = NULL;
11557   GtkWidget *button;
11558   GtkWidget *label;
11559
11560   if (!window)
11561     {
11562       window = gtk_dialog_new ();
11563
11564       gtk_window_set_screen (GTK_WINDOW (window),
11565                              gtk_widget_get_screen (widget));
11566
11567       g_signal_connect (window, "destroy",
11568                         G_CALLBACK (destroy_timeout_test),
11569                         &window);
11570
11571       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
11572       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11573
11574       label = gtk_label_new ("count: 0");
11575       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11576       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11577                           label, TRUE, TRUE, 0);
11578       gtk_widget_show (label);
11579
11580       button = gtk_button_new_with_label ("close");
11581       g_signal_connect_swapped (button, "clicked",
11582                                 G_CALLBACK (gtk_widget_destroy),
11583                                 window);
11584       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11585       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11586                           button, TRUE, TRUE, 0);
11587       gtk_widget_grab_default (button);
11588       gtk_widget_show (button);
11589
11590       button = gtk_button_new_with_label ("start");
11591       g_signal_connect (button, "clicked",
11592                         G_CALLBACK(start_timeout_test),
11593                         label);
11594       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11595       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11596                           button, TRUE, TRUE, 0);
11597       gtk_widget_show (button);
11598
11599       button = gtk_button_new_with_label ("stop");
11600       g_signal_connect (button, "clicked",
11601                         G_CALLBACK (stop_timeout_test),
11602                         NULL);
11603       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11604       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11605                           button, TRUE, TRUE, 0);
11606       gtk_widget_show (button);
11607     }
11608
11609   if (!GTK_WIDGET_VISIBLE (window))
11610     gtk_widget_show (window);
11611   else
11612     gtk_widget_destroy (window);
11613 }
11614
11615 /*
11616  * Idle Test
11617  */
11618
11619 static int idle_id = 0;
11620
11621 static gint
11622 idle_test (GtkWidget *label)
11623 {
11624   static int count = 0;
11625   static char buffer[32];
11626
11627   sprintf (buffer, "count: %d", ++count);
11628   gtk_label_set_text (GTK_LABEL (label), buffer);
11629
11630   return TRUE;
11631 }
11632
11633 static void
11634 start_idle_test (GtkWidget *widget,
11635                  GtkWidget *label)
11636 {
11637   if (!idle_id)
11638     {
11639       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
11640     }
11641 }
11642
11643 static void
11644 stop_idle_test (GtkWidget *widget,
11645                 gpointer   data)
11646 {
11647   if (idle_id)
11648     {
11649       gtk_idle_remove (idle_id);
11650       idle_id = 0;
11651     }
11652 }
11653
11654 static void
11655 destroy_idle_test (GtkWidget  *widget,
11656                    GtkWidget **window)
11657 {
11658   stop_idle_test (NULL, NULL);
11659
11660   *window = NULL;
11661 }
11662
11663 static void
11664 toggle_idle_container (GObject *button,
11665                        GtkContainer *container)
11666 {
11667   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
11668 }
11669
11670 static void
11671 create_idle_test (GtkWidget *widget)
11672 {
11673   static GtkWidget *window = NULL;
11674   GtkWidget *button;
11675   GtkWidget *label;
11676   GtkWidget *container;
11677
11678   if (!window)
11679     {
11680       GtkWidget *button2;
11681       GtkWidget *frame;
11682       GtkWidget *box;
11683
11684       window = gtk_dialog_new ();
11685
11686       gtk_window_set_screen (GTK_WINDOW (window),
11687                              gtk_widget_get_screen (widget));
11688
11689       g_signal_connect (window, "destroy",
11690                         G_CALLBACK (destroy_idle_test),
11691                         &window);
11692
11693       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
11694       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11695
11696       label = gtk_label_new ("count: 0");
11697       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11698       gtk_widget_show (label);
11699       
11700       container =
11701         gtk_widget_new (GTK_TYPE_HBOX,
11702                         "visible", TRUE,
11703                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
11704                          * "GtkWidget::visible", TRUE,
11705                          */
11706                          "child", label,
11707                         /* NULL), */
11708                         NULL);
11709       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11710                           container, TRUE, TRUE, 0);
11711
11712       frame =
11713         gtk_widget_new (GTK_TYPE_FRAME,
11714                         "border_width", 5,
11715                         "label", "Label Container",
11716                         "visible", TRUE,
11717                         "parent", GTK_DIALOG (window)->vbox,
11718                         NULL);
11719       box =
11720         gtk_widget_new (GTK_TYPE_VBOX,
11721                         "visible", TRUE,
11722                         "parent", frame,
11723                         NULL);
11724       button =
11725         g_object_connect (gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11726                                           "label", "Resize-Parent",
11727                                           "user_data", (void*)GTK_RESIZE_PARENT,
11728                                           "visible", TRUE,
11729                                           "parent", box,
11730                                           NULL),
11731                           "signal::clicked", toggle_idle_container, container,
11732                           NULL);
11733       button = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11734                                "label", "Resize-Queue",
11735                                "user_data", (void*)GTK_RESIZE_QUEUE,
11736                                "group", button,
11737                                "visible", TRUE,
11738                                "parent", box,
11739                                NULL);
11740       g_object_connect (button,
11741                         "signal::clicked", toggle_idle_container, container,
11742                         NULL);
11743       button2 = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11744                                 "label", "Resize-Immediate",
11745                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
11746                                 NULL);
11747       g_object_connect (button2,
11748                         "signal::clicked", toggle_idle_container, container,
11749                         NULL);
11750       g_object_set (button2,
11751                     "group", button,
11752                     "visible", TRUE,
11753                     "parent", box,
11754                     NULL);
11755
11756       button = gtk_button_new_with_label ("close");
11757       g_signal_connect_swapped (button, "clicked",
11758                                 G_CALLBACK (gtk_widget_destroy),
11759                                 window);
11760       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11761       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11762                           button, TRUE, TRUE, 0);
11763       gtk_widget_grab_default (button);
11764       gtk_widget_show (button);
11765
11766       button = gtk_button_new_with_label ("start");
11767       g_signal_connect (button, "clicked",
11768                         G_CALLBACK (start_idle_test),
11769                         label);
11770       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11771       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11772                           button, TRUE, TRUE, 0);
11773       gtk_widget_show (button);
11774
11775       button = gtk_button_new_with_label ("stop");
11776       g_signal_connect (button, "clicked",
11777                         G_CALLBACK (stop_idle_test),
11778                         NULL);
11779       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11780       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11781                           button, TRUE, TRUE, 0);
11782       gtk_widget_show (button);
11783     }
11784
11785   if (!GTK_WIDGET_VISIBLE (window))
11786     gtk_widget_show (window);
11787   else
11788     gtk_widget_destroy (window);
11789 }
11790
11791 /*
11792  * rc file test
11793  */
11794
11795 void
11796 reload_all_rc_files (void)
11797 {
11798   static GdkAtom atom_rcfiles = GDK_NONE;
11799
11800   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
11801   int i;
11802   
11803   if (!atom_rcfiles)
11804     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
11805
11806   for(i = 0; i < 5; i++)
11807     send_event->client.data.l[i] = 0;
11808   send_event->client.data_format = 32;
11809   send_event->client.message_type = atom_rcfiles;
11810   gdk_event_send_clientmessage_toall (send_event);
11811
11812   gdk_event_free (send_event);
11813 }
11814
11815 void
11816 create_rc_file (GtkWidget *widget)
11817 {
11818   static GtkWidget *window = NULL;
11819   GtkWidget *button;
11820   GtkWidget *frame;
11821   GtkWidget *vbox;
11822   GtkWidget *label;
11823
11824   if (!window)
11825     {
11826       window = gtk_dialog_new ();
11827
11828       gtk_window_set_screen (GTK_WINDOW (window),
11829                              gtk_widget_get_screen (widget));
11830
11831       g_signal_connect (window, "destroy",
11832                         G_CALLBACK (gtk_widget_destroyed),
11833                         &window);
11834
11835       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
11836       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), frame, FALSE, FALSE, 0);
11837
11838       vbox = gtk_vbox_new (FALSE, 0);
11839       gtk_container_add (GTK_CONTAINER (frame), vbox);
11840       
11841       label = gtk_label_new ("This label should be red");
11842       gtk_widget_set_name (label, "testgtk-red-label");
11843       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11844
11845       label = gtk_label_new ("This label should be green");
11846       gtk_widget_set_name (label, "testgtk-green-label");
11847       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11848
11849       label = gtk_label_new ("This label should be blue");
11850       gtk_widget_set_name (label, "testgtk-blue-label");
11851       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11852
11853       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
11854       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11855
11856       button = gtk_button_new_with_label ("Reload");
11857       g_signal_connect (button, "clicked",
11858                         G_CALLBACK (gtk_rc_reparse_all), NULL);
11859       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11860       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11861                           button, TRUE, TRUE, 0);
11862       gtk_widget_grab_default (button);
11863
11864       button = gtk_button_new_with_label ("Reload All");
11865       g_signal_connect (button, "clicked",
11866                         G_CALLBACK (reload_all_rc_files), NULL);
11867       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11868       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11869                           button, TRUE, TRUE, 0);
11870
11871       button = gtk_button_new_with_label ("Close");
11872       g_signal_connect_swapped (button, "clicked",
11873                                 G_CALLBACK (gtk_widget_destroy),
11874                                 window);
11875       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11876       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11877                           button, TRUE, TRUE, 0);
11878     }
11879
11880   if (!GTK_WIDGET_VISIBLE (window))
11881     gtk_widget_show_all (window);
11882   else
11883     gtk_widget_destroy (window);
11884 }
11885
11886 /*
11887  * Test of recursive mainloop
11888  */
11889
11890 void
11891 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
11892 {
11893   *window = NULL;
11894   gtk_main_quit ();
11895 }
11896
11897 void
11898 create_mainloop (GtkWidget *widget)
11899 {
11900   static GtkWidget *window = NULL;
11901   GtkWidget *label;
11902   GtkWidget *button;
11903
11904   if (!window)
11905     {
11906       window = gtk_dialog_new ();
11907
11908       gtk_window_set_screen (GTK_WINDOW (window),
11909                              gtk_widget_get_screen (widget));
11910
11911       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
11912
11913       g_signal_connect (window, "destroy",
11914                         G_CALLBACK (mainloop_destroyed),
11915                         &window);
11916
11917       label = gtk_label_new ("In recursive main loop...");
11918       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
11919
11920       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
11921                           TRUE, TRUE, 0);
11922       gtk_widget_show (label);
11923
11924       button = gtk_button_new_with_label ("Leave");
11925       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
11926                           FALSE, TRUE, 0);
11927
11928       g_signal_connect_swapped (button, "clicked",
11929                                 G_CALLBACK (gtk_widget_destroy),
11930                                 window);
11931
11932       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11933       gtk_widget_grab_default (button);
11934
11935       gtk_widget_show (button);
11936     }
11937
11938   if (!GTK_WIDGET_VISIBLE (window))
11939     {
11940       gtk_widget_show (window);
11941
11942       g_print ("create_mainloop: start\n");
11943       gtk_main ();
11944       g_print ("create_mainloop: done\n");
11945     }
11946   else
11947     gtk_widget_destroy (window);
11948 }
11949
11950 gboolean
11951 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
11952 {
11953   GtkLayout *layout;
11954
11955   gint i,j;
11956   gint imin, imax, jmin, jmax;
11957
11958   layout = GTK_LAYOUT (widget);
11959
11960   if (event->window != layout->bin_window)
11961     return FALSE;
11962   
11963   imin = (event->area.x) / 10;
11964   imax = (event->area.x + event->area.width + 9) / 10;
11965
11966   jmin = (event->area.y) / 10;
11967   jmax = (event->area.y + event->area.height + 9) / 10;
11968
11969   for (i=imin; i<imax; i++)
11970     for (j=jmin; j<jmax; j++)
11971       if ((i+j) % 2)
11972         gdk_draw_rectangle (layout->bin_window,
11973                             widget->style->black_gc,
11974                             TRUE,
11975                             10*i, 10*j, 
11976                             1+i%10, 1+j%10);
11977   
11978   return FALSE;
11979 }
11980
11981 void create_layout (GtkWidget *widget)
11982 {
11983   static GtkWidget *window = NULL;
11984   GtkWidget *layout;
11985   GtkWidget *scrolledwindow;
11986   GtkWidget *button;
11987
11988   if (!window)
11989     {
11990       gchar buf[16];
11991
11992       gint i, j;
11993       
11994       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11995       gtk_window_set_screen (GTK_WINDOW (window),
11996                              gtk_widget_get_screen (widget));
11997
11998       g_signal_connect (window, "destroy",
11999                         G_CALLBACK (gtk_widget_destroyed),
12000                         &window);
12001
12002       gtk_window_set_title (GTK_WINDOW (window), "Layout");
12003       gtk_widget_set_size_request (window, 200, 200);
12004
12005       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
12006       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
12007                                            GTK_SHADOW_IN);
12008       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
12009                                          GTK_CORNER_TOP_RIGHT);
12010
12011       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
12012       
12013       layout = gtk_layout_new (NULL, NULL);
12014       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
12015
12016       /* We set step sizes here since GtkLayout does not set
12017        * them itself.
12018        */
12019       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
12020       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
12021       
12022       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
12023       g_signal_connect (layout, "expose_event",
12024                         G_CALLBACK (layout_expose_handler), NULL);
12025       
12026       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
12027       
12028       for (i=0 ; i < 16 ; i++)
12029         for (j=0 ; j < 16 ; j++)
12030           {
12031             sprintf(buf, "Button %d, %d", i, j);
12032             if ((i + j) % 2)
12033               button = gtk_button_new_with_label (buf);
12034             else
12035               button = gtk_label_new (buf);
12036
12037             gtk_layout_put (GTK_LAYOUT (layout), button,
12038                             j*100, i*100);
12039           }
12040
12041       for (i=16; i < 1280; i++)
12042         {
12043           sprintf(buf, "Button %d, %d", i, 0);
12044           if (i % 2)
12045             button = gtk_button_new_with_label (buf);
12046           else
12047             button = gtk_label_new (buf);
12048
12049           gtk_layout_put (GTK_LAYOUT (layout), button,
12050                           0, i*100);
12051         }
12052     }
12053
12054   if (!GTK_WIDGET_VISIBLE (window))
12055     gtk_widget_show_all (window);
12056   else
12057     gtk_widget_destroy (window);
12058 }
12059
12060 void
12061 create_styles (GtkWidget *widget)
12062 {
12063   static GtkWidget *window = NULL;
12064   GtkWidget *label;
12065   GtkWidget *button;
12066   GtkWidget *entry;
12067   GtkWidget *vbox;
12068   static GdkColor red =    { 0, 0xffff, 0,      0      };
12069   static GdkColor green =  { 0, 0,      0xffff, 0      };
12070   static GdkColor blue =   { 0, 0,      0,      0xffff };
12071   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
12072   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
12073   PangoFontDescription *font_desc;
12074
12075   GtkRcStyle *rc_style;
12076
12077   if (!window)
12078     {
12079       window = gtk_dialog_new ();
12080       gtk_window_set_screen (GTK_WINDOW (window),
12081                              gtk_widget_get_screen (widget));
12082      
12083       g_signal_connect (window, "destroy",
12084                         G_CALLBACK (gtk_widget_destroyed),
12085                         &window);
12086
12087       
12088       button = gtk_button_new_with_label ("Close");
12089       g_signal_connect_swapped (button, "clicked",
12090                                 G_CALLBACK (gtk_widget_destroy),
12091                                 window);
12092       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12093       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12094                           button, TRUE, TRUE, 0);
12095       gtk_widget_show (button);
12096
12097       vbox = gtk_vbox_new (FALSE, 5);
12098       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
12099       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, FALSE, FALSE, 0);
12100       
12101       label = gtk_label_new ("Font:");
12102       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12103       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12104
12105       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
12106
12107       button = gtk_button_new_with_label ("Some Text");
12108       gtk_widget_modify_font (GTK_BIN (button)->child, font_desc);
12109       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12110
12111       label = gtk_label_new ("Foreground:");
12112       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12113       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12114
12115       button = gtk_button_new_with_label ("Some Text");
12116       gtk_widget_modify_fg (GTK_BIN (button)->child, GTK_STATE_NORMAL, &red);
12117       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12118
12119       label = gtk_label_new ("Background:");
12120       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12121       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12122
12123       button = gtk_button_new_with_label ("Some Text");
12124       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
12125       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12126
12127       label = gtk_label_new ("Text:");
12128       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12129       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12130
12131       entry = gtk_entry_new ();
12132       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
12133       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
12134       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
12135
12136       label = gtk_label_new ("Base:");
12137       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12138       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12139
12140       entry = gtk_entry_new ();
12141       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
12142       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
12143       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
12144
12145       label = gtk_label_new ("Multiple:");
12146       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
12147       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12148
12149       button = gtk_button_new_with_label ("Some Text");
12150
12151       rc_style = gtk_rc_style_new ();
12152
12153       rc_style->font_desc = pango_font_description_copy (font_desc);
12154       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
12155       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
12156       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
12157       rc_style->fg[GTK_STATE_NORMAL] = yellow;
12158       rc_style->bg[GTK_STATE_NORMAL] = blue;
12159       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
12160       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
12161       rc_style->fg[GTK_STATE_ACTIVE] = red;
12162       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
12163       rc_style->xthickness = 5;
12164       rc_style->ythickness = 5;
12165
12166       gtk_widget_modify_style (button, rc_style);
12167       gtk_widget_modify_style (GTK_BIN (button)->child, rc_style);
12168
12169       g_object_unref (rc_style);
12170       
12171       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12172     }
12173   
12174   if (!GTK_WIDGET_VISIBLE (window))
12175     gtk_widget_show_all (window);
12176   else
12177     gtk_widget_destroy (window);
12178 }
12179
12180 /*
12181  * Main Window and Exit
12182  */
12183
12184 void
12185 do_exit (GtkWidget *widget, GtkWidget *window)
12186 {
12187   gtk_widget_destroy (window);
12188   gtk_main_quit ();
12189 }
12190
12191 struct {
12192   char *label;
12193   void (*func) ();
12194   gboolean do_not_benchmark;
12195 } buttons[] =
12196 {
12197   { "big windows", create_big_windows },
12198   { "button box", create_button_box },
12199   { "buttons", create_buttons },
12200   { "check buttons", create_check_buttons },
12201   { "clist", create_clist},
12202   { "color selection", create_color_selection },
12203   { "ctree", create_ctree },
12204   { "cursors", create_cursors },
12205   { "dialog", create_dialog },
12206   { "display & screen", create_display_screen },
12207   { "entry", create_entry },
12208   { "event watcher", create_event_watcher },
12209   { "file selection", create_file_selection },
12210   { "flipping", create_flipping },
12211   { "focus", create_focus },
12212   { "font selection", create_font_selection },
12213   { "gamma curve", create_gamma_curve, TRUE },
12214   { "gridded geometry", create_gridded_geometry, TRUE },
12215   { "handle box", create_handle_box },
12216   { "image from drawable", create_get_image },
12217   { "image", create_image },
12218   { "item factory", create_item_factory },
12219   { "key lookup", create_key_lookup },
12220   { "labels", create_labels },
12221   { "layout", create_layout },
12222   { "list", create_list },
12223   { "menus", create_menus },
12224   { "message dialog", create_message_dialog },
12225   { "modal window", create_modal_window, TRUE },
12226   { "notebook", create_notebook },
12227   { "panes", create_panes },
12228   { "paned keyboard", create_paned_keyboard_navigation },
12229   { "pixmap", create_pixmap },
12230   { "preview color", create_color_preview, TRUE },
12231   { "preview gray", create_gray_preview, TRUE },
12232   { "progress bar", create_progress_bar },
12233   { "properties", create_properties },
12234   { "radio buttons", create_radio_buttons },
12235   { "range controls", create_range_controls },
12236   { "rc file", create_rc_file },
12237   { "reparent", create_reparent },
12238   { "resize grips", create_resize_grips },
12239   { "rulers", create_rulers },
12240   { "saved position", create_saved_position },
12241   { "scrolled windows", create_scrolled_windows },
12242   { "shapes", create_shapes },
12243   { "size groups", create_size_groups },
12244   { "spinbutton", create_spins },
12245   { "statusbar", create_statusbar },
12246   { "styles", create_styles },
12247   { "test idle", create_idle_test },
12248   { "test mainloop", create_mainloop, TRUE },
12249   { "test scrolling", create_scroll_test },
12250   { "test selection", create_selection_test },
12251   { "test timeout", create_timeout_test },
12252   { "text", create_text },
12253   { "toggle buttons", create_toggle_buttons },
12254   { "toolbar", create_toolbar },
12255   { "tooltips", create_tooltips },
12256   { "tree", create_tree_mode_window},
12257   { "WM hints", create_wmhints },
12258   { "window sizing", create_window_sizing },
12259   { "window states", create_window_states }
12260 };
12261 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
12262
12263 void
12264 create_main_window (void)
12265 {
12266   GtkWidget *window;
12267   GtkWidget *box1;
12268   GtkWidget *box2;
12269   GtkWidget *scrolled_window;
12270   GtkWidget *button;
12271   GtkWidget *label;
12272   gchar buffer[64];
12273   GtkWidget *separator;
12274   GdkGeometry geometry;
12275   int i;
12276
12277   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12278   gtk_widget_set_name (window, "main window");
12279   gtk_widget_set_uposition (window, 20, 20);
12280   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
12281
12282   geometry.min_width = -1;
12283   geometry.min_height = -1;
12284   geometry.max_width = -1;
12285   geometry.max_height = G_MAXSHORT;
12286   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
12287                                  &geometry,
12288                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
12289
12290   g_signal_connect (window, "destroy",
12291                     G_CALLBACK (gtk_main_quit),
12292                     NULL);
12293   g_signal_connect (window, "delete-event",
12294                     G_CALLBACK (gtk_false),
12295                     NULL);
12296
12297   box1 = gtk_vbox_new (FALSE, 0);
12298   gtk_container_add (GTK_CONTAINER (window), box1);
12299
12300   if (gtk_micro_version > 0)
12301     sprintf (buffer,
12302              "Gtk+ v%d.%d.%d",
12303              gtk_major_version,
12304              gtk_minor_version,
12305              gtk_micro_version);
12306   else
12307     sprintf (buffer,
12308              "Gtk+ v%d.%d",
12309              gtk_major_version,
12310              gtk_minor_version);
12311
12312   label = gtk_label_new (buffer);
12313   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
12314   gtk_widget_set_name (label, "testgtk-version-label");
12315
12316   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
12317   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
12318   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
12319                                   GTK_POLICY_NEVER, 
12320                                   GTK_POLICY_AUTOMATIC);
12321   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
12322
12323   box2 = gtk_vbox_new (FALSE, 0);
12324   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12325   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
12326   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
12327                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
12328   gtk_widget_show (box2);
12329
12330   for (i = 0; i < nbuttons; i++)
12331     {
12332       button = gtk_button_new_with_label (buttons[i].label);
12333       if (buttons[i].func)
12334         g_signal_connect (button, 
12335                           "clicked", 
12336                           G_CALLBACK(buttons[i].func),
12337                           NULL);
12338       else
12339         gtk_widget_set_sensitive (button, FALSE);
12340       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12341     }
12342
12343   separator = gtk_hseparator_new ();
12344   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
12345
12346   box2 = gtk_vbox_new (FALSE, 10);
12347   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12348   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
12349
12350   button = gtk_button_new_with_mnemonic ("_Close");
12351   g_signal_connect (button, "clicked",
12352                     G_CALLBACK (do_exit),
12353                     window);
12354   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12355   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12356   gtk_widget_grab_default (button);
12357
12358   gtk_widget_show_all (window);
12359 }
12360
12361 static void
12362 test_init ()
12363 {
12364   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
12365                    G_FILE_TEST_EXISTS))
12366     {
12367       putenv ("GDK_PIXBUF_MODULE_FILE=../gdk-pixbuf/gdk-pixbuf.loaders");
12368       putenv ("GTK_IM_MODULE_FILE=../modules/input/gtk.immodules");
12369     }
12370 }
12371
12372 static char *
12373 pad (const char *str, int to)
12374 {
12375   static char buf[256];
12376   int len = strlen (str);
12377   int i;
12378
12379   for (i = 0; i < to; i++)
12380     buf[i] = ' ';
12381
12382   buf[to] = '\0';
12383
12384   memcpy (buf, str, len);
12385
12386   return buf;
12387 }
12388
12389 static void
12390 bench_iteration (void (* fn) ())
12391 {
12392   fn (); /* on */
12393   while (g_main_context_iteration (NULL, FALSE));
12394   fn (); /* off */
12395   while (g_main_context_iteration (NULL, FALSE));
12396 }
12397
12398 void
12399 do_real_bench (void (* fn) (), char *name, int num)
12400 {
12401   GTimeVal tv0, tv1;
12402   double dt_first;
12403   double dt;
12404   int n;
12405   static gboolean printed_headers = FALSE;
12406
12407   if (!printed_headers) {
12408     g_print ("Test                 Iters      First      Other\n");
12409     g_print ("-------------------- ----- ---------- ----------\n");
12410     printed_headers = TRUE;
12411   }
12412
12413   g_get_current_time (&tv0);
12414   bench_iteration (fn); 
12415   g_get_current_time (&tv1);
12416
12417   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12418         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12419
12420   g_get_current_time (&tv0);
12421   for (n = 0; n < num - 1; n++)
12422     bench_iteration (fn); 
12423   g_get_current_time (&tv1);
12424   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12425         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12426
12427   g_print ("%s %5d ", pad (name, 20), num);
12428   if (num > 1)
12429     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
12430   else
12431     g_print ("%10.1f\n", dt_first);
12432 }
12433
12434 void
12435 do_bench (char* what, int num)
12436 {
12437   int i;
12438   void (* fn) ();
12439   fn = NULL;
12440
12441   if (g_ascii_strcasecmp (what, "ALL") == 0)
12442     {
12443       for (i = 0; i < nbuttons; i++)
12444         {
12445           if (!buttons[i].do_not_benchmark)
12446             do_real_bench (buttons[i].func, buttons[i].label, num);
12447         }
12448
12449       return;
12450     }
12451   else
12452     {
12453       for (i = 0; i < nbuttons; i++)
12454         {
12455           if (strcmp (buttons[i].label, what) == 0)
12456             {
12457               fn = buttons[i].func;
12458               break;
12459             }
12460         }
12461       
12462       if (!fn)
12463         g_print ("Can't bench: \"%s\" not found.\n", what);
12464       else
12465         do_real_bench (fn, buttons[i].label, num);
12466     }
12467 }
12468
12469 void 
12470 usage (void)
12471 {
12472   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
12473   exit (1);
12474 }
12475
12476 int
12477 main (int argc, char *argv[])
12478 {
12479   GtkBindingSet *binding_set;
12480   int i;
12481   gboolean done_benchmarks = FALSE;
12482
12483   srand (time (NULL));
12484
12485   test_init ();
12486
12487   /* Check to see if we are being run from the correct
12488    * directory.
12489    */
12490   if (file_exists ("testgtkrc"))
12491     gtk_rc_add_default_file ("testgtkrc");
12492
12493   g_set_application_name ("GTK+ Test Program");
12494
12495   gtk_init (&argc, &argv);
12496
12497   /*  benchmarking
12498    */
12499   for (i = 1; i < argc; i++)
12500     {
12501       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
12502         {
12503           int num = 1;
12504           char *nextarg;
12505           char *what;
12506           char *count;
12507           
12508           nextarg = strchr (argv[i], '=');
12509           if (nextarg)
12510             nextarg++;
12511           else
12512             {
12513               i++;
12514               if (i == argc)
12515                 usage ();
12516               nextarg = argv[i];
12517             }
12518
12519           count = strchr (nextarg, ':');
12520           if (count)
12521             {
12522               what = g_strndup (nextarg, count - nextarg);
12523               count++;
12524               num = atoi (count);
12525               if (num <= 0)
12526                 usage ();
12527             }
12528           else
12529             what = g_strdup (nextarg);
12530
12531           do_bench (what, num ? num : 1);
12532           done_benchmarks = TRUE;
12533         }
12534       else
12535         usage ();
12536     }
12537   if (done_benchmarks)
12538     return 0;
12539
12540   /* bindings test
12541    */
12542   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
12543   gtk_binding_entry_add_signal (binding_set,
12544                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
12545                                 "debug_msg",
12546                                 1,
12547                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
12548   
12549   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
12550    * changes
12551    */
12552
12553   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
12554                        "   fg[NORMAL] = \"#ff0000\"\n"
12555                        "   font = \"Sans 18\"\n"
12556                        "}\n"
12557                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
12558   
12559   create_main_window ();
12560
12561   gtk_main ();
12562
12563   if (1)
12564     {
12565       while (g_main_context_pending (NULL))
12566         g_main_context_iteration (NULL, FALSE);
12567 #if 0
12568       sleep (1);
12569       while (g_main_context_pending (NULL))
12570         g_main_context_iteration (NULL, FALSE);
12571 #endif
12572     }
12573   return 0;
12574 }