]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
testgtk: Use draw signal in layout test
[~andy/gtk] / tests / testgtk.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27
28 #include "config.h"
29
30 #undef  G_LOG_DOMAIN
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include <math.h>
37 #include <time.h>
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 #include "gtk/gtk.h"
43 #include "gdk/gdk.h"
44 #include "gdk/gdkkeysyms.h"
45
46 #ifdef G_OS_WIN32
47 #define sleep(n) _sleep(n)
48 #endif
49
50 #include "prop-editor.h"
51
52 #include "test.xpm"
53
54 gboolean
55 file_exists (const char *filename)
56 {
57   struct stat statbuf;
58
59   return stat (filename, &statbuf) == 0;
60 }
61
62 GtkWidget *
63 shape_create_icon (GdkScreen *screen,
64                    char      *xpm_file,
65                    gint       x,
66                    gint       y,
67                    gint       px,
68                    gint       py,
69                    gint       window_type);
70
71 static GtkWidget *
72 build_option_menu (gchar           *items[],
73                    gint             num_items,
74                    gint             history,
75                    void           (*func) (GtkWidget *widget, gpointer data),
76                    gpointer         data);
77
78 /* macro, structure and variables used by tree window demos */
79 #define DEFAULT_NUMBER_OF_ITEM  3
80 #define DEFAULT_RECURSION_LEVEL 3
81
82 struct {
83   GSList* selection_mode_group;
84   GtkWidget* single_button;
85   GtkWidget* browse_button;
86   GtkWidget* multiple_button;
87   GtkWidget* draw_line_button;
88   GtkWidget* view_line_button;
89   GtkWidget* no_root_item_button;
90   GtkWidget* nb_item_spinner;
91   GtkWidget* recursion_spinner;
92 } sTreeSampleSelection;
93
94 typedef struct sTreeButtons {
95   guint nb_item_add;
96   GtkWidget* add_button;
97   GtkWidget* remove_button;
98   GtkWidget* subtree_button;
99 } sTreeButtons;
100 /* end of tree section */
101
102 static GtkWidget *
103 build_option_menu (gchar           *items[],
104                    gint             num_items,
105                    gint             history,
106                    void           (*func)(GtkWidget *widget, gpointer data),
107                    gpointer         data)
108 {
109   GtkWidget *omenu;
110   gint i;
111
112   omenu = gtk_combo_box_new_text ();
113   g_signal_connect (omenu, "changed",
114                     G_CALLBACK (func), data);
115       
116   for (i = 0; i < num_items; i++)
117       gtk_combo_box_append_text (GTK_COMBO_BOX (omenu), items[i]);
118
119   gtk_combo_box_set_active (GTK_COMBO_BOX (omenu), history);
120   
121   return omenu;
122 }
123
124 /*
125  * Windows with an alpha channel
126  */
127
128
129 static gboolean
130 on_alpha_window_draw (GtkWidget *widget,
131                       cairo_t   *cr)
132 {
133   cairo_pattern_t *pattern;
134   int radius, width, height;
135
136   width = gtk_widget_get_allocated_width (widget);
137   height = gtk_widget_get_allocated_height (widget);
138   radius = MIN (width, height) / 2;
139   pattern = cairo_pattern_create_radial (width / 2,
140                                          height / 2,
141                                          0.0,
142                                          width / 2,
143                                          height / 2,
144                                          radius * 1.33);
145
146   if (gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)) &&
147       gtk_widget_is_composited (widget))
148     cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
149   else
150     cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
151     
152   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
153   cairo_paint (cr);
154   
155   cairo_pattern_add_color_stop_rgba (pattern, 0.0,
156                                      1.0, 0.75, 0.0, 1.0); /* solid orange */
157   cairo_pattern_add_color_stop_rgba (pattern, 1.0,
158                                      1.0, 0.75, 0.0, 0.0); /* transparent orange */
159
160   cairo_set_source (cr, pattern);
161   cairo_pattern_destroy (pattern);
162   
163   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
164   cairo_paint (cr);
165
166   return FALSE;
167 }
168
169 static GtkWidget *
170 build_alpha_widgets (void)
171 {
172   GtkWidget *table;
173   GtkWidget *radio_button;
174   GtkWidget *hbox;
175   GtkWidget *label;
176   GtkWidget *entry;
177
178   table = gtk_table_new (1, 1, FALSE);
179
180   radio_button = gtk_radio_button_new_with_label (NULL, "Red");
181   gtk_table_attach (GTK_TABLE (table),
182                     radio_button,
183                     0, 1,                  0, 1,
184                     GTK_EXPAND | GTK_FILL, 0,
185                     0,                     0);
186
187   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
188   gtk_table_attach (GTK_TABLE (table),
189                     radio_button,
190                     0, 1,                  1, 2,
191                     GTK_EXPAND | GTK_FILL, 0,
192                     0,                     0);
193
194   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
195   gtk_table_attach (GTK_TABLE (table),
196                     radio_button,
197                     0, 1,                  2, 3,
198                     GTK_EXPAND | GTK_FILL, 0,
199                     0,                     0);
200
201   gtk_table_attach (GTK_TABLE (table),
202                     gtk_check_button_new_with_label ("Sedentary"),
203                     1, 2,                  0, 1,
204                     GTK_EXPAND | GTK_FILL, 0,
205                     0,                     0);
206   gtk_table_attach (GTK_TABLE (table),
207                     gtk_check_button_new_with_label ("Nocturnal"),
208                     1, 2,                  1, 2,
209                     GTK_EXPAND | GTK_FILL, 0,
210                     0,                     0);
211   gtk_table_attach (GTK_TABLE (table),
212                     gtk_check_button_new_with_label ("Compulsive"),
213                     1, 2,                  2, 3,
214                     GTK_EXPAND | GTK_FILL, 0,
215                     0,                     0);
216
217   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
218   gtk_table_attach (GTK_TABLE (table),
219                     radio_button,
220                     0, 1,                  1, 2,
221                     GTK_EXPAND | GTK_FILL, 0,
222                     0,                     0);
223
224   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
225   gtk_table_attach (GTK_TABLE (table),
226                     radio_button,
227                     0, 1,                  2, 3,
228                     GTK_EXPAND | GTK_FILL, 0,
229                     0,                     0);
230   
231   hbox = gtk_hbox_new (FALSE, 0);
232   label = gtk_label_new (NULL);
233   gtk_label_set_markup (GTK_LABEL (label), "<i>Entry: </i>");
234   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
235   entry = gtk_entry_new ();
236   gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
237   gtk_table_attach (GTK_TABLE (table),
238                     hbox,
239                     0, 1,                  3, 4,
240                     GTK_EXPAND | GTK_FILL, 0,
241                     0,                     0);
242   
243   return table;
244 }
245
246 static void
247 on_alpha_screen_changed (GtkWindow *window,
248                          GdkScreen *old_screen,
249                          GtkWidget *label)
250 {
251   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
252   GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
253
254   if (!visual)
255     {
256       visual = gdk_screen_get_system_visual (screen);
257       gtk_label_set_markup (GTK_LABEL (label), "<b>Screen doesn't support alpha</b>");
258     }
259   else
260     {
261       gtk_label_set_markup (GTK_LABEL (label), "<b>Screen supports alpha</b>");
262     }
263
264   gtk_window_set_visual (window, visual);
265 }
266
267 static void
268 on_composited_changed (GtkWidget *window,
269                       GtkLabel *label)
270 {
271   gboolean is_composited = gtk_widget_is_composited (window);
272
273   if (is_composited)
274     gtk_label_set_text (label, "Composited");
275   else
276     gtk_label_set_text (label, "Not composited");
277 }
278
279 void
280 create_alpha_window (GtkWidget *widget)
281 {
282   static GtkWidget *window;
283
284   if (!window)
285     {
286       GtkWidget *content_area;
287       GtkWidget *vbox;
288       GtkWidget *label;
289       
290       window = gtk_dialog_new_with_buttons ("Alpha Window",
291                                             GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
292                                             GTK_STOCK_CLOSE, 0,
293                                             NULL);
294
295       gtk_widget_set_app_paintable (window, TRUE);
296       g_signal_connect (window, "draw",
297                         G_CALLBACK (on_alpha_window_draw), NULL);
298
299       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
300       
301       vbox = gtk_vbox_new (FALSE, 8);
302       gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
303       gtk_box_pack_start (GTK_BOX (content_area), vbox,
304                           TRUE, TRUE, 0);
305
306       label = gtk_label_new (NULL);
307       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
308       on_alpha_screen_changed (GTK_WINDOW (window), NULL, label);
309       g_signal_connect (window, "screen-changed",
310                         G_CALLBACK (on_alpha_screen_changed), label);
311       
312       label = gtk_label_new (NULL);
313       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
314       on_composited_changed (window, GTK_LABEL (label));
315       g_signal_connect (window, "composited_changed", G_CALLBACK (on_composited_changed), label);
316       
317       gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
318
319       g_signal_connect (window, "destroy",
320                         G_CALLBACK (gtk_widget_destroyed),
321                         &window);
322       
323       g_signal_connect (window, "response",
324                         G_CALLBACK (gtk_widget_destroy),
325                         NULL); 
326     }
327
328   if (!gtk_widget_get_visible (window))
329     gtk_widget_show_all (window);
330   else
331     gtk_widget_destroy (window);
332 }
333
334 /*
335  * Composited non-toplevel window
336  */
337
338 /* The draw event handler for the event box.
339  *
340  * This function simply draws a transparency onto a widget on the area
341  * for which it receives expose events.  This is intended to give the
342  * event box a "transparent" background.
343  *
344  * In order for this to work properly, the widget must have an RGBA
345  * colourmap.  The widget should also be set as app-paintable since it
346  * doesn't make sense for GTK to draw a background if we are drawing it
347  * (and because GTK might actually replace our transparency with its
348  * default background colour).
349  */
350 static gboolean
351 transparent_draw (GtkWidget *widget,
352                   cairo_t   *cr)
353 {
354   cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
355   cairo_paint (cr);
356
357   return FALSE;
358 }
359
360 /* The expose event handler for the window.
361  *
362  * This function performs the actual compositing of the event box onto
363  * the already-existing background of the window at 50% normal opacity.
364  *
365  * In this case we do not want app-paintable to be set on the widget
366  * since we want it to draw its own (red) background.  Because of this,
367  * however, we must ensure that we use g_signal_register_after so that
368  * this handler is called after the red has been drawn.  If it was
369  * called before then GTK would just blindly paint over our work.
370  */
371 static gboolean
372 window_draw (GtkWidget *widget,
373              cairo_t   *cr)
374 {
375   GtkAllocation allocation;
376   GtkWidget *child;
377
378   /* get our child (in this case, the event box) */ 
379   child = gtk_bin_get_child (GTK_BIN (widget));
380
381   gtk_widget_get_allocation (child, &allocation);
382
383   /* the source data is the (composited) event box */
384   gdk_cairo_set_source_window (cr, gtk_widget_get_window (child),
385                                allocation.x,
386                                allocation.y);
387
388   /* composite, with a 50% opacity */
389   cairo_paint_with_alpha (cr, 0.5);
390
391   return FALSE;
392 }
393
394 void
395 create_composited_window (GtkWidget *widget)
396 {
397   static GtkWidget *window;
398
399   if (!window)
400     {
401       GtkWidget *event, *button;
402       GdkColor red;
403
404       /* make the widgets */
405       button = gtk_button_new_with_label ("A Button");
406       event = gtk_event_box_new ();
407       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
408
409       g_signal_connect (window, "destroy",
410                         G_CALLBACK (gtk_widget_destroyed),
411                         &window);
412
413       /* put a red background on the window */
414       gdk_color_parse ("red", &red);
415       gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &red);
416
417       /* set our event box to have a fully-transparent background
418        * drawn on it.  currently there is no way to simply tell gtk
419        * that "transparency" is the background colour for a widget.
420        */
421       gtk_widget_set_app_paintable (GTK_WIDGET (event), TRUE);
422       g_signal_connect (event, "draw",
423                         G_CALLBACK (transparent_draw), NULL);
424
425       /* put them inside one another */
426       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
427       gtk_container_add (GTK_CONTAINER (window), event);
428       gtk_container_add (GTK_CONTAINER (event), button);
429
430       /* realise and show everything */
431       gtk_widget_realize (button);
432
433       /* set the event box GdkWindow to be composited.
434        * obviously must be performed after event box is realised.
435        */
436       gdk_window_set_composited (gtk_widget_get_window (event),
437                                  TRUE);
438
439       /* set up the compositing handler.
440        * note that we do _after so that the normal (red) background is drawn
441        * by gtk before our compositing occurs.
442        */
443       g_signal_connect_after (window, "draw",
444                               G_CALLBACK (window_draw), NULL);
445     }
446
447   if (!gtk_widget_get_visible (window))
448     gtk_widget_show_all (window);
449   else
450     gtk_widget_destroy (window);
451 }
452
453 /*
454  * Big windows and guffaw scrolling
455  */
456
457 static void
458 pattern_set_bg (GtkWidget   *widget,
459                 GdkWindow   *child,
460                 gint         level)
461 {
462   static const GdkColor colors[] = {
463     { 0, 0x4444, 0x4444, 0xffff },
464     { 0, 0x8888, 0x8888, 0xffff },
465     { 0, 0xaaaa, 0xaaaa, 0xffff }
466   };
467     
468   gdk_window_set_user_data (child, widget);
469   gdk_window_set_background (child, &colors[level]);
470 }
471
472 static void
473 create_pattern (GtkWidget   *widget,
474                 GdkWindow   *parent,
475                 gint         level,
476                 gint         width,
477                 gint         height)
478 {
479   gint h = 1;
480   gint i = 0;
481     
482   GdkWindow *child;
483
484   while (2 * h <= height)
485     {
486       gint w = 1;
487       gint j = 0;
488       
489       while (2 * w <= width)
490         {
491           if ((i + j) % 2 == 0)
492             {
493               gint x = w  - 1;
494               gint y = h - 1;
495               
496               GdkWindowAttr attributes;
497
498               attributes.window_type = GDK_WINDOW_CHILD;
499               attributes.x = x;
500               attributes.y = y;
501               attributes.width = w;
502               attributes.height = h;
503               attributes.wclass = GDK_INPUT_OUTPUT;
504               attributes.event_mask = GDK_EXPOSURE_MASK;
505               attributes.visual = gtk_widget_get_visual (widget);
506               
507               child = gdk_window_new (parent, &attributes,
508                                       GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
509
510               pattern_set_bg (widget, child, level);
511
512               if (level < 2)
513                 create_pattern (widget, child, level + 1, w, h);
514
515               gdk_window_show (child);
516             }
517           j++;
518           w *= 2;
519         }
520       i++;
521       h *= 2;
522     }
523 }
524
525 #define PATTERN_SIZE (1 << 18)
526
527 static void
528 pattern_hadj_changed (GtkAdjustment *adj,
529                       GtkWidget     *darea)
530 {
531   gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value");
532   gint new_value = adj->value;
533
534   if (gtk_widget_get_realized (darea))
535     {
536       gdk_window_scroll (gtk_widget_get_window (darea),
537                          *old_value - new_value, 0);
538       *old_value = new_value;
539     }
540 }
541
542 static void
543 pattern_vadj_changed (GtkAdjustment *adj,
544                       GtkWidget *darea)
545 {
546   gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value");
547   gint new_value = adj->value;
548
549   if (gtk_widget_get_realized (darea))
550     {
551       gdk_window_scroll (gtk_widget_get_window (darea),
552                          0, *old_value - new_value);
553       *old_value = new_value;
554     }
555 }
556
557 static void
558 pattern_realize (GtkWidget *widget,
559                  gpointer   data)
560 {
561   GdkWindow *window;
562
563   window = gtk_widget_get_window (widget);
564   pattern_set_bg (widget, window, 0);
565   create_pattern (widget, window, 1, PATTERN_SIZE, PATTERN_SIZE);
566 }
567
568 static void 
569 create_big_windows (GtkWidget *widget)
570 {
571   static GtkWidget *window = NULL;
572   GtkWidget *content_area;
573   GtkWidget *darea, *table, *scrollbar;
574   GtkWidget *eventbox;
575   GtkAdjustment *hadj;
576   GtkAdjustment *vadj;
577   static gint current_x;
578   static gint current_y;
579  
580   if (!window)
581     {
582       current_x = 0;
583       current_y = 0;
584       
585       window = gtk_dialog_new_with_buttons ("Big Windows",
586                                             NULL, 0,
587                                             GTK_STOCK_CLOSE,
588                                             GTK_RESPONSE_NONE,
589                                             NULL);
590  
591       gtk_window_set_screen (GTK_WINDOW (window),
592                              gtk_widget_get_screen (widget));
593
594       gtk_window_set_default_size (GTK_WINDOW (window), 200, 300);
595
596       g_signal_connect (window, "destroy",
597                         G_CALLBACK (gtk_widget_destroyed),
598                         &window);
599
600       g_signal_connect (window, "response",
601                         G_CALLBACK (gtk_widget_destroy),
602                         NULL);
603
604       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
605
606       table = gtk_table_new (2, 2, FALSE);
607       gtk_box_pack_start (GTK_BOX (content_area), table, TRUE, TRUE, 0);
608
609       darea = gtk_drawing_area_new ();
610
611       hadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
612       g_signal_connect (hadj, "value_changed",
613                         G_CALLBACK (pattern_hadj_changed), darea);
614       g_object_set_data (G_OBJECT (hadj), "old-value", &current_x);
615       
616       vadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
617       g_signal_connect (vadj, "value_changed",
618                         G_CALLBACK (pattern_vadj_changed), darea);
619       g_object_set_data (G_OBJECT (vadj), "old-value", &current_y);
620       
621       g_signal_connect (darea, "realize",
622                         G_CALLBACK (pattern_realize),
623                         NULL);
624
625       eventbox = gtk_event_box_new ();
626       gtk_table_attach (GTK_TABLE (table), eventbox,
627                         0, 1,                  0, 1,
628                         GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
629                         0,                     0);
630
631       gtk_container_add (GTK_CONTAINER (eventbox), darea);
632
633       scrollbar = gtk_hscrollbar_new (hadj);
634       gtk_table_attach (GTK_TABLE (table), scrollbar,
635                         0, 1,                  1, 2,
636                         GTK_FILL | GTK_EXPAND, GTK_FILL,
637                         0,                     0);
638
639       scrollbar = gtk_vscrollbar_new (vadj);
640       gtk_table_attach (GTK_TABLE (table), scrollbar,
641                         1, 2,                  0, 1,
642                         GTK_FILL,              GTK_EXPAND | GTK_FILL,
643                         0,                     0);
644
645     }
646
647   if (!gtk_widget_get_visible (window))
648     gtk_widget_show_all (window);
649   else
650     gtk_widget_hide (window);
651 }
652
653 /*
654  * GtkButton
655  */
656
657 static void
658 button_window (GtkWidget *widget,
659                GtkWidget *button)
660 {
661   if (!gtk_widget_get_visible (button))
662     gtk_widget_show (button);
663   else
664     gtk_widget_hide (button);
665 }
666
667 static void
668 create_buttons (GtkWidget *widget)
669 {
670   static GtkWidget *window = NULL;
671   GtkWidget *box1;
672   GtkWidget *box2;
673   GtkWidget *table;
674   GtkWidget *button[10];
675   GtkWidget *separator;
676
677   if (!window)
678     {
679       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
680       gtk_window_set_screen (GTK_WINDOW (window),
681                              gtk_widget_get_screen (widget));
682
683       g_signal_connect (window, "destroy",
684                         G_CALLBACK (gtk_widget_destroyed),
685                         &window);
686
687       gtk_window_set_title (GTK_WINDOW (window), "GtkButton");
688       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
689
690       box1 = gtk_vbox_new (FALSE, 0);
691       gtk_container_add (GTK_CONTAINER (window), box1);
692
693       table = gtk_table_new (3, 3, FALSE);
694       gtk_table_set_row_spacings (GTK_TABLE (table), 5);
695       gtk_table_set_col_spacings (GTK_TABLE (table), 5);
696       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
697       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
698
699       button[0] = gtk_button_new_with_label ("button1");
700       button[1] = gtk_button_new_with_mnemonic ("_button2");
701       button[2] = gtk_button_new_with_mnemonic ("_button3");
702       button[3] = gtk_button_new_from_stock (GTK_STOCK_OK);
703       button[4] = gtk_button_new_with_label ("button5");
704       button[5] = gtk_button_new_with_label ("button6");
705       button[6] = gtk_button_new_with_label ("button7");
706       button[7] = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
707       button[8] = gtk_button_new_with_label ("button9");
708       
709       g_signal_connect (button[0], "clicked",
710                         G_CALLBACK (button_window),
711                         button[1]);
712
713       gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
714                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
715
716       g_signal_connect (button[1], "clicked",
717                         G_CALLBACK (button_window),
718                         button[2]);
719
720       gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
721                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
722
723       g_signal_connect (button[2], "clicked",
724                         G_CALLBACK (button_window),
725                         button[3]);
726       gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
727                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
728
729       g_signal_connect (button[3], "clicked",
730                         G_CALLBACK (button_window),
731                         button[4]);
732       gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
733                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
734
735       g_signal_connect (button[4], "clicked",
736                         G_CALLBACK (button_window),
737                         button[5]);
738       gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
739                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
740
741       g_signal_connect (button[5], "clicked",
742                         G_CALLBACK (button_window),
743                         button[6]);
744       gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
745                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
746
747       g_signal_connect (button[6], "clicked",
748                         G_CALLBACK (button_window),
749                         button[7]);
750       gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
751                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
752
753       g_signal_connect (button[7], "clicked",
754                         G_CALLBACK (button_window),
755                         button[8]);
756       gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
757                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
758
759       g_signal_connect (button[8], "clicked",
760                         G_CALLBACK (button_window),
761                         button[0]);
762       gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
763                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
764
765       separator = gtk_hseparator_new ();
766       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
767
768       box2 = gtk_vbox_new (FALSE, 10);
769       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
770       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
771
772       button[9] = gtk_button_new_with_label ("close");
773       g_signal_connect_swapped (button[9], "clicked",
774                                 G_CALLBACK (gtk_widget_destroy),
775                                 window);
776       gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
777       gtk_widget_set_can_default (button[9], TRUE);
778       gtk_widget_grab_default (button[9]);
779     }
780
781   if (!gtk_widget_get_visible (window))
782     gtk_widget_show_all (window);
783   else
784     gtk_widget_destroy (window);
785 }
786
787 /*
788  * GtkToggleButton
789  */
790
791 static void
792 create_toggle_buttons (GtkWidget *widget)
793 {
794   static GtkWidget *window = NULL;
795   GtkWidget *box1;
796   GtkWidget *box2;
797   GtkWidget *button;
798   GtkWidget *separator;
799
800   if (!window)
801     {
802       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
803       gtk_window_set_screen (GTK_WINDOW (window),
804                              gtk_widget_get_screen (widget));
805
806       g_signal_connect (window, "destroy",
807                         G_CALLBACK (gtk_widget_destroyed),
808                         &window);
809
810       gtk_window_set_title (GTK_WINDOW (window), "GtkToggleButton");
811       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
812
813       box1 = gtk_vbox_new (FALSE, 0);
814       gtk_container_add (GTK_CONTAINER (window), box1);
815
816       box2 = gtk_vbox_new (FALSE, 10);
817       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
818       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
819
820       button = gtk_toggle_button_new_with_label ("button1");
821       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
822
823       button = gtk_toggle_button_new_with_label ("button2");
824       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
825
826       button = gtk_toggle_button_new_with_label ("button3");
827       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
828
829       button = gtk_toggle_button_new_with_label ("inconsistent");
830       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
831       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
832       
833       separator = gtk_hseparator_new ();
834       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
835
836       box2 = gtk_vbox_new (FALSE, 10);
837       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
838       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
839
840       button = gtk_button_new_with_label ("close");
841       g_signal_connect_swapped (button, "clicked",
842                                 G_CALLBACK (gtk_widget_destroy),
843                                 window);
844       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
845       gtk_widget_set_can_default (button, TRUE);
846       gtk_widget_grab_default (button);
847     }
848
849   if (!gtk_widget_get_visible (window))
850     gtk_widget_show_all (window);
851   else
852     gtk_widget_destroy (window);
853 }
854
855 static GtkWidget *
856 create_widget_grid (GType widget_type)
857 {
858   GtkWidget *table;
859   GtkWidget *group_widget = NULL;
860   gint i, j;
861   
862   table = gtk_table_new (FALSE, 3, 3);
863   
864   for (i = 0; i < 5; i++)
865     {
866       for (j = 0; j < 5; j++)
867         {
868           GtkWidget *widget;
869           char *tmp;
870           
871           if (i == 0 && j == 0)
872             {
873               widget = NULL;
874             }
875           else if (i == 0)
876             {
877               tmp = g_strdup_printf ("%d", j);
878               widget = gtk_label_new (tmp);
879               g_free (tmp);
880             }
881           else if (j == 0)
882             {
883               tmp = g_strdup_printf ("%c", 'A' + i - 1);
884               widget = gtk_label_new (tmp);
885               g_free (tmp);
886             }
887           else
888             {
889               widget = g_object_new (widget_type, NULL);
890               
891               if (g_type_is_a (widget_type, GTK_TYPE_RADIO_BUTTON))
892                 {
893                   if (!group_widget)
894                     group_widget = widget;
895                   else
896                     g_object_set (widget, "group", group_widget, NULL);
897                 }
898             }
899           
900           if (widget)
901             gtk_table_attach (GTK_TABLE (table), widget,
902                               i, i + 1, j, j + 1,
903                               0,        0,
904                               0,        0);
905         }
906     }
907
908   return table;
909 }
910
911 /*
912  * GtkCheckButton
913  */
914
915 static void
916 create_check_buttons (GtkWidget *widget)
917 {
918   static GtkWidget *window = NULL;
919   GtkWidget *box1;
920   GtkWidget *box2;
921   GtkWidget *button;
922   GtkWidget *separator;
923   GtkWidget *table;
924   
925   if (!window)
926     {
927       window = gtk_dialog_new_with_buttons ("Check Buttons",
928                                             NULL, 0,
929                                             GTK_STOCK_CLOSE,
930                                             GTK_RESPONSE_NONE,
931                                             NULL);
932
933       gtk_window_set_screen (GTK_WINDOW (window), 
934                              gtk_widget_get_screen (widget));
935
936       g_signal_connect (window, "destroy",
937                         G_CALLBACK (gtk_widget_destroyed),
938                         &window);
939       g_signal_connect (window, "response",
940                         G_CALLBACK (gtk_widget_destroy),
941                         NULL);
942
943       box1 = gtk_dialog_get_content_area (GTK_DIALOG (window));
944       
945       box2 = gtk_vbox_new (FALSE, 10);
946       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
947       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
948
949       button = gtk_check_button_new_with_mnemonic ("_button1");
950       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
951
952       button = gtk_check_button_new_with_label ("button2");
953       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
954
955       button = gtk_check_button_new_with_label ("button3");
956       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
957
958       button = gtk_check_button_new_with_label ("inconsistent");
959       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
960       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
961
962       separator = gtk_hseparator_new ();
963       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
964
965       table = create_widget_grid (GTK_TYPE_CHECK_BUTTON);
966       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
967       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
968     }
969
970   if (!gtk_widget_get_visible (window))
971     gtk_widget_show_all (window);
972   else
973     gtk_widget_destroy (window);
974 }
975
976 /*
977  * GtkRadioButton
978  */
979
980 static void
981 create_radio_buttons (GtkWidget *widget)
982 {
983   static GtkWidget *window = NULL;
984   GtkWidget *box1;
985   GtkWidget *box2;
986   GtkWidget *button;
987   GtkWidget *separator;
988   GtkWidget *table;
989
990   if (!window)
991     {
992       window = gtk_dialog_new_with_buttons ("Radio Buttons",
993                                             NULL, 0,
994                                             GTK_STOCK_CLOSE,
995                                             GTK_RESPONSE_NONE,
996                                             NULL);
997
998       gtk_window_set_screen (GTK_WINDOW (window),
999                              gtk_widget_get_screen (widget));
1000
1001       g_signal_connect (window, "destroy",
1002                         G_CALLBACK (gtk_widget_destroyed),
1003                         &window);
1004       g_signal_connect (window, "response",
1005                         G_CALLBACK (gtk_widget_destroy),
1006                         NULL);
1007
1008       box1 = gtk_dialog_get_content_area (GTK_DIALOG (window));
1009
1010       box2 = gtk_vbox_new (FALSE, 10);
1011       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1012       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1013
1014       button = gtk_radio_button_new_with_label (NULL, "button1");
1015       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1016
1017       button = gtk_radio_button_new_with_label (
1018                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1019                  "button2");
1020       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1021       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1022
1023       button = gtk_radio_button_new_with_label (
1024                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1025                  "button3");
1026       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1027
1028       button = gtk_radio_button_new_with_label (
1029                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1030                  "inconsistent");
1031       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
1032       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1033       
1034       separator = gtk_hseparator_new ();
1035       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1036
1037       box2 = gtk_vbox_new (FALSE, 10);
1038       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1039       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1040
1041       button = gtk_radio_button_new_with_label (NULL, "button4");
1042       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
1043       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1044
1045       button = gtk_radio_button_new_with_label (
1046                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1047                  "button5");
1048       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1049       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
1050       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1051
1052       button = gtk_radio_button_new_with_label (
1053                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1054                  "button6");
1055       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
1056       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1057
1058       separator = gtk_hseparator_new ();
1059       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1060
1061       table = create_widget_grid (GTK_TYPE_RADIO_BUTTON);
1062       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
1063       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
1064     }
1065
1066   if (!gtk_widget_get_visible (window))
1067     gtk_widget_show_all (window);
1068   else
1069     gtk_widget_destroy (window);
1070 }
1071
1072 /*
1073  * GtkButtonBox
1074  */
1075
1076 static GtkWidget *
1077 create_bbox (gint  horizontal,
1078              char* title, 
1079              gint  spacing,
1080              gint  child_w,
1081              gint  child_h,
1082              gint  layout)
1083 {
1084   GtkWidget *frame;
1085   GtkWidget *bbox;
1086   GtkWidget *button;
1087         
1088   frame = gtk_frame_new (title);
1089
1090   if (horizontal)
1091     bbox = gtk_hbutton_box_new ();
1092   else
1093     bbox = gtk_vbutton_box_new ();
1094
1095   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
1096   gtk_container_add (GTK_CONTAINER (frame), bbox);
1097
1098   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
1099   gtk_box_set_spacing (GTK_BOX (bbox), spacing);
1100   
1101   button = gtk_button_new_with_label ("OK");
1102   gtk_container_add (GTK_CONTAINER (bbox), button);
1103   
1104   button = gtk_button_new_with_label ("Cancel");
1105   gtk_container_add (GTK_CONTAINER (bbox), button);
1106   
1107   button = gtk_button_new_with_label ("Help");
1108   gtk_container_add (GTK_CONTAINER (bbox), button);
1109
1110   return frame;
1111 }
1112
1113 static void
1114 create_button_box (GtkWidget *widget)
1115 {
1116   static GtkWidget* window = NULL;
1117   GtkWidget *main_vbox;
1118   GtkWidget *vbox;
1119   GtkWidget *hbox;
1120   GtkWidget *frame_horz;
1121   GtkWidget *frame_vert;
1122
1123   if (!window)
1124   {
1125     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1126     gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (widget));
1127     gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
1128     
1129     g_signal_connect (window, "destroy",
1130                       G_CALLBACK (gtk_widget_destroyed),
1131                       &window);
1132
1133     gtk_container_set_border_width (GTK_CONTAINER (window), 10);
1134
1135     main_vbox = gtk_vbox_new (FALSE, 0);
1136     gtk_container_add (GTK_CONTAINER (window), main_vbox);
1137     
1138     frame_horz = gtk_frame_new ("Horizontal Button Boxes");
1139     gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz, TRUE, TRUE, 10);
1140     
1141     vbox = gtk_vbox_new (FALSE, 0);
1142     gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
1143     gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
1144     
1145     gtk_box_pack_start (GTK_BOX (vbox), 
1146                         create_bbox (TRUE, "Spread", 40, 85, 20, GTK_BUTTONBOX_SPREAD),
1147                         TRUE, TRUE, 0);
1148     
1149     gtk_box_pack_start (GTK_BOX (vbox), 
1150                         create_bbox (TRUE, "Edge", 40, 85, 20, GTK_BUTTONBOX_EDGE),
1151                         TRUE, TRUE, 5);
1152     
1153     gtk_box_pack_start (GTK_BOX (vbox), 
1154                         create_bbox (TRUE, "Start", 40, 85, 20, GTK_BUTTONBOX_START),
1155                         TRUE, TRUE, 5);
1156     
1157     gtk_box_pack_start (GTK_BOX (vbox), 
1158                         create_bbox (TRUE, "End", 40, 85, 20, GTK_BUTTONBOX_END),
1159                         TRUE, TRUE, 5);
1160     
1161     gtk_box_pack_start (GTK_BOX (vbox),
1162                         create_bbox (TRUE, "Center", 40, 85, 20, GTK_BUTTONBOX_CENTER),
1163                         TRUE, TRUE, 5);
1164     
1165     frame_vert = gtk_frame_new ("Vertical Button Boxes");
1166     gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert, TRUE, TRUE, 10);
1167     
1168     hbox = gtk_hbox_new (FALSE, 0);
1169     gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
1170     gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
1171
1172     gtk_box_pack_start (GTK_BOX (hbox), 
1173                         create_bbox (FALSE, "Spread", 30, 85, 20, GTK_BUTTONBOX_SPREAD),
1174                         TRUE, TRUE, 0);
1175     
1176     gtk_box_pack_start (GTK_BOX (hbox), 
1177                         create_bbox (FALSE, "Edge", 30, 85, 20, GTK_BUTTONBOX_EDGE),
1178                         TRUE, TRUE, 5);
1179     
1180     gtk_box_pack_start (GTK_BOX (hbox), 
1181                         create_bbox (FALSE, "Start", 30, 85, 20, GTK_BUTTONBOX_START),
1182                         TRUE, TRUE, 5);
1183     
1184     gtk_box_pack_start (GTK_BOX (hbox), 
1185                         create_bbox (FALSE, "End", 30, 85, 20, GTK_BUTTONBOX_END),
1186                         TRUE, TRUE, 5);
1187     
1188     gtk_box_pack_start (GTK_BOX (hbox),
1189                         create_bbox (FALSE, "Center", 30, 85, 20, GTK_BUTTONBOX_CENTER),
1190                         TRUE, TRUE, 5);
1191   }
1192
1193   if (!gtk_widget_get_visible (window))
1194     gtk_widget_show_all (window);
1195   else
1196     gtk_widget_destroy (window);
1197 }
1198
1199 /*
1200  * GtkToolBar
1201  */
1202
1203 static GtkWidget*
1204 new_pixbuf (char      *filename,
1205             GdkWindow *window,
1206             GdkColor  *background)
1207 {
1208   GtkWidget *widget;
1209   GdkPixbuf *pixbuf;
1210
1211   if (strcmp (filename, "test.xpm") == 0)
1212     pixbuf = NULL;
1213   else
1214     pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1215
1216   if (pixbuf == NULL)
1217     pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
1218   
1219   widget = gtk_image_new_from_pixbuf (pixbuf);
1220
1221   g_object_unref (pixbuf);
1222
1223   return widget;
1224 }
1225
1226
1227 static void
1228 set_toolbar_small_stock (GtkWidget *widget,
1229                          gpointer   data)
1230 {
1231   gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_SMALL_TOOLBAR);
1232 }
1233
1234 static void
1235 set_toolbar_large_stock (GtkWidget *widget,
1236                          gpointer   data)
1237 {
1238   gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_LARGE_TOOLBAR);
1239 }
1240
1241 static void
1242 set_toolbar_horizontal (GtkWidget *widget,
1243                         gpointer   data)
1244 {
1245   gtk_orientable_set_orientation (GTK_ORIENTABLE (data), GTK_ORIENTATION_HORIZONTAL);
1246 }
1247
1248 static void
1249 set_toolbar_vertical (GtkWidget *widget,
1250                       gpointer   data)
1251 {
1252   gtk_orientable_set_orientation (GTK_ORIENTABLE (data), GTK_ORIENTATION_VERTICAL);
1253 }
1254
1255 static void
1256 set_toolbar_icons (GtkWidget *widget,
1257                    gpointer   data)
1258 {
1259   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
1260 }
1261
1262 static void
1263 set_toolbar_text (GtkWidget *widget,
1264                   gpointer   data)
1265 {
1266   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
1267 }
1268
1269 static void
1270 set_toolbar_both (GtkWidget *widget,
1271                   gpointer   data)
1272 {
1273   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
1274 }
1275
1276 static void
1277 set_toolbar_both_horiz (GtkWidget *widget,
1278                         gpointer   data)
1279 {
1280   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH_HORIZ);
1281 }
1282
1283 static void
1284 set_toolbar_enable (GtkWidget *widget,
1285                     gpointer   data)
1286 {
1287   GtkSettings *settings = gtk_widget_get_settings (widget);
1288   g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL);
1289 }
1290
1291 static void
1292 set_toolbar_disable (GtkWidget *widget,
1293                      gpointer   data)
1294 {
1295   GtkSettings *settings = gtk_widget_get_settings (widget);
1296   g_object_set (settings, "gtk-enable-tooltips", FALSE, NULL);
1297 }
1298
1299 static GtkActionEntry create_toolbar_items[] = {
1300     { NULL, GTK_STOCK_NEW, NULL, NULL, "Stock icon: New",
1301       G_CALLBACK (set_toolbar_small_stock) },
1302     { NULL, GTK_STOCK_OPEN, NULL, NULL, "Stock icon: Open",
1303       G_CALLBACK (set_toolbar_large_stock) },
1304     { NULL, NULL, "Horizontal", NULL, "Horizontal toolbar layout",
1305       G_CALLBACK (set_toolbar_horizontal) },
1306     { NULL, NULL, "Vertical", NULL, "Vertical toolbar layout",
1307       G_CALLBACK (set_toolbar_vertical) },
1308     { NULL },
1309     { NULL, NULL, "Icons", NULL, "Only show toolbar icons",
1310       G_CALLBACK (set_toolbar_icons) },
1311     { NULL, NULL, "Text", NULL, "Only show toolbar text",
1312       G_CALLBACK (set_toolbar_text) },
1313     { NULL, NULL, "Both", NULL, "Show toolbar icons and text",
1314       G_CALLBACK (set_toolbar_both) },
1315     { NULL, NULL, "Both (horizontal)", NULL, "Show toolbar icons and text in a horizontal fashion",
1316       G_CALLBACK (set_toolbar_both_horiz) },
1317     { NULL },
1318     { "entry", NULL, NULL, "This is an unusable GtkEntry ;)",
1319       NULL },
1320     { NULL },
1321     { NULL },
1322     { NULL, NULL, "Enable", NULL, "Enable tooltips",
1323       G_CALLBACK (set_toolbar_enable) },
1324     { NULL, NULL, "Disable", NULL, "Disable tooltips",
1325       G_CALLBACK (set_toolbar_disable) },
1326     { NULL },
1327     { NULL, NULL, "Frobate", NULL, "Frobate tooltip",
1328       NULL },
1329     { NULL, NULL, "Baz", NULL, "Baz tooltip",
1330       NULL },
1331     { NULL },
1332     { NULL, NULL, "Blah", NULL, "Blash tooltip",
1333       NULL },
1334     { NULL, NULL, "Bar", NULL, "Bar tooltip",
1335       NULL },
1336 };
1337
1338 static void
1339 create_toolbar (GtkWidget *widget)
1340 {
1341   static GtkWidget *window = NULL;
1342   GtkWidget *toolbar;
1343
1344   if (!window)
1345     {
1346       guint i;
1347
1348       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1349       gtk_window_set_screen (GTK_WINDOW (window),
1350                              gtk_widget_get_screen (widget));
1351       
1352       gtk_window_set_title (GTK_WINDOW (window), "Toolbar test");
1353
1354       g_signal_connect (window, "destroy",
1355                         G_CALLBACK (gtk_widget_destroyed),
1356                         &window);
1357
1358       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1359       gtk_widget_realize (window);
1360
1361       toolbar = gtk_toolbar_new ();
1362       for (i = 0; i < G_N_ELEMENTS (create_toolbar_items); i++)
1363         {
1364           GtkToolItem *toolitem;
1365
1366           if (create_toolbar_items[i].tooltip == NULL)
1367             toolitem = gtk_separator_tool_item_new ();
1368           else if (g_strcmp0 (create_toolbar_items[i].name, "entry") == 0)
1369             {
1370               GtkWidget *entry;
1371
1372               toolitem = gtk_tool_item_new ();
1373               entry = gtk_entry_new ();
1374               gtk_container_add (GTK_CONTAINER (toolitem), entry);
1375             }
1376           else if (create_toolbar_items[i].stock_id)
1377             toolitem = gtk_tool_button_new_from_stock (create_toolbar_items[i].stock_id);
1378           else
1379             {
1380               GtkWidget *icon;
1381
1382               icon = new_pixbuf ("test.xpm", gtk_widget_get_window (window),
1383                                  &gtk_widget_get_style (window)->bg[GTK_STATE_NORMAL]);
1384               toolitem = gtk_tool_button_new (icon, create_toolbar_items[i].label);
1385             }
1386           if (create_toolbar_items[i].callback)
1387             g_signal_connect (toolitem, "clicked",
1388                               create_toolbar_items[i].callback, toolbar);
1389           gtk_tool_item_set_tooltip_text (toolitem, create_toolbar_items[i].tooltip);
1390           gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
1391         }
1392
1393       gtk_container_add (GTK_CONTAINER (window), toolbar);
1394
1395       gtk_widget_set_size_request (toolbar, 200, -1);
1396     }
1397
1398   if (!gtk_widget_get_visible (window))
1399     gtk_widget_show_all (window);
1400   else
1401     gtk_widget_destroy (window);
1402 }
1403
1404 static GtkActionEntry make_toolbar_items[] = {
1405     { NULL, NULL, "Horizontal", NULL, "Horizontal toolbar layout",
1406       G_CALLBACK (set_toolbar_horizontal) },
1407     { NULL, NULL, "Vertical", NULL, "Vertical toolbar layout",
1408       G_CALLBACK (set_toolbar_vertical) },
1409     { NULL },
1410     { NULL, NULL, "Icons", NULL, "Only show toolbar icons",
1411       G_CALLBACK (set_toolbar_icons) },
1412     { NULL, NULL, "Text", NULL, "Only show toolbar text",
1413       G_CALLBACK (set_toolbar_text) },
1414     { NULL, NULL, "Both", NULL, "Show toolbar icons and text",
1415       G_CALLBACK (set_toolbar_both) },
1416     { NULL },
1417     { NULL, NULL, "Woot", NULL, "Woot woot woot",
1418       NULL },
1419     { NULL, NULL, "Blah", NULL, "Blah blah blah",
1420       NULL },
1421     { NULL },
1422     { NULL, NULL, "Enable", NULL, "Enable tooltips",
1423       G_CALLBACK (set_toolbar_enable) },
1424     { NULL, NULL, "Disable", NULL, "Disable tooltips",
1425       G_CALLBACK (set_toolbar_disable) },
1426     { NULL },
1427     { NULL, NULL, "Hoo", NULL, "Hoo tooltip",
1428       NULL },
1429     { NULL, NULL, "Woo", NULL, "Woo tooltip",
1430       NULL }
1431 };
1432
1433 static GtkWidget*
1434 make_toolbar (GtkWidget *window)
1435 {
1436   GtkWidget *toolbar;
1437   guint i;
1438
1439   if (!gtk_widget_get_realized (window))
1440     gtk_widget_realize (window);
1441
1442   toolbar = gtk_toolbar_new ();
1443   for (i = 0; i < G_N_ELEMENTS (make_toolbar_items); i++)
1444     {
1445       GtkWidget *icon;
1446       GtkToolItem *toolitem;
1447
1448       if (make_toolbar_items[i].label == NULL)
1449         {
1450           toolitem = gtk_separator_tool_item_new ();
1451           continue;
1452         }
1453       icon  = new_pixbuf ("test.xpm", gtk_widget_get_window (window),
1454                           &gtk_widget_get_style (window)->bg[GTK_STATE_NORMAL]);
1455       toolitem = gtk_tool_button_new (icon, make_toolbar_items[i].label);
1456       gtk_tool_item_set_tooltip_text (toolitem, make_toolbar_items[i].tooltip);
1457       if (make_toolbar_items[i].callback != NULL)
1458         g_signal_connect (toolitem, "clicked",  make_toolbar_items[i].callback, toolbar);
1459       gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
1460     }
1461
1462   return toolbar;
1463 }
1464
1465 /*
1466  * GtkStatusBar
1467  */
1468
1469 static guint statusbar_counter = 1;
1470
1471 static void
1472 statusbar_push (GtkWidget *button,
1473                 GtkStatusbar *statusbar)
1474 {
1475   gchar text[1024];
1476
1477   sprintf (text, "something %d", statusbar_counter++);
1478
1479   gtk_statusbar_push (statusbar, 1, text);
1480 }
1481
1482 static void
1483 statusbar_push_long (GtkWidget *button,
1484                      GtkStatusbar *statusbar)
1485 {
1486   gchar text[1024];
1487
1488   sprintf (text, "Just because a system has menu choices written with English words, phrases or sentences, that is no guarantee, that it is comprehensible. Individual words may not be familiar to some users (for example, \"repaginate\"), and two menu items may appear to satisfy the users's needs, whereas only one does (for example, \"put away\" or \"eject\").");
1489
1490   gtk_statusbar_push (statusbar, 1, text);
1491 }
1492
1493 static void
1494 statusbar_pop (GtkWidget *button,
1495                GtkStatusbar *statusbar)
1496 {
1497   gtk_statusbar_pop (statusbar, 1);
1498 }
1499
1500 static void
1501 statusbar_steal (GtkWidget *button,
1502                  GtkStatusbar *statusbar)
1503 {
1504   gtk_statusbar_remove (statusbar, 1, 4);
1505 }
1506
1507 static void
1508 statusbar_popped (GtkStatusbar  *statusbar,
1509                   guint          context_id,
1510                   const gchar   *text)
1511 {
1512   if (!text)
1513     statusbar_counter = 1;
1514 }
1515
1516 static void
1517 statusbar_contexts (GtkStatusbar *statusbar)
1518 {
1519   gchar *string;
1520
1521   string = "any context";
1522   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1523            string,
1524            gtk_statusbar_get_context_id (statusbar, string));
1525   
1526   string = "idle messages";
1527   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1528            string,
1529            gtk_statusbar_get_context_id (statusbar, string));
1530   
1531   string = "some text";
1532   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1533            string,
1534            gtk_statusbar_get_context_id (statusbar, string));
1535
1536   string = "hit the mouse";
1537   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1538            string,
1539            gtk_statusbar_get_context_id (statusbar, string));
1540
1541   string = "hit the mouse2";
1542   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1543            string,
1544            gtk_statusbar_get_context_id (statusbar, string));
1545 }
1546
1547 static void
1548 create_statusbar (GtkWidget *widget)
1549 {
1550   static GtkWidget *window = NULL;
1551   GtkWidget *box1;
1552   GtkWidget *box2;
1553   GtkWidget *button;
1554   GtkWidget *separator;
1555   GtkWidget *statusbar;
1556
1557   if (!window)
1558     {
1559       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1560       gtk_window_set_screen (GTK_WINDOW (window),
1561                              gtk_widget_get_screen (widget));
1562
1563       g_signal_connect (window, "destroy",
1564                         G_CALLBACK (gtk_widget_destroyed),
1565                         &window);
1566
1567       gtk_window_set_title (GTK_WINDOW (window), "statusbar");
1568       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1569
1570       box1 = gtk_vbox_new (FALSE, 0);
1571       gtk_container_add (GTK_CONTAINER (window), box1);
1572
1573       box2 = gtk_vbox_new (FALSE, 10);
1574       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1575       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1576
1577       statusbar = gtk_statusbar_new ();
1578       gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
1579       g_signal_connect (statusbar,
1580                         "text_popped",
1581                         G_CALLBACK (statusbar_popped),
1582                         NULL);
1583
1584       button = g_object_new (gtk_button_get_type (),
1585                                "label", "push something",
1586                                "visible", TRUE,
1587                                "parent", box2,
1588                                NULL);
1589       g_object_connect (button,
1590                         "signal::clicked", statusbar_push, statusbar,
1591                         NULL);
1592
1593       button = g_object_connect (g_object_new (gtk_button_get_type (),
1594                                                  "label", "pop",
1595                                                  "visible", TRUE,
1596                                                  "parent", box2,
1597                                                  NULL),
1598                                  "signal_after::clicked", statusbar_pop, statusbar,
1599                                  NULL);
1600
1601       button = g_object_connect (g_object_new (gtk_button_get_type (),
1602                                                  "label", "steal #4",
1603                                                  "visible", TRUE,
1604                                                  "parent", box2,
1605                                                  NULL),
1606                                  "signal_after::clicked", statusbar_steal, statusbar,
1607                                  NULL);
1608
1609       button = g_object_connect (g_object_new (gtk_button_get_type (),
1610                                                  "label", "test contexts",
1611                                                  "visible", TRUE,
1612                                                  "parent", box2,
1613                                                  NULL),
1614                                  "swapped_signal_after::clicked", statusbar_contexts, statusbar,
1615                                  NULL);
1616
1617       button = g_object_connect (g_object_new (gtk_button_get_type (),
1618                                                  "label", "push something long",
1619                                                  "visible", TRUE,
1620                                                  "parent", box2,
1621                                                  NULL),
1622                                  "signal_after::clicked", statusbar_push_long, statusbar,
1623                                  NULL);
1624       
1625       separator = gtk_hseparator_new ();
1626       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1627
1628       box2 = gtk_vbox_new (FALSE, 10);
1629       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1630       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1631
1632       button = gtk_button_new_with_label ("close");
1633       g_signal_connect_swapped (button, "clicked",
1634                                 G_CALLBACK (gtk_widget_destroy),
1635                                 window);
1636       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1637       gtk_widget_set_can_default (button, TRUE);
1638       gtk_widget_grab_default (button);
1639     }
1640
1641   if (!gtk_widget_get_visible (window))
1642     gtk_widget_show_all (window);
1643   else
1644     gtk_widget_destroy (window);
1645 }
1646
1647 /*
1648  * Gridded geometry
1649  */
1650 #define GRID_SIZE 20
1651 #define DEFAULT_GEOMETRY "10x10"
1652
1653 static gboolean
1654 gridded_geometry_draw (GtkWidget *widget,
1655                        cairo_t   *cr)
1656 {
1657   GtkStateType state;
1658   GtkStyle *style;
1659   int i, j, width, height;
1660
1661   style = gtk_widget_get_style (widget);
1662   state = gtk_widget_get_state (widget);
1663   width = gtk_widget_get_allocated_width (widget);
1664   height = gtk_widget_get_allocated_height (widget);
1665
1666   gdk_cairo_set_source_color (cr, &style->base[state]);
1667   cairo_paint (cr);
1668
1669   for (i = 0 ; i * GRID_SIZE < width; i++)
1670     for (j = 0 ; j * GRID_SIZE < height; j++)
1671       {
1672         if ((i + j) % 2 == 0)
1673           cairo_rectangle (cr, i * GRID_SIZE, j * GRID_SIZE, GRID_SIZE, GRID_SIZE);
1674       }
1675
1676   gdk_cairo_set_source_color (cr, &style->text[state]);
1677   cairo_fill (cr);
1678
1679   return FALSE;
1680 }
1681
1682 static void
1683 gridded_geometry_subresponse (GtkDialog *dialog,
1684                               gint       response_id,
1685                               gchar     *geometry_string)
1686 {
1687   if (response_id == GTK_RESPONSE_NONE)
1688     {
1689       gtk_widget_destroy (GTK_WIDGET (dialog));
1690     }
1691   else
1692     {
1693       if (!gtk_window_parse_geometry (GTK_WINDOW (dialog), geometry_string))
1694         {
1695           g_print ("Can't parse geometry string %s\n", geometry_string);
1696           gtk_window_parse_geometry (GTK_WINDOW (dialog), DEFAULT_GEOMETRY);
1697         }
1698     }
1699 }
1700
1701 static void
1702 gridded_geometry_response (GtkDialog *dialog,
1703                            gint       response_id,
1704                            GtkEntry  *entry)
1705 {
1706   if (response_id == GTK_RESPONSE_NONE)
1707     {
1708       gtk_widget_destroy (GTK_WIDGET (dialog));
1709     }
1710   else
1711     {
1712       gchar *geometry_string = g_strdup (gtk_entry_get_text (entry));
1713       gchar *title = g_strdup_printf ("Gridded window at: %s", geometry_string);
1714       GtkWidget *content_area;
1715       GtkWidget *window;
1716       GtkWidget *drawing_area;
1717       GtkWidget *box;
1718       GdkGeometry geometry;
1719       
1720       window = gtk_dialog_new_with_buttons (title,
1721                                             NULL, 0,
1722                                             "Reset", 1,
1723                                             GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
1724                                             NULL);
1725
1726       gtk_window_set_screen (GTK_WINDOW (window), 
1727                              gtk_widget_get_screen (GTK_WIDGET (dialog)));
1728       g_free (title);
1729       g_signal_connect (window, "response",
1730                         G_CALLBACK (gridded_geometry_subresponse), geometry_string);
1731
1732       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
1733
1734       box = gtk_vbox_new (FALSE, 0);
1735       gtk_box_pack_start (GTK_BOX (content_area), box, TRUE, TRUE, 0);
1736       
1737       gtk_container_set_border_width (GTK_CONTAINER (box), 7);
1738       
1739       drawing_area = gtk_drawing_area_new ();
1740       g_signal_connect (drawing_area, "draw",
1741                         G_CALLBACK (gridded_geometry_draw), NULL);
1742       gtk_box_pack_start (GTK_BOX (box), drawing_area, TRUE, TRUE, 0);
1743
1744       /* Gross hack to work around bug 68668... if we set the size request
1745        * large enough, then  the current
1746        *
1747        *   request_of_window - request_of_geometry_widget
1748        *
1749        * method of getting the base size works more or less works.
1750        */
1751       gtk_widget_set_size_request (drawing_area, 2000, 2000);
1752
1753       geometry.base_width = 0;
1754       geometry.base_height = 0;
1755       geometry.min_width = 2 * GRID_SIZE;
1756       geometry.min_height = 2 * GRID_SIZE;
1757       geometry.width_inc = GRID_SIZE;
1758       geometry.height_inc = GRID_SIZE;
1759
1760       gtk_window_set_geometry_hints (GTK_WINDOW (window), drawing_area,
1761                                      &geometry,
1762                                      GDK_HINT_BASE_SIZE | GDK_HINT_MIN_SIZE | GDK_HINT_RESIZE_INC);
1763
1764       if (!gtk_window_parse_geometry (GTK_WINDOW (window), geometry_string))
1765         {
1766           g_print ("Can't parse geometry string %s\n", geometry_string);
1767           gtk_window_parse_geometry (GTK_WINDOW (window), DEFAULT_GEOMETRY);
1768         }
1769
1770       gtk_widget_show_all (window);
1771     }
1772 }
1773
1774 static void 
1775 create_gridded_geometry (GtkWidget *widget)
1776 {
1777   static GtkWidget *window = NULL;
1778   gpointer window_ptr;
1779   GtkWidget *content_area;
1780   GtkWidget *entry;
1781   GtkWidget *label;
1782
1783   if (!window)
1784     {
1785       window = gtk_dialog_new_with_buttons ("Gridded Geometry",
1786                                             NULL, 0,
1787                                             "Create", 1,
1788                                             GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
1789                                             NULL);
1790       
1791       gtk_window_set_screen (GTK_WINDOW (window),
1792                              gtk_widget_get_screen (widget));
1793
1794       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
1795
1796       label = gtk_label_new ("Geometry string:");
1797       gtk_box_pack_start (GTK_BOX (content_area), label, FALSE, FALSE, 0);
1798
1799       entry = gtk_entry_new ();
1800       gtk_entry_set_text (GTK_ENTRY (entry), DEFAULT_GEOMETRY);
1801       gtk_box_pack_start (GTK_BOX (content_area), entry, FALSE, FALSE, 0);
1802
1803       g_signal_connect (window, "response",
1804                         G_CALLBACK (gridded_geometry_response), entry);
1805       window_ptr = &window;
1806       g_object_add_weak_pointer (G_OBJECT (window), window_ptr);
1807
1808       gtk_widget_show_all (window);
1809     }
1810   else
1811     gtk_widget_destroy (window);
1812 }
1813
1814 /*
1815  * GtkHandleBox
1816  */
1817
1818 static void
1819 handle_box_child_signal (GtkHandleBox *hb,
1820                          GtkWidget    *child,
1821                          const gchar  *action)
1822 {
1823   printf ("%s: child <%s> %sed\n",
1824           g_type_name (G_OBJECT_TYPE (hb)),
1825           g_type_name (G_OBJECT_TYPE (child)),
1826           action);
1827 }
1828
1829 static void
1830 create_handle_box (GtkWidget *widget)
1831 {
1832   static GtkWidget* window = NULL;
1833   GtkWidget *handle_box;
1834   GtkWidget *handle_box2;
1835   GtkWidget *vbox;
1836   GtkWidget *hbox;
1837   GtkWidget *toolbar;
1838   GtkWidget *label;
1839   GtkWidget *separator;
1840
1841   if (!window)
1842   {
1843     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1844     
1845     gtk_window_set_screen (GTK_WINDOW (window),
1846                            gtk_widget_get_screen (widget));
1847     gtk_window_set_modal (GTK_WINDOW (window), FALSE);
1848     gtk_window_set_title (GTK_WINDOW (window),
1849                           "Handle Box Test");
1850     gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
1851     
1852     g_signal_connect (window, "destroy",
1853                       G_CALLBACK (gtk_widget_destroyed),
1854                       &window);
1855     
1856     gtk_container_set_border_width (GTK_CONTAINER (window), 20);
1857
1858     vbox = gtk_vbox_new (FALSE, 0);
1859     gtk_container_add (GTK_CONTAINER (window), vbox);
1860     gtk_widget_show (vbox);
1861
1862     label = gtk_label_new ("Above");
1863     gtk_container_add (GTK_CONTAINER (vbox), label);
1864     gtk_widget_show (label);
1865
1866     separator = gtk_hseparator_new ();
1867     gtk_container_add (GTK_CONTAINER (vbox), separator);
1868     gtk_widget_show (separator);
1869     
1870     hbox = gtk_hbox_new (FALSE, 10);
1871     gtk_container_add (GTK_CONTAINER (vbox), hbox);
1872     gtk_widget_show (hbox);
1873
1874     separator = gtk_hseparator_new ();
1875     gtk_container_add (GTK_CONTAINER (vbox), separator);
1876     gtk_widget_show (separator);
1877
1878     label = gtk_label_new ("Below");
1879     gtk_container_add (GTK_CONTAINER (vbox), label);
1880     gtk_widget_show (label);
1881
1882     handle_box = gtk_handle_box_new ();
1883     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
1884     g_signal_connect (handle_box,
1885                       "child_attached",
1886                       G_CALLBACK (handle_box_child_signal),
1887                       "attached");
1888     g_signal_connect (handle_box,
1889                       "child_detached",
1890                       G_CALLBACK (handle_box_child_signal),
1891                       "detached");
1892     gtk_widget_show (handle_box);
1893
1894     toolbar = make_toolbar (window);
1895     
1896     gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1897     gtk_widget_show (toolbar);
1898
1899     handle_box = gtk_handle_box_new ();
1900     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
1901     g_signal_connect (handle_box,
1902                       "child_attached",
1903                       G_CALLBACK (handle_box_child_signal),
1904                       "attached");
1905     g_signal_connect (handle_box,
1906                       "child_detached",
1907                       G_CALLBACK (handle_box_child_signal),
1908                       "detached");
1909     gtk_widget_show (handle_box);
1910
1911     handle_box2 = gtk_handle_box_new ();
1912     gtk_container_add (GTK_CONTAINER (handle_box), handle_box2);
1913     g_signal_connect (handle_box2,
1914                       "child_attached",
1915                       G_CALLBACK (handle_box_child_signal),
1916                       "attached");
1917     g_signal_connect (handle_box2,
1918                       "child_detached",
1919                       G_CALLBACK (handle_box_child_signal),
1920                       "detached");
1921     gtk_widget_show (handle_box2);
1922
1923     hbox = g_object_new (GTK_TYPE_HBOX, "visible", 1, "parent", handle_box2, NULL);
1924     label = gtk_label_new ("Fooo!");
1925     gtk_container_add (GTK_CONTAINER (hbox), label);
1926     gtk_widget_show (label);
1927     g_object_new (GTK_TYPE_ARROW, "visible", 1, "parent", hbox, NULL);
1928   }
1929
1930   if (!gtk_widget_get_visible (window))
1931     gtk_widget_show (window);
1932   else
1933     gtk_widget_destroy (window);
1934 }
1935
1936 /* 
1937  * Label Demo
1938  */
1939 static void
1940 sensitivity_toggled (GtkWidget *toggle,
1941                      GtkWidget *widget)
1942 {
1943   gtk_widget_set_sensitive (widget,  GTK_TOGGLE_BUTTON (toggle)->active);  
1944 }
1945
1946 static GtkWidget*
1947 create_sensitivity_control (GtkWidget *widget)
1948 {
1949   GtkWidget *button;
1950
1951   button = gtk_toggle_button_new_with_label ("Sensitive");  
1952
1953   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
1954                                 gtk_widget_is_sensitive (widget));
1955   
1956   g_signal_connect (button,
1957                     "toggled",
1958                     G_CALLBACK (sensitivity_toggled),
1959                     widget);
1960   
1961   gtk_widget_show_all (button);
1962
1963   return button;
1964 }
1965
1966 static void
1967 set_selectable_recursive (GtkWidget *widget,
1968                           gboolean   setting)
1969 {
1970   if (GTK_IS_CONTAINER (widget))
1971     {
1972       GList *children;
1973       GList *tmp;
1974       
1975       children = gtk_container_get_children (GTK_CONTAINER (widget));
1976       tmp = children;
1977       while (tmp)
1978         {
1979           set_selectable_recursive (tmp->data, setting);
1980
1981           tmp = tmp->next;
1982         }
1983       g_list_free (children);
1984     }
1985   else if (GTK_IS_LABEL (widget))
1986     {
1987       gtk_label_set_selectable (GTK_LABEL (widget), setting);
1988     }
1989 }
1990
1991 static void
1992 selectable_toggled (GtkWidget *toggle,
1993                     GtkWidget *widget)
1994 {
1995   set_selectable_recursive (widget,
1996                             GTK_TOGGLE_BUTTON (toggle)->active);
1997 }
1998
1999 static GtkWidget*
2000 create_selectable_control (GtkWidget *widget)
2001 {
2002   GtkWidget *button;
2003
2004   button = gtk_toggle_button_new_with_label ("Selectable");  
2005
2006   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
2007                                 FALSE);
2008   
2009   g_signal_connect (button,
2010                     "toggled",
2011                     G_CALLBACK (selectable_toggled),
2012                     widget);
2013   
2014   gtk_widget_show_all (button);
2015
2016   return button;
2017 }
2018
2019 static void
2020 dialog_response (GtkWidget *dialog, gint response_id, GtkLabel *label)
2021 {
2022   const gchar *text;
2023
2024   gtk_widget_destroy (dialog);
2025
2026   text = "Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
2027          "as hyperlinks, which can be clicked\n"
2028          "or activated via <a href=\"keynav\">keynav</a>.\n"
2029          "The links remain the same.";
2030   gtk_label_set_markup (label, text);
2031 }
2032
2033 static gboolean
2034 activate_link (GtkWidget *label, const gchar *uri, gpointer data)
2035 {
2036   if (g_strcmp0 (uri, "keynav") == 0)
2037     {
2038       GtkWidget *dialog;
2039
2040       dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel (label)),
2041                                        GTK_DIALOG_DESTROY_WITH_PARENT,
2042                                        GTK_MESSAGE_INFO,
2043                                        GTK_BUTTONS_OK,
2044                                        "The term <i>keynav</i> is a shorthand for "
2045                                        "keyboard navigation and refers to the process of using a program "
2046                                        "(exclusively) via keyboard input.");
2047
2048       gtk_window_present (GTK_WINDOW (dialog));
2049
2050       g_signal_connect (dialog, "response", G_CALLBACK (dialog_response), label);
2051
2052       return TRUE;
2053     }
2054
2055   return FALSE;
2056 }
2057
2058 void create_labels (GtkWidget *widget)
2059 {
2060   static GtkWidget *window = NULL;
2061   GtkWidget *hbox;
2062   GtkWidget *vbox;
2063   GtkWidget *frame;
2064   GtkWidget *label;
2065   GtkWidget *button;
2066
2067   if (!window)
2068     {
2069       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2070
2071       gtk_window_set_screen (GTK_WINDOW (window),
2072                              gtk_widget_get_screen (widget));
2073
2074       g_signal_connect (window, "destroy",
2075                         G_CALLBACK (gtk_widget_destroyed),
2076                         &window);
2077
2078       gtk_window_set_title (GTK_WINDOW (window), "Label");
2079
2080       vbox = gtk_vbox_new (FALSE, 5);
2081       
2082       hbox = gtk_hbox_new (FALSE, 5);
2083       gtk_container_add (GTK_CONTAINER (window), vbox);
2084
2085       gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2086
2087       button = create_sensitivity_control (hbox);
2088
2089       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2090
2091       button = create_selectable_control (hbox);
2092
2093       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2094       
2095       vbox = gtk_vbox_new (FALSE, 5);
2096       
2097       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2098       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
2099
2100       frame = gtk_frame_new ("Normal Label");
2101       label = gtk_label_new ("This is a Normal label");
2102       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
2103       gtk_container_add (GTK_CONTAINER (frame), label);
2104       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2105
2106       frame = gtk_frame_new ("Multi-line Label");
2107       label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
2108       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
2109       gtk_container_add (GTK_CONTAINER (frame), label);
2110       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2111
2112       frame = gtk_frame_new ("Left Justified Label");
2113       label = gtk_label_new ("This is a Left-Justified\nMulti-line label.\nThird      line");
2114       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
2115       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2116       gtk_container_add (GTK_CONTAINER (frame), label);
2117       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2118
2119       frame = gtk_frame_new ("Right Justified Label");
2120       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
2121       label = gtk_label_new ("This is a Right-Justified\nMulti-line label.\nFourth line, (j/k)");
2122       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
2123       gtk_container_add (GTK_CONTAINER (frame), label);
2124       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2125
2126       frame = gtk_frame_new ("Internationalized Label");
2127       label = gtk_label_new (NULL);
2128       gtk_label_set_markup (GTK_LABEL (label),
2129                             "French (Fran\303\247ais) Bonjour, Salut\n"
2130                             "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"
2131                             "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"
2132                             "Chinese (Simplified) <span lang=\"zh-cn\">\345\205\203\346\260\224 \345\274\200\345\217\221</span>\n"
2133                             "Chinese (Traditional) <span lang=\"zh-tw\">\345\205\203\346\260\243        \351\226\213\347\231\274</span>\n"
2134                             "Japanese <span lang=\"ja\">\345\205\203\346\260\227        \351\226\213\347\231\272</span>");
2135       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2136       gtk_container_add (GTK_CONTAINER (frame), label);
2137       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2138
2139       frame = gtk_frame_new ("Bidirection Label");
2140       label = gtk_label_new ("\342\200\217Arabic        \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205\n"
2141                              "\342\200\217Hebrew        \327\251\327\234\327\225\327\235");
2142       gtk_container_add (GTK_CONTAINER (frame), label);
2143       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2144
2145       frame = gtk_frame_new ("Links in a label");
2146       label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
2147                              "as hyperlinks, which can be clicked\n"
2148                              "or activated via <a href=\"keynav\">keynav</a>");
2149       gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
2150       gtk_container_add (GTK_CONTAINER (frame), label);
2151       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2152       g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
2153
2154       vbox = gtk_vbox_new (FALSE, 5);
2155       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2156       frame = gtk_frame_new ("Line wrapped label");
2157       label = gtk_label_new ("This is an example of a line-wrapped label.  It should not be taking "\
2158                              "up the entire             "/* big space to test spacing */\
2159                              "width allocated to it, but automatically wraps the words to fit.  "\
2160                              "The time has come, for all good men, to come to the aid of their party.  "\
2161                              "The sixth sheik's six sheep's sick.\n"\
2162                              "     It supports multiple paragraphs correctly, and  correctly   adds "\
2163                              "many          extra  spaces. ");
2164
2165       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2166       gtk_container_add (GTK_CONTAINER (frame), label);
2167       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2168
2169       frame = gtk_frame_new ("Filled, wrapped label");
2170       label = gtk_label_new ("This is an example of a line-wrapped, filled label.  It should be taking "\
2171                              "up the entire              width allocated to it.  Here is a seneance to prove "\
2172                              "my point.  Here is another sentence. "\
2173                              "Here comes the sun, do de do de do.\n"\
2174                              "    This is a new paragraph.\n"\
2175                              "    This is another newer, longer, better paragraph.  It is coming to an end, "\
2176                              "unfortunately.");
2177       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_FILL);
2178       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2179       gtk_container_add (GTK_CONTAINER (frame), label);
2180       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2181
2182       frame = gtk_frame_new ("Underlined label");
2183       label = gtk_label_new ("This label is underlined!\n"
2184                              "This one is underlined (\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257) in quite a funky fashion");
2185       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
2186       gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __  ___ ____ _____");
2187       gtk_container_add (GTK_CONTAINER (frame), label);
2188       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2189
2190       frame = gtk_frame_new ("Markup label");
2191       label = gtk_label_new (NULL);
2192
2193       /* There's also a gtk_label_set_markup() without accel if you
2194        * don't have an accelerator key
2195        */
2196       gtk_label_set_markup_with_mnemonic (GTK_LABEL (label),
2197                                           "This <span foreground=\"blue\" background=\"orange\">label</span> has "
2198                                           "<b>markup</b> _such as "
2199                                           "<big><i>Big Italics</i></big>\n"
2200                                           "<tt>Monospace font</tt>\n"
2201                                           "<u>Underline!</u>\n"
2202                                           "foo\n"
2203                                           "<span foreground=\"green\" background=\"red\">Ugly colors</span>\n"
2204                                           "and nothing on this line,\n"
2205                                           "or this.\n"
2206                                           "or this either\n"
2207                                           "or even on this one\n"
2208                                           "la <big>la <big>la <big>la <big>la</big></big></big></big>\n"
2209                                           "but this _word is <span foreground=\"purple\"><big>purple</big></span>\n"
2210                                           "<span underline=\"double\">We like <sup>superscript</sup> and <sub>subscript</sub> too</span>");
2211
2212       g_assert (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)) == GDK_KEY_s);
2213       
2214       gtk_container_add (GTK_CONTAINER (frame), label);
2215       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
2216     }
2217   
2218   if (!gtk_widget_get_visible (window))
2219     gtk_widget_show_all (window);
2220   else
2221     gtk_widget_destroy (window);
2222 }
2223
2224 static void
2225 on_angle_scale_changed (GtkRange *range,
2226                         GtkLabel *label)
2227 {
2228   gtk_label_set_angle (GTK_LABEL (label), gtk_range_get_value (range));
2229 }
2230
2231 static void
2232 create_rotated_label (GtkWidget *widget)
2233 {
2234   static GtkWidget *window = NULL;
2235   GtkWidget *content_area;
2236   GtkWidget *vbox;
2237   GtkWidget *hscale;
2238   GtkWidget *label;  
2239   GtkWidget *scale_label;  
2240   GtkWidget *scale_hbox;  
2241
2242   if (!window)
2243     {
2244       window = gtk_dialog_new_with_buttons ("Rotated Label",
2245                                             GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
2246                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
2247                                             NULL);
2248
2249       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
2250
2251       gtk_window_set_screen (GTK_WINDOW (window),
2252                              gtk_widget_get_screen (widget));
2253
2254       g_signal_connect (window, "response",
2255                         G_CALLBACK (gtk_object_destroy), NULL);
2256       g_signal_connect (window, "destroy",
2257                         G_CALLBACK (gtk_widget_destroyed), &window);
2258
2259       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
2260
2261       vbox = gtk_vbox_new (FALSE, 5);
2262       gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
2263       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
2264
2265       label = gtk_label_new (NULL);
2266       gtk_label_set_markup (GTK_LABEL (label), "Hello World\n<i>Rotate</i> <span underline='single' foreground='blue'>me</span>");
2267       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
2268
2269       scale_hbox = gtk_hbox_new (FALSE, 0);
2270       gtk_box_pack_start (GTK_BOX (vbox), scale_hbox, FALSE, FALSE, 0);
2271       
2272       scale_label = gtk_label_new (NULL);
2273       gtk_label_set_markup (GTK_LABEL (scale_label), "<i>Angle: </i>");
2274       gtk_box_pack_start (GTK_BOX (scale_hbox), scale_label, FALSE, FALSE, 0);
2275
2276       hscale = gtk_hscale_new_with_range (0, 360, 5);
2277       g_signal_connect (hscale, "value-changed",
2278                         G_CALLBACK (on_angle_scale_changed), label);
2279       
2280       gtk_range_set_value (GTK_RANGE (hscale), 45);
2281       gtk_widget_set_size_request (hscale, 200, -1);
2282       gtk_box_pack_start (GTK_BOX (scale_hbox), hscale, TRUE, TRUE, 0);
2283     }
2284   
2285   if (!gtk_widget_get_visible (window))
2286     gtk_widget_show_all (window);
2287   else
2288     gtk_widget_destroy (window);
2289 }
2290
2291 #define DEFAULT_TEXT_RADIUS 200
2292
2293 static void
2294 on_rotated_text_unrealize (GtkWidget *widget)
2295 {
2296   g_object_set_data (G_OBJECT (widget), "text-gc", NULL);
2297 }
2298
2299 static gboolean
2300 on_rotated_text_draw (GtkWidget *widget,
2301                       cairo_t   *cr,
2302                       GdkPixbuf *tile_pixbuf)
2303 {
2304   static const gchar *words[] = { "The", "grand", "old", "Duke", "of", "York",
2305                                   "had", "10,000", "men" };
2306   int n_words;
2307   int i;
2308   int width, height;
2309   double radius;
2310   PangoLayout *layout;
2311   PangoContext *context;
2312   PangoFontDescription *desc;
2313
2314   if (tile_pixbuf)
2315     {
2316       gdk_cairo_set_source_pixbuf (cr, tile_pixbuf, 0, 0);
2317       cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
2318     }
2319   else
2320     cairo_set_source_rgb (cr, 0, 0, 0);
2321
2322   width = gtk_widget_get_allocated_width (widget);
2323   height = gtk_widget_get_allocated_height (widget);
2324   radius = MIN (width, height) / 2.;
2325
2326   cairo_translate (cr,
2327                    radius + (width - 2 * radius) / 2,
2328                    radius + (height - 2 * radius) / 2);
2329   cairo_scale (cr, radius / DEFAULT_TEXT_RADIUS, radius / DEFAULT_TEXT_RADIUS);
2330
2331   context = gtk_widget_get_pango_context (widget);
2332   layout = pango_layout_new (context);
2333   desc = pango_font_description_from_string ("Sans Bold 30");
2334   pango_layout_set_font_description (layout, desc);
2335   pango_font_description_free (desc);
2336     
2337   n_words = G_N_ELEMENTS (words);
2338   for (i = 0; i < n_words; i++)
2339     {
2340       int width, height;
2341
2342       cairo_save (cr);
2343
2344       cairo_rotate (cr, 2 * G_PI * i / n_words);
2345       pango_cairo_update_layout (cr, layout);
2346
2347       pango_layout_set_text (layout, words[i], -1);
2348       pango_layout_get_size (layout, &width, &height);
2349
2350       cairo_move_to (cr, - width / 2 / PANGO_SCALE, - DEFAULT_TEXT_RADIUS);
2351       pango_cairo_show_layout (cr, layout);
2352
2353       cairo_restore (cr);
2354     }
2355   
2356   g_object_unref (layout);
2357
2358   return FALSE;
2359 }
2360
2361 static void
2362 create_rotated_text (GtkWidget *widget)
2363 {
2364   static GtkWidget *window = NULL;
2365
2366   if (!window)
2367     {
2368       const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
2369       GtkRequisition requisition;
2370       GtkWidget *content_area;
2371       GtkWidget *drawing_area;
2372       GdkPixbuf *tile_pixbuf;
2373
2374       window = gtk_dialog_new_with_buttons ("Rotated Text",
2375                                             GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
2376                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
2377                                             NULL);
2378
2379       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
2380
2381       gtk_window_set_screen (GTK_WINDOW (window),
2382                              gtk_widget_get_screen (widget));
2383
2384       g_signal_connect (window, "response",
2385                         G_CALLBACK (gtk_object_destroy), NULL);
2386       g_signal_connect (window, "destroy",
2387                         G_CALLBACK (gtk_widget_destroyed), &window);
2388
2389       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
2390
2391       drawing_area = gtk_drawing_area_new ();
2392       gtk_box_pack_start (GTK_BOX (content_area), drawing_area, TRUE, TRUE, 0);
2393       gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &white);
2394
2395       tile_pixbuf = gdk_pixbuf_new_from_file ("marble.xpm", NULL);
2396       
2397       g_signal_connect (drawing_area, "draw",
2398                         G_CALLBACK (on_rotated_text_draw), tile_pixbuf);
2399       g_signal_connect (drawing_area, "unrealize",
2400                         G_CALLBACK (on_rotated_text_unrealize), NULL);
2401
2402       gtk_widget_show_all (gtk_bin_get_child (GTK_BIN (window)));
2403       
2404       gtk_widget_set_size_request (drawing_area, DEFAULT_TEXT_RADIUS * 2, DEFAULT_TEXT_RADIUS * 2);
2405       gtk_size_request_get_size (GTK_SIZE_REQUEST (window),
2406                                  &requisition, NULL);
2407       gtk_widget_set_size_request (drawing_area, -1, -1);
2408       gtk_window_resize (GTK_WINDOW (window), requisition.width, requisition.height);
2409     }
2410   
2411   if (!gtk_widget_get_visible (window))
2412     gtk_widget_show (window);
2413   else
2414     gtk_widget_destroy (window);
2415 }
2416
2417 /*
2418  * Reparent demo
2419  */
2420
2421 static void
2422 reparent_label (GtkWidget *widget,
2423                 GtkWidget *new_parent)
2424 {
2425   GtkWidget *label;
2426
2427   label = g_object_get_data (G_OBJECT (widget), "user_data");
2428
2429   gtk_widget_reparent (label, new_parent);
2430 }
2431
2432 static void
2433 set_parent_signal (GtkWidget *child,
2434                    GtkWidget *old_parent,
2435                    gpointer   func_data)
2436 {
2437   GtkWidget *parent;
2438
2439   parent = gtk_widget_get_parent (child);
2440   g_message ("set_parent for \"%s\": new parent: \"%s\", old parent: \"%s\", data: %d\n",
2441              g_type_name (G_OBJECT_TYPE (child)),
2442              parent ? g_type_name (G_OBJECT_TYPE (parent)) : "NULL",
2443              old_parent ? g_type_name (G_OBJECT_TYPE (old_parent)) : "NULL",
2444              GPOINTER_TO_INT (func_data));
2445 }
2446
2447 static void
2448 create_reparent (GtkWidget *widget)
2449 {
2450   static GtkWidget *window = NULL;
2451   GtkWidget *box1;
2452   GtkWidget *box2;
2453   GtkWidget *box3;
2454   GtkWidget *frame;
2455   GtkWidget *button;
2456   GtkWidget *label;
2457   GtkWidget *separator;
2458   GtkWidget *event_box;
2459
2460   if (!window)
2461     {
2462       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2463
2464       gtk_window_set_screen (GTK_WINDOW (window),
2465                              gtk_widget_get_screen (widget));
2466
2467       g_signal_connect (window, "destroy",
2468                         G_CALLBACK (gtk_widget_destroyed),
2469                         &window);
2470
2471       gtk_window_set_title (GTK_WINDOW (window), "reparent");
2472       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2473
2474       box1 = gtk_vbox_new (FALSE, 0);
2475       gtk_container_add (GTK_CONTAINER (window), box1);
2476
2477       box2 = gtk_hbox_new (FALSE, 5);
2478       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2479       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2480
2481       label = gtk_label_new ("Hello World");
2482
2483       frame = gtk_frame_new ("Frame 1");
2484       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
2485
2486       box3 = gtk_vbox_new (FALSE, 5);
2487       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
2488       gtk_container_add (GTK_CONTAINER (frame), box3);
2489
2490       button = gtk_button_new_with_label ("switch");
2491       g_object_set_data (G_OBJECT (button), "user_data", label);
2492       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
2493
2494       event_box = gtk_event_box_new ();
2495       gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
2496       gtk_container_add (GTK_CONTAINER (event_box), label);
2497                          
2498       g_signal_connect (button, "clicked",
2499                         G_CALLBACK (reparent_label),
2500                         event_box);
2501       
2502       g_signal_connect (label, "parent_set",
2503                         G_CALLBACK (set_parent_signal),
2504                         GINT_TO_POINTER (42));
2505
2506       frame = gtk_frame_new ("Frame 2");
2507       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
2508
2509       box3 = gtk_vbox_new (FALSE, 5);
2510       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
2511       gtk_container_add (GTK_CONTAINER (frame), box3);
2512
2513       button = gtk_button_new_with_label ("switch");
2514       g_object_set_data (G_OBJECT (button), "user_data", label);
2515       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
2516       
2517       event_box = gtk_event_box_new ();
2518       gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
2519
2520       g_signal_connect (button, "clicked",
2521                         G_CALLBACK (reparent_label),
2522                         event_box);
2523
2524       separator = gtk_hseparator_new ();
2525       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2526
2527       box2 = gtk_vbox_new (FALSE, 10);
2528       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2529       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2530
2531       button = gtk_button_new_with_label ("close");
2532       g_signal_connect_swapped (button, "clicked",
2533                                 G_CALLBACK (gtk_widget_destroy), window);
2534       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2535       gtk_widget_set_can_default (button, TRUE);
2536       gtk_widget_grab_default (button);
2537     }
2538
2539   if (!gtk_widget_get_visible (window))
2540     gtk_widget_show_all (window);
2541   else
2542     gtk_widget_destroy (window);
2543 }
2544
2545 /*
2546  * Resize Grips
2547  */
2548 static gboolean
2549 grippy_button_press (GtkWidget *area, GdkEventButton *event, GdkWindowEdge edge)
2550 {
2551   if (event->type == GDK_BUTTON_PRESS) 
2552     {
2553       if (event->button == 1)
2554         gtk_window_begin_resize_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)), edge,
2555                                       event->button, event->x_root, event->y_root,
2556                                       event->time);
2557       else if (event->button == 2)
2558         gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)), 
2559                                     event->button, event->x_root, event->y_root,
2560                                     event->time);
2561     }
2562   return TRUE;
2563 }
2564
2565 static gboolean
2566 grippy_draw (GtkWidget *area, cairo_t *cr, GdkWindowEdge edge)
2567 {
2568   gtk_cairo_paint_resize_grip (gtk_widget_get_style (area),
2569                          cr,
2570                          gtk_widget_get_state (area),
2571                          area,
2572                          "statusbar",
2573                          edge,
2574                          0, 0,
2575                          gtk_widget_get_allocated_width (area),
2576                          gtk_widget_get_allocated_height (area));
2577
2578   return TRUE;
2579 }
2580
2581 static void
2582 create_resize_grips (GtkWidget *widget)
2583 {
2584   static GtkWidget *window = NULL;
2585   GtkWidget *area;
2586   GtkWidget *hbox, *vbox;
2587   if (!window)
2588     {
2589       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2590
2591       gtk_window_set_screen (GTK_WINDOW (window),
2592                              gtk_widget_get_screen (widget));
2593
2594       gtk_window_set_title (GTK_WINDOW (window), "resize grips");
2595       
2596       g_signal_connect (window, "destroy",
2597                         G_CALLBACK (gtk_widget_destroyed),
2598                         &window);
2599
2600       vbox = gtk_vbox_new (FALSE, 0);
2601       gtk_container_add (GTK_CONTAINER (window), vbox);
2602       
2603       hbox = gtk_hbox_new (FALSE, 0);
2604       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2605
2606       /* North west */
2607       area = gtk_drawing_area_new ();
2608       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2609       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2610       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2611                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_WEST));
2612       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2613                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_WEST));
2614       
2615       /* North */
2616       area = gtk_drawing_area_new ();
2617       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2618       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2619       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2620                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH));
2621       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2622                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH));
2623
2624       /* North east */
2625       area = gtk_drawing_area_new ();
2626       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2627       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2628       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2629                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_EAST));
2630       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2631                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_EAST));
2632
2633       hbox = gtk_hbox_new (FALSE, 0);
2634       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2635
2636       /* West */
2637       area = gtk_drawing_area_new ();
2638       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2639       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2640       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2641                         GINT_TO_POINTER (GDK_WINDOW_EDGE_WEST));
2642       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2643                         GINT_TO_POINTER (GDK_WINDOW_EDGE_WEST));
2644
2645       /* Middle */
2646       area = gtk_drawing_area_new ();
2647       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2648
2649       /* East */
2650       area = gtk_drawing_area_new ();
2651       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2652       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2653       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2654                         GINT_TO_POINTER (GDK_WINDOW_EDGE_EAST));
2655       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2656                         GINT_TO_POINTER (GDK_WINDOW_EDGE_EAST));
2657
2658
2659       hbox = gtk_hbox_new (FALSE, 0);
2660       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2661
2662       /* South west */
2663       area = gtk_drawing_area_new ();
2664       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2665       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2666       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2667                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
2668       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2669                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
2670       /* South */
2671       area = gtk_drawing_area_new ();
2672       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2673       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2674       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2675                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
2676       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2677                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
2678       
2679       /* South east */
2680       area = gtk_drawing_area_new ();
2681       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2682       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2683       g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2684                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
2685       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2686                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
2687     }
2688
2689   if (!gtk_widget_get_visible (window))
2690     gtk_widget_show_all (window);
2691   else
2692     gtk_widget_destroy (window);
2693 }
2694
2695 /*
2696  * Saved Position
2697  */
2698 gint upositionx = 0;
2699 gint upositiony = 0;
2700
2701 static gint
2702 uposition_configure (GtkWidget *window)
2703 {
2704   GtkLabel *lx;
2705   GtkLabel *ly;
2706   gchar buffer[64];
2707
2708   lx = g_object_get_data (G_OBJECT (window), "x");
2709   ly = g_object_get_data (G_OBJECT (window), "y");
2710
2711   gdk_window_get_root_origin (gtk_widget_get_window (window),
2712                               &upositionx, &upositiony);
2713   sprintf (buffer, "%d", upositionx);
2714   gtk_label_set_text (lx, buffer);
2715   sprintf (buffer, "%d", upositiony);
2716   gtk_label_set_text (ly, buffer);
2717
2718   return FALSE;
2719 }
2720
2721 static void
2722 uposition_stop_configure (GtkToggleButton *toggle,
2723                           GtkObject       *window)
2724 {
2725   if (toggle->active)
2726     g_signal_handlers_block_by_func (window, G_CALLBACK (uposition_configure), NULL);
2727   else
2728     g_signal_handlers_unblock_by_func (window, G_CALLBACK (uposition_configure), NULL);
2729 }
2730
2731 static void
2732 create_saved_position (GtkWidget *widget)
2733 {
2734   static GtkWidget *window = NULL;
2735
2736   if (!window)
2737     {
2738       GtkWidget *hbox;
2739       GtkWidget *main_vbox;
2740       GtkWidget *vbox;
2741       GtkWidget *x_label;
2742       GtkWidget *y_label;
2743       GtkWidget *button;
2744       GtkWidget *label;
2745       GtkWidget *any;
2746
2747       window = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
2748                                                  "type", GTK_WINDOW_TOPLEVEL,
2749                                                  "title", "Saved Position",
2750                                                  NULL),
2751                                  "signal::configure_event", uposition_configure, NULL,
2752                                  NULL);
2753
2754       gtk_window_move (GTK_WINDOW (window), upositionx, upositiony);
2755
2756       gtk_window_set_screen (GTK_WINDOW (window),
2757                              gtk_widget_get_screen (widget));
2758       
2759
2760       g_signal_connect (window, "destroy",
2761                         G_CALLBACK (gtk_widget_destroyed),
2762                         &window);
2763
2764       main_vbox = gtk_vbox_new (FALSE, 5);
2765       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
2766       gtk_container_add (GTK_CONTAINER (window), main_vbox);
2767
2768       vbox =
2769         g_object_new (gtk_vbox_get_type (),
2770                         "GtkBox::homogeneous", FALSE,
2771                         "GtkBox::spacing", 5,
2772                         "GtkContainer::border_width", 10,
2773                         "GtkWidget::parent", main_vbox,
2774                         "GtkWidget::visible", TRUE,
2775                         "child", g_object_connect (g_object_new (GTK_TYPE_TOGGLE_BUTTON,
2776                                                                    "label", "Stop Events",
2777                                                                    "active", FALSE,
2778                                                                    "visible", TRUE,
2779                                                                    NULL),
2780                                                    "signal::clicked", uposition_stop_configure, window,
2781                                                    NULL),
2782                         NULL);
2783
2784       hbox = gtk_hbox_new (FALSE, 0);
2785       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2786       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2787
2788       label = gtk_label_new ("X Origin : ");
2789       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2790       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2791
2792       x_label = gtk_label_new ("");
2793       gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
2794       g_object_set_data (G_OBJECT (window), "x", x_label);
2795
2796       hbox = gtk_hbox_new (FALSE, 0);
2797       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2798       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2799
2800       label = gtk_label_new ("Y Origin : ");
2801       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2802       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2803
2804       y_label = gtk_label_new ("");
2805       gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
2806       g_object_set_data (G_OBJECT (window), "y", y_label);
2807
2808       any =
2809         g_object_new (gtk_hseparator_get_type (),
2810                         "GtkWidget::visible", TRUE,
2811                         NULL);
2812       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
2813
2814       hbox = gtk_hbox_new (FALSE, 0);
2815       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
2816       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
2817
2818       button = gtk_button_new_with_label ("Close");
2819       g_signal_connect_swapped (button, "clicked",
2820                                 G_CALLBACK (gtk_widget_destroy),
2821                                 window);
2822       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
2823       gtk_widget_set_can_default (button, TRUE);
2824       gtk_widget_grab_default (button);
2825       
2826       gtk_widget_show_all (window);
2827     }
2828   else
2829     gtk_widget_destroy (window);
2830 }
2831
2832 /*
2833  * GtkPixmap
2834  */
2835
2836 static void
2837 create_pixbuf (GtkWidget *widget)
2838 {
2839   static GtkWidget *window = NULL;
2840   GtkWidget *box1;
2841   GtkWidget *box2;
2842   GtkWidget *box3;
2843   GtkWidget *button;
2844   GtkWidget *label;
2845   GtkWidget *separator;
2846   GtkWidget *pixbufwid;
2847   GdkWindow *gdk_window;
2848
2849   if (!window)
2850     {
2851       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2852
2853       gtk_window_set_screen (GTK_WINDOW (window),
2854                              gtk_widget_get_screen (widget));
2855
2856       g_signal_connect (window, "destroy",
2857                         G_CALLBACK (gtk_widget_destroyed),
2858                         &window);
2859
2860       gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
2861       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2862       gtk_widget_realize(window);
2863
2864       box1 = gtk_vbox_new (FALSE, 0);
2865       gtk_container_add (GTK_CONTAINER (window), box1);
2866
2867       box2 = gtk_vbox_new (FALSE, 10);
2868       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2869       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2870
2871       button = gtk_button_new ();
2872       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2873
2874       gdk_window = gtk_widget_get_window (window);
2875
2876       pixbufwid = new_pixbuf ("test.xpm", gdk_window, NULL);
2877
2878       label = gtk_label_new ("Pixbuf\ntest");
2879       box3 = gtk_hbox_new (FALSE, 0);
2880       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2881       gtk_container_add (GTK_CONTAINER (box3), pixbufwid);
2882       gtk_container_add (GTK_CONTAINER (box3), label);
2883       gtk_container_add (GTK_CONTAINER (button), box3);
2884
2885       button = gtk_button_new ();
2886       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2887
2888       pixbufwid = new_pixbuf ("test.xpm", gdk_window, NULL);
2889
2890       label = gtk_label_new ("Pixbuf\ntest");
2891       box3 = gtk_hbox_new (FALSE, 0);
2892       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2893       gtk_container_add (GTK_CONTAINER (box3), pixbufwid);
2894       gtk_container_add (GTK_CONTAINER (box3), label);
2895       gtk_container_add (GTK_CONTAINER (button), box3);
2896
2897       gtk_widget_set_sensitive (button, FALSE);
2898       
2899       separator = gtk_hseparator_new ();
2900       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2901
2902       box2 = gtk_vbox_new (FALSE, 10);
2903       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2904       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2905
2906       button = gtk_button_new_with_label ("close");
2907       g_signal_connect_swapped (button, "clicked",
2908                                 G_CALLBACK (gtk_widget_destroy),
2909                                 window);
2910       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2911       gtk_widget_set_can_default (button, TRUE);
2912       gtk_widget_grab_default (button);
2913     }
2914
2915   if (!gtk_widget_get_visible (window))
2916     gtk_widget_show_all (window);
2917   else
2918     gtk_widget_destroy (window);
2919 }
2920
2921 static void
2922 create_tooltips (GtkWidget *widget)
2923 {
2924   static GtkWidget *window = NULL;
2925   GtkWidget *box1;
2926   GtkWidget *box2;
2927   GtkWidget *box3;
2928   GtkWidget *button;
2929   GtkWidget *toggle;
2930   GtkWidget *frame;
2931   GtkWidget *separator;
2932
2933   if (!window)
2934     {
2935       window =
2936         g_object_new (gtk_window_get_type (),
2937                         "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
2938                         "GtkContainer::border_width", 0,
2939                         "GtkWindow::title", "Tooltips",
2940                         "GtkWindow::resizable", FALSE,
2941                         NULL);
2942
2943       gtk_window_set_screen (GTK_WINDOW (window),
2944                              gtk_widget_get_screen (widget));
2945
2946       box1 = gtk_vbox_new (FALSE, 0);
2947       gtk_container_add (GTK_CONTAINER (window), box1);
2948
2949       box2 = gtk_vbox_new (FALSE, 10);
2950       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2951       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2952
2953       button = gtk_toggle_button_new_with_label ("button1");
2954       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2955
2956       gtk_widget_set_tooltip_text (button, "This is button 1");
2957
2958       button = gtk_toggle_button_new_with_label ("button2");
2959       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2960
2961       gtk_widget_set_tooltip_text (button,
2962         "This is button 2. This is also a really long tooltip which probably "
2963         "won't fit on a single line and will therefore need to be wrapped. "
2964         "Hopefully the wrapping will work correctly.");
2965
2966       toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
2967       gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
2968
2969       gtk_widget_set_tooltip_text (toggle, "Toggle TipsQuery view.");
2970
2971       box3 =
2972         g_object_new (gtk_vbox_get_type (),
2973                         "homogeneous", FALSE,
2974                         "spacing", 5,
2975                         "border_width", 5,
2976                         "visible", TRUE,
2977                         NULL);
2978
2979       button =
2980         g_object_new (gtk_button_get_type (),
2981                         "label", "[?]",
2982                         "visible", TRUE,
2983                         "parent", box3,
2984                         NULL);
2985       gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
2986       gtk_widget_set_tooltip_text (button, "Start the Tooltips Inspector");
2987       
2988       frame = g_object_new (gtk_frame_get_type (),
2989                               "label", "ToolTips Inspector",
2990                               "label_xalign", (double) 0.5,
2991                               "border_width", 0,
2992                               "visible", TRUE,
2993                               "parent", box2,
2994                               "child", box3,
2995                               NULL);
2996       gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
2997
2998       separator = gtk_hseparator_new ();
2999       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3000
3001       box2 = gtk_vbox_new (FALSE, 10);
3002       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3003       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3004
3005       button = gtk_button_new_with_label ("close");
3006       g_signal_connect_swapped (button, "clicked",
3007                                 G_CALLBACK (gtk_widget_destroy),
3008                                 window);
3009       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3010       gtk_widget_set_can_default (button, TRUE);
3011       gtk_widget_grab_default (button);
3012
3013       gtk_widget_set_tooltip_text (button, "Push this button to close window");
3014     }
3015
3016   if (!gtk_widget_get_visible (window))
3017     gtk_widget_show_all (window);
3018   else
3019     gtk_widget_destroy (window);
3020 }
3021
3022 /*
3023  * GtkImage
3024  */
3025
3026 static void
3027 pack_image (GtkWidget *box,
3028             const gchar *text,
3029             GtkWidget *image)
3030 {
3031   gtk_box_pack_start (GTK_BOX (box),
3032                       gtk_label_new (text),
3033                       FALSE, FALSE, 0);
3034
3035   gtk_box_pack_start (GTK_BOX (box),
3036                       image,
3037                       TRUE, TRUE, 0);  
3038 }
3039
3040 static void
3041 create_image (GtkWidget *widget)
3042 {
3043   static GtkWidget *window = NULL;
3044
3045   if (window == NULL)
3046     {
3047       GtkWidget *vbox;
3048       GdkPixbuf *pixbuf;
3049         
3050       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3051       
3052       gtk_window_set_screen (GTK_WINDOW (window),
3053                              gtk_widget_get_screen (widget));
3054
3055       /* this is bogus for testing drawing when allocation < request,
3056        * don't copy into real code
3057        */
3058       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
3059
3060       g_signal_connect (window, "destroy",
3061                         G_CALLBACK (gtk_widget_destroyed),
3062                         &window);
3063
3064       vbox = gtk_vbox_new (FALSE, 5);
3065
3066       gtk_container_add (GTK_CONTAINER (window), vbox);
3067
3068       pack_image (vbox, "Stock Warning Dialog",
3069                   gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
3070                                             GTK_ICON_SIZE_DIALOG));
3071
3072       pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
3073       
3074       pack_image (vbox, "Pixbuf",
3075                   gtk_image_new_from_pixbuf (pixbuf));
3076
3077       g_object_unref (pixbuf);
3078     }
3079
3080   if (!gtk_widget_get_visible (window))
3081     gtk_widget_show_all (window);
3082   else
3083     gtk_widget_destroy (window);
3084 }
3085      
3086 /*
3087  * Menu demo
3088  */
3089
3090 static GtkWidget*
3091 create_menu (GdkScreen *screen, gint depth, gint length, gboolean tearoff)
3092 {
3093   GtkWidget *menu;
3094   GtkWidget *menuitem;
3095   GtkWidget *image;
3096   GSList *group;
3097   char buf[32];
3098   int i, j;
3099
3100   if (depth < 1)
3101     return NULL;
3102
3103   menu = gtk_menu_new ();
3104   gtk_menu_set_screen (GTK_MENU (menu), screen);
3105
3106   group = NULL;
3107
3108   if (tearoff)
3109     {
3110       menuitem = gtk_tearoff_menu_item_new ();
3111       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3112       gtk_widget_show (menuitem);
3113     }
3114
3115   image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
3116                                     GTK_ICON_SIZE_MENU);
3117   gtk_widget_show (image);
3118   menuitem = gtk_image_menu_item_new_with_label ("Image item");
3119   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3120   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3121   gtk_widget_show (menuitem);
3122   
3123   for (i = 0, j = 1; i < length; i++, j++)
3124     {
3125       sprintf (buf, "item %2d - %d", depth, j);
3126
3127       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
3128       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
3129
3130       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3131       gtk_widget_show (menuitem);
3132       if (i == 3)
3133         gtk_widget_set_sensitive (menuitem, FALSE);
3134
3135       if (i == 5)
3136         gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (menuitem),
3137                                               TRUE);
3138
3139       if (i < 5)
3140         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), 
3141                                    create_menu (screen, depth - 1, 5,  TRUE));
3142     }
3143
3144   return menu;
3145 }
3146
3147 static GtkWidget*
3148 create_table_menu (GdkScreen *screen, gint cols, gint rows, gboolean tearoff)
3149 {
3150   GtkWidget *menu;
3151   GtkWidget *menuitem;
3152   GtkWidget *submenu;
3153   GtkWidget *image;
3154   char buf[32];
3155   int i, j;
3156
3157   menu = gtk_menu_new ();
3158   gtk_menu_set_screen (GTK_MENU (menu), screen);
3159
3160   j = 0;
3161   if (tearoff)
3162     {
3163       menuitem = gtk_tearoff_menu_item_new ();
3164       gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
3165       gtk_widget_show (menuitem);
3166       j++;
3167     }
3168   
3169   menuitem = gtk_menu_item_new_with_label ("items");
3170   gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
3171
3172   submenu = gtk_menu_new ();
3173   gtk_menu_set_screen (GTK_MENU (submenu), screen);
3174   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3175   gtk_widget_show (menuitem);
3176   j++;
3177
3178   /* now fill the items submenu */
3179   image = gtk_image_new_from_stock (GTK_STOCK_HELP,
3180                                     GTK_ICON_SIZE_MENU);
3181   gtk_widget_show (image);
3182   menuitem = gtk_image_menu_item_new_with_label ("Image");
3183   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3184   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
3185   gtk_widget_show (menuitem);
3186
3187   menuitem = gtk_menu_item_new_with_label ("x");
3188   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 0, 1);
3189   gtk_widget_show (menuitem);
3190
3191   menuitem = gtk_menu_item_new_with_label ("x");
3192   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 2);
3193   gtk_widget_show (menuitem);
3194   
3195   image = gtk_image_new_from_stock (GTK_STOCK_HELP,
3196                                     GTK_ICON_SIZE_MENU);
3197   gtk_widget_show (image);
3198   menuitem = gtk_image_menu_item_new_with_label ("Image");
3199   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3200   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
3201   gtk_widget_show (menuitem);
3202
3203   menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
3204   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 2, 3);
3205   gtk_widget_show (menuitem);
3206
3207   menuitem = gtk_menu_item_new_with_label ("x");
3208   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 2, 3);
3209   gtk_widget_show (menuitem);
3210
3211   menuitem = gtk_menu_item_new_with_label ("x");
3212   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 3, 4);
3213   gtk_widget_show (menuitem);
3214   
3215   menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
3216   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 3, 4);
3217   gtk_widget_show (menuitem);
3218
3219   menuitem = gtk_check_menu_item_new_with_label ("Check");
3220   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 4, 5);
3221   gtk_widget_show (menuitem);
3222
3223   menuitem = gtk_menu_item_new_with_label ("x");
3224   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 4, 5);
3225   gtk_widget_show (menuitem);
3226
3227   menuitem = gtk_menu_item_new_with_label ("x");
3228   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 5, 6);
3229   gtk_widget_show (menuitem);
3230   
3231   menuitem = gtk_check_menu_item_new_with_label ("Check");
3232   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 5, 6);
3233   gtk_widget_show (menuitem);
3234
3235   menuitem = gtk_menu_item_new_with_label ("1. Inserted normally (8)");
3236   gtk_widget_show (menuitem);
3237   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 8);
3238
3239   menuitem = gtk_menu_item_new_with_label ("2. Inserted normally (2)");
3240   gtk_widget_show (menuitem);
3241   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 2);
3242
3243   menuitem = gtk_menu_item_new_with_label ("3. Inserted normally (0)");
3244   gtk_widget_show (menuitem);
3245   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 0);
3246
3247   menuitem = gtk_menu_item_new_with_label ("4. Inserted normally (-1)");
3248   gtk_widget_show (menuitem);
3249   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, -1);
3250   
3251   /* end of items submenu */
3252
3253   menuitem = gtk_menu_item_new_with_label ("spanning");
3254   gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
3255
3256   submenu = gtk_menu_new ();
3257   gtk_menu_set_screen (GTK_MENU (submenu), screen);
3258   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3259   gtk_widget_show (menuitem);
3260   j++;
3261
3262   /* now fill the spanning submenu */
3263   menuitem = gtk_menu_item_new_with_label ("a");
3264   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 2, 0, 1);
3265   gtk_widget_show (menuitem);
3266
3267   menuitem = gtk_menu_item_new_with_label ("b");
3268   gtk_menu_attach (GTK_MENU (submenu), menuitem, 2, 3, 0, 2);
3269   gtk_widget_show (menuitem);
3270
3271   menuitem = gtk_menu_item_new_with_label ("c");
3272   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 3);
3273   gtk_widget_show (menuitem);
3274
3275   menuitem = gtk_menu_item_new_with_label ("d");
3276   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
3277   gtk_widget_show (menuitem);
3278
3279   menuitem = gtk_menu_item_new_with_label ("e");
3280   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 3, 2, 3);
3281   gtk_widget_show (menuitem);
3282   /* end of spanning submenu */
3283   
3284   menuitem = gtk_menu_item_new_with_label ("left");
3285   gtk_menu_attach (GTK_MENU (menu), menuitem, 0, 1, j, j + 1);
3286   submenu = gtk_menu_new ();
3287   gtk_menu_set_screen (GTK_MENU (submenu), screen);
3288   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3289   gtk_widget_show (menuitem);
3290
3291   menuitem = gtk_menu_item_new_with_label ("Empty");
3292   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
3293   submenu = gtk_menu_new ();
3294   gtk_menu_set_screen (GTK_MENU (submenu), screen);
3295   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3296   gtk_widget_show (menuitem);
3297
3298   menuitem = gtk_menu_item_new_with_label ("right");
3299   gtk_menu_attach (GTK_MENU (menu), menuitem, 1, 2, j, j + 1);
3300   submenu = gtk_menu_new ();
3301   gtk_menu_set_screen (GTK_MENU (submenu), screen);
3302   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3303   gtk_widget_show (menuitem);
3304
3305   menuitem = gtk_menu_item_new_with_label ("Empty");
3306   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
3307   gtk_widget_show (menuitem);
3308
3309   j++;
3310
3311   for (; j < rows; j++)
3312       for (i = 0; i < cols; i++)
3313       {
3314         sprintf (buf, "(%d %d)", i, j);
3315         menuitem = gtk_menu_item_new_with_label (buf);
3316         gtk_menu_attach (GTK_MENU (menu), menuitem, i, i + 1, j, j + 1);
3317         gtk_widget_show (menuitem);
3318       }
3319   
3320   menuitem = gtk_menu_item_new_with_label ("1. Inserted normally (8)");
3321   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 8);
3322   gtk_widget_show (menuitem);
3323   menuitem = gtk_menu_item_new_with_label ("2. Inserted normally (2)");
3324   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 2);
3325   gtk_widget_show (menuitem);
3326   menuitem = gtk_menu_item_new_with_label ("3. Inserted normally (0)");
3327   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 0);
3328   gtk_widget_show (menuitem);
3329   menuitem = gtk_menu_item_new_with_label ("4. Inserted normally (-1)");
3330   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
3331   gtk_widget_show (menuitem);
3332   
3333   return menu;
3334 }
3335
3336 static void
3337 create_menus (GtkWidget *widget)
3338 {
3339   static GtkWidget *window = NULL;
3340   GtkWidget *box1;
3341   GtkWidget *box2;
3342   GtkWidget *button;
3343   GtkWidget *optionmenu;
3344   GtkWidget *separator;
3345   
3346   if (!window)
3347     {
3348       GtkWidget *menubar;
3349       GtkWidget *menu;
3350       GtkWidget *menuitem;
3351       GtkAccelGroup *accel_group;
3352       GtkWidget *image;
3353       GdkScreen *screen = gtk_widget_get_screen (widget);
3354       
3355       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3356
3357       gtk_window_set_screen (GTK_WINDOW (window), screen);
3358       
3359       g_signal_connect (window, "destroy",
3360                         G_CALLBACK (gtk_widget_destroyed),
3361                         &window);
3362       g_signal_connect (window, "delete-event",
3363                         G_CALLBACK (gtk_true),
3364                         NULL);
3365       
3366       accel_group = gtk_accel_group_new ();
3367       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3368
3369       gtk_window_set_title (GTK_WINDOW (window), "menus");
3370       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3371       
3372       
3373       box1 = gtk_vbox_new (FALSE, 0);
3374       gtk_container_add (GTK_CONTAINER (window), box1);
3375       gtk_widget_show (box1);
3376       
3377       menubar = gtk_menu_bar_new ();
3378       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3379       gtk_widget_show (menubar);
3380       
3381       menu = create_menu (screen, 2, 50, TRUE);
3382       
3383       menuitem = gtk_menu_item_new_with_label ("test\nline2");
3384       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3385       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3386       gtk_widget_show (menuitem);
3387
3388       menu = create_table_menu (screen, 2, 50, TRUE);
3389       
3390       menuitem = gtk_menu_item_new_with_label ("table");
3391       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3392       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3393       gtk_widget_show (menuitem);
3394       
3395       menuitem = gtk_menu_item_new_with_label ("foo");
3396       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE));
3397       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3398       gtk_widget_show (menuitem);
3399
3400       image = gtk_image_new_from_stock (GTK_STOCK_HELP,
3401                                         GTK_ICON_SIZE_MENU);
3402       gtk_widget_show (image);
3403       menuitem = gtk_image_menu_item_new_with_label ("Help");
3404       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3405       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 4, 5, TRUE));
3406       gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
3407       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3408       gtk_widget_show (menuitem);
3409       
3410       menubar = gtk_menu_bar_new ();
3411       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3412       gtk_widget_show (menubar);
3413       
3414       menu = create_menu (screen, 2, 10, TRUE);
3415       
3416       menuitem = gtk_menu_item_new_with_label ("Second menu bar");
3417       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3418       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3419       gtk_widget_show (menuitem);
3420       
3421       box2 = gtk_vbox_new (FALSE, 10);
3422       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3423       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3424       gtk_widget_show (box2);
3425       
3426       menu = create_menu (screen, 1, 5, FALSE);
3427       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
3428
3429       menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
3430       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3431       gtk_widget_show (menuitem);
3432       
3433       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
3434       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3435       gtk_widget_show (menuitem);
3436       gtk_widget_add_accelerator (menuitem,
3437                                   "activate",
3438                                   accel_group,
3439                                   GDK_KEY_F1,
3440                                   0,
3441                                   GTK_ACCEL_VISIBLE);
3442       menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
3443       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3444       gtk_widget_show (menuitem);
3445       gtk_widget_add_accelerator (menuitem,
3446                                   "activate",
3447                                   accel_group,
3448                                   GDK_KEY_F2,
3449                                   0,
3450                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3451       menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
3452       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3453       gtk_widget_show (menuitem);
3454       gtk_widget_add_accelerator (menuitem,
3455                                   "activate",
3456                                   accel_group,
3457                                   GDK_KEY_F2,
3458                                   0,
3459                                   GTK_ACCEL_VISIBLE);
3460       gtk_widget_add_accelerator (menuitem,
3461                                   "activate",
3462                                   accel_group,
3463                                   GDK_KEY_F3,
3464                                   0,
3465                                   GTK_ACCEL_VISIBLE);
3466       
3467       optionmenu = gtk_combo_box_new_text ();
3468       gtk_combo_box_set_active (GTK_COMBO_BOX (optionmenu), 3);
3469       gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
3470       gtk_widget_show (optionmenu);
3471
3472       separator = gtk_hseparator_new ();
3473       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3474       gtk_widget_show (separator);
3475
3476       box2 = gtk_vbox_new (FALSE, 10);
3477       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3478       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3479       gtk_widget_show (box2);
3480
3481       button = gtk_button_new_with_label ("close");
3482       g_signal_connect_swapped (button, "clicked",
3483                                 G_CALLBACK (gtk_widget_destroy),
3484                                 window);
3485       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3486       gtk_widget_set_can_default (button, TRUE);
3487       gtk_widget_grab_default (button);
3488       gtk_widget_show (button);
3489     }
3490
3491   if (!gtk_widget_get_visible (window))
3492     gtk_widget_show (window);
3493   else
3494     gtk_widget_destroy (window);
3495 }
3496
3497 /* GdkPixbuf RGBA C-Source image dump */
3498
3499 static const guint8 apple[] = 
3500 { ""
3501   /* Pixbuf magic (0x47646b50) */
3502   "GdkP"
3503   /* length: header (24) + pixel_data (2304) */
3504   "\0\0\11\30"
3505   /* pixdata_type (0x1010002) */
3506   "\1\1\0\2"
3507   /* rowstride (96) */
3508   "\0\0\0`"
3509   /* width (24) */
3510   "\0\0\0\30"
3511   /* height (24) */
3512   "\0\0\0\30"
3513   /* pixel_data: */
3514   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3515   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3516   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3517   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3518   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3519   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3520   "\0\0\0\0\0\0\0\0\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"
3521   "\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"
3522   "\0\0\0\0\0\0\0\0\0\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"
3523   "[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"
3524   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3525   "\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"
3526   "\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"
3527   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3528   "\0\0\0\0\0\0`l\\\20iw_\356y\211h\373x\207g\364~\216i\364u\204e\366gt"
3529   "_\374^jX\241A;-_\0\0\0~\0\0\0\0SM4)SM21B9&\22\320\270\204\1\320\270\204"
3530   "\0\0\0\0\0\0\0\0\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"
3531   "]\212r\200c\366v\205f\371jx_\323_kY\232_kZH^jY\26]iW\211@G9\272:6%j\220"
3532   "\211]\320\221\211`\377\212\203Z\377~xP\377mkE\331]^;|/0\37\21\0\0\0\0"
3533   "\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["
3534   "eT<\216\200Z\203\227\211_\354\234\217c\377\232\217b\362\232\220c\337"
3535   "\243\233k\377\252\241p\377\250\236p\377\241\225h\377\231\214_\377\210"
3536   "\202U\377srI\377[]:\355KO0U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0i"
3537   "v^\200`lY\211^jY\"\0\0\0\0\221\204\\\273\250\233r\377\302\267\224\377"
3538   "\311\300\237\377\272\256\204\377\271\256\177\377\271\257\200\377\267"
3539   "\260\177\377\260\251x\377\250\236l\377\242\225e\377\226\213]\377~zP\377"
3540   "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"
3541   "\0\213\203[v\253\240t\377\334\326\301\377\344\340\317\377\321\312\253"
3542   "\377\303\271\217\377\300\270\213\377\277\267\210\377\272\264\203\377"
3543   "\261\255z\377\250\242n\377\243\232h\377\232\220`\377\210\202V\377nnE"
3544   "\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"
3545   "\234\222e\362\304\274\232\377\337\333\306\377\332\325\273\377\311\302"
3546   "\232\377\312\303\236\377\301\273\216\377\300\271\212\377\270\264\200"
3547   "\377\256\253v\377\246\243n\377\236\232h\377\230\220`\377\213\203V\377"
3548   "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"
3549   "\203Zl\242\234l\377\321\315\260\377\331\324\271\377\320\313\251\377\307"
3550   "\301\232\377\303\276\224\377\300\272\214\377\274\267\206\377\264\260"
3551   "|\377\253\251s\377\244\243n\377\232\230e\377\223\216^\377\207\200U\377"
3552   "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"
3553   "\210\204Y\240\245\237o\377\316\310\253\377\310\303\237\377\304\300\230"
3554   "\377\303\277\225\377\277\272\216\377\274\270\210\377\266\263\200\377"
3555   "\256\254v\377\247\246p\377\237\236j\377\227\226d\377\215\212[\377\203"
3556   "\177T\377qsH\377X]8\377FN.\377DK-\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3557   "\0\0\0\0\207\204X\257\244\240o\377\300\275\231\377\301\275\226\377\274"
3558   "\270\213\377\274\270\214\377\267\264\205\377\264\262\200\377\260\256"
3559   "z\377\251\251s\377\243\244n\377\231\232g\377\220\222`\377\210\211Y\377"
3560   "|}Q\377hlC\377PU3\377CK,\377DL/Y\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
3561   "\0\0\205\204X\220\232\230h\377\261\260\204\377\266\264\212\377\261\260"
3562   "\201\377\263\260\200\377\260\257}\377\256\256x\377\253\254t\377\244\246"
3563   "o\377\233\236i\377\221\224b\377\211\214\\\377\202\204V\377txM\377]b>"
3564   "\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>"
3565   "\215\215_\377\237\237r\377\247\247x\377\247\247t\377\252\252w\377\252"
3566   "\252u\377\252\253t\377\243\246o\377\235\240j\377\223\230c\377\213\217"
3567   "]\377\201\206V\377x}P\377gkD\377RY5\377BI,\377AI,\262\0\0\0\0\0\0\0\0"
3568   "\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"
3569   "\232g\377\234\236i\377\236\241l\377\241\244n\377\240\244m\377\232\237"
3570   "i\377\223\230c\377\212\221]\377\200\210W\377v|P\377jnG\377Za>\377HP2"
3571   "\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"
3572   "\0wzQ6\177\201U\371\206\211Z\377\216\222`\377\220\225a\377\220\225b\377"
3573   "\220\226a\377\213\221_\377\204\213Z\377{\203R\377ryN\377iqH\377^fA\377"
3574   "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"
3575   "\0\0\0\0\0\0\0\0\0\0\0\0ptJTw|Q\371z\177R\377}\202T\377|\203T\377z\200"
3576   "R\377v|O\377pwL\377jpF\377dlB\377`hB\377Yb@\377LT6\377<C*\377\11\12\6"
3577   "\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"
3578   "\0\0\0\0\0\0\0\0\0\0\\`=UgnE\370hnG\377gmE\377djB\377]d>\377[c<\377Y"
3579   "b<\377Zc>\377V_>\377OW8\377BK/\377\16\20\12\377\0\0\0\377\0\0\0\377\0"
3580   "\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"
3581   "\0\1\0\0\0\40\22\24\15\260@D+\377W`;\377OV5\377.3\36\377.3\37\377IP0"
3582   "\377RZ7\377PZ8\3776=&\377\14\15\10\377\0\0\0\377\0\0\0\377\0\0\0\377"
3583   "\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"
3584   "\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"
3585   "\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"
3586   "\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"
3587   "\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"
3588   "\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"
3589   "\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"
3590   "\0\0\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"
3591   "\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"
3592   "\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"};
3593
3594
3595 static GtkWidget *
3596 accel_button_new (GtkAccelGroup *accel_group,
3597                   const gchar   *text,
3598                   const gchar   *accel)
3599 {
3600   guint keyval;
3601   GdkModifierType modifiers;
3602   GtkWidget *button;
3603   GtkWidget *label;
3604
3605   gtk_accelerator_parse (accel, &keyval, &modifiers);
3606   g_assert (keyval);
3607
3608   button = gtk_button_new ();
3609   gtk_widget_add_accelerator (button, "activate", accel_group,
3610                               keyval, modifiers, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3611
3612   label = gtk_accel_label_new (text);
3613   gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), button);
3614   gtk_widget_show (label);
3615   
3616   gtk_container_add (GTK_CONTAINER (button), label);
3617
3618   return button;
3619 }
3620
3621 static void
3622 create_key_lookup (GtkWidget *widget)
3623 {
3624   static GtkWidget *window = NULL;
3625   gpointer window_ptr;
3626
3627   if (!window)
3628     {
3629       GtkAccelGroup *accel_group = gtk_accel_group_new ();
3630       GtkWidget *button;
3631       GtkWidget *content_area;
3632
3633       window = gtk_dialog_new_with_buttons ("Key Lookup", NULL, 0,
3634                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
3635                                             NULL);
3636
3637       gtk_window_set_screen (GTK_WINDOW (window),
3638                              gtk_widget_get_screen (widget));
3639
3640       /* We have to expand it so the accel labels will draw their labels
3641        */
3642       gtk_window_set_default_size (GTK_WINDOW (window), 300, -1);
3643       
3644       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3645
3646       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
3647       
3648       button = gtk_button_new_with_mnemonic ("Button 1 (_a)");
3649       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3650       button = gtk_button_new_with_mnemonic ("Button 2 (_A)");
3651       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3652       button = gtk_button_new_with_mnemonic ("Button 3 (_\321\204)");
3653       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3654       button = gtk_button_new_with_mnemonic ("Button 4 (_\320\244)");
3655       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3656       button = gtk_button_new_with_mnemonic ("Button 6 (_b)");
3657       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3658       button = accel_button_new (accel_group, "Button 7", "<Alt><Shift>b");
3659       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3660       button = accel_button_new (accel_group, "Button 8", "<Alt>d");
3661       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3662       button = accel_button_new (accel_group, "Button 9", "<Alt>Cyrillic_ve");
3663       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3664       button = gtk_button_new_with_mnemonic ("Button 10 (_1)");
3665       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3666       button = gtk_button_new_with_mnemonic ("Button 11 (_!)");
3667       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3668       button = accel_button_new (accel_group, "Button 12", "<Super>a");
3669       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3670       button = accel_button_new (accel_group, "Button 13", "<Hyper>a");
3671       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3672       button = accel_button_new (accel_group, "Button 14", "<Meta>a");
3673       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3674       button = accel_button_new (accel_group, "Button 15", "<Shift><Mod4>b");
3675       gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3676
3677       window_ptr = &window;
3678       g_object_add_weak_pointer (G_OBJECT (window), window_ptr);
3679       g_signal_connect (window, "response", G_CALLBACK (gtk_object_destroy), NULL);
3680
3681       gtk_widget_show_all (window);
3682     }
3683   else
3684     gtk_widget_destroy (window);
3685 }
3686
3687
3688 /*
3689  create_modal_window
3690  */
3691
3692 static gboolean
3693 cmw_destroy_cb(GtkWidget *widget)
3694 {
3695   /* This is needed to get out of gtk_main */
3696   gtk_main_quit ();
3697
3698   return FALSE;
3699 }
3700
3701 static void
3702 cmw_color (GtkWidget *widget, GtkWidget *parent)
3703 {
3704     GtkWidget *csd;
3705     GtkWidget *colorsel;
3706     GtkWidget *ok_button, *cancel_button;
3707
3708     csd = gtk_color_selection_dialog_new ("This is a modal color selection dialog");
3709
3710     gtk_window_set_screen (GTK_WINDOW (csd), gtk_widget_get_screen (parent));
3711
3712     colorsel = gtk_color_selection_dialog_get_color_selection (GTK_COLOR_SELECTION_DIALOG (csd));
3713     gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (colorsel),
3714                                          TRUE);
3715     
3716     /* Set as modal */
3717     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
3718
3719     /* And mark it as a transient dialog */
3720     gtk_window_set_transient_for (GTK_WINDOW (csd), GTK_WINDOW (parent));
3721     
3722     g_signal_connect (csd, "destroy",
3723                       G_CALLBACK (cmw_destroy_cb), NULL);
3724
3725     g_object_get (csd,
3726                   "ok-button", &ok_button,
3727                   "cancel-button", &cancel_button,
3728                   NULL);
3729
3730     g_signal_connect_swapped (ok_button,
3731                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
3732     g_signal_connect_swapped (cancel_button,
3733                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
3734     
3735     /* wait until destroy calls gtk_main_quit */
3736     gtk_widget_show (csd);    
3737     gtk_main ();
3738 }
3739
3740 static void
3741 cmw_file (GtkWidget *widget, GtkWidget *parent)
3742 {
3743     GtkWidget *fs;
3744
3745     fs = gtk_file_chooser_dialog_new ("This is a modal file selection dialog",
3746       GTK_WINDOW (parent), GTK_FILE_CHOOSER_ACTION_OPEN,
3747       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
3748       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
3749       NULL);
3750     gtk_window_set_screen (GTK_WINDOW (fs), gtk_widget_get_screen (parent));
3751     gtk_window_set_modal (GTK_WINDOW (fs), TRUE);
3752
3753     g_signal_connect (fs, "destroy",
3754                       G_CALLBACK (cmw_destroy_cb), NULL);
3755     g_signal_connect_swapped (fs, "response",
3756                       G_CALLBACK (gtk_widget_destroy), fs);
3757
3758     /* wait until destroy calls gtk_main_quit */
3759     gtk_widget_show (fs);
3760     gtk_main();
3761 }
3762
3763
3764 static void
3765 create_modal_window (GtkWidget *widget)
3766 {
3767   GtkWidget *window = NULL;
3768   GtkWidget *box1,*box2;
3769   GtkWidget *frame1;
3770   GtkWidget *btnColor,*btnFile,*btnClose;
3771
3772   /* Create modal window (Here you can use any window descendent )*/
3773   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3774   gtk_window_set_screen (GTK_WINDOW (window),
3775                          gtk_widget_get_screen (widget));
3776
3777   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
3778
3779   /* Set window as modal */
3780   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
3781
3782   /* Create widgets */
3783   box1 = gtk_vbox_new (FALSE,5);
3784   frame1 = gtk_frame_new ("Standard dialogs in modal form");
3785   box2 = gtk_vbox_new (TRUE,5);
3786   btnColor = gtk_button_new_with_label ("Color");
3787   btnFile = gtk_button_new_with_label ("File Selection");
3788   btnClose = gtk_button_new_with_label ("Close");
3789
3790   /* Init widgets */
3791   gtk_container_set_border_width (GTK_CONTAINER (box1), 3);
3792   gtk_container_set_border_width (GTK_CONTAINER (box2), 3);
3793     
3794   /* Pack widgets */
3795   gtk_container_add (GTK_CONTAINER (window), box1);
3796   gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
3797   gtk_container_add (GTK_CONTAINER (frame1), box2);
3798   gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
3799   gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
3800   gtk_box_pack_start (GTK_BOX (box1), gtk_hseparator_new (), FALSE, FALSE, 4);
3801   gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
3802    
3803   /* connect signals */
3804   g_signal_connect_swapped (btnClose, "clicked",
3805                             G_CALLBACK (gtk_widget_destroy), window);
3806
3807   g_signal_connect (window, "destroy",
3808                     G_CALLBACK (cmw_destroy_cb), NULL);
3809   
3810   g_signal_connect (btnColor, "clicked",
3811                     G_CALLBACK (cmw_color), window);
3812   g_signal_connect (btnFile, "clicked",
3813                     G_CALLBACK (cmw_file), window);
3814
3815   /* Show widgets */
3816   gtk_widget_show_all (window);
3817
3818   /* wait until dialog get destroyed */
3819   gtk_main();
3820 }
3821
3822 /*
3823  * GtkMessageDialog
3824  */
3825
3826 static void
3827 make_message_dialog (GdkScreen *screen,
3828                      GtkWidget **dialog,
3829                      GtkMessageType  type,
3830                      GtkButtonsType  buttons,
3831                      guint           default_response)
3832 {
3833   if (*dialog)
3834     {
3835       gtk_widget_destroy (*dialog);
3836
3837       return;
3838     }
3839
3840   *dialog = gtk_message_dialog_new (NULL, 0, type, buttons,
3841                                     "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.)");
3842
3843   gtk_window_set_screen (GTK_WINDOW (*dialog), screen);
3844
3845   g_signal_connect_swapped (*dialog,
3846                             "response",
3847                             G_CALLBACK (gtk_widget_destroy),
3848                             *dialog);
3849   
3850   g_signal_connect (*dialog,
3851                     "destroy",
3852                     G_CALLBACK (gtk_widget_destroyed),
3853                     dialog);
3854
3855   gtk_dialog_set_default_response (GTK_DIALOG (*dialog), default_response);
3856
3857   gtk_widget_show (*dialog);
3858 }
3859
3860 static void
3861 create_message_dialog (GtkWidget *widget)
3862 {
3863   static GtkWidget *info = NULL;
3864   static GtkWidget *warning = NULL;
3865   static GtkWidget *error = NULL;
3866   static GtkWidget *question = NULL;
3867   GdkScreen *screen = gtk_widget_get_screen (widget);
3868
3869   make_message_dialog (screen, &info, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, GTK_RESPONSE_OK);
3870   make_message_dialog (screen, &warning, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE);
3871   make_message_dialog (screen, &error, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK);
3872   make_message_dialog (screen, &question, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, GTK_RESPONSE_NO);
3873 }
3874
3875 /*
3876  * GtkScrolledWindow
3877  */
3878
3879 static GtkWidget *sw_parent = NULL;
3880 static GtkWidget *sw_float_parent;
3881 static guint sw_destroyed_handler = 0;
3882
3883 static gboolean
3884 scrolled_windows_delete_cb (GtkWidget *widget, GdkEventAny *event, GtkWidget *scrollwin)
3885 {
3886   gtk_widget_reparent (scrollwin, sw_parent);
3887   
3888   g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
3889   sw_float_parent = NULL;
3890   sw_parent = NULL;
3891   sw_destroyed_handler = 0;
3892
3893   return FALSE;
3894 }
3895
3896 static void
3897 scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
3898 {
3899   gtk_widget_destroy (sw_float_parent);
3900
3901   sw_float_parent = NULL;
3902   sw_parent = NULL;
3903   sw_destroyed_handler = 0;
3904 }
3905
3906 static void
3907 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
3908 {
3909   if (sw_parent)
3910     {
3911       gtk_widget_reparent (scrollwin, sw_parent);
3912       gtk_widget_destroy (sw_float_parent);
3913
3914       g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
3915       sw_float_parent = NULL;
3916       sw_parent = NULL;
3917       sw_destroyed_handler = 0;
3918     }
3919   else
3920     {
3921       sw_parent = gtk_widget_get_parent (scrollwin);
3922       sw_float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3923       gtk_window_set_screen (GTK_WINDOW (sw_float_parent),
3924                              gtk_widget_get_screen (widget));
3925       
3926       gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), 200, 200);
3927       
3928       gtk_widget_reparent (scrollwin, sw_float_parent);
3929       gtk_widget_show (sw_float_parent);
3930
3931       sw_destroyed_handler =
3932         g_signal_connect (sw_parent, "destroy",
3933                           G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
3934       g_signal_connect (sw_float_parent, "delete_event",
3935                         G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
3936     }
3937 }
3938
3939 static void
3940 create_scrolled_windows (GtkWidget *widget)
3941 {
3942   static GtkWidget *window;
3943   GtkWidget *content_area, *action_area;
3944   GtkWidget *scrolled_window;
3945   GtkWidget *table;
3946   GtkWidget *button;
3947   char buffer[32];
3948   int i, j;
3949
3950   if (!window)
3951     {
3952       window = gtk_dialog_new ();
3953
3954       gtk_window_set_screen (GTK_WINDOW (window),
3955                              gtk_widget_get_screen (widget));
3956
3957       g_signal_connect (window, "destroy",
3958                         G_CALLBACK (gtk_widget_destroyed),
3959                         &window);
3960
3961       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
3962       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
3963
3964       gtk_window_set_title (GTK_WINDOW (window), "dialog");
3965       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3966
3967       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
3968       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
3969       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
3970                                       GTK_POLICY_AUTOMATIC,
3971                                       GTK_POLICY_AUTOMATIC);
3972       gtk_box_pack_start (GTK_BOX (content_area), scrolled_window, TRUE, TRUE, 0);
3973       gtk_widget_show (scrolled_window);
3974
3975       table = gtk_table_new (20, 20, FALSE);
3976       gtk_table_set_row_spacings (GTK_TABLE (table), 10);
3977       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
3978       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
3979       gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
3980                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
3981       gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
3982                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
3983       gtk_widget_show (table);
3984
3985       for (i = 0; i < 20; i++)
3986         for (j = 0; j < 20; j++)
3987           {
3988             sprintf (buffer, "button (%d,%d)\n", i, j);
3989             button = gtk_toggle_button_new_with_label (buffer);
3990             gtk_table_attach_defaults (GTK_TABLE (table), button,
3991                                        i, i+1, j, j+1);
3992             gtk_widget_show (button);
3993           }
3994
3995
3996       button = gtk_button_new_with_label ("Close");
3997       g_signal_connect_swapped (button, "clicked",
3998                                 G_CALLBACK (gtk_widget_destroy),
3999                                 window);
4000       gtk_widget_set_can_default (button, TRUE);
4001       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
4002       gtk_widget_grab_default (button);
4003       gtk_widget_show (button);
4004
4005       button = gtk_button_new_with_label ("Reparent Out");
4006       g_signal_connect (button, "clicked",
4007                         G_CALLBACK (scrolled_windows_remove),
4008                         scrolled_window);
4009       gtk_widget_set_can_default (button, TRUE);
4010       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
4011       gtk_widget_grab_default (button);
4012       gtk_widget_show (button);
4013
4014       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
4015     }
4016
4017   if (!gtk_widget_get_visible (window))
4018     gtk_widget_show (window);
4019   else
4020     gtk_widget_destroy (window);
4021 }
4022
4023 /*
4024  * GtkEntry
4025  */
4026
4027 static void
4028 entry_toggle_frame (GtkWidget *checkbutton,
4029                     GtkWidget *entry)
4030 {
4031    gtk_entry_set_has_frame (GTK_ENTRY(entry),
4032                             GTK_TOGGLE_BUTTON(checkbutton)->active);
4033 }
4034
4035 static void
4036 entry_toggle_sensitive (GtkWidget *checkbutton,
4037                         GtkWidget *entry)
4038 {
4039    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
4040 }
4041
4042 static gboolean
4043 entry_progress_timeout (gpointer data)
4044 {
4045   if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "progress-pulse")))
4046     {
4047       gtk_entry_progress_pulse (GTK_ENTRY (data));
4048     }
4049   else
4050     {
4051       gdouble fraction;
4052
4053       fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (data));
4054
4055       fraction += 0.05;
4056       if (fraction > 1.0001)
4057         fraction = 0.0;
4058
4059       gtk_entry_set_progress_fraction (GTK_ENTRY (data), fraction);
4060     }
4061
4062   return TRUE;
4063 }
4064
4065 static void
4066 entry_remove_timeout (gpointer data)
4067 {
4068   g_source_remove (GPOINTER_TO_UINT (data));
4069 }
4070
4071 static void
4072 entry_toggle_progress (GtkWidget *checkbutton,
4073                        GtkWidget *entry)
4074 {
4075   if (GTK_TOGGLE_BUTTON (checkbutton)->active)
4076     {
4077       guint timeout = gdk_threads_add_timeout (100,
4078                                                entry_progress_timeout,
4079                                                entry);
4080       g_object_set_data_full (G_OBJECT (entry), "timeout-id",
4081                               GUINT_TO_POINTER (timeout),
4082                               entry_remove_timeout);
4083     }
4084   else
4085     {
4086       g_object_set_data (G_OBJECT (entry), "timeout-id",
4087                          GUINT_TO_POINTER (0));
4088
4089       gtk_entry_set_progress_fraction (GTK_ENTRY (entry), 0.0);
4090     }
4091 }
4092
4093 static void
4094 entry_toggle_pulse (GtkWidget *checkbutton,
4095                     GtkWidget *entry)
4096 {
4097   g_object_set_data (G_OBJECT (entry), "progress-pulse",
4098                      GUINT_TO_POINTER ((guint) GTK_TOGGLE_BUTTON (checkbutton)->active));
4099 }
4100
4101 static void
4102 props_clicked (GtkWidget *button,
4103                GObject   *object)
4104 {
4105   GtkWidget *window = create_prop_editor (object, 0);
4106
4107   gtk_window_set_title (GTK_WINDOW (window), "Object Properties");
4108 }
4109
4110 static void
4111 create_entry (GtkWidget *widget)
4112 {
4113   static GtkWidget *window = NULL;
4114   GtkWidget *box1;
4115   GtkWidget *box2;
4116   GtkWidget *hbox;
4117   GtkWidget *has_frame_check;
4118   GtkWidget *sensitive_check;
4119   GtkWidget *progress_check;
4120   GtkWidget *entry;
4121   GtkComboBox *cb;
4122   GtkWidget *cb_entry;
4123   GtkWidget *button;
4124   GtkWidget *separator;
4125
4126   if (!window)
4127     {
4128       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4129       gtk_window_set_screen (GTK_WINDOW (window),
4130                              gtk_widget_get_screen (widget));
4131
4132       g_signal_connect (window, "destroy",
4133                         G_CALLBACK (gtk_widget_destroyed),
4134                         &window);
4135
4136       gtk_window_set_title (GTK_WINDOW (window), "entry");
4137       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4138
4139
4140       box1 = gtk_vbox_new (FALSE, 0);
4141       gtk_container_add (GTK_CONTAINER (window), box1);
4142
4143
4144       box2 = gtk_vbox_new (FALSE, 10);
4145       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4146       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4147
4148       hbox = gtk_hbox_new (FALSE, 5);
4149       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
4150       
4151       entry = gtk_entry_new ();
4152       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");
4153       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
4154       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
4155
4156       button = gtk_button_new_with_mnemonic ("_Props");
4157       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4158       g_signal_connect (button, "clicked",
4159                         G_CALLBACK (props_clicked),
4160                         entry);
4161
4162       cb = GTK_COMBO_BOX (gtk_combo_box_entry_new_text ());
4163       gtk_combo_box_append_text (cb, "item0");
4164       gtk_combo_box_append_text (cb, "item0");
4165       gtk_combo_box_append_text (cb, "item1 item1");
4166       gtk_combo_box_append_text (cb, "item2 item2 item2");
4167       gtk_combo_box_append_text (cb, "item3 item3 item3 item3");
4168       gtk_combo_box_append_text (cb, "item4 item4 item4 item4 item4");
4169       gtk_combo_box_append_text (cb, "item5 item5 item5 item5 item5 item5");
4170       gtk_combo_box_append_text (cb, "item6 item6 item6 item6 item6");
4171       gtk_combo_box_append_text (cb, "item7 item7 item7 item7");
4172       gtk_combo_box_append_text (cb, "item8 item8 item8");
4173       gtk_combo_box_append_text (cb, "item9 item9");
4174
4175       cb_entry = gtk_bin_get_child (GTK_BIN (cb));
4176       gtk_entry_set_text (GTK_ENTRY (cb_entry), "hello world \n\n\n foo");
4177       gtk_editable_select_region (GTK_EDITABLE (cb_entry), 0, -1);
4178       gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (cb), TRUE, TRUE, 0);
4179
4180       sensitive_check = gtk_check_button_new_with_label("Sensitive");
4181       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
4182       g_signal_connect (sensitive_check, "toggled",
4183                         G_CALLBACK (entry_toggle_sensitive), entry);
4184       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
4185
4186       has_frame_check = gtk_check_button_new_with_label("Has Frame");
4187       gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
4188       g_signal_connect (has_frame_check, "toggled",
4189                         G_CALLBACK (entry_toggle_frame), entry);
4190       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
4191
4192       progress_check = gtk_check_button_new_with_label("Show Progress");
4193       gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
4194       g_signal_connect (progress_check, "toggled",
4195                         G_CALLBACK (entry_toggle_progress), entry);
4196
4197       progress_check = gtk_check_button_new_with_label("Pulse Progress");
4198       gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
4199       g_signal_connect (progress_check, "toggled",
4200                         G_CALLBACK (entry_toggle_pulse), entry);
4201
4202       separator = gtk_hseparator_new ();
4203       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4204
4205       box2 = gtk_vbox_new (FALSE, 10);
4206       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4207       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4208
4209       button = gtk_button_new_with_label ("close");
4210       g_signal_connect_swapped (button, "clicked",
4211                                 G_CALLBACK (gtk_widget_destroy),
4212                                 window);
4213       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4214       gtk_widget_set_can_default (button, TRUE);
4215       gtk_widget_grab_default (button);
4216     }
4217
4218   if (!gtk_widget_get_visible (window))
4219     gtk_widget_show_all (window);
4220   else
4221     gtk_widget_destroy (window);
4222 }
4223
4224 static void
4225 create_expander (GtkWidget *widget)
4226 {
4227   GtkWidget *box1;
4228   GtkWidget *expander;
4229   GtkWidget *hidden;
4230   static GtkWidget *window = NULL;
4231
4232   if (!window)
4233     {
4234       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4235       gtk_window_set_screen (GTK_WINDOW (window),
4236                              gtk_widget_get_screen (widget));
4237       
4238       g_signal_connect (window, "destroy",
4239                         G_CALLBACK (gtk_widget_destroyed),
4240                         &window);
4241       
4242       gtk_window_set_title (GTK_WINDOW (window), "expander");
4243       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4244       
4245       box1 = gtk_vbox_new (FALSE, 0);
4246       gtk_container_add (GTK_CONTAINER (window), box1);
4247       
4248       expander = gtk_expander_new ("The Hidden");
4249       
4250       gtk_box_pack_start (GTK_BOX (box1), expander, TRUE, TRUE, 0);
4251       
4252       hidden = gtk_label_new ("Revealed!");
4253       
4254       gtk_container_add (GTK_CONTAINER (expander), hidden);
4255     }
4256   
4257   if (!gtk_widget_get_visible (window))
4258     gtk_widget_show_all (window);
4259   else
4260     gtk_widget_destroy (window);
4261 }
4262
4263
4264 /* GtkEventBox */
4265
4266
4267 static void
4268 event_box_label_pressed (GtkWidget        *widget,
4269                          GdkEventButton   *event,
4270                          gpointer user_data)
4271 {
4272   g_print ("clicked on event box\n");
4273 }
4274
4275 static void
4276 event_box_button_clicked (GtkWidget *widget,
4277                           GtkWidget *button,
4278                           gpointer user_data)
4279 {
4280   g_print ("pushed button\n");
4281 }
4282
4283 static void
4284 event_box_toggle_visible_window (GtkWidget *checkbutton,
4285                                  GtkEventBox *event_box)
4286 {
4287   gtk_event_box_set_visible_window (event_box,
4288                                     GTK_TOGGLE_BUTTON(checkbutton)->active);
4289 }
4290
4291 static void
4292 event_box_toggle_above_child (GtkWidget *checkbutton,
4293                               GtkEventBox *event_box)
4294 {
4295   gtk_event_box_set_above_child (event_box,
4296                                  GTK_TOGGLE_BUTTON(checkbutton)->active);
4297 }
4298
4299 static void
4300 create_event_box (GtkWidget *widget)
4301 {
4302   static GtkWidget *window = NULL;
4303   GtkWidget *box1;
4304   GtkWidget *box2;
4305   GtkWidget *hbox;
4306   GtkWidget *vbox;
4307   GtkWidget *button;
4308   GtkWidget *separator;
4309   GtkWidget *event_box;
4310   GtkWidget *label;
4311   GtkWidget *visible_window_check;
4312   GtkWidget *above_child_check;
4313   GdkColor color;
4314
4315   if (!window)
4316     {
4317       color.red = 0;
4318       color.blue = 65535;
4319       color.green = 0;
4320       
4321       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4322       gtk_window_set_screen (GTK_WINDOW (window),
4323                              gtk_widget_get_screen (widget));
4324
4325       g_signal_connect (window, "destroy",
4326                         G_CALLBACK (gtk_widget_destroyed),
4327                         &window);
4328
4329       gtk_window_set_title (GTK_WINDOW (window), "event box");
4330       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4331
4332       box1 = gtk_vbox_new (FALSE, 0);
4333       gtk_container_add (GTK_CONTAINER (window), box1);
4334       gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &color);
4335
4336       hbox = gtk_hbox_new (FALSE, 0);
4337       gtk_box_pack_start (GTK_BOX (box1), hbox, TRUE, FALSE, 0);
4338       
4339       event_box = gtk_event_box_new ();
4340       gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, FALSE, 0);
4341
4342       vbox = gtk_vbox_new (FALSE, 0);
4343       gtk_container_add (GTK_CONTAINER (event_box), vbox);
4344       g_signal_connect (event_box, "button_press_event",
4345                         G_CALLBACK (event_box_label_pressed),
4346                         NULL);
4347       
4348       label = gtk_label_new ("Click on this label");
4349       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
4350
4351       button = gtk_button_new_with_label ("button in eventbox");
4352       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, FALSE, 0);
4353       g_signal_connect (button, "clicked",
4354                         G_CALLBACK (event_box_button_clicked),
4355                         NULL);
4356       
4357
4358       visible_window_check = gtk_check_button_new_with_label("Visible Window");
4359       gtk_box_pack_start (GTK_BOX (box1), visible_window_check, FALSE, TRUE, 0);
4360       g_signal_connect (visible_window_check, "toggled",
4361                         G_CALLBACK (event_box_toggle_visible_window), event_box);
4362       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (visible_window_check), FALSE);
4363       
4364       above_child_check = gtk_check_button_new_with_label("Above Child");
4365       gtk_box_pack_start (GTK_BOX (box1), above_child_check, FALSE, TRUE, 0);
4366       g_signal_connect (above_child_check, "toggled",
4367                         G_CALLBACK (event_box_toggle_above_child), event_box);
4368       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (above_child_check), FALSE);
4369       
4370       separator = gtk_hseparator_new ();
4371       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4372
4373       box2 = gtk_vbox_new (FALSE, 10);
4374       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4375       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4376
4377       button = gtk_button_new_with_label ("close");
4378       g_signal_connect_swapped (button, "clicked",
4379                                 G_CALLBACK (gtk_widget_destroy),
4380                                 window);
4381       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4382       gtk_widget_set_can_default (button, TRUE);
4383       gtk_widget_grab_default (button);
4384     }
4385
4386   if (!gtk_widget_get_visible (window))
4387     gtk_widget_show_all (window);
4388   else
4389     gtk_widget_destroy (window);
4390 }
4391
4392
4393 /*
4394  * GtkSizeGroup
4395  */
4396
4397 #define SIZE_GROUP_INITIAL_SIZE 50
4398
4399 static void
4400 size_group_hsize_changed (GtkSpinButton *spin_button,
4401                           GtkWidget     *button)
4402 {
4403   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
4404                                gtk_spin_button_get_value_as_int (spin_button),
4405                                -1);
4406 }
4407
4408 static void
4409 size_group_vsize_changed (GtkSpinButton *spin_button,
4410                           GtkWidget     *button)
4411 {
4412   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
4413                                -1,
4414                                gtk_spin_button_get_value_as_int (spin_button));
4415 }
4416
4417 static GtkWidget *
4418 create_size_group_window (GdkScreen    *screen,
4419                           GtkSizeGroup *master_size_group)
4420 {
4421   GtkWidget *content_area;
4422   GtkWidget *window;
4423   GtkWidget *table;
4424   GtkWidget *main_button;
4425   GtkWidget *button;
4426   GtkWidget *spin_button;
4427   GtkWidget *hbox;
4428   GtkSizeGroup *hgroup1;
4429   GtkSizeGroup *hgroup2;
4430   GtkSizeGroup *vgroup1;
4431   GtkSizeGroup *vgroup2;
4432
4433   window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
4434                                         NULL, 0,
4435                                         GTK_STOCK_CLOSE,
4436                                         GTK_RESPONSE_NONE,
4437                                         NULL);
4438
4439   gtk_window_set_screen (GTK_WINDOW (window), screen);
4440
4441   gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
4442
4443   g_signal_connect (window, "response",
4444                     G_CALLBACK (gtk_widget_destroy),
4445                     NULL);
4446
4447   content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
4448
4449   table = gtk_table_new (2, 2, FALSE);
4450   gtk_box_pack_start (GTK_BOX (content_area), table, TRUE, TRUE, 0);
4451
4452   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
4453   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
4454   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
4455   gtk_widget_set_size_request (table, 250, 250);
4456
4457   hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4458   hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4459   vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4460   vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4461
4462   main_button = gtk_button_new_with_label ("X");
4463   
4464   gtk_table_attach (GTK_TABLE (table), main_button,
4465                     0, 1,       0, 1,
4466                     GTK_EXPAND, GTK_EXPAND,
4467                     0,          0);
4468   gtk_size_group_add_widget (master_size_group, main_button);
4469   gtk_size_group_add_widget (hgroup1, main_button);
4470   gtk_size_group_add_widget (vgroup1, main_button);
4471   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (main_button)),
4472                                SIZE_GROUP_INITIAL_SIZE,
4473                                SIZE_GROUP_INITIAL_SIZE);
4474
4475   button = gtk_button_new ();
4476   gtk_table_attach (GTK_TABLE (table), button,
4477                     1, 2,       0, 1,
4478                     GTK_EXPAND, GTK_EXPAND,
4479                     0,          0);
4480   gtk_size_group_add_widget (vgroup1, button);
4481   gtk_size_group_add_widget (vgroup2, button);
4482
4483   button = gtk_button_new ();
4484   gtk_table_attach (GTK_TABLE (table), button,
4485                     0, 1,       1, 2,
4486                     GTK_EXPAND, GTK_EXPAND,
4487                     0,          0);
4488   gtk_size_group_add_widget (hgroup1, button);
4489   gtk_size_group_add_widget (hgroup2, button);
4490
4491   button = gtk_button_new ();
4492   gtk_table_attach (GTK_TABLE (table), button,
4493                     1, 2,       1, 2,
4494                     GTK_EXPAND, GTK_EXPAND,
4495                     0,          0);
4496   gtk_size_group_add_widget (hgroup2, button);
4497   gtk_size_group_add_widget (vgroup2, button);
4498
4499   g_object_unref (hgroup1);
4500   g_object_unref (hgroup2);
4501   g_object_unref (vgroup1);
4502   g_object_unref (vgroup2);
4503   
4504   hbox = gtk_hbox_new (FALSE, 5);
4505   gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
4506   
4507   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4508   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4509   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4510   g_signal_connect (spin_button, "value_changed",
4511                     G_CALLBACK (size_group_hsize_changed), main_button);
4512
4513   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4514   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4515   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4516   g_signal_connect (spin_button, "value_changed",
4517                     G_CALLBACK (size_group_vsize_changed), main_button);
4518
4519   return window;
4520 }
4521
4522 static void
4523 create_size_groups (GtkWidget *widget)
4524 {
4525   static GtkWidget *window1 = NULL;
4526   static GtkWidget *window2 = NULL;
4527   static GtkSizeGroup *master_size_group;
4528
4529   if (!master_size_group)
4530     master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
4531
4532   if (!window1)
4533     {
4534       window1 = create_size_group_window (gtk_widget_get_screen (widget),
4535                                           master_size_group);
4536
4537       g_signal_connect (window1, "destroy",
4538                         G_CALLBACK (gtk_widget_destroyed),
4539                         &window1);
4540     }
4541
4542   if (!window2)
4543     {
4544       window2 = create_size_group_window (gtk_widget_get_screen (widget),
4545                                           master_size_group);
4546
4547       g_signal_connect (window2, "destroy",
4548                         G_CALLBACK (gtk_widget_destroyed),
4549                         &window2);
4550     }
4551
4552   if (gtk_widget_get_visible (window1) && gtk_widget_get_visible (window2))
4553     {
4554       gtk_widget_destroy (window1);
4555       gtk_widget_destroy (window2);
4556     }
4557   else
4558     {
4559       if (!gtk_widget_get_visible (window1))
4560         gtk_widget_show_all (window1);
4561       if (!gtk_widget_get_visible (window2))
4562         gtk_widget_show_all (window2);
4563     }
4564 }
4565
4566 /*
4567  * GtkSpinButton
4568  */
4569
4570 static GtkWidget *spinner1;
4571
4572 static void
4573 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
4574 {
4575   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
4576 }
4577
4578 static void
4579 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
4580 {
4581   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
4582 }
4583
4584 static void
4585 change_digits (GtkWidget *widget, GtkSpinButton *spin)
4586 {
4587   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
4588                               gtk_spin_button_get_value_as_int (spin));
4589 }
4590
4591 static void
4592 get_value (GtkWidget *widget, gpointer data)
4593 {
4594   gchar buf[32];
4595   GtkLabel *label;
4596   GtkSpinButton *spin;
4597
4598   spin = GTK_SPIN_BUTTON (spinner1);
4599   label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
4600   if (GPOINTER_TO_INT (data) == 1)
4601     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
4602   else
4603     sprintf (buf, "%0.*f",
4604              gtk_spin_button_get_digits (spin),
4605              gtk_spin_button_get_value (spin));
4606
4607   gtk_label_set_text (label, buf);
4608 }
4609
4610 static void
4611 get_spin_value (GtkWidget *widget, gpointer data)
4612 {
4613   gchar *buffer;
4614   GtkLabel *label;
4615   GtkSpinButton *spin;
4616
4617   spin = GTK_SPIN_BUTTON (widget);
4618   label = GTK_LABEL (data);
4619
4620   buffer = g_strdup_printf ("%0.*f",
4621                             gtk_spin_button_get_digits (spin),
4622                             gtk_spin_button_get_value (spin));
4623   gtk_label_set_text (label, buffer);
4624
4625   g_free (buffer);
4626 }
4627
4628 static gint
4629 spin_button_time_output_func (GtkSpinButton *spin_button)
4630 {
4631   GtkAdjustment *adjustment;
4632   static gchar buf[6];
4633   gdouble hours;
4634   gdouble minutes;
4635
4636   adjustment = gtk_spin_button_get_adjustment (spin_button);
4637   hours = gtk_adjustment_get_value (adjustment) / 60.0;
4638   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
4639   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
4640   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4641     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4642   return TRUE;
4643 }
4644
4645 static gint
4646 spin_button_month_input_func (GtkSpinButton *spin_button,
4647                               gdouble       *new_val)
4648 {
4649   gint i;
4650   static gchar *month[12] = { "January", "February", "March", "April",
4651                               "May", "June", "July", "August",
4652                               "September", "October", "November", "December" };
4653   gchar *tmp1, *tmp2;
4654   gboolean found = FALSE;
4655
4656   for (i = 1; i <= 12; i++)
4657     {
4658       tmp1 = g_ascii_strup (month[i - 1], -1);
4659       tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
4660       if (strstr (tmp1, tmp2) == tmp1)
4661         found = TRUE;
4662       g_free (tmp1);
4663       g_free (tmp2);
4664       if (found)
4665         break;
4666     }
4667   if (!found)
4668     {
4669       *new_val = 0.0;
4670       return GTK_INPUT_ERROR;
4671     }
4672   *new_val = (gdouble) i;
4673   return TRUE;
4674 }
4675
4676 static gint
4677 spin_button_month_output_func (GtkSpinButton *spin_button)
4678 {
4679   GtkAdjustment *adjustment;
4680   gdouble value;
4681   gint i;
4682   static gchar *month[12] = { "January", "February", "March", "April",
4683                               "May", "June", "July", "August", "September",
4684                               "October", "November", "December" };
4685
4686   adjustment = gtk_spin_button_get_adjustment (spin_button);
4687   value = gtk_adjustment_get_value (adjustment);
4688   for (i = 1; i <= 12; i++)
4689     if (fabs (value - (double)i) < 1e-5)
4690       {
4691         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
4692           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
4693       }
4694   return TRUE;
4695 }
4696
4697 static gint
4698 spin_button_hex_input_func (GtkSpinButton *spin_button,
4699                             gdouble       *new_val)
4700 {
4701   const gchar *buf;
4702   gchar *err;
4703   gdouble res;
4704
4705   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
4706   res = strtol(buf, &err, 16);
4707   *new_val = res;
4708   if (*err)
4709     return GTK_INPUT_ERROR;
4710   else
4711     return TRUE;
4712 }
4713
4714 static gint
4715 spin_button_hex_output_func (GtkSpinButton *spin_button)
4716 {
4717   GtkAdjustment *adjustment;
4718   static gchar buf[7];
4719   gint val;
4720
4721   adjustment = gtk_spin_button_get_adjustment (spin_button);
4722   val = (gint) gtk_adjustment_get_value (adjustment);
4723   if (fabs (val) < 1e-5)
4724     sprintf (buf, "0x00");
4725   else
4726     sprintf (buf, "0x%.2X", val);
4727   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4728     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4729   return TRUE;
4730 }
4731
4732 static void
4733 create_spins (GtkWidget *widget)
4734 {
4735   static GtkWidget *window = NULL;
4736   GtkWidget *frame;
4737   GtkWidget *hbox;
4738   GtkWidget *main_vbox;
4739   GtkWidget *vbox;
4740   GtkWidget *vbox2;
4741   GtkWidget *spinner2;
4742   GtkWidget *spinner;
4743   GtkWidget *button;
4744   GtkWidget *label;
4745   GtkWidget *val_label;
4746   GtkAdjustment *adj;
4747
4748   if (!window)
4749     {
4750       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4751       gtk_window_set_screen (GTK_WINDOW (window),
4752                              gtk_widget_get_screen (widget));
4753       
4754       g_signal_connect (window, "destroy",
4755                         G_CALLBACK (gtk_widget_destroyed),
4756                         &window);
4757       
4758       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
4759       
4760       main_vbox = gtk_vbox_new (FALSE, 5);
4761       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
4762       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4763       
4764       frame = gtk_frame_new ("Not accelerated");
4765       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4766       
4767       vbox = gtk_vbox_new (FALSE, 0);
4768       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4769       gtk_container_add (GTK_CONTAINER (frame), vbox);
4770       
4771       /* Time, month, hex spinners */
4772       
4773       hbox = gtk_hbox_new (FALSE, 0);
4774       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
4775       
4776       vbox2 = gtk_vbox_new (FALSE, 0);
4777       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4778       
4779       label = gtk_label_new ("Time :");
4780       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4781       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4782       
4783       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
4784       spinner = gtk_spin_button_new (adj, 0, 0);
4785       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
4786       g_signal_connect (spinner,
4787                         "output",
4788                         G_CALLBACK (spin_button_time_output_func),
4789                         NULL);
4790       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4791       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 5);
4792       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4793
4794       vbox2 = gtk_vbox_new (FALSE, 0);
4795       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4796       
4797       label = gtk_label_new ("Month :");
4798       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4799       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4800       
4801       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
4802                                                   5.0, 0.0);
4803       spinner = gtk_spin_button_new (adj, 0, 0);
4804       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
4805                                          GTK_UPDATE_IF_VALID);
4806       g_signal_connect (spinner,
4807                         "input",
4808                         G_CALLBACK (spin_button_month_input_func),
4809                         NULL);
4810       g_signal_connect (spinner,
4811                         "output",
4812                         G_CALLBACK (spin_button_month_output_func),
4813                         NULL);
4814       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4815       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 9);
4816       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4817       
4818       vbox2 = gtk_vbox_new (FALSE, 0);
4819       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4820
4821       label = gtk_label_new ("Hex :");
4822       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4823       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4824
4825       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 255, 1, 16, 0);
4826       spinner = gtk_spin_button_new (adj, 0, 0);
4827       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
4828       g_signal_connect (spinner,
4829                         "input",
4830                         G_CALLBACK (spin_button_hex_input_func),
4831                         NULL);
4832       g_signal_connect (spinner,
4833                         "output",
4834                         G_CALLBACK (spin_button_hex_output_func),
4835                         NULL);
4836       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4837       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 4);
4838       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4839
4840       frame = gtk_frame_new ("Accelerated");
4841       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4842   
4843       vbox = gtk_vbox_new (FALSE, 0);
4844       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4845       gtk_container_add (GTK_CONTAINER (frame), vbox);
4846       
4847       hbox = gtk_hbox_new (FALSE, 0);
4848       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4849       
4850       vbox2 = gtk_vbox_new (FALSE, 0);
4851       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4852       
4853       label = gtk_label_new ("Value :");
4854       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4855       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4856
4857       adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,
4858                                                   0.5, 100.0, 0.0);
4859       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
4860       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
4861       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
4862
4863       vbox2 = gtk_vbox_new (FALSE, 0);
4864       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4865
4866       label = gtk_label_new ("Digits :");
4867       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4868       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4869
4870       adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 15, 1, 1, 0);
4871       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
4872       g_signal_connect (adj, "value_changed",
4873                         G_CALLBACK (change_digits),
4874                         spinner2);
4875       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
4876
4877       hbox = gtk_hbox_new (FALSE, 0);
4878       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4879
4880       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
4881       g_signal_connect (button, "clicked",
4882                         G_CALLBACK (toggle_snap),
4883                         spinner1);
4884       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4885       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4886
4887       button = gtk_check_button_new_with_label ("Numeric only input mode");
4888       g_signal_connect (button, "clicked",
4889                         G_CALLBACK (toggle_numeric),
4890                         spinner1);
4891       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4892       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4893
4894       val_label = gtk_label_new ("");
4895
4896       hbox = gtk_hbox_new (FALSE, 0);
4897       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4898
4899       button = gtk_button_new_with_label ("Value as Int");
4900       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4901       g_signal_connect (button, "clicked",
4902                         G_CALLBACK (get_value),
4903                         GINT_TO_POINTER (1));
4904       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4905
4906       button = gtk_button_new_with_label ("Value as Float");
4907       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4908       g_signal_connect (button, "clicked",
4909                         G_CALLBACK (get_value),
4910                         GINT_TO_POINTER (2));
4911       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4912
4913       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
4914       gtk_label_set_text (GTK_LABEL (val_label), "0");
4915
4916       frame = gtk_frame_new ("Using Convenience Constructor");
4917       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4918   
4919       hbox = gtk_hbox_new (FALSE, 0);
4920       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4921       gtk_container_add (GTK_CONTAINER (frame), hbox);
4922       
4923       val_label = gtk_label_new ("0.0");
4924
4925       spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
4926       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
4927       g_signal_connect (spinner, "value_changed",
4928                         G_CALLBACK (get_spin_value), val_label);
4929       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
4930       gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
4931
4932       hbox = gtk_hbox_new (FALSE, 0);
4933       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4934   
4935       button = gtk_button_new_with_label ("Close");
4936       g_signal_connect_swapped (button, "clicked",
4937                                 G_CALLBACK (gtk_widget_destroy),
4938                                 window);
4939       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4940     }
4941
4942   if (!gtk_widget_get_visible (window))
4943     gtk_widget_show_all (window);
4944   else
4945     gtk_widget_destroy (window);
4946 }
4947
4948
4949 /*
4950  * Cursors
4951  */
4952
4953 static gint
4954 cursor_draw (GtkWidget *widget,
4955              cairo_t   *cr,
4956              gpointer   user_data)
4957 {
4958   int width, height;
4959
4960   width = gtk_widget_get_allocated_width (widget);
4961   height = gtk_widget_get_allocated_height (widget);
4962
4963   cairo_set_source_rgb (cr, 1, 1, 1);
4964   cairo_rectangle (cr, 0, 0, width, height / 2);
4965   cairo_fill (cr);
4966
4967   cairo_set_source_rgb (cr, 0, 0, 0);
4968   cairo_rectangle (cr, 0, height / 2, width, height / 2);
4969   cairo_fill (cr);
4970
4971   gdk_cairo_set_source_color (cr, &gtk_widget_get_style (widget)->bg[GTK_STATE_NORMAL]);
4972   cairo_rectangle (cr, width / 3, height / 3, width / 3, height / 3);
4973   cairo_fill (cr);
4974
4975   return TRUE;
4976 }
4977
4978 static void
4979 set_cursor (GtkWidget *spinner,
4980             GtkWidget *widget)
4981 {
4982   guint c;
4983   GdkCursor *cursor;
4984   GtkWidget *label;
4985   GEnumClass *class;
4986   GEnumValue *vals;
4987
4988   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
4989   c &= 0xfe;
4990
4991   label = g_object_get_data (G_OBJECT (spinner), "user_data");
4992   
4993   class = g_type_class_ref (GDK_TYPE_CURSOR_TYPE);
4994   vals = class->values;
4995
4996   while (vals && vals->value != c)
4997     vals++;
4998   if (vals)
4999     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
5000   else
5001     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
5002
5003   g_type_class_unref (class);
5004
5005   cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), c);
5006   gdk_window_set_cursor (gtk_widget_get_window (widget),
5007                          cursor);
5008   gdk_cursor_unref (cursor);
5009 }
5010
5011 static gint
5012 cursor_event (GtkWidget          *widget,
5013               GdkEvent           *event,
5014               GtkSpinButton      *spinner)
5015 {
5016   if ((event->type == GDK_BUTTON_PRESS) &&
5017       ((event->button.button == 1) ||
5018        (event->button.button == 3)))
5019     {
5020       gtk_spin_button_spin (spinner, event->button.button == 1 ?
5021                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
5022       return TRUE;
5023     }
5024
5025   return FALSE;
5026 }
5027
5028 #ifdef GDK_WINDOWING_X11
5029 #include "x11/gdkx.h"
5030
5031 static void
5032 change_cursor_theme (GtkWidget *widget,
5033                      gpointer   data)
5034 {
5035   const gchar *theme;
5036   gint size;
5037   GList *children;
5038
5039   children = gtk_container_get_children (GTK_CONTAINER (data));
5040
5041   theme = gtk_entry_get_text (GTK_ENTRY (children->next->data));
5042   size = (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (children->next->next->data));
5043
5044   g_list_free (children);
5045
5046   gdk_x11_display_set_cursor_theme (gtk_widget_get_display (widget),
5047                                     theme, size);
5048 }
5049 #endif
5050
5051
5052 static void
5053 create_cursors (GtkWidget *widget)
5054 {
5055   static GtkWidget *window = NULL;
5056   GtkWidget *frame;
5057   GtkWidget *hbox;
5058   GtkWidget *main_vbox;
5059   GtkWidget *vbox;
5060   GtkWidget *darea;
5061   GtkWidget *spinner;
5062   GtkWidget *button;
5063   GtkWidget *label;
5064   GtkWidget *any;
5065   GtkAdjustment *adj;
5066   GtkWidget *entry;
5067   GtkWidget *size;  
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), "Cursors");
5080       
5081       main_vbox = gtk_vbox_new (FALSE, 5);
5082       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
5083       gtk_container_add (GTK_CONTAINER (window), main_vbox);
5084
5085       vbox =
5086         g_object_new (gtk_vbox_get_type (),
5087                         "GtkBox::homogeneous", FALSE,
5088                         "GtkBox::spacing", 5,
5089                         "GtkContainer::border_width", 10,
5090                         "GtkWidget::parent", main_vbox,
5091                         "GtkWidget::visible", TRUE,
5092                         NULL);
5093
5094 #ifdef GDK_WINDOWING_X11
5095       hbox = gtk_hbox_new (FALSE, 0);
5096       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5097       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5098
5099       label = gtk_label_new ("Cursor Theme : ");
5100       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5101       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5102
5103       entry = gtk_entry_new ();
5104       gtk_entry_set_text (GTK_ENTRY (entry), "default");
5105       gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
5106
5107       size = gtk_spin_button_new_with_range (1.0, 64.0, 1.0);
5108       gtk_spin_button_set_value (GTK_SPIN_BUTTON (size), 24.0);
5109       gtk_box_pack_start (GTK_BOX (hbox), size, TRUE, TRUE, 0);
5110       
5111       g_signal_connect (entry, "changed", 
5112                         G_CALLBACK (change_cursor_theme), hbox);
5113       g_signal_connect (size, "changed", 
5114                         G_CALLBACK (change_cursor_theme), hbox);
5115 #endif
5116
5117       hbox = gtk_hbox_new (FALSE, 0);
5118       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5119       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5120
5121       label = gtk_label_new ("Cursor Value : ");
5122       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5123       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5124       
5125       adj = (GtkAdjustment *) gtk_adjustment_new (0,
5126                                                   0, 152,
5127                                                   2,
5128                                                   10, 0);
5129       spinner = gtk_spin_button_new (adj, 0, 0);
5130       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
5131
5132       frame =
5133         g_object_new (gtk_frame_get_type (),
5134                         "GtkFrame::label_xalign", 0.5,
5135                         "GtkFrame::label", "Cursor Area",
5136                         "GtkContainer::border_width", 10,
5137                         "GtkWidget::parent", vbox,
5138                         "GtkWidget::visible", TRUE,
5139                         NULL);
5140
5141       darea = gtk_drawing_area_new ();
5142       gtk_widget_set_size_request (darea, 80, 80);
5143       gtk_container_add (GTK_CONTAINER (frame), darea);
5144       g_signal_connect (darea,
5145                         "draw",
5146                         G_CALLBACK (cursor_draw),
5147                         NULL);
5148       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
5149       g_signal_connect (darea,
5150                         "button_press_event",
5151                         G_CALLBACK (cursor_event),
5152                         spinner);
5153       gtk_widget_show (darea);
5154
5155       g_signal_connect (spinner, "changed",
5156                         G_CALLBACK (set_cursor),
5157                         darea);
5158
5159       label = g_object_new (GTK_TYPE_LABEL,
5160                               "visible", TRUE,
5161                               "label", "XXX",
5162                               "parent", vbox,
5163                               NULL);
5164       gtk_container_child_set (GTK_CONTAINER (vbox), label,
5165                                "expand", FALSE,
5166                                NULL);
5167       g_object_set_data (G_OBJECT (spinner), "user_data", label);
5168
5169       any =
5170         g_object_new (gtk_hseparator_get_type (),
5171                         "GtkWidget::visible", TRUE,
5172                         NULL);
5173       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
5174   
5175       hbox = gtk_hbox_new (FALSE, 0);
5176       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
5177       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
5178
5179       button = gtk_button_new_with_label ("Close");
5180       g_signal_connect_swapped (button, "clicked",
5181                                 G_CALLBACK (gtk_widget_destroy),
5182                                 window);
5183       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5184
5185       gtk_widget_show_all (window);
5186
5187       set_cursor (spinner, darea);
5188     }
5189   else
5190     gtk_widget_destroy (window);
5191 }
5192
5193 /*
5194  * GtkColorSelection
5195  */
5196
5197 void
5198 color_selection_ok (GtkWidget               *w,
5199                     GtkColorSelectionDialog *cs)
5200 {
5201   GtkWidget *colorsel;
5202   GdkColor color;
5203
5204   colorsel = gtk_color_selection_dialog_get_color_selection (cs);
5205
5206   gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5207   gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5208 }
5209
5210 void
5211 color_selection_changed (GtkWidget *w,
5212                          GtkColorSelectionDialog *cs)
5213 {
5214   GtkWidget *colorsel;
5215   GdkColor color;
5216
5217   colorsel = gtk_color_selection_dialog_get_color_selection (cs);
5218   gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5219   gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5220 }
5221
5222 #if 0 /* unused */
5223 static void
5224 opacity_toggled_cb (GtkWidget *w,
5225                     GtkColorSelectionDialog *cs)
5226 {
5227   GtkColorSelection *colorsel;
5228
5229   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
5230   gtk_color_selection_set_has_opacity_control (colorsel,
5231                                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
5232 }
5233
5234 static void
5235 palette_toggled_cb (GtkWidget *w,
5236                     GtkColorSelectionDialog *cs)
5237 {
5238   GtkColorSelection *colorsel;
5239
5240   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
5241   gtk_color_selection_set_has_palette (colorsel,
5242                                        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
5243 }
5244 #endif
5245
5246 void
5247 create_color_selection (GtkWidget *widget)
5248 {
5249   static GtkWidget *window = NULL;
5250
5251   if (!window)
5252     {
5253       GtkWidget *picker;
5254       GtkWidget *hbox;
5255       GtkWidget *label;
5256       GtkWidget *button;
5257       
5258       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5259       gtk_window_set_screen (GTK_WINDOW (window), 
5260                              gtk_widget_get_screen (widget));
5261                              
5262       g_signal_connect (window, "destroy",
5263                         G_CALLBACK (gtk_widget_destroyed),
5264                         &window);
5265
5266       gtk_window_set_title (GTK_WINDOW (window), "GtkColorButton");
5267       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5268
5269       hbox = gtk_hbox_new (FALSE, 8);
5270       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5271       gtk_container_add (GTK_CONTAINER (window), hbox);
5272       
5273       label = gtk_label_new ("Pick a color");
5274       gtk_container_add (GTK_CONTAINER (hbox), label);
5275
5276       picker = gtk_color_button_new ();
5277       gtk_color_button_set_use_alpha (GTK_COLOR_BUTTON (picker), TRUE);
5278       gtk_container_add (GTK_CONTAINER (hbox), picker);
5279
5280       button = gtk_button_new_with_mnemonic ("_Props");
5281       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
5282       g_signal_connect (button, "clicked",
5283                         G_CALLBACK (props_clicked),
5284                         picker);
5285     }
5286
5287   if (!gtk_widget_get_visible (window))
5288     gtk_widget_show_all (window);
5289   else
5290     gtk_widget_destroy (window);
5291 }
5292
5293 void
5294 flipping_toggled_cb (GtkWidget *widget, gpointer data)
5295 {
5296   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
5297   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
5298
5299   gtk_widget_set_default_direction (new_direction);
5300 }
5301
5302 static void
5303 orientable_toggle_orientation (GtkOrientable *orientable)
5304 {
5305   GtkOrientation orientation;
5306
5307   orientation = gtk_orientable_get_orientation (orientable);
5308   gtk_orientable_set_orientation (orientable,
5309                                   orientation == GTK_ORIENTATION_HORIZONTAL ?
5310                                   GTK_ORIENTATION_VERTICAL :
5311                                   GTK_ORIENTATION_HORIZONTAL);
5312
5313   if (GTK_IS_CONTAINER (orientable))
5314     {
5315       GList *children;
5316       GList *child;
5317
5318       children = gtk_container_get_children (GTK_CONTAINER (orientable));
5319
5320       for (child = children; child; child = child->next)
5321         {
5322           if (GTK_IS_ORIENTABLE (child->data))
5323             orientable_toggle_orientation (child->data);
5324         }
5325
5326       g_list_free (children);
5327     }
5328 }
5329
5330 void
5331 flipping_orientation_toggled_cb (GtkWidget *widget, gpointer data)
5332 {
5333   GtkWidget *content_area;
5334   GtkWidget *toplevel;
5335
5336   toplevel = gtk_widget_get_toplevel (widget);
5337   content_area = gtk_dialog_get_content_area (GTK_DIALOG (toplevel));
5338   orientable_toggle_orientation (GTK_ORIENTABLE (content_area));
5339 }
5340
5341 static void
5342 set_direction_recurse (GtkWidget *widget,
5343                        gpointer   data)
5344 {
5345   GtkTextDirection *dir = data;
5346   
5347   gtk_widget_set_direction (widget, *dir);
5348   if (GTK_IS_CONTAINER (widget))
5349     gtk_container_foreach (GTK_CONTAINER (widget),
5350                            set_direction_recurse,
5351                            data);
5352 }
5353
5354 static GtkWidget *
5355 create_forward_back (const char       *title,
5356                      GtkTextDirection  text_dir)
5357 {
5358   GtkWidget *frame = gtk_frame_new (title);
5359   GtkWidget *bbox = gtk_hbutton_box_new ();
5360   GtkWidget *back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
5361   GtkWidget *forward_button = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
5362
5363   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
5364   
5365   gtk_container_add (GTK_CONTAINER (frame), bbox);
5366   gtk_container_add (GTK_CONTAINER (bbox), back_button);
5367   gtk_container_add (GTK_CONTAINER (bbox), forward_button);
5368
5369   set_direction_recurse (frame, &text_dir);
5370
5371   return frame;
5372 }
5373
5374 void
5375 create_flipping (GtkWidget *widget)
5376 {
5377   static GtkWidget *window = NULL;
5378   GtkWidget *check_button, *button;
5379   GtkWidget *action_area, *content_area;
5380
5381   if (!window)
5382     {
5383       window = gtk_dialog_new ();
5384
5385       gtk_window_set_screen (GTK_WINDOW (window),
5386                              gtk_widget_get_screen (widget));
5387
5388       g_signal_connect (window, "destroy",
5389                         G_CALLBACK (gtk_widget_destroyed),
5390                         &window);
5391
5392       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5393       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
5394
5395       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
5396
5397       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
5398       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
5399       gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
5400
5401       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
5402         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
5403
5404       g_signal_connect (check_button, "toggled",
5405                         G_CALLBACK (flipping_toggled_cb), NULL);
5406
5407       check_button = gtk_check_button_new_with_label ("Toggle orientation of all boxes");
5408       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
5409       gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
5410
5411       g_signal_connect (check_button, "toggled",
5412                         G_CALLBACK (flipping_orientation_toggled_cb), NULL);
5413
5414       gtk_box_pack_start (GTK_BOX (content_area),
5415                           create_forward_back ("Default", GTK_TEXT_DIR_NONE),
5416                           TRUE, TRUE, 0);
5417
5418       gtk_box_pack_start (GTK_BOX (content_area),
5419                           create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
5420                           TRUE, TRUE, 0);
5421
5422       gtk_box_pack_start (GTK_BOX (content_area),
5423                           create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
5424                           TRUE, TRUE, 0);
5425
5426       button = gtk_button_new_with_label ("Close");
5427       g_signal_connect_swapped (button, "clicked",
5428                                 G_CALLBACK (gtk_widget_destroy), window);
5429       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5430     }
5431   
5432   if (!gtk_widget_get_visible (window))
5433     gtk_widget_show_all (window);
5434   else
5435     gtk_widget_destroy (window);
5436 }
5437
5438 /*
5439  * Focus test
5440  */
5441
5442 static GtkWidget*
5443 make_focus_table (GList **list)
5444 {
5445   GtkWidget *table;
5446   gint i, j;
5447   
5448   table = gtk_table_new (5, 5, FALSE);
5449
5450   i = 0;
5451   j = 0;
5452
5453   while (i < 5)
5454     {
5455       j = 0;
5456       while (j < 5)
5457         {
5458           GtkWidget *widget;
5459           
5460           if ((i + j) % 2)
5461             widget = gtk_entry_new ();
5462           else
5463             widget = gtk_button_new_with_label ("Foo");
5464
5465           *list = g_list_prepend (*list, widget);
5466           
5467           gtk_table_attach (GTK_TABLE (table),
5468                             widget,
5469                             i, i + 1,
5470                             j, j + 1,
5471                             GTK_EXPAND | GTK_FILL,
5472                             GTK_EXPAND | GTK_FILL,
5473                             5, 5);
5474           
5475           ++j;
5476         }
5477
5478       ++i;
5479     }
5480
5481   *list = g_list_reverse (*list);
5482   
5483   return table;
5484 }
5485
5486 static void
5487 create_focus (GtkWidget *widget)
5488 {
5489   static GtkWidget *window = NULL;
5490   
5491   if (!window)
5492     {
5493       GtkWidget *content_area;
5494       GtkWidget *table;
5495       GtkWidget *frame;
5496       GList *list = NULL;
5497       
5498       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
5499                                             NULL, 0,
5500                                             GTK_STOCK_CLOSE,
5501                                             GTK_RESPONSE_NONE,
5502                                             NULL);
5503
5504       gtk_window_set_screen (GTK_WINDOW (window),
5505                              gtk_widget_get_screen (widget));
5506
5507       g_signal_connect (window, "destroy",
5508                         G_CALLBACK (gtk_widget_destroyed),
5509                         &window);
5510
5511       g_signal_connect (window, "response",
5512                         G_CALLBACK (gtk_widget_destroy),
5513                         NULL);
5514
5515       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5516       
5517       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
5518
5519       frame = gtk_frame_new ("Weird tab focus chain");
5520
5521       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5522       
5523       table = make_focus_table (&list);
5524
5525       gtk_container_add (GTK_CONTAINER (frame), table);
5526
5527       gtk_container_set_focus_chain (GTK_CONTAINER (table),
5528                                      list);
5529
5530       g_list_free (list);
5531       
5532       frame = gtk_frame_new ("Default tab focus chain");
5533
5534       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5535
5536       list = NULL;
5537       table = make_focus_table (&list);
5538
5539       g_list_free (list);
5540       
5541       gtk_container_add (GTK_CONTAINER (frame), table);      
5542     }
5543   
5544   if (!gtk_widget_get_visible (window))
5545     gtk_widget_show_all (window);
5546   else
5547     gtk_widget_destroy (window);
5548 }
5549
5550 /*
5551  * GtkFontSelection
5552  */
5553
5554 void
5555 font_selection_ok (GtkWidget              *w,
5556                    GtkFontSelectionDialog *fs)
5557 {
5558   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
5559
5560   g_print ("%s\n", s);
5561   g_free (s);
5562   gtk_widget_destroy (GTK_WIDGET (fs));
5563 }
5564
5565 void
5566 create_font_selection (GtkWidget *widget)
5567 {
5568   static GtkWidget *window = NULL;
5569
5570   if (!window)
5571     {
5572       GtkWidget *picker;
5573       GtkWidget *hbox;
5574       GtkWidget *label;
5575       
5576       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5577       gtk_window_set_screen (GTK_WINDOW (window),
5578                              gtk_widget_get_screen (widget));
5579
5580       g_signal_connect (window, "destroy",
5581                         G_CALLBACK (gtk_widget_destroyed),
5582                         &window);
5583
5584       gtk_window_set_title (GTK_WINDOW (window), "GtkFontButton");
5585       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5586
5587       hbox = gtk_hbox_new (FALSE, 8);
5588       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5589       gtk_container_add (GTK_CONTAINER (window), hbox);
5590       
5591       label = gtk_label_new ("Pick a font");
5592       gtk_container_add (GTK_CONTAINER (hbox), label);
5593
5594       picker = gtk_font_button_new ();
5595       gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
5596       gtk_container_add (GTK_CONTAINER (hbox), picker);
5597     }
5598   
5599   if (!gtk_widget_get_visible (window))
5600     gtk_widget_show_all (window);
5601   else
5602     gtk_widget_destroy (window);
5603 }
5604
5605 /*
5606  * GtkDialog
5607  */
5608
5609 static GtkWidget *dialog_window = NULL;
5610
5611 static void
5612 label_toggle (GtkWidget  *widget,
5613               GtkWidget **label)
5614 {
5615   if (!(*label))
5616     {
5617       *label = gtk_label_new ("Dialog Test");
5618       g_signal_connect (*label,
5619                         "destroy",
5620                         G_CALLBACK (gtk_widget_destroyed),
5621                         label);
5622       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
5623       gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog_window))),
5624                           *label, TRUE, TRUE, 0);
5625       gtk_widget_show (*label);
5626     }
5627   else
5628     gtk_widget_destroy (*label);
5629 }
5630
5631 static void
5632 create_dialog (GtkWidget *widget)
5633 {
5634   static GtkWidget *label;
5635   GtkWidget *action_area;
5636   GtkWidget *button;
5637
5638   if (!dialog_window)
5639     {
5640       /* This is a terrible example; it's much simpler to create
5641        * dialogs than this. Don't use testgtk for example code,
5642        * use gtk-demo ;-)
5643        */
5644       
5645       dialog_window = gtk_dialog_new ();
5646       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5647                              gtk_widget_get_screen (widget));
5648
5649       g_signal_connect (dialog_window, "destroy",
5650                         G_CALLBACK (gtk_widget_destroyed),
5651                         &dialog_window);
5652
5653       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5654
5655       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5656       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5657
5658       button = gtk_button_new_with_label ("OK");
5659       gtk_widget_set_can_default (button, TRUE);
5660       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5661       gtk_widget_grab_default (button);
5662       gtk_widget_show (button);
5663
5664       button = gtk_button_new_with_label ("Toggle");
5665       g_signal_connect (button, "clicked",
5666                         G_CALLBACK (label_toggle),
5667                         &label);
5668       gtk_widget_set_can_default (button, TRUE);
5669       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5670       gtk_widget_show (button);
5671
5672       label = NULL;
5673     }
5674
5675   if (!gtk_widget_get_visible (dialog_window))
5676     gtk_widget_show (dialog_window);
5677   else
5678     gtk_widget_destroy (dialog_window);
5679 }
5680
5681 /* Display & Screen test 
5682  */
5683
5684 typedef struct
5685 {
5686   GtkWidget *combo;
5687   GtkWidget *entry;
5688   GtkWidget *radio_dpy;
5689   GtkWidget *toplevel;
5690   GtkWidget *dialog_window;
5691 } ScreenDisplaySelection;
5692
5693 static void
5694 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
5695 {
5696   const gchar *display_name;
5697   GdkDisplay *display = gtk_widget_get_display (widget);
5698   GtkWidget *dialog;
5699   GdkScreen *new_screen = NULL;
5700   GdkScreen *current_screen = gtk_widget_get_screen (widget);
5701   
5702   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
5703     {
5704       display_name = gtk_entry_get_text (GTK_ENTRY (data->entry));
5705       display = gdk_display_open (display_name);
5706       
5707       if (!display)
5708         {
5709           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
5710                                            GTK_DIALOG_DESTROY_WITH_PARENT,
5711                                            GTK_MESSAGE_ERROR,
5712                                            GTK_BUTTONS_OK,
5713                                            "The display :\n%s\ncannot be opened",
5714                                            display_name);
5715           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
5716           gtk_widget_show (dialog);
5717           g_signal_connect (dialog, "response",
5718                             G_CALLBACK (gtk_widget_destroy),
5719                             NULL);
5720         }
5721       else
5722         {
5723           GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->combo));
5724           gint i = 0;
5725           GtkTreeIter iter;
5726           gboolean found = FALSE;
5727           while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i++))
5728             {
5729               gchar *name;
5730               gtk_tree_model_get (model, &iter, 0, &name, -1);
5731               found = !g_ascii_strcasecmp (display_name, name);
5732               g_free (name);
5733
5734               if (found)
5735                 break;
5736             }
5737           if (!found)
5738             gtk_combo_box_append_text (GTK_COMBO_BOX (data->combo), display_name);
5739           new_screen = gdk_display_get_default_screen (display);
5740         }
5741     }
5742   else
5743     {
5744       gint number_of_screens = gdk_display_get_n_screens (display);
5745       gint screen_num = gdk_screen_get_number (current_screen);
5746       if ((screen_num +1) < number_of_screens)
5747         new_screen = gdk_display_get_screen (display, screen_num + 1);
5748       else
5749         new_screen = gdk_display_get_screen (display, 0);
5750     }
5751   
5752   if (new_screen) 
5753     {
5754       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
5755       gtk_widget_destroy (data->dialog_window);
5756     }
5757 }
5758
5759 void
5760 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
5761 {
5762   gtk_widget_destroy (data);
5763 }
5764
5765 void
5766 create_display_screen (GtkWidget *widget)
5767 {
5768   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
5769   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
5770   GtkWidget *bbox;
5771   ScreenDisplaySelection *scr_dpy_data;
5772   GdkScreen *screen = gtk_widget_get_screen (widget);
5773   GdkDisplay *display = gdk_screen_get_display (screen);
5774
5775   window = g_object_new (gtk_window_get_type (),
5776                            "screen", screen,
5777                            "user_data", NULL,
5778                            "type", GTK_WINDOW_TOPLEVEL,
5779                            "title",
5780                            "Screen or Display selection",
5781                            "border_width", 10, NULL);
5782   g_signal_connect (window, "destroy", 
5783                     G_CALLBACK (gtk_widget_destroy), NULL);
5784
5785   vbox = gtk_vbox_new (FALSE, 3);
5786   gtk_container_add (GTK_CONTAINER (window), vbox);
5787   
5788   frame = gtk_frame_new ("Select screen or display");
5789   gtk_container_add (GTK_CONTAINER (vbox), frame);
5790   
5791   table = gtk_table_new (2, 2, TRUE);
5792   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
5793   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
5794
5795   gtk_container_add (GTK_CONTAINER (frame), table);
5796
5797   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
5798   if (gdk_display_get_n_screens(display) > 1)
5799     radio_scr = gtk_radio_button_new_with_label 
5800     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
5801   else
5802     {    
5803       radio_scr = gtk_radio_button_new_with_label 
5804         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
5805          "only one screen on the current display");
5806       gtk_widget_set_sensitive (radio_scr, FALSE);
5807     }
5808   combo_dpy = gtk_combo_box_new_text ();
5809   gtk_combo_box_append_text (GTK_COMBO_BOX (combo_dpy), "diabolo:0.0");
5810   gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo_dpy))),
5811                       "<hostname>:<X Server Num>.<Screen Num>");
5812
5813   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
5814   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
5815   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
5816
5817   bbox = gtk_hbutton_box_new ();
5818   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
5819   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
5820   
5821   gtk_container_add (GTK_CONTAINER (vbox), bbox);
5822
5823   gtk_container_add (GTK_CONTAINER (bbox), applyb);
5824   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
5825
5826   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
5827
5828   scr_dpy_data->entry = gtk_bin_get_child (GTK_BIN (combo_dpy));
5829   scr_dpy_data->radio_dpy = radio_dpy;
5830   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
5831   scr_dpy_data->dialog_window = window;
5832
5833   g_signal_connect (cancelb, "clicked", 
5834                     G_CALLBACK (screen_display_destroy_diag), window);
5835   g_signal_connect (applyb, "clicked", 
5836                     G_CALLBACK (screen_display_check), scr_dpy_data);
5837   gtk_widget_show_all (window);
5838 }
5839
5840 /* Event Watcher
5841  */
5842 static gboolean event_watcher_enter_id = 0;
5843 static gboolean event_watcher_leave_id = 0;
5844
5845 static gboolean
5846 event_watcher (GSignalInvocationHint *ihint,
5847                guint                  n_param_values,
5848                const GValue          *param_values,
5849                gpointer               data)
5850 {
5851   g_print ("Watch: \"%s\" emitted for %s\n",
5852            g_signal_name (ihint->signal_id),
5853            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
5854
5855   return TRUE;
5856 }
5857
5858 static void
5859 event_watcher_down (void)
5860 {
5861   if (event_watcher_enter_id)
5862     {
5863       guint signal_id;
5864
5865       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5866       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5867       event_watcher_enter_id = 0;
5868       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5869       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5870       event_watcher_leave_id = 0;
5871     }
5872 }
5873
5874 static void
5875 event_watcher_toggle (void)
5876 {
5877   if (event_watcher_enter_id)
5878     event_watcher_down ();
5879   else
5880     {
5881       guint signal_id;
5882
5883       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5884       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5885       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5886       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5887     }
5888 }
5889
5890 static void
5891 create_event_watcher (GtkWidget *widget)
5892 {
5893   GtkWidget *action_area, *content_area;
5894   GtkWidget *button;
5895
5896   if (!dialog_window)
5897     {
5898       dialog_window = gtk_dialog_new ();
5899       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5900                              gtk_widget_get_screen (widget));
5901
5902       g_signal_connect (dialog_window, "destroy",
5903                         G_CALLBACK (gtk_widget_destroyed),
5904                         &dialog_window);
5905       g_signal_connect (dialog_window, "destroy",
5906                         G_CALLBACK (event_watcher_down),
5907                         NULL);
5908
5909       content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
5910       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5911
5912       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5913       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5914       gtk_widget_set_size_request (dialog_window, 200, 110);
5915
5916       button = gtk_toggle_button_new_with_label ("Activate Watch");
5917       g_signal_connect (button, "clicked",
5918                         G_CALLBACK (event_watcher_toggle),
5919                         NULL);
5920       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5921       gtk_box_pack_start (GTK_BOX (content_area), button, TRUE, TRUE, 0);
5922       gtk_widget_show (button);
5923
5924       button = gtk_button_new_with_label ("Close");
5925       g_signal_connect_swapped (button, "clicked",
5926                                 G_CALLBACK (gtk_widget_destroy),
5927                                 dialog_window);
5928       gtk_widget_set_can_default (button, TRUE);
5929       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5930       gtk_widget_grab_default (button);
5931       gtk_widget_show (button);
5932     }
5933
5934   if (!gtk_widget_get_visible (dialog_window))
5935     gtk_widget_show (dialog_window);
5936   else
5937     gtk_widget_destroy (dialog_window);
5938 }
5939
5940 /*
5941  * GtkRange
5942  */
5943
5944 static gchar*
5945 reformat_value (GtkScale *scale,
5946                 gdouble   value)
5947 {
5948   return g_strdup_printf ("-->%0.*g<--",
5949                           gtk_scale_get_digits (scale), value);
5950 }
5951
5952 static void
5953 create_range_controls (GtkWidget *widget)
5954 {
5955   static GtkWidget *window = NULL;
5956   GtkWidget *box1;
5957   GtkWidget *box2;
5958   GtkWidget *button;
5959   GtkWidget *scrollbar;
5960   GtkWidget *scale;
5961   GtkWidget *separator;
5962   GtkObject *adjustment;
5963   GtkWidget *hbox;
5964
5965   if (!window)
5966     {
5967       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5968
5969       gtk_window_set_screen (GTK_WINDOW (window),
5970                              gtk_widget_get_screen (widget));
5971
5972       g_signal_connect (window, "destroy",
5973                         G_CALLBACK (gtk_widget_destroyed),
5974                         &window);
5975
5976       gtk_window_set_title (GTK_WINDOW (window), "range controls");
5977       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5978
5979
5980       box1 = gtk_vbox_new (FALSE, 0);
5981       gtk_container_add (GTK_CONTAINER (window), box1);
5982       gtk_widget_show (box1);
5983
5984
5985       box2 = gtk_vbox_new (FALSE, 10);
5986       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5987       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5988       gtk_widget_show (box2);
5989
5990
5991       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5992
5993       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
5994       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
5995       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
5996       gtk_scale_set_digits (GTK_SCALE (scale), 1);
5997       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5998       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5999       gtk_widget_show (scale);
6000
6001       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
6002       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
6003                                    GTK_UPDATE_CONTINUOUS);
6004       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
6005       gtk_widget_show (scrollbar);
6006
6007       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
6008       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
6009       g_signal_connect (scale,
6010                         "format_value",
6011                         G_CALLBACK (reformat_value),
6012                         NULL);
6013       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
6014       gtk_widget_show (scale);
6015       
6016       hbox = gtk_hbox_new (FALSE, 0);
6017
6018       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
6019       gtk_widget_set_size_request (scale, -1, 200);
6020       gtk_scale_set_digits (GTK_SCALE (scale), 2);
6021       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
6022       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
6023       gtk_widget_show (scale);
6024
6025       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
6026       gtk_widget_set_size_request (scale, -1, 200);
6027       gtk_scale_set_digits (GTK_SCALE (scale), 2);
6028       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
6029       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
6030       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
6031       gtk_widget_show (scale);
6032
6033       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
6034       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
6035       g_signal_connect (scale,
6036                         "format_value",
6037                         G_CALLBACK (reformat_value),
6038                         NULL);
6039       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
6040       gtk_widget_show (scale);
6041
6042       
6043       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
6044       gtk_widget_show (hbox);
6045       
6046       separator = gtk_hseparator_new ();
6047       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
6048       gtk_widget_show (separator);
6049
6050
6051       box2 = gtk_vbox_new (FALSE, 10);
6052       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6053       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6054       gtk_widget_show (box2);
6055
6056
6057       button = gtk_button_new_with_label ("close");
6058       g_signal_connect_swapped (button, "clicked",
6059                                 G_CALLBACK (gtk_widget_destroy),
6060                                 window);
6061       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6062       gtk_widget_set_can_default (button, TRUE);
6063       gtk_widget_grab_default (button);
6064       gtk_widget_show (button);
6065     }
6066
6067   if (!gtk_widget_get_visible (window))
6068     gtk_widget_show (window);
6069   else
6070     gtk_widget_destroy (window);
6071 }
6072
6073 /*
6074  * GtkRulers
6075  */
6076
6077 void
6078 create_rulers (GtkWidget *widget)
6079 {
6080   static GtkWidget *window = NULL;
6081   GtkWidget *table;
6082   GtkWidget *ruler;
6083
6084   if (!window)
6085     {
6086       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6087
6088       gtk_window_set_screen (GTK_WINDOW (window),
6089                              gtk_widget_get_screen (widget));
6090
6091       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
6092
6093       g_signal_connect (window, "destroy",
6094                         G_CALLBACK (gtk_widget_destroyed),
6095                         &window);
6096
6097       gtk_window_set_title (GTK_WINDOW (window), "rulers");
6098       gtk_widget_set_size_request (window, 300, 300);
6099       gtk_widget_set_events (window, 
6100                              GDK_POINTER_MOTION_MASK 
6101                              | GDK_POINTER_MOTION_HINT_MASK);
6102       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6103
6104       table = gtk_table_new (2, 2, FALSE);
6105       gtk_container_add (GTK_CONTAINER (window), table);
6106       gtk_widget_show (table);
6107
6108       ruler = gtk_hruler_new ();
6109       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
6110       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
6111
6112       g_signal_connect_swapped (window, 
6113                                 "motion_notify_event",
6114                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
6115                                 ruler);
6116       
6117       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
6118                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
6119       gtk_widget_show (ruler);
6120
6121
6122       ruler = gtk_vruler_new ();
6123       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
6124
6125       g_signal_connect_swapped (window, 
6126                                 "motion_notify_event",
6127                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
6128                                 ruler);
6129       
6130       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
6131                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
6132       gtk_widget_show (ruler);
6133     }
6134
6135   if (!gtk_widget_get_visible (window))
6136     gtk_widget_show (window);
6137   else
6138     gtk_widget_destroy (window);
6139 }
6140
6141 struct {
6142   GdkColor color;
6143   gchar *name;
6144 } text_colors[] = {
6145  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
6146  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
6147  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
6148  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
6149  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
6150  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
6151  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
6152  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
6153 };
6154
6155 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
6156
6157 /*
6158  * GtkNotebook
6159  */
6160
6161 static const char * book_open_xpm[] = {
6162 "16 16 4 1",
6163 "       c None s None",
6164 ".      c black",
6165 "X      c #808080",
6166 "o      c white",
6167 "                ",
6168 "  ..            ",
6169 " .Xo.    ...    ",
6170 " .Xoo. ..oo.    ",
6171 " .Xooo.Xooo...  ",
6172 " .Xooo.oooo.X.  ",
6173 " .Xooo.Xooo.X.  ",
6174 " .Xooo.oooo.X.  ",
6175 " .Xooo.Xooo.X.  ",
6176 " .Xooo.oooo.X.  ",
6177 "  .Xoo.Xoo..X.  ",
6178 "   .Xo.o..ooX.  ",
6179 "    .X..XXXXX.  ",
6180 "    ..X.......  ",
6181 "     ..         ",
6182 "                "};
6183
6184 static const char * book_closed_xpm[] = {
6185 "16 16 6 1",
6186 "       c None s None",
6187 ".      c black",
6188 "X      c red",
6189 "o      c yellow",
6190 "O      c #808080",
6191 "#      c white",
6192 "                ",
6193 "       ..       ",
6194 "     ..XX.      ",
6195 "   ..XXXXX.     ",
6196 " ..XXXXXXXX.    ",
6197 ".ooXXXXXXXXX.   ",
6198 "..ooXXXXXXXXX.  ",
6199 ".X.ooXXXXXXXXX. ",
6200 ".XX.ooXXXXXX..  ",
6201 " .XX.ooXXX..#O  ",
6202 "  .XX.oo..##OO. ",
6203 "   .XX..##OO..  ",
6204 "    .X.#OO..    ",
6205 "     ..O..      ",
6206 "      ..        ",
6207 "                "};
6208
6209 GdkPixbuf *book_open;
6210 GdkPixbuf *book_closed;
6211 GtkWidget *sample_notebook;
6212
6213 static void
6214 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
6215 {
6216   GtkWidget *page_widget;
6217   GtkWidget *pixwid;
6218
6219   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
6220
6221   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
6222   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
6223   
6224   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
6225   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
6226 }
6227
6228 static void
6229 page_switch (GtkWidget *widget, gpointer *page, gint page_num)
6230 {
6231   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
6232   gint old_page_num = gtk_notebook_get_current_page (notebook);
6233  
6234   if (page_num == old_page_num)
6235     return;
6236
6237   set_page_image (notebook, page_num, book_open);
6238
6239   if (old_page_num != -1)
6240     set_page_image (notebook, old_page_num, book_closed);
6241 }
6242
6243 static void
6244 tab_fill (GtkToggleButton *button, GtkWidget *child)
6245 {
6246   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6247                            "tab-fill", gtk_toggle_button_get_active (button),
6248                            NULL);
6249 }
6250
6251 static void
6252 tab_expand (GtkToggleButton *button, GtkWidget *child)
6253 {
6254   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6255                            "tab-expand", gtk_toggle_button_get_active (button),
6256                            NULL);
6257 }
6258
6259 static void
6260 create_pages (GtkNotebook *notebook, gint start, gint end)
6261 {
6262   GtkWidget *child = NULL;
6263   GtkWidget *button;
6264   GtkWidget *label;
6265   GtkWidget *hbox;
6266   GtkWidget *vbox;
6267   GtkWidget *label_box;
6268   GtkWidget *menu_box;
6269   GtkWidget *pixwid;
6270   gint i;
6271   char buffer[32];
6272   char accel_buffer[32];
6273
6274   for (i = start; i <= end; i++)
6275     {
6276       sprintf (buffer, "Page %d", i);
6277       sprintf (accel_buffer, "Page _%d", i);
6278
6279       child = gtk_frame_new (buffer);
6280       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
6281
6282       vbox = gtk_vbox_new (TRUE,0);
6283       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
6284       gtk_container_add (GTK_CONTAINER (child), vbox);
6285
6286       hbox = gtk_hbox_new (TRUE,0);
6287       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
6288
6289       button = gtk_check_button_new_with_label ("Fill Tab");
6290       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6291       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
6292       g_signal_connect (button, "toggled",
6293                         G_CALLBACK (tab_fill), child);
6294
6295       button = gtk_check_button_new_with_label ("Expand Tab");
6296       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6297       g_signal_connect (button, "toggled",
6298                         G_CALLBACK (tab_expand), child);
6299
6300       button = gtk_button_new_with_label ("Hide Page");
6301       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
6302       g_signal_connect_swapped (button, "clicked",
6303                                 G_CALLBACK (gtk_widget_hide),
6304                                 child);
6305
6306       gtk_widget_show_all (child);
6307
6308       label_box = gtk_hbox_new (FALSE, 0);
6309       pixwid = gtk_image_new_from_pixbuf (book_closed);
6310       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
6311                            
6312       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
6313       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
6314       label = gtk_label_new_with_mnemonic (accel_buffer);
6315       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
6316       gtk_widget_show_all (label_box);
6317       
6318                                        
6319       menu_box = gtk_hbox_new (FALSE, 0);
6320       pixwid = gtk_image_new_from_pixbuf (book_closed);
6321       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
6322       
6323       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
6324       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
6325       label = gtk_label_new (buffer);
6326       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
6327       gtk_widget_show_all (menu_box);
6328
6329       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
6330     }
6331 }
6332
6333 static void
6334 rotate_notebook (GtkButton   *button,
6335                  GtkNotebook *notebook)
6336 {
6337   gtk_notebook_set_tab_pos (notebook, (gtk_notebook_get_tab_pos (notebook) + 1) % 4);
6338 }
6339
6340 static void
6341 show_all_pages (GtkButton   *button,
6342                 GtkNotebook *notebook)
6343 {  
6344   gtk_container_foreach (GTK_CONTAINER (notebook),
6345                          (GtkCallback) gtk_widget_show, NULL);
6346 }
6347
6348 static void
6349 notebook_type_changed (GtkWidget *optionmenu,
6350                        gpointer   data)
6351 {
6352   GtkNotebook *notebook;
6353   gint i, c;
6354
6355   enum {
6356     STANDARD,
6357     NOTABS,
6358     BORDERLESS,
6359     SCROLLABLE
6360   };
6361
6362   notebook = GTK_NOTEBOOK (data);
6363
6364   c = gtk_combo_box_get_active (GTK_COMBO_BOX (optionmenu));
6365
6366   switch (c)
6367     {
6368     case STANDARD:
6369       /* standard notebook */
6370       gtk_notebook_set_show_tabs (notebook, TRUE);
6371       gtk_notebook_set_show_border (notebook, TRUE);
6372       gtk_notebook_set_scrollable (notebook, FALSE);
6373       break;
6374
6375     case NOTABS:
6376       /* notabs notebook */
6377       gtk_notebook_set_show_tabs (notebook, FALSE);
6378       gtk_notebook_set_show_border (notebook, TRUE);
6379       break;
6380
6381     case BORDERLESS:
6382       /* borderless */
6383       gtk_notebook_set_show_tabs (notebook, FALSE);
6384       gtk_notebook_set_show_border (notebook, FALSE);
6385       break;
6386
6387     case SCROLLABLE:  
6388       /* scrollable */
6389       gtk_notebook_set_show_tabs (notebook, TRUE);
6390       gtk_notebook_set_show_border (notebook, TRUE);
6391       gtk_notebook_set_scrollable (notebook, TRUE);
6392       if (gtk_notebook_get_n_pages (notebook) == 5)
6393         create_pages (notebook, 6, 15);
6394
6395       return;
6396       break;
6397     }
6398
6399   if (gtk_notebook_get_n_pages (notebook) == 15)
6400     for (i = 0; i < 10; i++)
6401       gtk_notebook_remove_page (notebook, 5);
6402 }
6403
6404 static void
6405 notebook_popup (GtkToggleButton *button,
6406                 GtkNotebook     *notebook)
6407 {
6408   if (button->active)
6409     gtk_notebook_popup_enable (notebook);
6410   else
6411     gtk_notebook_popup_disable (notebook);
6412 }
6413
6414 static void
6415 create_notebook (GtkWidget *widget)
6416 {
6417   static GtkWidget *window = NULL;
6418   GtkWidget *box1;
6419   GtkWidget *box2;
6420   GtkWidget *button;
6421   GtkWidget *separator;
6422   GtkWidget *omenu;
6423   GtkWidget *label;
6424
6425   static gchar *items[] =
6426   {
6427     "Standard",
6428     "No tabs",
6429     "Borderless",
6430     "Scrollable"
6431   };
6432   
6433   if (!window)
6434     {
6435       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6436       gtk_window_set_screen (GTK_WINDOW (window),
6437                              gtk_widget_get_screen (widget));
6438
6439       g_signal_connect (window, "destroy",
6440                         G_CALLBACK (gtk_widget_destroyed),
6441                         &window);
6442
6443       gtk_window_set_title (GTK_WINDOW (window), "notebook");
6444       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6445
6446       box1 = gtk_vbox_new (FALSE, 0);
6447       gtk_container_add (GTK_CONTAINER (window), box1);
6448
6449       sample_notebook = gtk_notebook_new ();
6450       g_signal_connect (sample_notebook, "switch_page",
6451                         G_CALLBACK (page_switch), NULL);
6452       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
6453       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
6454       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
6455
6456       gtk_widget_realize (sample_notebook);
6457
6458       if (!book_open)
6459         book_open = gdk_pixbuf_new_from_xpm_data (book_open_xpm);
6460                                                   
6461       if (!book_closed)
6462         book_closed = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
6463
6464       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
6465
6466       separator = gtk_hseparator_new ();
6467       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
6468       
6469       box2 = gtk_hbox_new (FALSE, 5);
6470       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6471       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6472
6473       button = gtk_check_button_new_with_label ("popup menu");
6474       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6475       g_signal_connect (button, "clicked",
6476                         G_CALLBACK (notebook_popup),
6477                         sample_notebook);
6478
6479       box2 = gtk_hbox_new (FALSE, 5);
6480       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6481       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6482
6483       label = gtk_label_new ("Notebook Style :");
6484       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
6485
6486       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
6487                                  notebook_type_changed,
6488                                  sample_notebook);
6489       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
6490
6491       button = gtk_button_new_with_label ("Show all Pages");
6492       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
6493       g_signal_connect (button, "clicked",
6494                         G_CALLBACK (show_all_pages), sample_notebook);
6495
6496       box2 = gtk_hbox_new (TRUE, 10);
6497       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6498       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6499
6500       button = gtk_button_new_with_label ("prev");
6501       g_signal_connect_swapped (button, "clicked",
6502                                 G_CALLBACK (gtk_notebook_prev_page),
6503                                 sample_notebook);
6504       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6505
6506       button = gtk_button_new_with_label ("next");
6507       g_signal_connect_swapped (button, "clicked",
6508                                 G_CALLBACK (gtk_notebook_next_page),
6509                                 sample_notebook);
6510       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6511
6512       button = gtk_button_new_with_label ("rotate");
6513       g_signal_connect (button, "clicked",
6514                         G_CALLBACK (rotate_notebook), sample_notebook);
6515       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6516
6517       separator = gtk_hseparator_new ();
6518       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
6519
6520       button = gtk_button_new_with_label ("close");
6521       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
6522       g_signal_connect_swapped (button, "clicked",
6523                                 G_CALLBACK (gtk_widget_destroy),
6524                                 window);
6525       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
6526       gtk_widget_set_can_default (button, TRUE);
6527       gtk_widget_grab_default (button);
6528     }
6529
6530   if (!gtk_widget_get_visible (window))
6531     gtk_widget_show_all (window);
6532   else
6533     gtk_widget_destroy (window);
6534 }
6535
6536 /*
6537  * GtkPanes
6538  */
6539
6540 void
6541 toggle_resize (GtkWidget *widget, GtkWidget *child)
6542 {
6543   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6544   GValue value = { 0, };
6545   g_value_init (&value, G_TYPE_BOOLEAN);
6546   gtk_container_child_get_property (container, child, "resize", &value);
6547   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6548   gtk_container_child_set_property (container, child, "resize", &value);
6549 }
6550
6551 void
6552 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6553 {
6554   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6555   GValue value = { 0, };
6556   g_value_init (&value, G_TYPE_BOOLEAN);
6557   gtk_container_child_get_property (container, child, "shrink", &value);
6558   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6559   gtk_container_child_set_property (container, child, "shrink", &value);
6560 }
6561
6562 static void
6563 paned_props_clicked (GtkWidget *button,
6564                      GObject   *paned)
6565 {
6566   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
6567   
6568   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
6569 }
6570
6571 GtkWidget *
6572 create_pane_options (GtkPaned    *paned,
6573                      const gchar *frame_label,
6574                      const gchar *label1,
6575                      const gchar *label2)
6576 {
6577   GtkWidget *child1, *child2;
6578   GtkWidget *frame;
6579   GtkWidget *table;
6580   GtkWidget *label;
6581   GtkWidget *button;
6582   GtkWidget *check_button;
6583
6584   child1 = gtk_paned_get_child1 (paned);
6585   child2 = gtk_paned_get_child2 (paned);
6586
6587   frame = gtk_frame_new (frame_label);
6588   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6589   
6590   table = gtk_table_new (4, 2, 4);
6591   gtk_container_add (GTK_CONTAINER (frame), table);
6592   
6593   label = gtk_label_new (label1);
6594   gtk_table_attach_defaults (GTK_TABLE (table), label,
6595                              0, 1, 0, 1);
6596   
6597   check_button = gtk_check_button_new_with_label ("Resize");
6598   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6599                              0, 1, 1, 2);
6600   g_signal_connect (check_button, "toggled",
6601                     G_CALLBACK (toggle_resize),
6602                     child1);
6603
6604   check_button = gtk_check_button_new_with_label ("Shrink");
6605   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6606                              0, 1, 2, 3);
6607   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6608                                TRUE);
6609   g_signal_connect (check_button, "toggled",
6610                     G_CALLBACK (toggle_shrink),
6611                     child1);
6612
6613   label = gtk_label_new (label2);
6614   gtk_table_attach_defaults (GTK_TABLE (table), label,
6615                              1, 2, 0, 1);
6616   
6617   check_button = gtk_check_button_new_with_label ("Resize");
6618   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6619                              1, 2, 1, 2);
6620   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6621                                TRUE);
6622   g_signal_connect (check_button, "toggled",
6623                     G_CALLBACK (toggle_resize),
6624                     child2);
6625
6626   check_button = gtk_check_button_new_with_label ("Shrink");
6627   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6628                              1, 2, 2, 3);
6629   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6630                                TRUE);
6631   g_signal_connect (check_button, "toggled",
6632                     G_CALLBACK (toggle_shrink),
6633                     child2);
6634
6635   button = gtk_button_new_with_mnemonic ("_Properties");
6636   gtk_table_attach_defaults (GTK_TABLE (table), button,
6637                              0, 2, 3, 4);
6638   g_signal_connect (button, "clicked",
6639                     G_CALLBACK (paned_props_clicked),
6640                     paned);
6641
6642   return frame;
6643 }
6644
6645 void
6646 create_panes (GtkWidget *widget)
6647 {
6648   static GtkWidget *window = NULL;
6649   GtkWidget *frame;
6650   GtkWidget *hpaned;
6651   GtkWidget *vpaned;
6652   GtkWidget *button;
6653   GtkWidget *vbox;
6654
6655   if (!window)
6656     {
6657       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6658
6659       gtk_window_set_screen (GTK_WINDOW (window),
6660                              gtk_widget_get_screen (widget));
6661       
6662       g_signal_connect (window, "destroy",
6663                         G_CALLBACK (gtk_widget_destroyed),
6664                         &window);
6665
6666       gtk_window_set_title (GTK_WINDOW (window), "Panes");
6667       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6668
6669       vbox = gtk_vbox_new (FALSE, 0);
6670       gtk_container_add (GTK_CONTAINER (window), vbox);
6671       
6672       vpaned = gtk_vpaned_new ();
6673       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6674       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6675
6676       hpaned = gtk_hpaned_new ();
6677       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6678
6679       frame = gtk_frame_new (NULL);
6680       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6681       gtk_widget_set_size_request (frame, 60, 60);
6682       gtk_paned_add1 (GTK_PANED (hpaned), frame);
6683       
6684       button = gtk_button_new_with_label ("Hi there");
6685       gtk_container_add (GTK_CONTAINER(frame), button);
6686
6687       frame = gtk_frame_new (NULL);
6688       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6689       gtk_widget_set_size_request (frame, 80, 60);
6690       gtk_paned_add2 (GTK_PANED (hpaned), frame);
6691
6692       frame = gtk_frame_new (NULL);
6693       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6694       gtk_widget_set_size_request (frame, 60, 80);
6695       gtk_paned_add2 (GTK_PANED (vpaned), frame);
6696
6697       /* Now create toggle buttons to control sizing */
6698
6699       gtk_box_pack_start (GTK_BOX (vbox),
6700                           create_pane_options (GTK_PANED (hpaned),
6701                                                "Horizontal",
6702                                                "Left",
6703                                                "Right"),
6704                           FALSE, FALSE, 0);
6705
6706       gtk_box_pack_start (GTK_BOX (vbox),
6707                           create_pane_options (GTK_PANED (vpaned),
6708                                                "Vertical",
6709                                                "Top",
6710                                                "Bottom"),
6711                           FALSE, FALSE, 0);
6712
6713       gtk_widget_show_all (vbox);
6714     }
6715
6716   if (!gtk_widget_get_visible (window))
6717     gtk_widget_show (window);
6718   else
6719     gtk_widget_destroy (window);
6720 }
6721
6722 /*
6723  * Paned keyboard navigation
6724  */
6725
6726 static GtkWidget*
6727 paned_keyboard_window1 (GtkWidget *widget)
6728 {
6729   GtkWidget *window1;
6730   GtkWidget *hpaned1;
6731   GtkWidget *frame1;
6732   GtkWidget *vbox1;
6733   GtkWidget *button7;
6734   GtkWidget *button8;
6735   GtkWidget *button9;
6736   GtkWidget *vpaned1;
6737   GtkWidget *frame2;
6738   GtkWidget *frame5;
6739   GtkWidget *hbox1;
6740   GtkWidget *button5;
6741   GtkWidget *button6;
6742   GtkWidget *frame3;
6743   GtkWidget *frame4;
6744   GtkWidget *table1;
6745   GtkWidget *button1;
6746   GtkWidget *button2;
6747   GtkWidget *button3;
6748   GtkWidget *button4;
6749
6750   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6751   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
6752   gtk_window_set_screen (GTK_WINDOW (window1), 
6753                          gtk_widget_get_screen (widget));
6754
6755   hpaned1 = gtk_hpaned_new ();
6756   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
6757
6758   frame1 = gtk_frame_new (NULL);
6759   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
6760   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
6761
6762   vbox1 = gtk_vbox_new (FALSE, 0);
6763   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
6764
6765   button7 = gtk_button_new_with_label ("button7");
6766   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
6767
6768   button8 = gtk_button_new_with_label ("button8");
6769   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
6770
6771   button9 = gtk_button_new_with_label ("button9");
6772   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
6773
6774   vpaned1 = gtk_vpaned_new ();
6775   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
6776
6777   frame2 = gtk_frame_new (NULL);
6778   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
6779   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
6780
6781   frame5 = gtk_frame_new (NULL);
6782   gtk_container_add (GTK_CONTAINER (frame2), frame5);
6783
6784   hbox1 = gtk_hbox_new (FALSE, 0);
6785   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
6786
6787   button5 = gtk_button_new_with_label ("button5");
6788   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
6789
6790   button6 = gtk_button_new_with_label ("button6");
6791   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
6792
6793   frame3 = gtk_frame_new (NULL);
6794   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
6795   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
6796
6797   frame4 = gtk_frame_new ("Buttons");
6798   gtk_container_add (GTK_CONTAINER (frame3), frame4);
6799   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
6800
6801   table1 = gtk_table_new (2, 2, FALSE);
6802   gtk_container_add (GTK_CONTAINER (frame4), table1);
6803   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
6804
6805   button1 = gtk_button_new_with_label ("button1");
6806   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
6807                     (GtkAttachOptions) (GTK_FILL),
6808                     (GtkAttachOptions) (0), 0, 0);
6809
6810   button2 = gtk_button_new_with_label ("button2");
6811   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
6812                     (GtkAttachOptions) (GTK_FILL),
6813                     (GtkAttachOptions) (0), 0, 0);
6814
6815   button3 = gtk_button_new_with_label ("button3");
6816   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
6817                     (GtkAttachOptions) (GTK_FILL),
6818                     (GtkAttachOptions) (0), 0, 0);
6819
6820   button4 = gtk_button_new_with_label ("button4");
6821   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
6822                     (GtkAttachOptions) (GTK_FILL),
6823                     (GtkAttachOptions) (0), 0, 0);
6824
6825   return window1;
6826 }
6827
6828 static GtkWidget*
6829 paned_keyboard_window2 (GtkWidget *widget)
6830 {
6831   GtkWidget *window2;
6832   GtkWidget *hpaned2;
6833   GtkWidget *frame6;
6834   GtkWidget *button13;
6835   GtkWidget *hbox2;
6836   GtkWidget *vpaned2;
6837   GtkWidget *frame7;
6838   GtkWidget *button12;
6839   GtkWidget *frame8;
6840   GtkWidget *button11;
6841   GtkWidget *button10;
6842
6843   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6844   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
6845
6846   gtk_window_set_screen (GTK_WINDOW (window2), 
6847                          gtk_widget_get_screen (widget));
6848
6849   hpaned2 = gtk_hpaned_new ();
6850   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
6851
6852   frame6 = gtk_frame_new (NULL);
6853   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
6854   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
6855
6856   button13 = gtk_button_new_with_label ("button13");
6857   gtk_container_add (GTK_CONTAINER (frame6), button13);
6858
6859   hbox2 = gtk_hbox_new (FALSE, 0);
6860   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
6861
6862   vpaned2 = gtk_vpaned_new ();
6863   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
6864
6865   frame7 = gtk_frame_new (NULL);
6866   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
6867   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
6868
6869   button12 = gtk_button_new_with_label ("button12");
6870   gtk_container_add (GTK_CONTAINER (frame7), button12);
6871
6872   frame8 = gtk_frame_new (NULL);
6873   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
6874   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
6875
6876   button11 = gtk_button_new_with_label ("button11");
6877   gtk_container_add (GTK_CONTAINER (frame8), button11);
6878
6879   button10 = gtk_button_new_with_label ("button10");
6880   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
6881
6882   return window2;
6883 }
6884
6885 static GtkWidget*
6886 paned_keyboard_window3 (GtkWidget *widget)
6887 {
6888   GtkWidget *window3;
6889   GtkWidget *vbox2;
6890   GtkWidget *label1;
6891   GtkWidget *hpaned3;
6892   GtkWidget *frame9;
6893   GtkWidget *button14;
6894   GtkWidget *hpaned4;
6895   GtkWidget *frame10;
6896   GtkWidget *button15;
6897   GtkWidget *hpaned5;
6898   GtkWidget *frame11;
6899   GtkWidget *button16;
6900   GtkWidget *frame12;
6901   GtkWidget *button17;
6902
6903   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6904   g_object_set_data (G_OBJECT (window3), "window3", window3);
6905   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
6906
6907   gtk_window_set_screen (GTK_WINDOW (window3), 
6908                          gtk_widget_get_screen (widget));
6909   
6910
6911   vbox2 = gtk_vbox_new (FALSE, 0);
6912   gtk_container_add (GTK_CONTAINER (window3), vbox2);
6913
6914   label1 = gtk_label_new ("Three panes nested inside each other");
6915   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
6916
6917   hpaned3 = gtk_hpaned_new ();
6918   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
6919
6920   frame9 = gtk_frame_new (NULL);
6921   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
6922   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
6923
6924   button14 = gtk_button_new_with_label ("button14");
6925   gtk_container_add (GTK_CONTAINER (frame9), button14);
6926
6927   hpaned4 = gtk_hpaned_new ();
6928   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
6929
6930   frame10 = gtk_frame_new (NULL);
6931   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
6932   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
6933
6934   button15 = gtk_button_new_with_label ("button15");
6935   gtk_container_add (GTK_CONTAINER (frame10), button15);
6936
6937   hpaned5 = gtk_hpaned_new ();
6938   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
6939
6940   frame11 = gtk_frame_new (NULL);
6941   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
6942   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
6943
6944   button16 = gtk_button_new_with_label ("button16");
6945   gtk_container_add (GTK_CONTAINER (frame11), button16);
6946
6947   frame12 = gtk_frame_new (NULL);
6948   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
6949   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
6950
6951   button17 = gtk_button_new_with_label ("button17");
6952   gtk_container_add (GTK_CONTAINER (frame12), button17);
6953
6954   return window3;
6955 }
6956
6957 static GtkWidget*
6958 paned_keyboard_window4 (GtkWidget *widget)
6959 {
6960   GtkWidget *window4;
6961   GtkWidget *vbox3;
6962   GtkWidget *label2;
6963   GtkWidget *hpaned6;
6964   GtkWidget *vpaned3;
6965   GtkWidget *button19;
6966   GtkWidget *button18;
6967   GtkWidget *hbox3;
6968   GtkWidget *vpaned4;
6969   GtkWidget *button21;
6970   GtkWidget *button20;
6971   GtkWidget *vpaned5;
6972   GtkWidget *button23;
6973   GtkWidget *button22;
6974   GtkWidget *vpaned6;
6975   GtkWidget *button25;
6976   GtkWidget *button24;
6977
6978   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6979   g_object_set_data (G_OBJECT (window4), "window4", window4);
6980   gtk_window_set_title (GTK_WINDOW (window4), "window4");
6981
6982   gtk_window_set_screen (GTK_WINDOW (window4), 
6983                          gtk_widget_get_screen (widget));
6984
6985   vbox3 = gtk_vbox_new (FALSE, 0);
6986   gtk_container_add (GTK_CONTAINER (window4), vbox3);
6987
6988   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
6989   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
6990   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
6991
6992   hpaned6 = gtk_hpaned_new ();
6993   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
6994
6995   vpaned3 = gtk_vpaned_new ();
6996   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
6997
6998   button19 = gtk_button_new_with_label ("button19");
6999   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
7000
7001   button18 = gtk_button_new_with_label ("button18");
7002   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
7003
7004   hbox3 = gtk_hbox_new (FALSE, 0);
7005   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
7006
7007   vpaned4 = gtk_vpaned_new ();
7008   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
7009
7010   button21 = gtk_button_new_with_label ("button21");
7011   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
7012
7013   button20 = gtk_button_new_with_label ("button20");
7014   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
7015
7016   vpaned5 = gtk_vpaned_new ();
7017   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
7018
7019   button23 = gtk_button_new_with_label ("button23");
7020   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
7021
7022   button22 = gtk_button_new_with_label ("button22");
7023   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
7024
7025   vpaned6 = gtk_vpaned_new ();
7026   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
7027
7028   button25 = gtk_button_new_with_label ("button25");
7029   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
7030
7031   button24 = gtk_button_new_with_label ("button24");
7032   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
7033
7034   return window4;
7035 }
7036
7037 static void
7038 create_paned_keyboard_navigation (GtkWidget *widget)
7039 {
7040   static GtkWidget *window1 = NULL;
7041   static GtkWidget *window2 = NULL;
7042   static GtkWidget *window3 = NULL;
7043   static GtkWidget *window4 = NULL;
7044
7045   if (window1 && 
7046      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
7047     {
7048       gtk_widget_destroy (window1);
7049       gtk_widget_destroy (window2);
7050       gtk_widget_destroy (window3);
7051       gtk_widget_destroy (window4);
7052     }
7053   
7054   if (!window1)
7055     {
7056       window1 = paned_keyboard_window1 (widget);
7057       g_signal_connect (window1, "destroy",
7058                         G_CALLBACK (gtk_widget_destroyed),
7059                         &window1);
7060     }
7061
7062   if (!window2)
7063     {
7064       window2 = paned_keyboard_window2 (widget);
7065       g_signal_connect (window2, "destroy",
7066                         G_CALLBACK (gtk_widget_destroyed),
7067                         &window2);
7068     }
7069
7070   if (!window3)
7071     {
7072       window3 = paned_keyboard_window3 (widget);
7073       g_signal_connect (window3, "destroy",
7074                         G_CALLBACK (gtk_widget_destroyed),
7075                         &window3);
7076     }
7077
7078   if (!window4)
7079     {
7080       window4 = paned_keyboard_window4 (widget);
7081       g_signal_connect (window4, "destroy",
7082                         G_CALLBACK (gtk_widget_destroyed),
7083                         &window4);
7084     }
7085
7086   if (gtk_widget_get_visible (window1))
7087     gtk_widget_destroy (GTK_WIDGET (window1));
7088   else
7089     gtk_widget_show_all (GTK_WIDGET (window1));
7090
7091   if (gtk_widget_get_visible (window2))
7092     gtk_widget_destroy (GTK_WIDGET (window2));
7093   else
7094     gtk_widget_show_all (GTK_WIDGET (window2));
7095
7096   if (gtk_widget_get_visible (window3))
7097     gtk_widget_destroy (GTK_WIDGET (window3));
7098   else
7099     gtk_widget_show_all (GTK_WIDGET (window3));
7100
7101   if (gtk_widget_get_visible (window4))
7102     gtk_widget_destroy (GTK_WIDGET (window4));
7103   else
7104     gtk_widget_show_all (GTK_WIDGET (window4));
7105 }
7106
7107
7108 /*
7109  * Shaped Windows
7110  */
7111
7112 typedef struct _cursoroffset {gint x,y;} CursorOffset;
7113
7114 static void
7115 shape_pressed (GtkWidget *widget, GdkEventButton *event)
7116 {
7117   CursorOffset *p;
7118
7119   /* ignore double and triple click */
7120   if (event->type != GDK_BUTTON_PRESS)
7121     return;
7122
7123   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
7124   p->x = (int) event->x;
7125   p->y = (int) event->y;
7126
7127   gtk_grab_add (widget);
7128   gdk_pointer_grab (gtk_widget_get_window (widget), TRUE,
7129                     GDK_BUTTON_RELEASE_MASK |
7130                     GDK_BUTTON_MOTION_MASK |
7131                     GDK_POINTER_MOTION_HINT_MASK,
7132                     NULL, NULL, 0);
7133 }
7134
7135 static void
7136 shape_released (GtkWidget *widget)
7137 {
7138   gtk_grab_remove (widget);
7139   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
7140                               GDK_CURRENT_TIME);
7141 }
7142
7143 static void
7144 shape_motion (GtkWidget      *widget, 
7145               GdkEventMotion *event)
7146 {
7147   gint xp, yp;
7148   CursorOffset * p;
7149   GdkModifierType mask;
7150
7151   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
7152
7153   /*
7154    * Can't use event->x / event->y here 
7155    * because I need absolute coordinates.
7156    */
7157   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
7158   gtk_window_move (GTK_WINDOW (widget), xp  - p->x, yp  - p->y);
7159 }
7160
7161 GtkWidget *
7162 shape_create_icon (GdkScreen *screen,
7163                    char      *xpm_file,
7164                    gint       x,
7165                    gint       y,
7166                    gint       px,
7167                    gint       py,
7168                    gint       window_type)
7169 {
7170   GtkWidget *window;
7171   GtkWidget *image;
7172   GtkWidget *fixed;
7173   CursorOffset* icon_pos;
7174   cairo_surface_t *mask;
7175   cairo_region_t *mask_region;
7176   GdkPixbuf *pixbuf;
7177   cairo_t *cr;
7178
7179   /*
7180    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
7181    */
7182   window = gtk_window_new (window_type);
7183   gtk_window_set_screen (GTK_WINDOW (window), screen);
7184   
7185   fixed = gtk_fixed_new ();
7186   gtk_widget_set_size_request (fixed, 100, 100);
7187   gtk_container_add (GTK_CONTAINER (window), fixed);
7188   gtk_widget_show (fixed);
7189   
7190   gtk_widget_set_events (window, 
7191                          gtk_widget_get_events (window) |
7192                          GDK_BUTTON_MOTION_MASK |
7193                          GDK_POINTER_MOTION_HINT_MASK |
7194                          GDK_BUTTON_PRESS_MASK);
7195
7196   gtk_widget_realize (window);
7197
7198   pixbuf = gdk_pixbuf_new_from_file (xpm_file, NULL);
7199   g_assert (pixbuf); /* FIXME: error handling */
7200
7201   mask = cairo_image_surface_create (CAIRO_FORMAT_A1,
7202                                      gdk_pixbuf_get_width (pixbuf),
7203                                      gdk_pixbuf_get_height (pixbuf));
7204   cr = cairo_create (mask);
7205   gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
7206   cairo_paint (cr);
7207   cairo_destroy (cr);
7208
7209   mask_region = gdk_cairo_region_create_from_surface (mask);
7210                                                   
7211   cairo_region_translate (mask_region, px, py);
7212
7213   image = gtk_image_new_from_pixbuf (pixbuf);
7214   gtk_fixed_put (GTK_FIXED (fixed), image, px,py);
7215   gtk_widget_show (image);
7216   
7217   gtk_widget_shape_combine_region (window, mask_region);
7218   
7219   cairo_region_destroy (mask_region);
7220   cairo_surface_destroy (mask);
7221   g_object_unref (pixbuf);
7222
7223   g_signal_connect (window, "button_press_event",
7224                     G_CALLBACK (shape_pressed), NULL);
7225   g_signal_connect (window, "button_release_event",
7226                     G_CALLBACK (shape_released), NULL);
7227   g_signal_connect (window, "motion_notify_event",
7228                     G_CALLBACK (shape_motion), NULL);
7229
7230   icon_pos = g_new (CursorOffset, 1);
7231   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
7232
7233   gtk_window_move (GTK_WINDOW (window), x, y);
7234   gtk_widget_show (window);
7235   
7236   return window;
7237 }
7238
7239 void 
7240 create_shapes (GtkWidget *widget)
7241 {
7242   /* Variables used by the Drag/Drop and Shape Window demos */
7243   static GtkWidget *modeller = NULL;
7244   static GtkWidget *sheets = NULL;
7245   static GtkWidget *rings = NULL;
7246   static GtkWidget *with_region = NULL;
7247   GdkScreen *screen = gtk_widget_get_screen (widget);
7248   
7249   if (!(file_exists ("Modeller.xpm") &&
7250         file_exists ("FilesQueue.xpm") &&
7251         file_exists ("3DRings.xpm")))
7252     return;
7253   
7254
7255   if (!modeller)
7256     {
7257       modeller = shape_create_icon (screen, "Modeller.xpm",
7258                                     440, 140, 0,0, GTK_WINDOW_POPUP);
7259
7260       g_signal_connect (modeller, "destroy",
7261                         G_CALLBACK (gtk_widget_destroyed),
7262                         &modeller);
7263     }
7264   else
7265     gtk_widget_destroy (modeller);
7266
7267   if (!sheets)
7268     {
7269       sheets = shape_create_icon (screen, "FilesQueue.xpm",
7270                                   580, 170, 0,0, GTK_WINDOW_POPUP);
7271
7272       g_signal_connect (sheets, "destroy",
7273                         G_CALLBACK (gtk_widget_destroyed),
7274                         &sheets);
7275
7276     }
7277   else
7278     gtk_widget_destroy (sheets);
7279
7280   if (!rings)
7281     {
7282       rings = shape_create_icon (screen, "3DRings.xpm",
7283                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7284
7285       g_signal_connect (rings, "destroy",
7286                         G_CALLBACK (gtk_widget_destroyed),
7287                         &rings);
7288     }
7289   else
7290     gtk_widget_destroy (rings);
7291
7292   if (!with_region)
7293     {
7294       cairo_region_t *region;
7295       gint x, y;
7296       
7297       with_region = shape_create_icon (screen, "3DRings.xpm",
7298                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7299
7300       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
7301       
7302       g_signal_connect (with_region, "destroy",
7303                         G_CALLBACK (gtk_widget_destroyed),
7304                         &with_region);
7305
7306       /* reset shape from mask to a region */
7307       x = 0;
7308       y = 0;
7309       region = cairo_region_create ();
7310
7311       while (x < 460)
7312         {
7313           while (y < 270)
7314             {
7315               GdkRectangle rect;
7316               rect.x = x;
7317               rect.y = y;
7318               rect.width = 10;
7319               rect.height = 10;
7320
7321               cairo_region_union_rectangle (region, &rect);
7322               
7323               y += 20;
7324             }
7325           y = 0;
7326           x += 20;
7327         }
7328
7329       gdk_window_shape_combine_region (gtk_widget_get_window (with_region),
7330                                        region,
7331                                        0, 0);
7332     }
7333   else
7334     gtk_widget_destroy (with_region);
7335 }
7336
7337 /*
7338  * WM Hints demo
7339  */
7340
7341 void
7342 create_wmhints (GtkWidget *widget)
7343 {
7344   static GtkWidget *window = NULL;
7345   GtkWidget *label;
7346   GtkWidget *separator;
7347   GtkWidget *button;
7348   GtkWidget *box1;
7349   GtkWidget *box2;
7350   GdkWindow *gdk_window;
7351   GdkPixbuf *pixbuf;
7352   GList *list;
7353
7354   if (!window)
7355     {
7356       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7357
7358       gtk_window_set_screen (GTK_WINDOW (window),
7359                              gtk_widget_get_screen (widget));
7360       
7361       g_signal_connect (window, "destroy",
7362                         G_CALLBACK (gtk_widget_destroyed),
7363                         &window);
7364
7365       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
7366       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7367
7368       gtk_widget_realize (window);
7369
7370       gdk_window = gtk_widget_get_window (window);
7371
7372       pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
7373       list = g_list_prepend (NULL, pixbuf);
7374
7375       gdk_window_set_icon_list (gdk_window, list);
7376       
7377       g_list_free (list);
7378       g_object_unref (pixbuf);
7379
7380       gdk_window_set_icon_name (gdk_window, "WMHints Test Icon");
7381   
7382       gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL | GDK_DECOR_MENU);
7383       gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
7384       
7385       box1 = gtk_vbox_new (FALSE, 0);
7386       gtk_container_add (GTK_CONTAINER (window), box1);
7387       gtk_widget_show (box1);
7388
7389       label = gtk_label_new ("Try iconizing me!");
7390       gtk_widget_set_size_request (label, 150, 50);
7391       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
7392       gtk_widget_show (label);
7393
7394
7395       separator = gtk_hseparator_new ();
7396       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7397       gtk_widget_show (separator);
7398
7399
7400       box2 = gtk_vbox_new (FALSE, 10);
7401       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7402       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7403       gtk_widget_show (box2);
7404
7405
7406       button = gtk_button_new_with_label ("close");
7407
7408       g_signal_connect_swapped (button, "clicked",
7409                                 G_CALLBACK (gtk_widget_destroy),
7410                                 window);
7411
7412       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7413       gtk_widget_set_can_default (button, TRUE);
7414       gtk_widget_grab_default (button);
7415       gtk_widget_show (button);
7416     }
7417
7418   if (!gtk_widget_get_visible (window))
7419     gtk_widget_show (window);
7420   else
7421     gtk_widget_destroy (window);
7422 }
7423
7424
7425 /*
7426  * Window state tracking
7427  */
7428
7429 static gint
7430 window_state_callback (GtkWidget *widget,
7431                        GdkEventWindowState *event,
7432                        gpointer data)
7433 {
7434   GtkWidget *label = data;
7435   gchar *msg;
7436
7437   msg = g_strconcat (gtk_window_get_title (GTK_WINDOW (widget)), ": ",
7438                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
7439                      "withdrawn" : "not withdrawn", ", ",
7440                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
7441                      "iconified" : "not iconified", ", ",
7442                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
7443                      "sticky" : "not sticky", ", ",
7444                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
7445                      "maximized" : "not maximized", ", ",
7446                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
7447                      "fullscreen" : "not fullscreen",
7448                      (event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
7449                      "above" : "not above", ", ",
7450                      (event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
7451                      "below" : "not below", ", ",
7452                      NULL);
7453   
7454   gtk_label_set_text (GTK_LABEL (label), msg);
7455
7456   g_free (msg);
7457
7458   return FALSE;
7459 }
7460
7461 static GtkWidget*
7462 tracking_label (GtkWidget *window)
7463 {
7464   GtkWidget *label;
7465   GtkWidget *hbox;
7466   GtkWidget *button;
7467
7468   hbox = gtk_hbox_new (FALSE, 5);
7469
7470   g_signal_connect_object (hbox,
7471                            "destroy",
7472                            G_CALLBACK (gtk_widget_destroy),
7473                            window,
7474                            G_CONNECT_SWAPPED);
7475   
7476   label = gtk_label_new ("<no window state events received>");
7477   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
7478   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
7479   
7480   g_signal_connect (window,
7481                     "window_state_event",
7482                     G_CALLBACK (window_state_callback),
7483                     label);
7484
7485   button = gtk_button_new_with_label ("Deiconify");
7486   g_signal_connect_object (button,
7487                            "clicked",
7488                            G_CALLBACK (gtk_window_deiconify),
7489                            window,
7490                            G_CONNECT_SWAPPED);
7491   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7492
7493   button = gtk_button_new_with_label ("Iconify");
7494   g_signal_connect_object (button,
7495                            "clicked",
7496                            G_CALLBACK (gtk_window_iconify),
7497                            window,
7498                            G_CONNECT_SWAPPED);
7499   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7500
7501   button = gtk_button_new_with_label ("Fullscreen");
7502   g_signal_connect_object (button,
7503                            "clicked",
7504                            G_CALLBACK (gtk_window_fullscreen),
7505                            window,
7506                            G_CONNECT_SWAPPED);
7507   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7508
7509   button = gtk_button_new_with_label ("Unfullscreen");
7510   g_signal_connect_object (button,
7511                            "clicked",
7512                            G_CALLBACK (gtk_window_unfullscreen),
7513                            window,
7514                            G_CONNECT_SWAPPED);
7515   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7516   
7517   button = gtk_button_new_with_label ("Present");
7518   g_signal_connect_object (button,
7519                            "clicked",
7520                            G_CALLBACK (gtk_window_present),
7521                            window,
7522                            G_CONNECT_SWAPPED);
7523   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7524
7525   button = gtk_button_new_with_label ("Show");
7526   g_signal_connect_object (button,
7527                            "clicked",
7528                            G_CALLBACK (gtk_widget_show),
7529                            window,
7530                            G_CONNECT_SWAPPED);
7531   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7532   
7533   gtk_widget_show_all (hbox);
7534   
7535   return hbox;
7536 }
7537
7538 void
7539 keep_window_above (GtkToggleButton *togglebutton, gpointer data)
7540 {
7541   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7542
7543   gtk_window_set_keep_above (GTK_WINDOW (data),
7544                              gtk_toggle_button_get_active (togglebutton));
7545
7546   if (gtk_toggle_button_get_active (togglebutton))
7547     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7548 }
7549
7550 void
7551 keep_window_below (GtkToggleButton *togglebutton, gpointer data)
7552 {
7553   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7554
7555   gtk_window_set_keep_below (GTK_WINDOW (data),
7556                              gtk_toggle_button_get_active (togglebutton));
7557
7558   if (gtk_toggle_button_get_active (togglebutton))
7559     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7560 }
7561
7562
7563 static GtkWidget*
7564 get_state_controls (GtkWidget *window)
7565 {
7566   GtkWidget *vbox;
7567   GtkWidget *button;
7568   GtkWidget *button_above;
7569   GtkWidget *button_below;
7570
7571   vbox = gtk_vbox_new (FALSE, 0);
7572   
7573   button = gtk_button_new_with_label ("Stick");
7574   g_signal_connect_object (button,
7575                            "clicked",
7576                            G_CALLBACK (gtk_window_stick),
7577                            window,
7578                            G_CONNECT_SWAPPED);
7579   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7580
7581   button = gtk_button_new_with_label ("Unstick");
7582   g_signal_connect_object (button,
7583                            "clicked",
7584                            G_CALLBACK (gtk_window_unstick),
7585                            window,
7586                            G_CONNECT_SWAPPED);
7587   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7588   
7589   button = gtk_button_new_with_label ("Maximize");
7590   g_signal_connect_object (button,
7591                            "clicked",
7592                            G_CALLBACK (gtk_window_maximize),
7593                            window,
7594                            G_CONNECT_SWAPPED);
7595   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7596
7597   button = gtk_button_new_with_label ("Unmaximize");
7598   g_signal_connect_object (button,
7599                            "clicked",
7600                            G_CALLBACK (gtk_window_unmaximize),
7601                            window,
7602                            G_CONNECT_SWAPPED);
7603   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7604
7605   button = gtk_button_new_with_label ("Iconify");
7606   g_signal_connect_object (button,
7607                            "clicked",
7608                            G_CALLBACK (gtk_window_iconify),
7609                            window,
7610                            G_CONNECT_SWAPPED);
7611   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7612
7613   button = gtk_button_new_with_label ("Fullscreen");
7614   g_signal_connect_object (button,
7615                            "clicked",
7616                            G_CALLBACK (gtk_window_fullscreen),
7617                            window,
7618                            G_CONNECT_SWAPPED);
7619   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7620
7621   button = gtk_button_new_with_label ("Unfullscreen");
7622   g_signal_connect_object (button,
7623                            "clicked",
7624                            G_CALLBACK (gtk_window_unfullscreen),
7625                            window,
7626                            G_CONNECT_SWAPPED);
7627   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7628
7629   button_above = gtk_toggle_button_new_with_label ("Keep above");
7630   g_signal_connect (button_above,
7631                     "toggled",
7632                     G_CALLBACK (keep_window_above),
7633                     window);
7634   gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
7635
7636   button_below = gtk_toggle_button_new_with_label ("Keep below");
7637   g_signal_connect (button_below,
7638                     "toggled",
7639                     G_CALLBACK (keep_window_below),
7640                     window);
7641   gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
7642
7643   g_object_set_data (G_OBJECT (button_above), "radio", button_below);
7644   g_object_set_data (G_OBJECT (button_below), "radio", button_above);
7645
7646   button = gtk_button_new_with_label ("Hide (withdraw)");
7647   g_signal_connect_object (button,
7648                            "clicked",
7649                            G_CALLBACK (gtk_widget_hide),
7650                            window,
7651                            G_CONNECT_SWAPPED);
7652   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7653   
7654   gtk_widget_show_all (vbox);
7655
7656   return vbox;
7657 }
7658
7659 void
7660 create_window_states (GtkWidget *widget)
7661 {
7662   static GtkWidget *window = NULL;
7663   GtkWidget *label;
7664   GtkWidget *box1;
7665   GtkWidget *iconified;
7666   GtkWidget *normal;
7667   GtkWidget *controls;
7668
7669   if (!window)
7670     {
7671       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7672       gtk_window_set_screen (GTK_WINDOW (window),
7673                              gtk_widget_get_screen (widget));
7674
7675       g_signal_connect (window, "destroy",
7676                         G_CALLBACK (gtk_widget_destroyed),
7677                         &window);
7678
7679       gtk_window_set_title (GTK_WINDOW (window), "Window states");
7680       
7681       box1 = gtk_vbox_new (FALSE, 0);
7682       gtk_container_add (GTK_CONTAINER (window), box1);
7683
7684       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7685
7686       gtk_window_set_screen (GTK_WINDOW (iconified),
7687                              gtk_widget_get_screen (widget));
7688       
7689       g_signal_connect_object (iconified, "destroy",
7690                                G_CALLBACK (gtk_widget_destroy),
7691                                window,
7692                                G_CONNECT_SWAPPED);
7693       gtk_window_iconify (GTK_WINDOW (iconified));
7694       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
7695       controls = get_state_controls (iconified);
7696       gtk_container_add (GTK_CONTAINER (iconified), controls);
7697       
7698       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7699
7700       gtk_window_set_screen (GTK_WINDOW (normal),
7701                              gtk_widget_get_screen (widget));
7702       
7703       g_signal_connect_object (normal, "destroy",
7704                                G_CALLBACK (gtk_widget_destroy),
7705                                window,
7706                                G_CONNECT_SWAPPED);
7707       
7708       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
7709       controls = get_state_controls (normal);
7710       gtk_container_add (GTK_CONTAINER (normal), controls);
7711       
7712       label = tracking_label (iconified);
7713       gtk_container_add (GTK_CONTAINER (box1), label);
7714
7715       label = tracking_label (normal);
7716       gtk_container_add (GTK_CONTAINER (box1), label);
7717
7718       gtk_widget_show_all (iconified);
7719       gtk_widget_show_all (normal);
7720       gtk_widget_show_all (box1);
7721     }
7722
7723   if (!gtk_widget_get_visible (window))
7724     gtk_widget_show (window);
7725   else
7726     gtk_widget_destroy (window);
7727 }
7728
7729 /*
7730  * Window sizing
7731  */
7732
7733 static gint
7734 configure_event_callback (GtkWidget *widget,
7735                           GdkEventConfigure *event,
7736                           gpointer data)
7737 {
7738   GtkWidget *label = data;
7739   gchar *msg;
7740   gint x, y;
7741   
7742   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
7743   
7744   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
7745                          "position: %d, %d",
7746                          event->x, event->y, event->width, event->height,
7747                          x, y);
7748   
7749   gtk_label_set_text (GTK_LABEL (label), msg);
7750
7751   g_free (msg);
7752
7753   return FALSE;
7754 }
7755
7756 static void
7757 get_ints (GtkWidget *window,
7758           gint      *a,
7759           gint      *b)
7760 {
7761   GtkWidget *spin1;
7762   GtkWidget *spin2;
7763
7764   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
7765   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
7766
7767   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
7768   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
7769 }
7770
7771 static void
7772 set_size_callback (GtkWidget *widget,
7773                    gpointer   data)
7774 {
7775   gint w, h;
7776   
7777   get_ints (data, &w, &h);
7778
7779   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
7780 }
7781
7782 static void
7783 unset_default_size_callback (GtkWidget *widget,
7784                              gpointer   data)
7785 {
7786   gtk_window_set_default_size (g_object_get_data (data, "target"),
7787                                -1, -1);
7788 }
7789
7790 static void
7791 set_default_size_callback (GtkWidget *widget,
7792                            gpointer   data)
7793 {
7794   gint w, h;
7795   
7796   get_ints (data, &w, &h);
7797
7798   gtk_window_set_default_size (g_object_get_data (data, "target"),
7799                                w, h);
7800 }
7801
7802 static void
7803 unset_size_request_callback (GtkWidget *widget,
7804                              gpointer   data)
7805 {
7806   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7807                                -1, -1);
7808 }
7809
7810 static void
7811 set_size_request_callback (GtkWidget *widget,
7812                            gpointer   data)
7813 {
7814   gint w, h;
7815   
7816   get_ints (data, &w, &h);
7817
7818   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7819                                w, h);
7820 }
7821
7822 static void
7823 set_location_callback (GtkWidget *widget,
7824                        gpointer   data)
7825 {
7826   gint x, y;
7827   
7828   get_ints (data, &x, &y);
7829
7830   gtk_window_move (g_object_get_data (data, "target"), x, y);
7831 }
7832
7833 static void
7834 move_to_position_callback (GtkWidget *widget,
7835                            gpointer   data)
7836 {
7837   gint x, y;
7838   GtkWindow *window;
7839
7840   window = g_object_get_data (data, "target");
7841   
7842   gtk_window_get_position (window, &x, &y);
7843
7844   gtk_window_move (window, x, y);
7845 }
7846
7847 static void
7848 set_geometry_callback (GtkWidget *entry,
7849                        gpointer   data)
7850 {
7851   gchar *text;
7852   GtkWindow *target;
7853
7854   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
7855   
7856   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
7857
7858   if (!gtk_window_parse_geometry (target, text))
7859     g_print ("Bad geometry string '%s'\n", text);
7860
7861   g_free (text);
7862 }
7863
7864 static void
7865 resizable_callback (GtkWidget *widget,
7866                      gpointer   data)
7867 {
7868   g_object_set (g_object_get_data (data, "target"),
7869                 "resizable", GTK_TOGGLE_BUTTON (widget)->active,
7870                 NULL);
7871 }
7872
7873 static void
7874 gravity_selected (GtkWidget *widget,
7875                   gpointer   data)
7876 {
7877   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
7878                           gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GDK_GRAVITY_NORTH_WEST);
7879 }
7880
7881 static void
7882 pos_selected (GtkWidget *widget,
7883               gpointer   data)
7884 {
7885   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
7886                            gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GTK_WIN_POS_NONE);
7887 }
7888
7889 static void
7890 move_gravity_window_to_current_position (GtkWidget *widget,
7891                                          gpointer   data)
7892 {
7893   gint x, y;
7894   GtkWindow *window;
7895
7896   window = GTK_WINDOW (data);    
7897   
7898   gtk_window_get_position (window, &x, &y);
7899
7900   gtk_window_move (window, x, y);
7901 }
7902
7903 static void
7904 get_screen_corner (GtkWindow *window,
7905                    gint      *x,
7906                    gint      *y)
7907 {
7908   int w, h;
7909   GdkScreen * screen = gtk_window_get_screen (window);
7910   
7911   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
7912
7913   switch (gtk_window_get_gravity (window))
7914     {
7915     case GDK_GRAVITY_SOUTH_EAST:
7916       *x = gdk_screen_get_width (screen) - w;
7917       *y = gdk_screen_get_height (screen) - h;
7918       break;
7919
7920     case GDK_GRAVITY_NORTH_EAST:
7921       *x = gdk_screen_get_width (screen) - w;
7922       *y = 0;
7923       break;
7924
7925     case GDK_GRAVITY_SOUTH_WEST:
7926       *x = 0;
7927       *y = gdk_screen_get_height (screen) - h;
7928       break;
7929
7930     case GDK_GRAVITY_NORTH_WEST:
7931       *x = 0;
7932       *y = 0;
7933       break;
7934       
7935     case GDK_GRAVITY_SOUTH:
7936       *x = (gdk_screen_get_width (screen) - w) / 2;
7937       *y = gdk_screen_get_height (screen) - h;
7938       break;
7939
7940     case GDK_GRAVITY_NORTH:
7941       *x = (gdk_screen_get_width (screen) - w) / 2;
7942       *y = 0;
7943       break;
7944
7945     case GDK_GRAVITY_WEST:
7946       *x = 0;
7947       *y = (gdk_screen_get_height (screen) - h) / 2;
7948       break;
7949
7950     case GDK_GRAVITY_EAST:
7951       *x = gdk_screen_get_width (screen) - w;
7952       *y = (gdk_screen_get_height (screen) - h) / 2;
7953       break;
7954
7955     case GDK_GRAVITY_CENTER:
7956       *x = (gdk_screen_get_width (screen) - w) / 2;
7957       *y = (gdk_screen_get_height (screen) - h) / 2;
7958       break;
7959
7960     case GDK_GRAVITY_STATIC:
7961       /* pick some random numbers */
7962       *x = 350;
7963       *y = 350;
7964       break;
7965
7966     default:
7967       g_assert_not_reached ();
7968       break;
7969     }
7970 }
7971
7972 static void
7973 move_gravity_window_to_starting_position (GtkWidget *widget,
7974                                           gpointer   data)
7975 {
7976   gint x, y;
7977   GtkWindow *window;
7978
7979   window = GTK_WINDOW (data);    
7980   
7981   get_screen_corner (window,
7982                      &x, &y);
7983   
7984   gtk_window_move (window, x, y);
7985 }
7986
7987 static GtkWidget*
7988 make_gravity_window (GtkWidget   *destroy_with,
7989                      GdkGravity   gravity,
7990                      const gchar *title)
7991 {
7992   GtkWidget *window;
7993   GtkWidget *button;
7994   GtkWidget *vbox;
7995   int x, y;
7996   
7997   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7998
7999   gtk_window_set_screen (GTK_WINDOW (window),
8000                          gtk_widget_get_screen (destroy_with));
8001
8002   vbox = gtk_vbox_new (FALSE, 0);
8003   gtk_widget_show (vbox);
8004   
8005   gtk_container_add (GTK_CONTAINER (window), vbox);
8006   gtk_window_set_title (GTK_WINDOW (window), title);
8007   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
8008
8009   g_signal_connect_object (destroy_with,
8010                            "destroy",
8011                            G_CALLBACK (gtk_widget_destroy),
8012                            window,
8013                            G_CONNECT_SWAPPED);
8014
8015   
8016   button = gtk_button_new_with_mnemonic ("_Move to current position");
8017
8018   g_signal_connect (button, "clicked",
8019                     G_CALLBACK (move_gravity_window_to_current_position),
8020                     window);
8021
8022   gtk_container_add (GTK_CONTAINER (vbox), button);
8023   gtk_widget_show (button);
8024
8025   button = gtk_button_new_with_mnemonic ("Move to _starting position");
8026
8027   g_signal_connect (button, "clicked",
8028                     G_CALLBACK (move_gravity_window_to_starting_position),
8029                     window);
8030
8031   gtk_container_add (GTK_CONTAINER (vbox), button);
8032   gtk_widget_show (button);
8033   
8034   /* Pretend this is the result of --geometry.
8035    * DO NOT COPY THIS CODE unless you are setting --geometry results,
8036    * and in that case you probably should just use gtk_window_parse_geometry().
8037    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
8038    * you are parsing --geometry or equivalent.
8039    */
8040   gtk_window_set_geometry_hints (GTK_WINDOW (window),
8041                                  NULL, NULL,
8042                                  GDK_HINT_USER_POS);
8043
8044   gtk_window_set_default_size (GTK_WINDOW (window),
8045                                200, 200);
8046
8047   get_screen_corner (GTK_WINDOW (window), &x, &y);
8048   
8049   gtk_window_move (GTK_WINDOW (window),
8050                    x, y);
8051   
8052   return window;
8053 }
8054
8055 static void
8056 do_gravity_test (GtkWidget *widget,
8057                  gpointer   data)
8058 {
8059   GtkWidget *destroy_with = data;
8060   GtkWidget *window;
8061   
8062   /* We put a window at each gravity point on the screen. */
8063   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
8064                                 "NorthWest");
8065   gtk_widget_show (window);
8066   
8067   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
8068                                 "SouthEast");
8069   gtk_widget_show (window);
8070
8071   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
8072                                 "NorthEast");
8073   gtk_widget_show (window);
8074
8075   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
8076                                 "SouthWest");
8077   gtk_widget_show (window);
8078
8079   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
8080                                 "South");
8081   gtk_widget_show (window);
8082
8083   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
8084                                 "North");
8085   gtk_widget_show (window);
8086
8087   
8088   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
8089                                 "West");
8090   gtk_widget_show (window);
8091
8092     
8093   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
8094                                 "East");
8095   gtk_widget_show (window);
8096
8097   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
8098                                 "Center");
8099   gtk_widget_show (window);
8100
8101   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
8102                                 "Static");
8103   gtk_widget_show (window);
8104 }
8105
8106 static GtkWidget*
8107 window_controls (GtkWidget *window)
8108 {
8109   GtkWidget *control_window;
8110   GtkWidget *label;
8111   GtkWidget *vbox;
8112   GtkWidget *button;
8113   GtkWidget *spin;
8114   GtkAdjustment *adj;
8115   GtkWidget *entry;
8116   GtkWidget *om;
8117   gint i;
8118   
8119   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8120
8121   gtk_window_set_screen (GTK_WINDOW (control_window),
8122                          gtk_widget_get_screen (window));
8123
8124   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
8125   
8126   g_object_set_data (G_OBJECT (control_window),
8127                      "target",
8128                      window);
8129   
8130   g_signal_connect_object (control_window,
8131                            "destroy",
8132                            G_CALLBACK (gtk_widget_destroy),
8133                            window,
8134                            G_CONNECT_SWAPPED);
8135
8136   vbox = gtk_vbox_new (FALSE, 5);
8137   
8138   gtk_container_add (GTK_CONTAINER (control_window), vbox);
8139   
8140   label = gtk_label_new ("<no configure events>");
8141   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
8142   
8143   g_signal_connect (window,
8144                     "configure_event",
8145                     G_CALLBACK (configure_event_callback),
8146                     label);
8147
8148   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
8149                                               5.0, 0.0);
8150   spin = gtk_spin_button_new (adj, 0, 0);
8151
8152   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
8153
8154   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
8155
8156   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
8157                                               5.0, 0.0);
8158   spin = gtk_spin_button_new (adj, 0, 0);
8159
8160   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
8161
8162   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
8163
8164   entry = gtk_entry_new ();
8165   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
8166
8167   g_signal_connect (entry, "changed",
8168                     G_CALLBACK (set_geometry_callback),
8169                     control_window);
8170
8171   button = gtk_button_new_with_label ("Show gravity test windows");
8172   g_signal_connect_swapped (button,
8173                             "clicked",
8174                             G_CALLBACK (do_gravity_test),
8175                             control_window);
8176   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8177
8178   button = gtk_button_new_with_label ("Reshow with initial size");
8179   g_signal_connect_object (button,
8180                            "clicked",
8181                            G_CALLBACK (gtk_window_reshow_with_initial_size),
8182                            window,
8183                            G_CONNECT_SWAPPED);
8184   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8185   
8186   button = gtk_button_new_with_label ("Queue resize");
8187   g_signal_connect_object (button,
8188                            "clicked",
8189                            G_CALLBACK (gtk_widget_queue_resize),
8190                            window,
8191                            G_CONNECT_SWAPPED);
8192   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8193   
8194   button = gtk_button_new_with_label ("Resize");
8195   g_signal_connect (button,
8196                     "clicked",
8197                     G_CALLBACK (set_size_callback),
8198                     control_window);
8199   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8200
8201   button = gtk_button_new_with_label ("Set default size");
8202   g_signal_connect (button,
8203                     "clicked",
8204                     G_CALLBACK (set_default_size_callback),
8205                     control_window);
8206   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8207
8208   button = gtk_button_new_with_label ("Unset default size");
8209   g_signal_connect (button,
8210                     "clicked",
8211                     G_CALLBACK (unset_default_size_callback),
8212                     control_window);
8213   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8214   
8215   button = gtk_button_new_with_label ("Set size request");
8216   g_signal_connect (button,
8217                     "clicked",
8218                     G_CALLBACK (set_size_request_callback),
8219                     control_window);
8220   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8221
8222   button = gtk_button_new_with_label ("Unset size request");
8223   g_signal_connect (button,
8224                     "clicked",
8225                     G_CALLBACK (unset_size_request_callback),
8226                     control_window);
8227   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8228   
8229   button = gtk_button_new_with_label ("Move");
8230   g_signal_connect (button,
8231                     "clicked",
8232                     G_CALLBACK (set_location_callback),
8233                     control_window);
8234   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8235
8236   button = gtk_button_new_with_label ("Move to current position");
8237   g_signal_connect (button,
8238                     "clicked",
8239                     G_CALLBACK (move_to_position_callback),
8240                     control_window);
8241   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8242
8243   button = gtk_check_button_new_with_label ("Allow resize");
8244   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8245   g_signal_connect (button,
8246                     "toggled",
8247                     G_CALLBACK (resizable_callback),
8248                     control_window);
8249   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8250   
8251   button = gtk_button_new_with_mnemonic ("_Show");
8252   g_signal_connect_object (button,
8253                            "clicked",
8254                            G_CALLBACK (gtk_widget_show),
8255                            window,
8256                            G_CONNECT_SWAPPED);
8257   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8258
8259   button = gtk_button_new_with_mnemonic ("_Hide");
8260   g_signal_connect_object (button,
8261                            "clicked",
8262                            G_CALLBACK (gtk_widget_hide),
8263                            window,
8264                            G_CONNECT_SWAPPED);
8265   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8266   
8267   om = gtk_combo_box_new_text ();
8268   i = 0;
8269   while (i < 10)
8270     {
8271       static gchar *names[] = {
8272         "GDK_GRAVITY_NORTH_WEST",
8273         "GDK_GRAVITY_NORTH",
8274         "GDK_GRAVITY_NORTH_EAST",
8275         "GDK_GRAVITY_WEST",
8276         "GDK_GRAVITY_CENTER",
8277         "GDK_GRAVITY_EAST",
8278         "GDK_GRAVITY_SOUTH_WEST",
8279         "GDK_GRAVITY_SOUTH",
8280         "GDK_GRAVITY_SOUTH_EAST",
8281         "GDK_GRAVITY_STATIC",
8282         NULL
8283       };
8284
8285       g_assert (names[i]);
8286       gtk_combo_box_append_text (GTK_COMBO_BOX (om), names[i]);
8287
8288       ++i;
8289     }
8290   
8291   g_signal_connect (om,
8292                     "changed",
8293                     G_CALLBACK (gravity_selected),
8294                     control_window);
8295
8296   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8297
8298
8299   om = gtk_combo_box_new_text ();
8300   i = 0;
8301   while (i < 5)
8302     {
8303       static gchar *names[] = {
8304         "GTK_WIN_POS_NONE",
8305         "GTK_WIN_POS_CENTER",
8306         "GTK_WIN_POS_MOUSE",
8307         "GTK_WIN_POS_CENTER_ALWAYS",
8308         "GTK_WIN_POS_CENTER_ON_PARENT",
8309         NULL
8310       };
8311
8312       g_assert (names[i]);
8313       gtk_combo_box_append_text (GTK_COMBO_BOX (om), names[i]);
8314
8315       ++i;
8316     }
8317
8318   g_signal_connect (om,
8319                     "changed",
8320                     G_CALLBACK (pos_selected),
8321                     control_window);
8322
8323   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8324   
8325   gtk_widget_show_all (vbox);
8326   
8327   return control_window;
8328 }
8329
8330 void
8331 create_window_sizing (GtkWidget *widget)
8332 {
8333   static GtkWidget *window = NULL;
8334   static GtkWidget *target_window = NULL;
8335
8336   if (!target_window)
8337     {
8338       GtkWidget *label;
8339       
8340       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8341       gtk_window_set_screen (GTK_WINDOW (target_window),
8342                              gtk_widget_get_screen (widget));
8343       label = gtk_label_new (NULL);
8344       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");
8345       gtk_container_add (GTK_CONTAINER (target_window), label);
8346       gtk_widget_show (label);
8347       
8348       g_signal_connect (target_window, "destroy",
8349                         G_CALLBACK (gtk_widget_destroyed),
8350                         &target_window);
8351
8352       window = window_controls (target_window);
8353       
8354       g_signal_connect (window, "destroy",
8355                         G_CALLBACK (gtk_widget_destroyed),
8356                         &window);
8357       
8358       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
8359     }
8360
8361   /* don't show target window by default, we want to allow testing
8362    * of behavior on first show.
8363    */
8364   
8365   if (!gtk_widget_get_visible (window))
8366     gtk_widget_show (window);
8367   else
8368     gtk_widget_destroy (window);
8369 }
8370
8371 /*
8372  * GtkProgressBar
8373  */
8374
8375 typedef struct _ProgressData {
8376   GtkWidget *window;
8377   GtkWidget *pbar;
8378   GtkWidget *block_spin;
8379   GtkWidget *x_align_spin;
8380   GtkWidget *y_align_spin;
8381   GtkWidget *step_spin;
8382   GtkWidget *act_blocks_spin;
8383   GtkWidget *label;
8384   GtkWidget *omenu1;
8385   GtkWidget *elmenu;
8386   GtkWidget *omenu2;
8387   GtkWidget *entry;
8388   int timer;
8389   gboolean activity;
8390 } ProgressData;
8391
8392 gboolean
8393 progress_timeout (gpointer data)
8394 {
8395   ProgressData *pdata = data;
8396   gdouble new_val;
8397   gchar *text;
8398
8399   if (pdata->activity)
8400     {
8401       gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
8402
8403       text = g_strdup_printf ("%s", "???");
8404     }
8405   else
8406     {
8407       new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
8408       if (new_val > 1.00)
8409         new_val = 0.00;
8410       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
8411
8412       text = g_strdup_printf ("%.0f%%", 100 * new_val);
8413     }
8414
8415   gtk_label_set_text (GTK_LABEL (pdata->label), text);
8416   g_free (text);
8417
8418   return TRUE;
8419 }
8420
8421 static void
8422 destroy_progress (GtkWidget     *widget,
8423                   ProgressData **pdata)
8424 {
8425   g_source_remove ((*pdata)->timer);
8426   (*pdata)->timer = 0;
8427   (*pdata)->window = NULL;
8428   g_free (*pdata);
8429   *pdata = NULL;
8430 }
8431
8432 static void
8433 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
8434 {
8435   ProgressData *pdata;
8436   gint i;
8437
8438   pdata = (ProgressData *) data;
8439
8440   if (!gtk_widget_get_mapped (widget))
8441     return;
8442
8443   i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8444
8445   if (i == 0 || i == 1)
8446     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_HORIZONTAL);
8447   else
8448     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_VERTICAL);
8449  
8450   if (i == 1 || i == 2)
8451     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), TRUE);
8452   else
8453     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), FALSE);
8454 }
8455
8456 static void
8457 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
8458 {
8459   gboolean active;
8460
8461   active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8462   gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pdata->pbar), active);
8463 }
8464
8465 static void
8466 progressbar_toggle_ellipsize (GtkWidget *widget,
8467                               gpointer   data)
8468 {
8469   ProgressData *pdata = data;
8470   if (gtk_widget_is_drawable (widget))
8471     {
8472       gint i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8473       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), i);
8474     }
8475 }
8476
8477 static void
8478 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
8479 {
8480   pdata->activity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8481 }
8482
8483 static void
8484 entry_changed (GtkWidget *widget, ProgressData *pdata)
8485 {
8486   gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar),
8487                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
8488 }
8489
8490 void
8491 create_progress_bar (GtkWidget *widget)
8492 {
8493   GtkWidget *action_area, *content_area;
8494   GtkWidget *button;
8495   GtkWidget *vbox;
8496   GtkWidget *vbox2;
8497   GtkWidget *hbox;
8498   GtkWidget *check;
8499   GtkWidget *frame;
8500   GtkWidget *tab;
8501   GtkWidget *label;
8502   GtkWidget *align;
8503   static ProgressData *pdata = NULL;
8504
8505   static gchar *items1[] =
8506   {
8507     "Left-Right",
8508     "Right-Left",
8509     "Bottom-Top",
8510     "Top-Bottom"
8511   };
8512
8513     static char *ellipsize_items[] = {
8514     "None",     // PANGO_ELLIPSIZE_NONE,
8515     "Start",    // PANGO_ELLIPSIZE_START,
8516     "Middle",   // PANGO_ELLIPSIZE_MIDDLE,
8517     "End",      // PANGO_ELLIPSIZE_END
8518   };
8519   
8520   if (!pdata)
8521     pdata = g_new0 (ProgressData, 1);
8522
8523   if (!pdata->window)
8524     {
8525       pdata->window = gtk_dialog_new ();
8526
8527       gtk_window_set_screen (GTK_WINDOW (pdata->window),
8528                              gtk_widget_get_screen (widget));
8529
8530       gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
8531
8532       g_signal_connect (pdata->window, "destroy",
8533                         G_CALLBACK (destroy_progress),
8534                         &pdata);
8535       pdata->timer = 0;
8536
8537       content_area = gtk_dialog_get_content_area (GTK_DIALOG (pdata->window));
8538       action_area = gtk_dialog_get_action_area (GTK_DIALOG (pdata->window));
8539
8540       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
8541       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
8542
8543       vbox = gtk_vbox_new (FALSE, 5);
8544       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8545       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, TRUE, 0);
8546
8547       frame = gtk_frame_new ("Progress");
8548       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8549
8550       vbox2 = gtk_vbox_new (FALSE, 5);
8551       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8552
8553       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8554       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8555
8556       pdata->pbar = gtk_progress_bar_new ();
8557       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar),
8558                                       PANGO_ELLIPSIZE_MIDDLE);
8559
8560       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
8561       pdata->timer = g_timeout_add (100, (GSourceFunc)progress_timeout, pdata);
8562
8563       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8564       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8565
8566       hbox = gtk_hbox_new (FALSE, 5);
8567       gtk_container_add (GTK_CONTAINER (align), hbox);
8568       label = gtk_label_new ("Label updated by user :"); 
8569       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8570       pdata->label = gtk_label_new ("");
8571       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
8572
8573       frame = gtk_frame_new ("Options");
8574       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8575
8576       vbox2 = gtk_vbox_new (FALSE, 5);
8577       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8578
8579       tab = gtk_table_new (7, 2, FALSE);
8580       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
8581
8582       label = gtk_label_new ("Orientation :");
8583       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
8584                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8585                         5, 5);
8586       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
8587
8588       pdata->omenu1 = build_option_menu (items1, 4, 0,
8589                                          progressbar_toggle_orientation,
8590                                          pdata);
8591       hbox = gtk_hbox_new (FALSE, 0);
8592       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
8593                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8594                         5, 5);
8595       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
8596       
8597       check = gtk_check_button_new_with_label ("Show text");
8598       g_signal_connect (check, "clicked",
8599                         G_CALLBACK (toggle_show_text),
8600                         pdata);
8601       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
8602                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8603                         5, 5);
8604
8605       hbox = gtk_hbox_new (FALSE, 0);
8606       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
8607                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8608                         5, 5);
8609
8610       label = gtk_label_new ("Text: ");
8611       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8612
8613       pdata->entry = gtk_entry_new ();
8614       g_signal_connect (pdata->entry, "changed",
8615                         G_CALLBACK (entry_changed),
8616                         pdata);
8617       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
8618       gtk_widget_set_size_request (pdata->entry, 100, -1);
8619
8620       label = gtk_label_new ("Ellipsize text :");
8621       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 10, 11,
8622                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8623                         5, 5);
8624       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
8625       pdata->elmenu = build_option_menu (ellipsize_items,
8626                                          sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
8627                                          2, // PANGO_ELLIPSIZE_MIDDLE
8628                                          progressbar_toggle_ellipsize,
8629                                          pdata);
8630       hbox = gtk_hbox_new (FALSE, 0);
8631       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 10, 11,
8632                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8633                         5, 5);
8634       gtk_box_pack_start (GTK_BOX (hbox), pdata->elmenu, TRUE, TRUE, 0);
8635
8636       check = gtk_check_button_new_with_label ("Activity mode");
8637       g_signal_connect (check, "clicked",
8638                         G_CALLBACK (toggle_activity_mode), pdata);
8639       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 15, 16,
8640                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8641                         5, 5);
8642
8643       button = gtk_button_new_with_label ("close");
8644       g_signal_connect_swapped (button, "clicked",
8645                                 G_CALLBACK (gtk_widget_destroy),
8646                                 pdata->window);
8647       gtk_widget_set_can_default (button, TRUE);
8648       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8649       gtk_widget_grab_default (button);
8650     }
8651
8652   if (!gtk_widget_get_visible (pdata->window))
8653     gtk_widget_show_all (pdata->window);
8654   else
8655     gtk_widget_destroy (pdata->window);
8656 }
8657
8658 /*
8659  * Properties
8660  */
8661
8662 typedef struct {
8663   int x;
8664   int y;
8665   gboolean found;
8666   gboolean first;
8667   GtkWidget *res_widget;
8668 } FindWidgetData;
8669
8670 static void
8671 find_widget (GtkWidget *widget, FindWidgetData *data)
8672 {
8673   GtkAllocation new_allocation;
8674   gint x_offset = 0;
8675   gint y_offset = 0;
8676
8677   gtk_widget_get_allocation (widget, &new_allocation);
8678
8679   if (data->found || !gtk_widget_get_mapped (widget))
8680     return;
8681
8682   /* Note that in the following code, we only count the
8683    * position as being inside a WINDOW widget if it is inside
8684    * widget->window; points that are outside of widget->window
8685    * but within the allocation are not counted. This is consistent
8686    * with the way we highlight drag targets.
8687    */
8688   if (gtk_widget_get_has_window (widget))
8689     {
8690       new_allocation.x = 0;
8691       new_allocation.y = 0;
8692     }
8693
8694   if (gtk_widget_get_parent (widget) && !data->first)
8695     {
8696       GdkWindow *window = gtk_widget_get_window (widget);
8697       while (window != gtk_widget_get_window (gtk_widget_get_parent (widget)))
8698         {
8699           gint tx, ty, twidth, theight;
8700           gdk_drawable_get_size (window, &twidth, &theight);
8701
8702           if (new_allocation.x < 0)
8703             {
8704               new_allocation.width += new_allocation.x;
8705               new_allocation.x = 0;
8706             }
8707           if (new_allocation.y < 0)
8708             {
8709               new_allocation.height += new_allocation.y;
8710               new_allocation.y = 0;
8711             }
8712           if (new_allocation.x + new_allocation.width > twidth)
8713             new_allocation.width = twidth - new_allocation.x;
8714           if (new_allocation.y + new_allocation.height > theight)
8715             new_allocation.height = theight - new_allocation.y;
8716
8717           gdk_window_get_position (window, &tx, &ty);
8718           new_allocation.x += tx;
8719           x_offset += tx;
8720           new_allocation.y += ty;
8721           y_offset += ty;
8722
8723           window = gdk_window_get_parent (window);
8724         }
8725     }
8726
8727   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
8728       (data->x < new_allocation.x + new_allocation.width) && 
8729       (data->y < new_allocation.y + new_allocation.height))
8730     {
8731       /* First, check if the drag is in a valid drop site in
8732        * one of our children 
8733        */
8734       if (GTK_IS_CONTAINER (widget))
8735         {
8736           FindWidgetData new_data = *data;
8737           
8738           new_data.x -= x_offset;
8739           new_data.y -= y_offset;
8740           new_data.found = FALSE;
8741           new_data.first = FALSE;
8742           
8743           gtk_container_forall (GTK_CONTAINER (widget),
8744                                 (GtkCallback)find_widget,
8745                                 &new_data);
8746           
8747           data->found = new_data.found;
8748           if (data->found)
8749             data->res_widget = new_data.res_widget;
8750         }
8751
8752       /* If not, and this widget is registered as a drop site, check to
8753        * emit "drag_motion" to check if we are actually in
8754        * a drop site.
8755        */
8756       if (!data->found)
8757         {
8758           data->found = TRUE;
8759           data->res_widget = widget;
8760         }
8761     }
8762 }
8763
8764 static GtkWidget *
8765 find_widget_at_pointer (GdkDisplay *display)
8766 {
8767   GtkWidget *widget = NULL;
8768   GdkWindow *pointer_window;
8769   gint x, y;
8770   FindWidgetData data;
8771  
8772  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);
8773  
8774  if (pointer_window)
8775    {
8776      gpointer widget_ptr;
8777
8778      gdk_window_get_user_data (pointer_window, &widget_ptr);
8779      widget = widget_ptr;
8780    }
8781
8782  if (widget)
8783    {
8784      gdk_window_get_pointer (gtk_widget_get_window (widget),
8785                              &x, &y, NULL);
8786      
8787      data.x = x;
8788      data.y = y;
8789      data.found = FALSE;
8790      data.first = TRUE;
8791
8792      find_widget (widget, &data);
8793      if (data.found)
8794        return data.res_widget;
8795      return widget;
8796    }
8797  return NULL;
8798 }
8799
8800 struct PropertiesData {
8801   GtkWidget **window;
8802   GdkCursor *cursor;
8803   gboolean in_query;
8804   gint handler;
8805 };
8806
8807 static void
8808 destroy_properties (GtkWidget             *widget,
8809                     struct PropertiesData *data)
8810 {
8811   if (data->window)
8812     {
8813       *data->window = NULL;
8814       data->window = NULL;
8815     }
8816
8817   if (data->cursor)
8818     {
8819       gdk_cursor_unref (data->cursor);
8820       data->cursor = NULL;
8821     }
8822
8823   if (data->handler)
8824     {
8825       g_signal_handler_disconnect (widget, data->handler);
8826       data->handler = 0;
8827     }
8828
8829   g_free (data);
8830 }
8831
8832 static gint
8833 property_query_event (GtkWidget        *widget,
8834                       GdkEvent         *event,
8835                       struct PropertiesData *data)
8836 {
8837   GtkWidget *res_widget = NULL;
8838
8839   if (!data->in_query)
8840     return FALSE;
8841   
8842   if (event->type == GDK_BUTTON_RELEASE)
8843     {
8844       gtk_grab_remove (widget);
8845       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
8846                                   GDK_CURRENT_TIME);
8847       
8848       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
8849       if (res_widget)
8850         {
8851           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
8852                              gtk_widget_get_screen (widget));
8853           create_prop_editor (G_OBJECT (res_widget), 0);
8854         }
8855
8856       data->in_query = FALSE;
8857     }
8858   return FALSE;
8859 }
8860
8861
8862 static void
8863 query_properties (GtkButton *button,
8864                   struct PropertiesData *data)
8865 {
8866   GtkWidget *widget = GTK_WIDGET (button);
8867   gint failure;
8868
8869   g_signal_connect (button, "event",
8870                     G_CALLBACK (property_query_event), data);
8871
8872
8873   if (!data->cursor)
8874     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
8875                                                GDK_TARGET);
8876
8877   failure = gdk_pointer_grab (gtk_widget_get_window (widget),
8878                               TRUE,
8879                               GDK_BUTTON_RELEASE_MASK,
8880                               NULL,
8881                               data->cursor,
8882                               GDK_CURRENT_TIME);
8883
8884   gtk_grab_add (widget);
8885
8886   data->in_query = TRUE;
8887 }
8888
8889 static void
8890 create_properties (GtkWidget *widget)
8891 {
8892   static GtkWidget *window = NULL;
8893   GtkWidget *button;
8894   GtkWidget *vbox;
8895   GtkWidget *label;
8896   struct PropertiesData *data;
8897
8898   data = g_new (struct PropertiesData, 1);
8899   data->window = &window;
8900   data->in_query = FALSE;
8901   data->cursor = NULL;
8902   data->handler = 0;
8903
8904   if (!window)
8905     {
8906       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8907
8908       gtk_window_set_screen (GTK_WINDOW (window),
8909                              gtk_widget_get_screen (widget));      
8910
8911       data->handler = g_signal_connect (window, "destroy",
8912                                         G_CALLBACK (destroy_properties),
8913                                         data);
8914
8915       gtk_window_set_title (GTK_WINDOW (window), "test properties");
8916       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8917
8918       vbox = gtk_vbox_new (FALSE, 1);
8919       gtk_container_add (GTK_CONTAINER (window), vbox);
8920             
8921       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
8922       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
8923       
8924       button = gtk_button_new_with_label ("Query properties");
8925       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8926       g_signal_connect (button, "clicked",
8927                         G_CALLBACK (query_properties),
8928                         data);
8929     }
8930
8931   if (!gtk_widget_get_visible (window))
8932     gtk_widget_show_all (window);
8933   else
8934     gtk_widget_destroy (window);
8935   
8936 }
8937
8938 /*
8939  * Selection Test
8940  */
8941
8942 void
8943 selection_test_received (GtkWidget        *tree_view,
8944                          GtkSelectionData *data)
8945 {
8946   GtkTreeModel *model;
8947   GtkListStore *store;
8948   GdkAtom *atoms;
8949   int i, l;
8950
8951   if (data->length < 0)
8952     {
8953       g_print ("Selection retrieval failed\n");
8954       return;
8955     }
8956   if (data->type != GDK_SELECTION_TYPE_ATOM)
8957     {
8958       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
8959       return;
8960     }
8961
8962   /* Clear out any current list items */
8963
8964   model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
8965   store = GTK_LIST_STORE (model);
8966   gtk_list_store_clear (store);
8967
8968   /* Add new items to list */
8969
8970   atoms = (GdkAtom *)data->data;
8971
8972   l = data->length / sizeof (GdkAtom);
8973   for (i = 0; i < l; i++)
8974     {
8975       char *name;
8976       GtkTreeIter iter;
8977
8978       name = gdk_atom_name (atoms[i]);
8979       if (name != NULL)
8980         {
8981           gtk_list_store_insert_with_values (store, &iter, i, 0, name, -1);
8982           g_free (name);
8983         }
8984       else
8985        gtk_list_store_insert_with_values (store, &iter, i, 0,  "(bad atom)", -1);
8986     }
8987
8988   return;
8989 }
8990
8991 void
8992 selection_test_get_targets (GtkWidget *widget, GtkWidget *tree_view)
8993 {
8994   static GdkAtom targets_atom = GDK_NONE;
8995
8996   if (targets_atom == GDK_NONE)
8997     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
8998
8999   gtk_selection_convert (tree_view, GDK_SELECTION_PRIMARY, targets_atom,
9000                          GDK_CURRENT_TIME);
9001 }
9002
9003 void
9004 create_selection_test (GtkWidget *widget)
9005 {
9006   static GtkWidget *window = NULL;
9007   GtkWidget *action_area, *content_area;
9008   GtkWidget *button;
9009   GtkWidget *vbox;
9010   GtkWidget *scrolled_win;
9011   GtkListStore* store;
9012   GtkWidget *tree_view;
9013   GtkTreeViewColumn *column;
9014   GtkCellRenderer *renderer;
9015   GtkWidget *label;
9016
9017   if (!window)
9018     {
9019       window = gtk_dialog_new ();
9020       
9021       gtk_window_set_screen (GTK_WINDOW (window),
9022                              gtk_widget_get_screen (widget));
9023
9024       g_signal_connect (window, "destroy",
9025                         G_CALLBACK (gtk_widget_destroyed),
9026                         &window);
9027
9028       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9029       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9030
9031       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
9032       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9033
9034       /* Create the list */
9035
9036       vbox = gtk_vbox_new (FALSE, 5);
9037       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9038       gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
9039
9040       label = gtk_label_new ("Gets available targets for current selection");
9041       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9042
9043       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
9044       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
9045                                       GTK_POLICY_AUTOMATIC, 
9046                                       GTK_POLICY_AUTOMATIC);
9047       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
9048       gtk_widget_set_size_request (scrolled_win, 100, 200);
9049
9050       store = gtk_list_store_new (1, G_TYPE_STRING);
9051       tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
9052       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), tree_view);
9053
9054       renderer = gtk_cell_renderer_text_new ();
9055       column = gtk_tree_view_column_new_with_attributes ("Target", renderer,
9056                                                          "text", 0, NULL);
9057       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
9058
9059       g_signal_connect (tree_view, "selection_received",
9060                         G_CALLBACK (selection_test_received), NULL);
9061
9062       /* .. And create some buttons */
9063       button = gtk_button_new_with_label ("Get Targets");
9064       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9065
9066       g_signal_connect (button, "clicked",
9067                         G_CALLBACK (selection_test_get_targets), tree_view);
9068
9069       button = gtk_button_new_with_label ("Quit");
9070       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9071
9072       g_signal_connect_swapped (button, "clicked",
9073                                 G_CALLBACK (gtk_widget_destroy),
9074                                 window);
9075     }
9076
9077   if (!gtk_widget_get_visible (window))
9078     gtk_widget_show_all (window);
9079   else
9080     gtk_widget_destroy (window);
9081 }
9082
9083 /*
9084  * Test scrolling
9085  */
9086
9087 static int scroll_test_pos = 0.0;
9088
9089 static gint
9090 scroll_test_draw (GtkWidget     *widget,
9091                   cairo_t       *cr,
9092                   GtkAdjustment *adj)
9093 {
9094   gint i,j;
9095   gint imin, imax, jmin, jmax;
9096   GdkRectangle clip;
9097   
9098   gdk_cairo_get_clip_rectangle (cr, &clip);
9099
9100   imin = (clip.x) / 10;
9101   imax = (clip.x + clip.width + 9) / 10;
9102
9103   jmin = ((int)adj->value + clip.y) / 10;
9104   jmax = ((int)adj->value + clip.y + clip.height + 9) / 10;
9105
9106   for (i=imin; i<imax; i++)
9107     for (j=jmin; j<jmax; j++)
9108       if ((i+j) % 2)
9109         cairo_rectangle (cr, 10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
9110
9111   cairo_fill (cr);
9112
9113   return TRUE;
9114 }
9115
9116 static gint
9117 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
9118                     GtkAdjustment *adj)
9119 {
9120   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
9121                                     -adj->page_increment / 2:
9122                                     adj->page_increment / 2);
9123   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
9124   gtk_adjustment_set_value (adj, new_value);  
9125   
9126   return TRUE;
9127 }
9128
9129 static void
9130 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
9131                        GtkAdjustment *adj)
9132 {
9133   GtkAllocation allocation;
9134
9135   gtk_widget_get_allocation (widget, &allocation);
9136   adj->page_increment = 0.9 * allocation.height;
9137   adj->page_size = allocation.height;
9138
9139   g_signal_emit_by_name (adj, "changed");
9140 }
9141
9142 static void
9143 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
9144 {
9145   GdkWindow *window;
9146   gint dy;
9147
9148   dy = scroll_test_pos - (int)adj->value;
9149   scroll_test_pos = adj->value;
9150
9151   if (!gtk_widget_is_drawable (widget))
9152     return;
9153
9154   window = gtk_widget_get_window (widget);
9155   gdk_window_scroll (window, 0, dy);
9156   gdk_window_process_updates (window, FALSE);
9157 }
9158
9159
9160 void
9161 create_scroll_test (GtkWidget *widget)
9162 {
9163   static GtkWidget *window = NULL;
9164   GtkWidget *action_area, *content_area;
9165   GtkWidget *hbox;
9166   GtkWidget *drawing_area;
9167   GtkWidget *scrollbar;
9168   GtkWidget *button;
9169   GtkAdjustment *adj;
9170   GdkGeometry geometry;
9171   GdkWindowHints geometry_mask;
9172
9173   if (!window)
9174     {
9175       window = gtk_dialog_new ();
9176
9177       gtk_window_set_screen (GTK_WINDOW (window),
9178                              gtk_widget_get_screen (widget));
9179
9180       g_signal_connect (window, "destroy",
9181                         G_CALLBACK (gtk_widget_destroyed),
9182                         &window);
9183
9184       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9185       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9186
9187       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
9188       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9189
9190       hbox = gtk_hbox_new (FALSE, 0);
9191       gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
9192       gtk_widget_show (hbox);
9193
9194       drawing_area = gtk_drawing_area_new ();
9195       gtk_widget_set_size_request (drawing_area, 200, 200);
9196       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
9197       gtk_widget_show (drawing_area);
9198
9199       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
9200
9201       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
9202       scroll_test_pos = 0.0;
9203
9204       scrollbar = gtk_vscrollbar_new (adj);
9205       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
9206       gtk_widget_show (scrollbar);
9207
9208       g_signal_connect (drawing_area, "draw",
9209                         G_CALLBACK (scroll_test_draw), adj);
9210       g_signal_connect (drawing_area, "configure_event",
9211                         G_CALLBACK (scroll_test_configure), adj);
9212       g_signal_connect (drawing_area, "scroll_event",
9213                         G_CALLBACK (scroll_test_scroll), adj);
9214       
9215       g_signal_connect (adj, "value_changed",
9216                         G_CALLBACK (scroll_test_adjustment_changed),
9217                         drawing_area);
9218       
9219       /* .. And create some buttons */
9220
9221       button = gtk_button_new_with_label ("Quit");
9222       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9223
9224       g_signal_connect_swapped (button, "clicked",
9225                                 G_CALLBACK (gtk_widget_destroy),
9226                                 window);
9227       gtk_widget_show (button);
9228
9229       /* Set up gridded geometry */
9230
9231       geometry_mask = GDK_HINT_MIN_SIZE | 
9232                        GDK_HINT_BASE_SIZE | 
9233                        GDK_HINT_RESIZE_INC;
9234
9235       geometry.min_width = 20;
9236       geometry.min_height = 20;
9237       geometry.base_width = 0;
9238       geometry.base_height = 0;
9239       geometry.width_inc = 10;
9240       geometry.height_inc = 10;
9241       
9242       gtk_window_set_geometry_hints (GTK_WINDOW (window),
9243                                drawing_area, &geometry, geometry_mask);
9244     }
9245
9246   if (!gtk_widget_get_visible (window))
9247     gtk_widget_show (window);
9248   else
9249     gtk_widget_destroy (window);
9250 }
9251
9252 /*
9253  * Timeout Test
9254  */
9255
9256 static int timer = 0;
9257
9258 gint
9259 timeout_test (GtkWidget *label)
9260 {
9261   static int count = 0;
9262   static char buffer[32];
9263
9264   sprintf (buffer, "count: %d", ++count);
9265   gtk_label_set_text (GTK_LABEL (label), buffer);
9266
9267   return TRUE;
9268 }
9269
9270 void
9271 start_timeout_test (GtkWidget *widget,
9272                     GtkWidget *label)
9273 {
9274   if (!timer)
9275     {
9276       timer = g_timeout_add (100, (GSourceFunc)timeout_test, label);
9277     }
9278 }
9279
9280 void
9281 stop_timeout_test (GtkWidget *widget,
9282                    gpointer   data)
9283 {
9284   if (timer)
9285     {
9286       g_source_remove (timer);
9287       timer = 0;
9288     }
9289 }
9290
9291 void
9292 destroy_timeout_test (GtkWidget  *widget,
9293                       GtkWidget **window)
9294 {
9295   stop_timeout_test (NULL, NULL);
9296
9297   *window = NULL;
9298 }
9299
9300 void
9301 create_timeout_test (GtkWidget *widget)
9302 {
9303   static GtkWidget *window = NULL;
9304   GtkWidget *action_area, *content_area;
9305   GtkWidget *button;
9306   GtkWidget *label;
9307
9308   if (!window)
9309     {
9310       window = gtk_dialog_new ();
9311
9312       gtk_window_set_screen (GTK_WINDOW (window),
9313                              gtk_widget_get_screen (widget));
9314
9315       g_signal_connect (window, "destroy",
9316                         G_CALLBACK (destroy_timeout_test),
9317                         &window);
9318
9319       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9320       action_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9321
9322       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
9323       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9324
9325       label = gtk_label_new ("count: 0");
9326       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
9327       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9328       gtk_widget_show (label);
9329
9330       button = gtk_button_new_with_label ("close");
9331       g_signal_connect_swapped (button, "clicked",
9332                                 G_CALLBACK (gtk_widget_destroy),
9333                                 window);
9334       gtk_widget_set_can_default (button, TRUE);
9335       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9336       gtk_widget_grab_default (button);
9337       gtk_widget_show (button);
9338
9339       button = gtk_button_new_with_label ("start");
9340       g_signal_connect (button, "clicked",
9341                         G_CALLBACK(start_timeout_test),
9342                         label);
9343       gtk_widget_set_can_default (button, TRUE);
9344       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9345       gtk_widget_show (button);
9346
9347       button = gtk_button_new_with_label ("stop");
9348       g_signal_connect (button, "clicked",
9349                         G_CALLBACK (stop_timeout_test),
9350                         NULL);
9351       gtk_widget_set_can_default (button, TRUE);
9352       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9353       gtk_widget_show (button);
9354     }
9355
9356   if (!gtk_widget_get_visible (window))
9357     gtk_widget_show (window);
9358   else
9359     gtk_widget_destroy (window);
9360 }
9361
9362 /*
9363  * Idle Test
9364  */
9365
9366 static int idle_id = 0;
9367
9368 static gint
9369 idle_test (GtkWidget *label)
9370 {
9371   static int count = 0;
9372   static char buffer[32];
9373
9374   sprintf (buffer, "count: %d", ++count);
9375   gtk_label_set_text (GTK_LABEL (label), buffer);
9376
9377   return TRUE;
9378 }
9379
9380 static void
9381 start_idle_test (GtkWidget *widget,
9382                  GtkWidget *label)
9383 {
9384   if (!idle_id)
9385     {
9386       idle_id = g_idle_add ((GSourceFunc) idle_test, label);
9387     }
9388 }
9389
9390 static void
9391 stop_idle_test (GtkWidget *widget,
9392                 gpointer   data)
9393 {
9394   if (idle_id)
9395     {
9396       g_source_remove (idle_id);
9397       idle_id = 0;
9398     }
9399 }
9400
9401 static void
9402 destroy_idle_test (GtkWidget  *widget,
9403                    GtkWidget **window)
9404 {
9405   stop_idle_test (NULL, NULL);
9406
9407   *window = NULL;
9408 }
9409
9410 static void
9411 toggle_idle_container (GObject *button,
9412                        GtkContainer *container)
9413 {
9414   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
9415 }
9416
9417 static void
9418 create_idle_test (GtkWidget *widget)
9419 {
9420   static GtkWidget *window = NULL;
9421   GtkWidget *button;
9422   GtkWidget *label;
9423   GtkWidget *container;
9424
9425   if (!window)
9426     {
9427       GtkWidget *action_area, *content_area;
9428       GtkWidget *button2;
9429       GtkWidget *frame;
9430       GtkWidget *box;
9431
9432       window = gtk_dialog_new ();
9433
9434       gtk_window_set_screen (GTK_WINDOW (window),
9435                              gtk_widget_get_screen (widget));
9436
9437       g_signal_connect (window, "destroy",
9438                         G_CALLBACK (destroy_idle_test),
9439                         &window);
9440
9441       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9442       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9443
9444       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
9445       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9446
9447       label = gtk_label_new ("count: 0");
9448       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
9449       gtk_widget_show (label);
9450       
9451       container =
9452         g_object_new (GTK_TYPE_HBOX,
9453                         "visible", TRUE,
9454                         /* "GtkContainer::child", g_object_new (GTK_TYPE_HBOX,
9455                          * "GtkWidget::visible", TRUE,
9456                          */
9457                          "child", label,
9458                         /* NULL), */
9459                         NULL);
9460       gtk_box_pack_start (GTK_BOX (content_area), container, TRUE, TRUE, 0);
9461
9462       frame =
9463         g_object_new (GTK_TYPE_FRAME,
9464                         "border_width", 5,
9465                         "label", "Label Container",
9466                         "visible", TRUE,
9467                         "parent", content_area,
9468                         NULL);
9469       box =
9470         g_object_new (GTK_TYPE_VBOX,
9471                         "visible", TRUE,
9472                         "parent", frame,
9473                         NULL);
9474       button =
9475         g_object_connect (g_object_new (GTK_TYPE_RADIO_BUTTON,
9476                                           "label", "Resize-Parent",
9477                                           "user_data", (void*)GTK_RESIZE_PARENT,
9478                                           "visible", TRUE,
9479                                           "parent", box,
9480                                           NULL),
9481                           "signal::clicked", toggle_idle_container, container,
9482                           NULL);
9483       button = g_object_new (GTK_TYPE_RADIO_BUTTON,
9484                                "label", "Resize-Queue",
9485                                "user_data", (void*)GTK_RESIZE_QUEUE,
9486                                "group", button,
9487                                "visible", TRUE,
9488                                "parent", box,
9489                                NULL);
9490       g_object_connect (button,
9491                         "signal::clicked", toggle_idle_container, container,
9492                         NULL);
9493       button2 = g_object_new (GTK_TYPE_RADIO_BUTTON,
9494                                 "label", "Resize-Immediate",
9495                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
9496                                 NULL);
9497       g_object_connect (button2,
9498                         "signal::clicked", toggle_idle_container, container,
9499                         NULL);
9500       g_object_set (button2,
9501                     "group", button,
9502                     "visible", TRUE,
9503                     "parent", box,
9504                     NULL);
9505
9506       button = gtk_button_new_with_label ("close");
9507       g_signal_connect_swapped (button, "clicked",
9508                                 G_CALLBACK (gtk_widget_destroy),
9509                                 window);
9510       gtk_widget_set_can_default (button, TRUE);
9511       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9512       gtk_widget_grab_default (button);
9513       gtk_widget_show (button);
9514
9515       button = gtk_button_new_with_label ("start");
9516       g_signal_connect (button, "clicked",
9517                         G_CALLBACK (start_idle_test),
9518                         label);
9519       gtk_widget_set_can_default (button, TRUE);
9520       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9521       gtk_widget_show (button);
9522
9523       button = gtk_button_new_with_label ("stop");
9524       g_signal_connect (button, "clicked",
9525                         G_CALLBACK (stop_idle_test),
9526                         NULL);
9527       gtk_widget_set_can_default (button, TRUE);
9528       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9529       gtk_widget_show (button);
9530     }
9531
9532   if (!gtk_widget_get_visible (window))
9533     gtk_widget_show (window);
9534   else
9535     gtk_widget_destroy (window);
9536 }
9537
9538 /*
9539  * rc file test
9540  */
9541
9542 void
9543 reload_all_rc_files (void)
9544 {
9545   static GdkAtom atom_rcfiles = GDK_NONE;
9546
9547   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
9548   int i;
9549   
9550   if (!atom_rcfiles)
9551     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
9552
9553   for(i = 0; i < 5; i++)
9554     send_event->client.data.l[i] = 0;
9555   send_event->client.data_format = 32;
9556   send_event->client.message_type = atom_rcfiles;
9557   gdk_event_send_clientmessage_toall (send_event);
9558
9559   gdk_event_free (send_event);
9560 }
9561
9562 void
9563 create_rc_file (GtkWidget *widget)
9564 {
9565   static GtkWidget *window = NULL;
9566   GtkWidget *action_area, *content_area;
9567   GtkWidget *button;
9568   GtkWidget *frame;
9569   GtkWidget *vbox;
9570   GtkWidget *label;
9571
9572   if (!window)
9573     {
9574       window = gtk_dialog_new ();
9575
9576       gtk_window_set_screen (GTK_WINDOW (window),
9577                              gtk_widget_get_screen (widget));
9578
9579       g_signal_connect (window, "destroy",
9580                         G_CALLBACK (gtk_widget_destroyed),
9581                         &window);
9582
9583       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9584       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9585
9586       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
9587       gtk_box_pack_start (GTK_BOX (content_area), frame, FALSE, FALSE, 0);
9588
9589       vbox = gtk_vbox_new (FALSE, 0);
9590       gtk_container_add (GTK_CONTAINER (frame), vbox);
9591       
9592       label = gtk_label_new ("This label should be red");
9593       gtk_widget_set_name (label, "testgtk-red-label");
9594       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9595
9596       label = gtk_label_new ("This label should be green");
9597       gtk_widget_set_name (label, "testgtk-green-label");
9598       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9599
9600       label = gtk_label_new ("This label should be blue");
9601       gtk_widget_set_name (label, "testgtk-blue-label");
9602       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9603
9604       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
9605       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9606
9607       button = gtk_button_new_with_label ("Reload");
9608       g_signal_connect (button, "clicked",
9609                         G_CALLBACK (gtk_rc_reparse_all), NULL);
9610       gtk_widget_set_can_default (button, TRUE);
9611       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9612       gtk_widget_grab_default (button);
9613
9614       button = gtk_button_new_with_label ("Reload All");
9615       g_signal_connect (button, "clicked",
9616                         G_CALLBACK (reload_all_rc_files), NULL);
9617       gtk_widget_set_can_default (button, TRUE);
9618       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9619
9620       button = gtk_button_new_with_label ("Close");
9621       g_signal_connect_swapped (button, "clicked",
9622                                 G_CALLBACK (gtk_widget_destroy),
9623                                 window);
9624       gtk_widget_set_can_default (button, TRUE);
9625       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9626     }
9627
9628   if (!gtk_widget_get_visible (window))
9629     gtk_widget_show_all (window);
9630   else
9631     gtk_widget_destroy (window);
9632 }
9633
9634 /*
9635  * Test of recursive mainloop
9636  */
9637
9638 void
9639 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
9640 {
9641   *window = NULL;
9642   gtk_main_quit ();
9643 }
9644
9645 void
9646 create_mainloop (GtkWidget *widget)
9647 {
9648   static GtkWidget *window = NULL;
9649   GtkWidget *action_area, *content_area;
9650   GtkWidget *label;
9651   GtkWidget *button;
9652
9653   if (!window)
9654     {
9655       window = gtk_dialog_new ();
9656
9657       gtk_window_set_screen (GTK_WINDOW (window),
9658                              gtk_widget_get_screen (widget));
9659
9660       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
9661
9662       g_signal_connect (window, "destroy",
9663                         G_CALLBACK (mainloop_destroyed),
9664                         &window);
9665
9666       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9667       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9668
9669       label = gtk_label_new ("In recursive main loop...");
9670       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
9671
9672       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9673       gtk_widget_show (label);
9674
9675       button = gtk_button_new_with_label ("Leave");
9676       gtk_box_pack_start (GTK_BOX (action_area), button, FALSE, TRUE, 0);
9677
9678       g_signal_connect_swapped (button, "clicked",
9679                                 G_CALLBACK (gtk_widget_destroy),
9680                                 window);
9681
9682       gtk_widget_set_can_default (button, TRUE);
9683       gtk_widget_grab_default (button);
9684
9685       gtk_widget_show (button);
9686     }
9687
9688   if (!gtk_widget_get_visible (window))
9689     {
9690       gtk_widget_show (window);
9691
9692       g_print ("create_mainloop: start\n");
9693       gtk_main ();
9694       g_print ("create_mainloop: done\n");
9695     }
9696   else
9697     gtk_widget_destroy (window);
9698 }
9699
9700 static gboolean
9701 layout_draw_handler (GtkWidget *widget, cairo_t *cr)
9702 {
9703   GtkLayout *layout;
9704   GdkWindow *bin_window;
9705   GdkRectangle clip;
9706   gint i,j,x,y;
9707   gint imin, imax, jmin, jmax;
9708
9709   layout = GTK_LAYOUT (widget);
9710   bin_window = gtk_layout_get_bin_window (layout);
9711
9712   if (!gtk_cairo_should_draw_window (cr, bin_window))
9713     return FALSE;
9714   
9715   gdk_window_get_position (bin_window, &x, &y);
9716   cairo_translate (cr, x, y);
9717
9718   gdk_cairo_get_clip_rectangle (cr, &clip);
9719
9720   imin = (clip.x) / 10;
9721   imax = (clip.x + clip.width + 9) / 10;
9722
9723   jmin = (clip.y) / 10;
9724   jmax = (clip.y + clip.height + 9) / 10;
9725
9726   for (i=imin; i<imax; i++)
9727     for (j=jmin; j<jmax; j++)
9728       if ((i+j) % 2)
9729         cairo_rectangle (cr,
9730                          10*i, 10*j, 
9731                          1+i%10, 1+j%10);
9732   
9733   cairo_fill (cr);
9734
9735   return FALSE;
9736 }
9737
9738 void create_layout (GtkWidget *widget)
9739 {
9740   GtkAdjustment *hadjustment, *vadjustment;
9741   GtkLayout *layout;
9742   static GtkWidget *window = NULL;
9743   GtkWidget *layout_widget;
9744   GtkWidget *scrolledwindow;
9745   GtkWidget *button;
9746
9747   if (!window)
9748     {
9749       gchar buf[16];
9750
9751       gint i, j;
9752       
9753       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9754       gtk_window_set_screen (GTK_WINDOW (window),
9755                              gtk_widget_get_screen (widget));
9756
9757       g_signal_connect (window, "destroy",
9758                         G_CALLBACK (gtk_widget_destroyed),
9759                         &window);
9760
9761       gtk_window_set_title (GTK_WINDOW (window), "Layout");
9762       gtk_widget_set_size_request (window, 200, 200);
9763
9764       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
9765       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
9766                                            GTK_SHADOW_IN);
9767       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
9768                                          GTK_CORNER_TOP_RIGHT);
9769
9770       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
9771
9772       layout_widget = gtk_layout_new (NULL, NULL);
9773       layout = GTK_LAYOUT (layout_widget);
9774       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout_widget);
9775
9776       /* We set step sizes here since GtkLayout does not set
9777        * them itself.
9778        */
9779       hadjustment = gtk_layout_get_hadjustment (layout);
9780       vadjustment = gtk_layout_get_vadjustment (layout);
9781       gtk_adjustment_set_step_increment (hadjustment, 10.0);
9782       gtk_adjustment_set_step_increment (vadjustment, 10.0);
9783       gtk_layout_set_hadjustment (layout, hadjustment);
9784       gtk_layout_set_vadjustment (layout, vadjustment);
9785
9786       gtk_widget_set_events (layout_widget, GDK_EXPOSURE_MASK);
9787       g_signal_connect (layout, "draw",
9788                         G_CALLBACK (layout_draw_handler), NULL);
9789
9790       gtk_layout_set_size (layout, 1600, 128000);
9791
9792       for (i=0 ; i < 16 ; i++)
9793         for (j=0 ; j < 16 ; j++)
9794           {
9795             sprintf(buf, "Button %d, %d", i, j);
9796             if ((i + j) % 2)
9797               button = gtk_button_new_with_label (buf);
9798             else
9799               button = gtk_label_new (buf);
9800
9801             gtk_layout_put (layout, button, j*100, i*100);
9802           }
9803
9804       for (i=16; i < 1280; i++)
9805         {
9806           sprintf(buf, "Button %d, %d", i, 0);
9807           if (i % 2)
9808             button = gtk_button_new_with_label (buf);
9809           else
9810             button = gtk_label_new (buf);
9811
9812           gtk_layout_put (layout, button, 0, i*100);
9813         }
9814     }
9815
9816   if (!gtk_widget_get_visible (window))
9817     gtk_widget_show_all (window);
9818   else
9819     gtk_widget_destroy (window);
9820 }
9821
9822 void
9823 create_styles (GtkWidget *widget)
9824 {
9825   static GtkWidget *window = NULL;
9826   GtkWidget *content_area, *action_area;
9827   GtkWidget *label;
9828   GtkWidget *button;
9829   GtkWidget *entry;
9830   GtkWidget *vbox;
9831   static GdkColor red =    { 0, 0xffff, 0,      0      };
9832   static GdkColor green =  { 0, 0,      0xffff, 0      };
9833   static GdkColor blue =   { 0, 0,      0,      0xffff };
9834   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
9835   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
9836   PangoFontDescription *font_desc;
9837
9838   GtkRcStyle *rc_style;
9839
9840   if (!window)
9841     {
9842       window = gtk_dialog_new ();
9843       gtk_window_set_screen (GTK_WINDOW (window),
9844                              gtk_widget_get_screen (widget));
9845      
9846       g_signal_connect (window, "destroy",
9847                         G_CALLBACK (gtk_widget_destroyed),
9848                         &window);
9849
9850       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9851       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9852
9853       button = gtk_button_new_with_label ("Close");
9854       g_signal_connect_swapped (button, "clicked",
9855                                 G_CALLBACK (gtk_widget_destroy),
9856                                 window);
9857       gtk_widget_set_can_default (button, TRUE);
9858       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9859       gtk_widget_show (button);
9860
9861       vbox = gtk_vbox_new (FALSE, 5);
9862       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9863       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
9864       
9865       label = gtk_label_new ("Font:");
9866       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9867       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9868
9869       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
9870
9871       button = gtk_button_new_with_label ("Some Text");
9872       gtk_widget_modify_font (gtk_bin_get_child (GTK_BIN (button)),
9873                               font_desc);
9874       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9875
9876       label = gtk_label_new ("Foreground:");
9877       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9878       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9879
9880       button = gtk_button_new_with_label ("Some Text");
9881       gtk_widget_modify_fg (gtk_bin_get_child (GTK_BIN (button)),
9882                             GTK_STATE_NORMAL, &red);
9883       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9884
9885       label = gtk_label_new ("Background:");
9886       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9887       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9888
9889       button = gtk_button_new_with_label ("Some Text");
9890       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
9891       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9892
9893       label = gtk_label_new ("Text:");
9894       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9895       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9896
9897       entry = gtk_entry_new ();
9898       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9899       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
9900       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9901
9902       label = gtk_label_new ("Base:");
9903       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9904       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9905
9906       entry = gtk_entry_new ();
9907       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9908       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
9909       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9910
9911       label = gtk_label_new ("Cursor:");
9912       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9913       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9914
9915       entry = gtk_entry_new ();
9916       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9917       gtk_widget_modify_cursor (entry, &red, &red);
9918       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9919
9920       label = gtk_label_new ("Multiple:");
9921       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9922       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9923
9924       button = gtk_button_new_with_label ("Some Text");
9925
9926       rc_style = gtk_rc_style_new ();
9927
9928       rc_style->font_desc = pango_font_description_copy (font_desc);
9929       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
9930       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
9931       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
9932       rc_style->fg[GTK_STATE_NORMAL] = yellow;
9933       rc_style->bg[GTK_STATE_NORMAL] = blue;
9934       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
9935       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
9936       rc_style->fg[GTK_STATE_ACTIVE] = red;
9937       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
9938       rc_style->xthickness = 5;
9939       rc_style->ythickness = 5;
9940
9941       gtk_widget_modify_style (button, rc_style);
9942       gtk_widget_modify_style (gtk_bin_get_child (GTK_BIN (button)), rc_style);
9943
9944       g_object_unref (rc_style);
9945       
9946       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9947     }
9948   
9949   if (!gtk_widget_get_visible (window))
9950     gtk_widget_show_all (window);
9951   else
9952     gtk_widget_destroy (window);
9953 }
9954
9955 /*
9956  * Main Window and Exit
9957  */
9958
9959 void
9960 do_exit (GtkWidget *widget, GtkWidget *window)
9961 {
9962   gtk_widget_destroy (window);
9963   gtk_main_quit ();
9964 }
9965
9966 struct {
9967   char *label;
9968   void (*func) (GtkWidget *widget);
9969   gboolean do_not_benchmark;
9970 } buttons[] =
9971 {
9972   { "alpha window", create_alpha_window },
9973   { "big windows", create_big_windows },
9974   { "button box", create_button_box },
9975   { "buttons", create_buttons },
9976   { "check buttons", create_check_buttons },
9977   { "color selection", create_color_selection },
9978   { "composited window", create_composited_window },
9979   { "cursors", create_cursors },
9980   { "dialog", create_dialog },
9981   { "display & screen", create_display_screen, TRUE },
9982   { "entry", create_entry },
9983   { "event box", create_event_box },
9984   { "event watcher", create_event_watcher },
9985   { "expander", create_expander },
9986   { "flipping", create_flipping },
9987   { "focus", create_focus },
9988   { "font selection", create_font_selection },
9989   { "gridded geometry", create_gridded_geometry },
9990   { "handle box", create_handle_box },
9991   { "image", create_image },
9992   { "key lookup", create_key_lookup },
9993   { "labels", create_labels },
9994   { "layout", create_layout },
9995   { "menus", create_menus },
9996   { "message dialog", create_message_dialog },
9997   { "modal window", create_modal_window, TRUE },
9998   { "notebook", create_notebook },
9999   { "panes", create_panes },
10000   { "paned keyboard", create_paned_keyboard_navigation },
10001   { "pixbuf", create_pixbuf },
10002   { "progress bar", create_progress_bar },
10003   { "properties", create_properties },
10004   { "radio buttons", create_radio_buttons },
10005   { "range controls", create_range_controls },
10006   { "rc file", create_rc_file },
10007   { "reparent", create_reparent },
10008   { "resize grips", create_resize_grips },
10009   { "rotated label", create_rotated_label },
10010   { "rotated text", create_rotated_text },
10011   { "rulers", create_rulers },
10012   { "saved position", create_saved_position },
10013   { "scrolled windows", create_scrolled_windows },
10014   { "shapes", create_shapes },
10015   { "size groups", create_size_groups },
10016   { "spinbutton", create_spins },
10017   { "statusbar", create_statusbar },
10018   { "styles", create_styles },
10019   { "test idle", create_idle_test },
10020   { "test mainloop", create_mainloop, TRUE },
10021   { "test scrolling", create_scroll_test },
10022   { "test selection", create_selection_test },
10023   { "test timeout", create_timeout_test },
10024   { "toggle buttons", create_toggle_buttons },
10025   { "toolbar", create_toolbar },
10026   { "tooltips", create_tooltips },
10027   { "WM hints", create_wmhints },
10028   { "window sizing", create_window_sizing },
10029   { "window states", create_window_states }
10030 };
10031 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
10032
10033 void
10034 create_main_window (void)
10035 {
10036   GtkWidget *window;
10037   GtkWidget *box1;
10038   GtkWidget *box2;
10039   GtkWidget *scrolled_window;
10040   GtkWidget *button;
10041   GtkWidget *label;
10042   gchar buffer[64];
10043   GtkWidget *separator;
10044   GdkGeometry geometry;
10045   int i;
10046
10047   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10048   gtk_widget_set_name (window, "main window");
10049   gtk_window_move (GTK_WINDOW (window), 50, 20);
10050   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
10051
10052   geometry.min_width = -1;
10053   geometry.min_height = -1;
10054   geometry.max_width = -1;
10055   geometry.max_height = G_MAXSHORT;
10056   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
10057                                  &geometry,
10058                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
10059
10060   g_signal_connect (window, "destroy",
10061                     G_CALLBACK (gtk_main_quit),
10062                     NULL);
10063   g_signal_connect (window, "delete-event",
10064                     G_CALLBACK (gtk_false),
10065                     NULL);
10066
10067   box1 = gtk_vbox_new (FALSE, 0);
10068   gtk_container_add (GTK_CONTAINER (window), box1);
10069
10070   if (gtk_micro_version > 0)
10071     sprintf (buffer,
10072              "Gtk+ v%d.%d.%d",
10073              gtk_get_major_version (),
10074              gtk_get_minor_version (),
10075              gtk_get_micro_version ());
10076   else
10077     sprintf (buffer,
10078              "Gtk+ v%d.%d",
10079              gtk_get_major_version (),
10080              gtk_get_minor_version ());
10081
10082   label = gtk_label_new (buffer);
10083   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
10084   gtk_widget_set_name (label, "testgtk-version-label");
10085
10086   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
10087   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
10088   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
10089                                   GTK_POLICY_NEVER, 
10090                                   GTK_POLICY_AUTOMATIC);
10091   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
10092
10093   box2 = gtk_vbox_new (FALSE, 0);
10094   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10095   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
10096   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
10097                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
10098   gtk_widget_show (box2);
10099
10100   for (i = 0; i < nbuttons; i++)
10101     {
10102       button = gtk_button_new_with_label (buttons[i].label);
10103       if (buttons[i].func)
10104         g_signal_connect (button, 
10105                           "clicked", 
10106                           G_CALLBACK(buttons[i].func),
10107                           NULL);
10108       else
10109         gtk_widget_set_sensitive (button, FALSE);
10110       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10111     }
10112
10113   separator = gtk_hseparator_new ();
10114   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
10115
10116   box2 = gtk_vbox_new (FALSE, 10);
10117   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10118   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
10119
10120   button = gtk_button_new_with_mnemonic ("_Close");
10121   g_signal_connect (button, "clicked",
10122                     G_CALLBACK (do_exit),
10123                     window);
10124   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10125   gtk_widget_set_can_default (button, TRUE);
10126   gtk_widget_grab_default (button);
10127
10128   gtk_widget_show_all (window);
10129 }
10130
10131 static void
10132 test_init (void)
10133 {
10134   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
10135                    G_FILE_TEST_EXISTS))
10136     {
10137       g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/loaders.cache", TRUE);
10138       g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
10139     }
10140 }
10141
10142 static char *
10143 pad (const char *str, int to)
10144 {
10145   static char buf[256];
10146   int len = strlen (str);
10147   int i;
10148
10149   for (i = 0; i < to; i++)
10150     buf[i] = ' ';
10151
10152   buf[to] = '\0';
10153
10154   memcpy (buf, str, len);
10155
10156   return buf;
10157 }
10158
10159 static void
10160 bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
10161 {
10162   fn (widget); /* on */
10163   while (g_main_context_iteration (NULL, FALSE));
10164   fn (widget); /* off */
10165   while (g_main_context_iteration (NULL, FALSE));
10166 }
10167
10168 void
10169 do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), char *name, int num)
10170 {
10171   GTimeVal tv0, tv1;
10172   double dt_first;
10173   double dt;
10174   int n;
10175   static gboolean printed_headers = FALSE;
10176
10177   if (!printed_headers) {
10178     g_print ("Test                 Iters      First      Other\n");
10179     g_print ("-------------------- ----- ---------- ----------\n");
10180     printed_headers = TRUE;
10181   }
10182
10183   g_get_current_time (&tv0);
10184   bench_iteration (widget, fn); 
10185   g_get_current_time (&tv1);
10186
10187   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
10188         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
10189
10190   g_get_current_time (&tv0);
10191   for (n = 0; n < num - 1; n++)
10192     bench_iteration (widget, fn); 
10193   g_get_current_time (&tv1);
10194   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
10195         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
10196
10197   g_print ("%s %5d ", pad (name, 20), num);
10198   if (num > 1)
10199     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
10200   else
10201     g_print ("%10.1f\n", dt_first);
10202 }
10203
10204 void
10205 do_bench (char* what, int num)
10206 {
10207   int i;
10208   GtkWidget *widget;
10209   void (* fn) (GtkWidget *widget);
10210   fn = NULL;
10211   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10212
10213   if (g_ascii_strcasecmp (what, "ALL") == 0)
10214     {
10215       for (i = 0; i < nbuttons; i++)
10216         {
10217           if (!buttons[i].do_not_benchmark)
10218             do_real_bench (widget, buttons[i].func, buttons[i].label, num);
10219         }
10220
10221       return;
10222     }
10223   else
10224     {
10225       for (i = 0; i < nbuttons; i++)
10226         {
10227           if (strcmp (buttons[i].label, what) == 0)
10228             {
10229               fn = buttons[i].func;
10230               break;
10231             }
10232         }
10233       
10234       if (!fn)
10235         g_print ("Can't bench: \"%s\" not found.\n", what);
10236       else
10237         do_real_bench (widget, fn, buttons[i].label, num);
10238     }
10239 }
10240
10241 void 
10242 usage (void)
10243 {
10244   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
10245   exit (1);
10246 }
10247
10248 int
10249 main (int argc, char *argv[])
10250 {
10251   GtkBindingSet *binding_set;
10252   int i;
10253   gboolean done_benchmarks = FALSE;
10254
10255   srand (time (NULL));
10256
10257   test_init ();
10258
10259   /* Check to see if we are being run from the correct
10260    * directory.
10261    */
10262   if (file_exists ("testgtkrc"))
10263     gtk_rc_add_default_file ("testgtkrc");
10264   else if (file_exists ("tests/testgtkrc"))
10265     gtk_rc_add_default_file ("tests/testgtkrc");
10266   else
10267     g_warning ("Couldn't find file \"testgtkrc\".");
10268
10269   g_set_application_name ("GTK+ Test Program");
10270
10271   gtk_init (&argc, &argv);
10272
10273   gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
10274                                         GDK_CONTROL_MASK |
10275                                         GDK_MOD1_MASK | 
10276                                         GDK_META_MASK |
10277                                         GDK_SUPER_MASK |
10278                                         GDK_HYPER_MASK |
10279                                         GDK_MOD4_MASK);
10280   /*  benchmarking
10281    */
10282   for (i = 1; i < argc; i++)
10283     {
10284       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
10285         {
10286           int num = 1;
10287           char *nextarg;
10288           char *what;
10289           char *count;
10290           
10291           nextarg = strchr (argv[i], '=');
10292           if (nextarg)
10293             nextarg++;
10294           else
10295             {
10296               i++;
10297               if (i == argc)
10298                 usage ();
10299               nextarg = argv[i];
10300             }
10301
10302           count = strchr (nextarg, ':');
10303           if (count)
10304             {
10305               what = g_strndup (nextarg, count - nextarg);
10306               count++;
10307               num = atoi (count);
10308               if (num <= 0)
10309                 usage ();
10310             }
10311           else
10312             what = g_strdup (nextarg);
10313
10314           do_bench (what, num ? num : 1);
10315           done_benchmarks = TRUE;
10316         }
10317       else
10318         usage ();
10319     }
10320   if (done_benchmarks)
10321     return 0;
10322
10323   /* bindings test
10324    */
10325   binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_WIDGET));
10326   gtk_binding_entry_add_signal (binding_set,
10327                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
10328                                 "debug_msg",
10329                                 1,
10330                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
10331   
10332   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
10333    * changes
10334    */
10335
10336   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
10337                        "   fg[NORMAL] = \"#ff0000\"\n"
10338                        "   font = \"Sans 18\"\n"
10339                        "}\n"
10340                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
10341   
10342   create_main_window ();
10343
10344   gtk_main ();
10345
10346   if (1)
10347     {
10348       while (g_main_context_pending (NULL))
10349         g_main_context_iteration (NULL, FALSE);
10350 #if 0
10351       sleep (1);
10352       while (g_main_context_pending (NULL))
10353         g_main_context_iteration (NULL, FALSE);
10354 #endif
10355     }
10356   return 0;
10357 }