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