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