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